Ich präsentiere Ihnen ein Tutorial zur Generierung von Zugriffsrechten für den Kubernetes-Cluster mit Dex, dex-k8s-authenticator und GitHub.

Ein lokales Meme aus dem russischsprachigen Kubernetes-Chat in
Einführung
Wir verwenden Kubernetes, um dynamische Umgebungen für unsere Entwickler- und QA-Teams zu schaffen. Daher möchten wir ihnen sowohl für das Dashboard als auch für kubectl Zugriff auf den Cluster gewähren. Im Gegensatz zu OpenShift bietet reines Kubernetes keine native Authentifizierung, weshalb wir auf Drittanbieter-Tools zurückgreifen.
In dieser Konfiguration verwenden wir:
- — eine Webanwendung zur Generierung der kubectl-Konfiguration
- — OpenID Connect-Anbieter
- GitHub – einfach, weil wir GitHub in unserem Unternehmen nutzen
Wir haben versucht, Google OIDC zu verwenden, aber leider hatten wir die Gruppen anzulegen, weshalb die Integration mit GitHub für uns gut passte. Ohne Gruppenabbildung ist es nicht möglich, gruppenbasierte RBAC-Richtlinien zu erstellen.
Also, wie funktioniert unser Authentifizierungsprozess in Kubernetes visuell dargestellt:

Der Authentifizierungsprozess
Ein wenig detaillierter und schrittweise:
- Der Benutzer loggt sich in dex-k8s-authenticator ein (
login.k8s.example.com) - dex-k8s-authenticator leitet die Anfrage an Dex weiter (
dex.k8s.example.com) - Dex leitet zur Authentifizierungsseite von GitHub weiter
- GitHub generiert die erforderlichen Autorisierungsinformationen und sendet sie an Dex zurück
- Dex überträgt die erhaltenen Informationen an 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 die Zugriffsrechte an kubectl zurück
- Der Benutzer erhält die Zugriffsrechte von kubectl
Vorbereitungsmaßnahmen
Selbstverständlich haben wir bereits einen Kubernetes-Cluster (k8s.example.com), sowie HELM vorinstalliert. Außerdem haben wir eine Organisation in GitHub (super-org).
Falls Sie kein HELM haben, ist die Installation .
Zunächst müssen wir GitHub einrichten.
Gehen Sie zur Seite der Organisationseinstellungen, (https://github.com/organizations/super-org/settings/applications) und erstellen Sie eine neue Anwendung (Autorisiertes OAuth-App):

Neue Anwendung in GitHub erstellen
Füllen Sie die Felder mit den erforderlichen URLs aus, zum Beispiel:
- Homepage-URL:
https://dex.k8s.example.com - URL für die Autorisierungsrückmeldung:
https://dex.k8s.example.com/callback
Seien Sie vorsichtig mit den Links, es ist wichtig, die Schrägstriche nicht zu verlieren.
Als Antwort auf das ausgefüllte Formular generiert GitHub Client-ID und Client-Secret, bewahren Sie sie an einem sicheren Ort auf, sie werden uns nützlich sein (wir verwenden beispielsweise zur Speicherung 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 Ingress-Einheiten.
Wir erstellen 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 Der ClusterIssuer mit dem Namen le-clusterissuer sollte bereits existieren, falls nicht, erstellen wir 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: {}
EOFKonfiguration des KubeAPIServer
Für den Betrieb des kubeAPIServer ist es notwendig, OIDC zu konfigurieren und das Cluster zu 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 --yesWir verwenden zum Bereitstellen von Clustern, aber es funktioniert analog auch für .
Konfiguration von Dex und dex-k8s-authenticator
Für den Betrieb von Dex benötigen wir ein Zertifikat und einen Schlüssel vom Kubernetes-Cluster, den wir dort herausziehen:
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 .
Wir beschreiben die Konfiguration für Dex:
cat < 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 < 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-authenticatorWir überprüfen die Funktionsfähigkeit der Services (Dex sollte Code 400 zurückgeben, dex-k8s-authenticator Code 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 200RBAC-Konfiguration
Wir erstellen eine ClusterRole für die Gruppe, in unserem Fall mit Read-Only-Zugriffsrechten:
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"]
EOFLassen Sie uns die Konfiguration für 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"
EOFJetzt sind wir bereit für Tests.
Tests
Wir gehen zur Anmeldeseite (https://login.k8s.example.com) und melden uns mit unserem GitHub-Konto an:

Anmeldeseite

Anmeldeseite umgeleitet zu GitHub

Befolgen Sie die erstellte Anweisung, um Zugriff zu erhalten
Nach dem Kopieren 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
Fehler vom Server (Forbidden): Pods "mypod" ist verboten: Benutzer "amet@example.com" kann Pods im Namespace "default" nicht löschen. Und es funktioniert, alle GitHub-Benutzer in unserer Organisation können Ressourcen sehen und auf Pods zugreifen, jedoch haben sie keine Rechte zur Änderung.
Quelle: habr.com
