Authentifizierung in Kubernetes mit GitHub OAuth und Dex

Ich präsentiere Ihnen das Tutorial zum Generieren des Zugriffs auf den Kubernetes-Cluster mit Dex, dex-k8s-authenticator und GitHub.

Bild

Lokales Mem aus dem russischsprachigen Chat Kubernetes on Telegram

Einführung


Wir verwenden Kubernetes, um dynamische Umgebungen für das Entwicklungsteam und die Qualitätssicherung zu erstellen. Daher möchten wir ihnen Zugriff auf den Cluster sowohl für Dashboards als auch für kubectl gewähren. Im Gegensatz zu OpenShift verfügt Vanilla Kubernetes nicht über eine native Authentifizierung. Daher verwenden wir hierfür Tools von Drittanbietern.

In dieser Konfiguration verwenden wir:

  • dex-k8s-authentulator - Webanwendung zum Generieren der kubectl-Konfiguration
  • Dex - OpenID Connect Provider
  • GitHub - einfach weil wir GitHub in unserem Unternehmen verwenden

Wir haben versucht, Google OIDC zu verwenden, konnten sie jedoch leider nicht in Gruppen einteilen. Daher war die Integration in GitHub für uns in Ordnung. Ohne Gruppenzuordnung können Sie keine gruppenbasierten RBAC-Richtlinien erstellen.

Wie funktioniert unser Autorisierungsprozess in Kubernetes in einer visuellen Darstellung:

Bild
Autorisierungsprozess

Ein bisschen mehr Details und Punkte:

  1. Benutzer meldet sich bei dex-k8s- login.k8s.example.com ( login.k8s.example.com )
  2. dex-k8s-authentifikator leitet die Anfrage an Dex weiter ( dex.k8s.example.com )
  3. Dex leitet zur GitHub-Anmeldeseite weiter
  4. GitHub generiert die erforderlichen Autorisierungsinformationen und gibt sie an Dex zurück
  5. Dex übergibt die empfangenen Informationen an den Dex-k8s-Authentifikator
  6. Der Benutzer erhält das OIDC-Token von GitHub
  7. dex-k8s-authentulator fügt kubeconfig ein Token hinzu
  8. kubectl übergibt das Token an KubeAPIServer
  9. KubeAPIServer, der auf dem übertragenen Token basiert, gibt Zugriffe in kubectl zurück
  10. Benutzer erhält Zugriff von kubectl

Vorbereitende Aktivitäten


Natürlich haben wir bereits einen Kubernetes-Cluster ( k8s.example.com ) sowie HELM installiert. Wir haben auch eine Organisation auf GitHub (Super-Org).
Wenn Sie nicht über HELM verfügen, ist die Installation sehr einfach .

Zuerst müssen wir GitHub konfigurieren.

Gehen Sie zur Einstellungsseite der Organisation ( https://github.com/organizations/super-org/settings/applications ) und erstellen Sie eine neue Anwendung (Authorized OAuth App):
Bild
Erstellen einer neuen Anwendung auf GitHub

Füllen Sie die Felder mit den erforderlichen URLs aus, zum Beispiel:

  • Homepage-URL: https://dex.k8s.example.com
  • Rückruf-URL für die Autorisierung: https://dex.k8s.example.com/callback

Seien Sie vorsichtig mit Links, es ist wichtig, keine Schrägstriche zu verlieren.

Als Antwort auf das ausgefüllte Formular generiert GitHub eine Client ID und ein Client secret , speichert sie an einem sicheren Ort und sie sind für uns nützlich (zum Beispiel verwenden wir Vault zum Speichern von Geheimnissen):

 Client ID: 1ab2c3d4e5f6g7h8 Client secret: 98z76y54x32w1 

login.k8s.example.com Sie DNS-Einträge für die Subdomains login.k8s.example.com und dex.k8s.example.com sowie SSL-Zertifikate für Eingriffe vor.

Erstellen Sie SSL-Zertifikate:

 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 

Ein ClusterIssuer mit dem Namen le-clusterissuer sollte bereits vorhanden sein. Wenn nicht, erstellen Sie ihn mit 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: k8s-admin@example.com privateKeySecretRef: name: le-clusterissuer http01: {} EOF 

KubeAPIServer-Konfiguration


Damit kubeAPIServer funktioniert, müssen Sie OIDC konfigurieren und den Cluster aktualisieren:

 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 

Wir verwenden Kops , um Cluster bereitzustellen , aber dies funktioniert auch für andere Cluster-Manager .

Dex- und Dex-k8s-Authentifikator-Konfiguration


Damit Dex funktioniert, müssen Sie über ein Zertifikat und einen Schlüssel des Kubernetes-Masters verfügen, die Sie von dort abrufen können:

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

Klonen Sie das Dex-k8s-Authentifikator-Repository:

 git clone git@github.com:mintel/dex-k8s-authenticator.git cd dex-k8s-authenticator/ 

Mit Wertedateien können wir flexibel Variablen für unsere HELM-Diagramme festlegen.

Beschreiben wir die Konfiguration für 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 

Und für dex-k8s-Authentifikator:
 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 

Installieren Sie Dex und 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 

Lassen Sie uns die Wartungsfreundlichkeit der Dienste überprüfen (Dex sollte den Code 400 und dex-k8s-Authenticator - den Code 200 zurückgeben):

 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-Konfiguration


Wir erstellen ClusterRole für die Gruppe, in unserem Fall mit schreibgeschützten Zugriffen:

 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 

Erstellen Sie eine Konfiguration für 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 

Jetzt sind wir bereit zum Testen.

Tests


Wir gehen zur Anmeldeseite ( https://login.k8s.example.com ) und melden uns mit dem GitHub-Konto an:

Bild
Anmeldeseite

Bild
Anmeldeseite zu GitHub umgeleitet

Bild
Befolgen Sie die generierten Anweisungen für den Zugriff

Nach dem Kopieren und Einfügen von der Webseite können wir kubectl verwenden, um die Ressourcen unseres Clusters zu verwalten:

 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 "amet@example.com" cannot delete pods in the namespace "default" 

Und es funktioniert, alle GitHub-Benutzer in unserer Organisation können Ressourcen sehen und Pods eingeben, aber sie haben nicht das Recht, sie zu ändern.

Source: https://habr.com/ru/post/de436238/


All Articles