Autenticació de Kubernetes amb GitHub OAuth i Dex

Us presento un tutorial per generar accés a un clúster de Kubernetes mitjançant Dex, dex-k8s-authenticator i GitHub.

Autenticació de Kubernetes amb GitHub OAuth i Dex
Meme local del xat de Kubernetes en rus telegram

Introducció

Utilitzem Kubernetes per crear entorns dinàmics per a l'equip de desenvolupament i control de qualitat. Per tant, volem donar-los accés al clúster tant per al tauler com per a kubectl. A diferència d'OpenShift, vanilla Kubernetes no té autenticació nativa, de manera que utilitzem eines de tercers per a això.

En aquesta configuració fem servir:

  • dex-k8s-authenticator  — aplicació web per generar kubectl config
  • dex — Proveïdor d'OpenID Connect
  • GitHub: simplement perquè utilitzem GitHub a la nostra empresa

Hem intentat utilitzar Google OIDC, però malauradament va fallar començar-los amb grups, així que la integració amb GitHub ens va anar força bé. Sense mapes de grups, no serà possible crear polítiques RBAC basades en grups.

Aleshores, com funciona el nostre procés d'autorització de Kubernetes en una representació visual:

Autenticació de Kubernetes amb GitHub OAuth i Dex
Procés d'autorització

Una mica més de detall i punt per punt:

  1. L'usuari inicia sessió a dex-k8s-authenticator (login.k8s.example.com)
  2. dex-k8s-authenticator reenvia la sol·licitud a Dex (dex.k8s.example.com)
  3. Dex redirigeix ​​a la pàgina d'inici de sessió de GitHub
  4. GitHub genera la informació d'autorització necessària i la torna a Dex
  5. Dex passa la informació rebuda a dex-k8s-authenticator
  6. L'usuari rep un testimoni OIDC de GitHub
  7. dex-k8s-authenticator afegeix un testimoni a kubeconfig
  8. kubectl passa el testimoni a KubeAPIServer
  9. KubeAPIServer retorna els accessos a kubectl en funció del testimoni passat
  10. L'usuari té accés des de kubectl

Accions preparatòries

Per descomptat, ja tenim instal·lat un clúster de Kubernetes (k8s.example.com), i també ve amb HELM preinstal·lat. També tenim una organització a GitHub (super-org).
Si no teniu HELM, instal·leu-lo molt simple.

Primer hem de configurar GitHub.

Aneu a la pàgina de configuració de l'organització, (https://github.com/organizations/super-org/settings/applications) i creeu una aplicació nova (aplicació OAuth autoritzada):
Autenticació de Kubernetes amb GitHub OAuth i Dex
Creació d'una nova aplicació a GitHub

Ompliu els camps amb els URL necessaris, per exemple:

  • URL de la pàgina d'inici: https://dex.k8s.example.com
  • URL de devolució de trucada d'autorització: https://dex.k8s.example.com/callback

Aneu amb compte amb els enllaços, és important no perdre barres.

En resposta a un formulari emplenat, es generarà GitHub Client ID и Client secret, guarda-los en un lloc segur, ens seran útils (per exemple, fem servir Volta per emmagatzemar secrets):

Client ID: 1ab2c3d4e5f6g7h8
Client secret: 98z76y54x32w1

Prepareu registres DNS per a subdominis login.k8s.example.com и dex.k8s.example.com, així com certificats SSL per a l'entrada.

Creem certificats SSL:

cat <<EOF | kubectl create -f -
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: cert-auth-dex
  namespace: kube-system
spec:
  secretName: cert-auth-dex
  dnsNames:
    - dex.k8s.example.com
  acme:
    config:
    - http01:
        ingressClass: nginx
      domains:
      - dex.k8s.example.com
  issuerRef:
    name: le-clusterissuer
    kind: ClusterIssuer
---
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: cert-auth-login
  namespace: kube-system
