Authentifizéieren a Kubernetes mat GitHub OAuth an Dex

Ech presentéieren Iech en Tutorial fir Zougang zu engem Kubernetes Cluster ze generéieren mat Dex, dex-k8s-authenticator a GitHub.

Authentifizéieren a Kubernetes mat GitHub OAuth an Dex
Lokal meme aus dem russeschsproochege Kubernetes chatten an Hëllefe profitéieren

Aféierung

Mir benotzen Kubernetes fir dynamesch Ëmfeld fir d'Entwécklung an d'QA Team ze kreéieren. Also mir wëllen hinnen Zougang zum Stärekoup fir béid Dashboard an kubectl ginn. Am Géigesaz zu OpenShift huet Vanilla Kubernetes keng gebierteg Authentifikatioun, also benotze mir Drëtt Partei Tools fir dëst.

An dëser Konfiguratioun benotze mir:

  • dex-k8s-authentifizéierer  - Webapplikatioun fir kubectl Config ze generéieren
  • Dex - OpenID Connect Provider
  • GitHub - einfach well mir GitHub an eiser Firma benotzen

Mir hu probéiert Google OIDC ze benotzen, awer leider ausgefall fir se mat Gruppen unzefänken, sou datt d'Integratioun mat GitHub eis ganz gutt passt. Ouni Gruppemapping wäert et net méiglech sinn RBAC-Politik op Basis vu Gruppen ze kreéieren.

Also, wéi funktionnéiert eise Kubernetes Autorisatiounsprozess an enger visueller Representatioun:

Authentifizéieren a Kubernetes mat GitHub OAuth an Dex
Autorisatioun Prozess

E bësse méi Detail a Punkt fir Punkt:

  1. De Benotzer loggt sech an dex-k8s-authenticator (login.k8s.example.com)
  2. dex-k8s-authenticator schéckt d'Ufro un Dex (dex.k8s.example.com)
  3. Dex redirects op d'GitHub Login Säit
  4. GitHub generéiert déi néideg Autorisatiounsinformatioun a gitt se an Dex zréck
  5. Dex passéiert déi kritt Informatioun un dex-k8s-authenticator
  6. De Benotzer kritt en OIDC Token vu GitHub
  7. dex-k8s-authenticator füügt Token un kubeconfig
  8. kubectl passt den Token un de KubeAPIServer
  9. KubeAPIServer gëtt Zougang zu kubectl op Basis vum passéierten Token zréck
  10. De Benotzer kritt Zougang vu kubectl

Virbereedungsaktivitéiten

Natierlech hu mir schonn e Kubernetes Cluster installéiert (k8s.example.com), a kënnt och mat HELM virinstalléiert. Mir hunn och eng Organisatioun op GitHub (super-org).
Wann Dir kee HELM hutt, installéiere se ganz einfach.

Als éischt musse mir GitHub opsetzen.

Gitt op d'Organisatioun Astellungssäit, (https://github.com/organizations/super-org/settings/applications) a erstellt eng nei Applikatioun (Autoriséiert OAuth App):
Authentifizéieren a Kubernetes mat GitHub OAuth an Dex
Erstellt eng nei Applikatioun op GitHub

Fëllt d'Felder mat den néidegen URLen aus, zum Beispill:

  • Homepage URL: https://dex.k8s.example.com
  • Autorisatioun Callback URL: https://dex.k8s.example.com/callback

Sidd virsiichteg mat Linken, et ass wichteg keng Schnëtt ze verléieren.

Als Äntwert op eng ausgefëllte Form generéiert GitHub Client ID и Client secret, halen se op enger sécherer Plaz, si wäerte fir eis nëtzlech sinn (zum Beispill, mir benotzen Vault fir Geheimnisser ze späicheren):

Client ID: 1ab2c3d4e5f6g7h8
Client secret: 98z76y54x32w1

Preparéieren DNS records fir Subdomains login.k8s.example.com и dex.k8s.example.com, souwéi SSL Certificaten fir Ingress.

Loosst eis SSL Certificaten erstellen:

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

ClusterIssuer mam Titel le-clusterissuer sollt scho existéieren, awer wann net, erstellt et mat 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

KubeAPIServer Konfiguratioun

Fir kubeAPIServer ze schaffen, musst Dir OIDC konfiguréieren an de Cluster aktualiséieren:

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

Mir benotzen kops fir Cluster z'installéieren, awer dëst funktionnéiert ähnlech fir aner Cluster Manager.

Dex Konfiguratioun an dex-k8s-authentifizéierer

Fir Dex ze schaffen, musst Dir e Certificat an e Schlëssel vum Kubernetes Master hunn, loosst eis et vun do kréien:

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

Loosst eis den dex-k8s-Authenticator Repository klone:

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

Mat Wäerterdateien kënne mir flexibel Variablen fir eis konfiguréieren HELM Charts.

Loosst eis d'Konfiguratioun fir Dex beschreiwen:

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

A fir dex-k8s-authentifizéierer:

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

Installéiert Dex an 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

Loosst eis d'Funktionalitéit vun de Servicer kontrolléieren (Dex soll de Code 400 zréckginn, an dex-k8s-Authenticator sollt de Code 200 zréckginn):

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

RBAC Configuratioun

Mir kreéieren eng ClusterRole fir de Grupp, an eisem Fall mat nëmmen-liesen Zougang:

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

Loosst eis eng Konfiguratioun fir ClusterRoleBinding erstellen:

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

Elo si mir prett fir ze testen.

Tester

Gitt op d'Login Säit (https://login.k8s.example.com) a loggt Iech mat Ärem GitHub Kont un:

Authentifizéieren a Kubernetes mat GitHub OAuth an Dex
Login Säit

Authentifizéieren a Kubernetes mat GitHub OAuth an Dex
Login Säit op GitHub ëmgeleet

Authentifizéieren a Kubernetes mat GitHub OAuth an Dex
 Follegt déi generéiert Instruktioune fir Zougang ze kréien

Nom Kopie-paste vun der Websäit kënne mir kubectl benotzen fir eis Clusterressourcen ze managen:

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"

An et funktionnéiert, all GitHub Benotzer an eiser Organisatioun kënne Ressourcen gesinn an a Pods aloggen, awer si hunn keng Rechter fir se z'änneren.

Source: will.com

Setzt e Commentaire