Vă prezint un tutorial pentru generarea accesului la un cluster Kubernetes cu ajutorul Dex, dex-k8s-authenticator și GitHub.

Un meme local din chatul în limba rusă Kubernetes în
Introducere
Folosim Kubernetes pentru a crea medii dinamice pentru echipa de dezvoltare și QA. Astfel, dorim să le oferim acces la cluster atât pentru tablou, cât și pentru kubectl. Spre deosebire de OpenShift, Kubernetes pur nu are autentificare nativă, așa că folosim instrumente externe pentru acest lucru.
În această configurație folosim:
- — aplicație web pentru generarea configurării kubectl
- — furnizor OpenID Connect
- GitHub — pur și simplu pentru că folosim GitHub în compania noastră
Am încercat să folosim Google OIDC, dar din păcate nu ne să le configurăm cu grupurile, așa că integrarea cu GitHub ne-a satisfăcut pe deplin. Fără maparea grupurilor, nu se vor putea crea politici RBAC bazate pe grupuri.
Așadar, cum funcționează procesul nostru de autorizare în Kubernetes, prezentat vizual:

Procesul de autentificare
Puțin mai detaliat și pe puncte:
- Utilizatorul se conectează la dex-k8s-authenticator (
login.k8s.example.com) - dex-k8s-authenticator redirecționează cererea către Dex (
dex.k8s.example.com) - Dex redirecționează la pagina de autentificare GitHub
- GitHub generează informațiile necesare pentru autorizare și le returnează la Dex
- Dex trimite informațiile obținute la dex-k8s-authenticator
- Utilizatorul primește token OIDC de la GitHub
- dex-k8s-authenticator adaugă tokenul în kubeconfig
- kubectl trimite tokenul către KubeAPIServer
- KubeAPIServer returnează accesul în kubectl bazat pe tokenul transmis
- Utilizatorul primește accesul de la kubectl
Acțiuni pregătitoare
Desigur, avem deja un cluster Kubernetes (k8s.example.com), precum și HELM preinstalat. De asemenea, avem o organizație pe GitHub (super-org).
Dacă nu aveți HELM, instalarea se face .
Mai întâi trebuie să configurăm GitHub.
Accesați pagina de setări a organizației, (https://github.com/organizations/super-org/settings/applications) și creați o aplicație nouă (Aplicație OAuth autorizată):

Crearea unei noi aplicații în GitHub
Completați câmpurile cu URL-urile necesare, de exemplu:
- Homepage URL:
https://dex.k8s.example.com - Authorization callback URL:
https://dex.k8s.example.com/callback
Fiți atenți la linkuri, este important să nu pierdeți slash-urile.
Ca răspuns la formularul completat, GitHub va genera ID-ul Clientului și Client secret, salvați-le într-un loc sigur, ne vor fi utile (de exemplu, folosim pentru a stoca secretele):
Client ID: 1ab2c3d4e5f6g7h8
Client secret: 98z76y54x32w1 Pregătiți înregistrările DNS pentru subdomenii login.k8s.example.com și dex.k8s.example.com, precum și certificatele SSL pentru ingressuri.
Vom crea certificate 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 ClusterIssuer cu numele le-clusterissuer trebuie să existe deja, altfel îl vom crea cu ajutorul 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: {}
EOFConfigurarea KubeAPIServer
Pentru a funcționa, kubeAPIServer trebuie configurat OIDC și să actualizăm cluster-ul:
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 --yesFolosim pentru desfășurarea cluster-elor, dar funcționează similar și pentru .
Configurarea Dex și dex-k8s-authenticator
Pentru a funcționa, Dex trebuie să aibă un certificat și o cheie de pe masterul Kubernetes, să le extragem de acolo:
sudo cat /srv/kubernetes/ca.{crt,key}
-----BEGIN CERTIFICATE-----
AAAAAAAAAAABBBBBBBBBBCCCCCC
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
DDDDDDDDDDDEEEEEEEEEEFFFFFF
-----END RSA PRIVATE KEY-----Vom clona repository-ul dex-k8s-authenticator:
git clone git@github.com:mintel/dex-k8s-authenticator.git
cd dex-k8s-authenticator/Cu ajutorul fișierelor values putem configura variabilele pentru .
Vom descrie configurația pentru 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
Și pentru 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
EOFVom instala 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-authenticatorSă verificăm funcționalitatea serviciilor (Dex ar trebui să returneze codul 400, iar dex-k8s-authenticator — codul 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 200Configurație RBAC
Creăm un ClusterRole pentru grup, în cazul nostru cu accesuri read-only:
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"]
EOFVom crea configurarea pentru 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"
EOFAcum suntem pregătiți pentru testare.
Teste
Accesăm pagina de autentificare (https://login.k8s.example.com) și ne autentificăm cu contul de GitHub:

Pagina de autentificare

Pagina de autentificare redirecționată pe GitHub

Urmăm instrucțiunile generate pentru a obține permisiunile
După copierea și lipirea de pe pagina web, putem folosi kubectl pentru a gestiona resursele clusterului nostru:
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" Și funcționează, toți utilizatorii de GitHub din organizația noastră pot vizualiza resursele și pot accesa pod-urile, dar nu au drepturi de modificare.
Sursa: habr.com
