Ich präsentiere Ihnen ein Tutorial zur Generierung von Zugängen zu einem Kubernetes-Cluster mit Dex, dex-k8s-authenticator und GitHub.

Ein lokales Meme aus dem russischsprachigen Kubernetes-Chat in
Einführung
Wir nutzen Kubernetes, um dynamische Umgebungen für unser Entwickler- und QA-Team zu schaffen. Daher möchten wir ihnen sowohl für das Dashboard als auch für kubectl Zugang zum Cluster gewähren. Im Gegensatz zu OpenShift verfügt Vanilla Kubernetes nicht über eine native Authentifizierung, weshalb wir Drittanbieter-Tools einsetzen.
In dieser Konfiguration verwenden wir:
- — eine Webanwendung zur Erstellung der kubectl-Konfiguration
- — ein OpenID Connect-Anbieter
- GitHub — einfach, weil wir GitHub in unserem Unternehmen verwenden
Wir haben versucht, Google OIDC zu verwenden, aber leider sie mit Gruppen einzurichten, daher war die Integration mit GitHub für uns völlig ausreichend. Ohne Gruppenzuordnungen können keine RBAC-Richtlinien basierend auf Gruppen erstellt werden.
Wie funktioniert also unser Authentifizierungsprozess in Kubernetes visuell dargestellt:

Der Autorisierungsprozess
Ein wenig mehr Details und Punkt für Punkt:
- Der Benutzer meldet sich beim dex-k8s-authenticator an (
login.k8s.example.com) - Der dex-k8s-authenticator leitet die Anfrage an Dex weiter (
dex.k8s.example.com) - Dex leitet zur Anmeldeseite in GitHub weiter
- GitHub generiert die erforderlichen Anmeldeinformationen und gibt sie an Dex zurück
- Dex überträgt die erhaltenen Informationen an den dex-k8s-authenticator
- Der Benutzer erhält ein OIDC-Token von GitHub
- dex-k8s-authenticator fügt das Token zur kubeconfig hinzu
- kubectl überträgt das Token an den KubeAPIServer
- Der KubeAPIServer gibt basierend auf dem übermittelten Token Zugriffsrechte an kubectl zurück
- Der Benutzer erhält die Zugriffsrechte von kubectl
Vorbereitende Schritte
Natürlich haben wir bereits ein Kubernetes-Cluster eingerichtet (k8s.example.com), und auch HELM ist bereits installiert. Außerdem haben wir eine Organisation in GitHub (super-org).
Falls Sie HELM nicht haben, ist die Installation ganz 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):

Erstellen einer neuen Anwendung in GitHub
Füllen Sie die erforderlichen Felder mit den entsprechenden URLs aus, zum Beispiel:
- Homepage-URL:
https://dex.k8s.example.com - Authorization Callback URL:
https://dex.k8s.example.com/callback
Achten Sie auf die Links, wichtig ist, dass die Slashes nicht verloren gehen.
Als Antwort auf das ausgefüllte Formular generiert GitHub Client-Geheimnis und Client Secret, bewahren Sie diese an einem sicheren Ort auf, wir werden sie benötigen (wir verwenden beispielsweise zum Speichern von Geheimnissen):
Client ID: 1ab2c3d4e5f6g7h8
Client secret: 98z76y54x32w1 Bereiten Sie die DNS-Einträge für Subdomains vor login.k8s.example.com und dex.k8s.example.com, sowie SSL-Zertifikate für Ingresses.
Lassen Sie uns SSL-Zertifikate 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 mit dem Namen le-clusterissuer muss bereits existieren, falls nicht, lassen Sie uns ihn mit HELM erstellen:
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: {}
EOFKubeAPIServer-Konfiguration
Um den kubeAPIServer zu betreiben, müssen OIDC konfiguriert und das Cluster aktualisiert werden:
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 --yesWir nutzen um Cluster bereitzustellen, aber es funktioniert ähnlich auch für .
Konfiguration von Dex und dex-k8s-authenticator
Um Dex zu betreiben, benötigen wir ein Zertifikat und einen Schlüssel vom Kubernetes-Master. Lassen Sie uns diese dort abrufen:
sudo cat /srv/kubernetes/ca.{crt,key}
-----BEGIN CERTIFICATE-----
AAAAAAAAAAABBBBBBBBBBCCCCCC
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
DDDDDDDDDDDEEEEEEEEEEFFFFFF
-----END RSA PRIVATE KEY-----Wir klonen das Repository dex-k8s-authenticator:
git clone git@github.com:mintel/dex-k8s-authenticator.git
cd dex-k8s-authenticator/Mit Hilfe von Values-Dateien können wir die Variablen für unsere .
Lassen Sie uns die Konfiguration für Dex beschreiben:
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-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
EOFWir installieren 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Überprüfen wir die Funktionalität der Dienste (Dex sollte Code 400 zurückgeben, während dex-k8s-authenticator Code 200 zurückgibt):
curl -sI https://dex.k8s.example.com/callback | head -1
HTTP/2 400
curl -sI https://login.k8s.example.com/ | head -1
HTTP/2 200RBAC-Konfiguration
Wir erstellen eine ClusterRole für die Gruppe, in unserem Fall mit read-only Zugängen:
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"]
EOFErstellen wir die 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"
EOFJetzt sind wir bereit für den Test.
Tests
Gehen Sie zur Anmeldeseite (https://login.k8s.example.com) und melden Sie sich mit Ihrem GitHub-Konto an:

Anmeldeseite

Anmeldeseite umgeleitet zu GitHub

Befolgen Sie die generierte Anleitung, um Zugriff zu erhalten.
Nach dem Kopieren von der Webseite können wir kubectl nutzen, 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
Fehler vom Server (Verboten): Pods "mypod" ist verboten: Benutzer "amet@example.com" kann Pods im Namespace "default" nicht löschen. Und es funktioniert, alle GitHub-Nutzer in unserer Organisation können die Ressourcen sehen und auf die Pods zugreifen, haben jedoch keine Berechtigung, diese zu ändern.
Quelle: habr.com