spec:
  secretName: cert-auth-login
  dnsNames:
    - login.k8s.example.com
  acme:
    config:
    - http01:
        ingressClass: nginx
      domains:
      - login.k8s.example.com
  issuerRef:
    name: le-clusterissuer
    kind: ClusterIssuer
EOF
kubectl describe certificates cert-auth-dex -n kube-system
kubectl describe certificates cert-auth-login -n kube-system

ClústerIssuer amb títol le-clusterissuer ja hauria d'existir, però si no, creeu-lo amb HELM:

helm install --namespace kube-system -n cert-manager stable/cert-manager
cat << EOF | kubectl create -f -
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: le-clusterissuer
  namespace: kube-system
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: le-clusterissuer
    http01: {}
EOF

Configuració de KubeAPIServer

Perquè kubeAPIServer funcioni, heu de configurar OIDC i actualitzar el clúster:

kops edit cluster
...
  kubeAPIServer:
    anonymousAuth: false
    authorizationMode: RBAC
    oidcClientID: dex-k8s-authenticator
    oidcGroupsClaim: groups
    oidcIssuerURL: https://dex.k8s.example.com/
    oidcUsernameClaim: email
kops update cluster --yes
kops rolling-update cluster --yes

Fem servir kops per desplegar clústers, però això funciona de manera similar altres gestors de clústers.

Configuració Dex i autenticador dex-k8s

Perquè Dex funcioni, cal tenir un certificat i una clau del mestre de Kubernetes, anem a obtenir-lo a partir d'aquí:

sudo cat /srv/kubernetes/ca.{crt,key}
-----BEGIN CERTIFICATE-----
AAAAAAAAAAABBBBBBBBBBCCCCCC
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
DDDDDDDDDDDEEEEEEEEEEFFFFFF
-----END RSA PRIVATE KEY-----

Clonem el dipòsit dex-k8s-authenticator:

git clone [email protected]:mintel/dex-k8s-authenticator.git
cd dex-k8s-authenticator/

Utilitzant fitxers de valors, podem configurar variables de manera flexible per al nostre Gràfiques HELM.

Descrivim la configuració de Dex:

cat << EOF > values-dex.yml
global:
  deployEnv: prod
tls:
  certificate: |-
    -----BEGIN CERTIFICATE-----
    AAAAAAAAAAABBBBBBBBBBCCCCCC
    -----END CERTIFICATE-----
  key: |-
    -----BEGIN RSA PRIVATE KEY-----
    DDDDDDDDDDDEEEEEEEEEEFFFFFF
    -----END RSA PRIVATE KEY-----
ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme: "true"
  path: /
  hosts:
    - dex.k8s.example.com
  tls:
    - secretName: cert-auth-dex
      hosts:
        - dex.k8s.example.com
serviceAccount:
  create: true
  name: dex-auth-sa
config: |
  issuer: https://dex.k8s.example.com/
  storage: # https://github.com/dexidp/dex/issues/798
    type: sqlite3
    config:
      file: /var/dex.db
  web:
    http: 0.0.0.0:5556
  frontend:
    theme: "coreos"
    issuer: "Example Co"
    issuerUrl: "https://example.com"
    logoUrl: https://example.com/images/logo-250x25.png
  expiry:
    signingKeys: "6h"
    idTokens: "24h"
  logger:
    level: debug
    format: json
  oauth2:
    responseTypes: ["code", "token", "id_token"]
    skipApprovalScreen: true
  connectors:
  - type: github
    id: github
    name: GitHub
    config:
      clientID: $GITHUB_CLIENT_ID
      clientSecret: $GITHUB_CLIENT_SECRET
      redirectURI: https://dex.k8s.example.com/callback
      orgs:
      - name: super-org
        teams:
        - team-red
  staticClients:
  - id: dex-k8s-authenticator
    name: dex-k8s-authenticator
    secret: generatedLongRandomPhrase
    redirectURIs:
      - https://login.k8s.example.com/callback/
envSecrets:
  GITHUB_CLIENT_ID: "1ab2c3d4e5f6g7h8"
  GITHUB_CLIENT_SECRET: "98z76y54x32w1"
