Je vous présente le tutoriel pour générer l'accès au cluster Kubernetes à l'aide de Dex, dex-k8s-authentificator et GitHub.
Mème local du chat en langue russe Kubernetes sur TelegramPrésentation
Nous utilisons Kubernetes pour créer des environnements dynamiques pour l'équipe de développement et le contrôle qualité. Ainsi, nous voulons leur donner accès au cluster pour les tableaux de bord et kubectl. Contrairement à OpenShift, vanilla Kubernetes n'a pas d'authentification native, nous utilisons donc des outils tiers pour cela.
Dans cette configuration, nous utilisons:
- dex-k8s-authentificator - application web pour générer la configuration de kubectl
- Dex - Fournisseur OpenID Connect
- GitHub - simplement parce que nous utilisons GitHub dans notre entreprise
Nous avons essayé d'utiliser Google OIDC, mais malheureusement nous n'avons
pas pu les obtenir avec des groupes, donc l'intégration avec GitHub nous convenait très bien. Sans mappage de groupe, vous ne pouvez pas créer de stratégies RBAC basées sur un groupe.
Alors, comment fonctionne notre processus d'autorisation dans Kubernetes dans une représentation visuelle:
Processus d'autorisationUn peu plus de détails et de points:
- L'utilisateur se connecte Ă dex-k8s-authentifier (
login.k8s.example.com
) - dex-k8s-authentator redirige la demande vers Dex (
dex.k8s.example.com
) - Dex redirige vers la page de connexion GitHub
- GitHub génère les informations d'autorisation nécessaires et les renvoie à Dex
- Dex transmet les informations reçues à l'authentification dex-k8s
- L'utilisateur obtient le jeton OIDC de GitHub
- dex-k8s-authentifier ajoute un jeton Ă kubeconfig
- kubectl passe le jeton Ă KubeAPIServer
- KubeAPIServer basé sur le jeton transféré renvoie les accès dans kubectl
- L'utilisateur obtient l'accès à partir de kubectl
Activités préparatoires
Bien sûr, nous avons déjà un cluster
k8s.example.com
(
k8s.example.com
) installé, ainsi que HELM. Nous avons également une organisation sur GitHub (super-org).
Si vous n'avez pas de HELM, il est
très facile à installer.
Nous devons d'abord configurer GitHub.
Accédez à la page des paramètres de l'organisation (
https://github.com/organizations/super-org/settings/applications
) et créez une nouvelle application (application OAuth autorisée):
Créer une nouvelle application sur GitHubRemplissez les champs avec les URL nécessaires, par exemple:
- URL de la page d'accueil:
https://dex.k8s.example.com
- URL de rappel d'autorisation:
https://dex.k8s.example.com/callback
Attention aux liens, il est important de ne pas perdre de barres obliques.En réponse au formulaire rempli, GitHub va générer l'
Client ID
et le
Client secret
, les enregistrer dans un endroit sûr, ils nous seront utiles (par exemple, nous utilisons
Vault pour stocker des secrets):
Client ID: 1ab2c3d4e5f6g7h8 Client secret: 98z76y54x32w1
Préparez les enregistrements DNS pour les sous-domaines
login.k8s.example.com
et
dex.k8s.example.com
, ainsi que les certificats SSL pour les entrées.
Créez des certificats 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
Un ClusterIssuer avec le nom
le-clusterissuer
devrait déjà exister, sinon, créez-le en utilisant 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
Configuration de KubeAPIServer
Pour que kubeAPIServer fonctionne, vous devez configurer OIDC et mettre Ă jour le cluster:
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
Nous utilisons
kops pour déployer des clusters, mais cela fonctionne de la même manière pour les
autres gestionnaires de clusters .
Configuration des authentificateurs Dex et dex-k8s
Pour que Dex fonctionne, vous devez avoir un certificat et une clé du maître Kubernetes, en les tirant de là :
sudo cat /srv/kubernetes/ca.{crt,key} -----BEGIN CERTIFICATE----- AAAAAAAAAAABBBBBBBBBBCCCCCC -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- DDDDDDDDDDDEEEEEEEEEEFFFFFF -----END RSA PRIVATE KEY-----
Clonez le référentiel dex-k8s-authentifier:
git clone git@github.com:mintel/dex-k8s-authenticator.git cd dex-k8s-authenticator/
En utilisant des fichiers de valeurs, nous pouvons définir de manière flexible des variables pour nos
graphiques HELM .
Décrivons la configuration de 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
Et pour l'authentificateur dex-k8s:
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
Installez Dex et dex-k8s-authentifier:
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
Vérifions la facilité de service des services (Dex devrait retourner le code 400, et dex-k8s-authentifier - le 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 200
Configuration RBAC
Nous créons ClusterRole pour le groupe, dans notre cas avec des accès en lecture seule:
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
Créez une configuration pour 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
Nous sommes maintenant prĂŞts pour les tests.
Les tests
Nous allons sur la page de connexion (
https://login.k8s.example.com
) et nous connectons en utilisant le compte GitHub:
Page de connexion
Page de connexion redirigée vers GitHub
Suivez les instructions générées pour l'accèsAprès un copier-coller à partir de la page Web, nous pouvons utiliser kubectl pour gérer les ressources de notre cluster:
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"
Et cela fonctionne, tous les utilisateurs de GitHub de notre organisation peuvent voir les ressources et entrer dans les pods, mais ils n'ont pas le droit de les modifier.