EOF

I per a dex-k8s-authenticator:

cat << EOF > values-auth.yml
global:
  deployEnv: prod
dexK8sAuthenticator:
  clusters:
  - name: k8s.example.com
    short_description: "k8s cluster"
    description: "Kubernetes cluster"
    issuer: https://dex.k8s.example.com/
    k8s_master_uri: https://api.k8s.example.com
    client_id: dex-k8s-authenticator
    client_secret: generatedLongRandomPhrase
    redirect_uri: https://login.k8s.example.com/callback/
    k8s_ca_pem: |
      -----BEGIN CERTIFICATE-----
      AAAAAAAAAAABBBBBBBBBBCCCCCC
      -----END CERTIFICATE-----
ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme: "true"
  path: /
  hosts:
    - login.k8s.example.com
  tls:
    - secretName: cert-auth-login
      hosts:
        - login.k8s.example.com
EOF

Instal·leu Dex i dex-k8s-authenticator:

helm install -n dex --namespace kube-system --values values-dex.yml charts/dex
helm install -n dex-auth --namespace kube-system --values values-auth.yml charts/dex-k8s-authenticator

Comprovem la funcionalitat dels serveis (Dex hauria de tornar el codi 400 i dex-k8s-authenticator hauria de tornar el codi 200):

curl -sI https://dex.k8s.example.com/callback | head -1
HTTP/2 400
curl -sI https://login.k8s.example.com/ | head -1
HTTP/2 200

Configuració RBAC

Creem un ClusterRole per al grup, en el nostre cas amb accés de només lectura:

cat << EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-read-all
rules:
  -
    apiGroups:
      - ""
      - apps
      - autoscaling
      - batch
      - extensions
      - policy
      - rbac.authorization.k8s.io
      - storage.k8s.io
    resources:
      - componentstatuses
      - configmaps
      - cronjobs
      - daemonsets
      - deployments
      - events
      - endpoints
      - horizontalpodautoscalers
      - ingress
      - ingresses
      - jobs
      - limitranges
      - namespaces
      - nodes
      - pods
      - pods/log
      - pods/exec
      - persistentvolumes
      - persistentvolumeclaims
      - resourcequotas
      - replicasets
      - replicationcontrollers
      - serviceaccounts
      - services
      - statefulsets
      - storageclasses
      - clusterroles
      - roles
    verbs:
      - get
      - watch
      - list
  - nonResourceURLs: ["*"]
    verbs:
      - get
      - watch
      - list
  - apiGroups: [""]
    resources: ["pods/exec"]
    verbs: ["create"]
EOF

Creem una configuració per a ClusterRoleBinding:

cat <<EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: dex-cluster-auth
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-read-all
subjects:
  kind: Group
  name: "super-org:team-red"
EOF

Ara estem preparats per a la prova.

Proves

Aneu a la pàgina d'inici de sessió (https://login.k8s.example.com) i inicieu la sessió amb el vostre compte de GitHub:

Autenticació de Kubernetes amb GitHub OAuth i Dex
Pàgina d'inici de sessió

Autenticació de Kubernetes amb GitHub OAuth i Dex
Pàgina d'inici de sessió redirigida a GitHub

Autenticació de Kubernetes amb GitHub OAuth i Dex
 Seguiu les instruccions generades per accedir-hi

Després de copiar i enganxar des de la pàgina web, podem utilitzar kubectl per gestionar els recursos del nostre clúster:

kubectl get po
NAME                READY   STATUS    RESTARTS   AGE
mypod               1/1     Running   0          3d

kubectl delete po mypod
Error from server (Forbidden): pods "mypod" is forbidden: User "[email protected]" cannot delete pods in the namespace "default"

I funciona, tots els usuaris de GitHub de la nostra organització poden veure recursos i iniciar sessió als pods, però no tenen drets per canviar-los.

Font: www.habr.com

Afegeix comentari