Έλεγχος ταυτότητας Kubernetes με GitHub OAuth και Dex

Παρουσιάζω στην προσοχή σας ένα σεμινάριο για τη δημιουργία πρόσβασης σε ένα σύμπλεγμα Kubernetes χρησιμοποιώντας Dex, dex-k8s-authenticator και GitHub.

Έλεγχος ταυτότητας Kubernetes με GitHub OAuth και Dex
Τοπικό μιμίδιο από τη ρωσόφωνη συνομιλία Kubernetes Telegram

Εισαγωγή

Χρησιμοποιούμε το Kubernetes για να δημιουργήσουμε δυναμικά περιβάλλοντα για την ομάδα ανάπτυξης και QA. Θέλουμε λοιπόν να τους δώσουμε πρόσβαση στο σύμπλεγμα τόσο για τον πίνακα ελέγχου όσο και για το kubectl. Σε αντίθεση με το ίδιο OpenShift, το vanilla Kubernetes δεν διαθέτει εγγενή έλεγχο ταυτότητας, επομένως χρησιμοποιούμε εργαλεία τρίτων για αυτό.

Σε αυτή τη διαμόρφωση χρησιμοποιούμε:

  • dex-k8s-authenticator  - εφαρμογή web για τη δημιουργία ρυθμίσεων kubectl
  • Dex - Πάροχος OpenID Connect
  • GitHub - απλώς επειδή χρησιμοποιούμε το GitHub στην εταιρεία μας

Προσπαθήσαμε να χρησιμοποιήσουμε το Google OIDC, αλλά δυστυχώς απέτυχε να τα ξεκινήσουμε με ομάδες, οπότε η ενσωμάτωση με το GitHub μας ταίριαζε μια χαρά. Χωρίς ομαδική αντιστοίχιση, δεν θα είναι δυνατή η δημιουργία πολιτικών RBAC που βασίζονται σε ομάδες.

Λοιπόν, πώς λειτουργεί η διαδικασία εξουσιοδότησης Kubernetes σε μια οπτική αναπαράσταση:

Έλεγχος ταυτότητας Kubernetes με GitHub OAuth και Dex
Διαδικασία εξουσιοδότησης

Λίγο πιο αναλυτικά και σημείο προς σημείο:

  1. Ο χρήστης συνδέεται στο dex-k8s-authenticator (login.k8s.example.com)
  2. Το dex-k8s-authenticator ανακατευθύνει το αίτημα στο Dex (dex.k8s.example.com)
  3. Ο Dex ανακατευθύνει στη σελίδα σύνδεσης του GitHub
  4. Το GitHub δημιουργεί τις απαιτούμενες πληροφορίες εξουσιοδότησης και τις επιστρέφει στο Dex
  5. Το Dex μεταβιβάζει τις ληφθείσες πληροφορίες στο dex-k8s-authenticator
  6. Ο χρήστης λαμβάνει το διακριτικό OIDC από το GitHub
  7. Το dex-k8s-authenticator προσθέτει διακριτικό στο kubeconfig
  8. Το kubectl περνάει διακριτικό στον KubeAPIServer
  9. Ο KubeAPIServer που βασίζεται στο διαβιβασμένο διακριτικό επιστρέφει πρόσβαση στο kubectl
  10. Πρόσβαση χρήστη από το kubectl

Προπαρασκευαστικές ενέργειες

Φυσικά, έχουμε ήδη εγκαταστήσει ένα σύμπλεγμα Kubernetes (k8s.example.com), καθώς και το HELM προεγκατεστημένο. Έχουμε επίσης έναν οργανισμό στο GitHub (super-org).
Εάν δεν έχετε HELM, εγκαταστήστε το πολύ απλό.

Πρώτα πρέπει να ρυθμίσουμε το GitHub.

Μεταβείτε στη σελίδα ρυθμίσεων οργανισμού, (https://github.com/organizations/super-org/settings/applications) και δημιουργήστε μια νέα εφαρμογή (Authorized OAuth App):
Έλεγχος ταυτότητας Kubernetes με GitHub OAuth και Dex
Δημιουργήστε μια νέα εφαρμογή στο GitHub

Συμπληρώστε τα πεδία με τις απαιτούμενες διευθύνσεις URL, για παράδειγμα:

  • URL αρχικής σελίδας: https://dex.k8s.example.com
  • Διεύθυνση URL επανάκλησης εξουσιοδότησης: https://dex.k8s.example.com/callback

Να είστε προσεκτικοί με τους συνδέσμους, είναι σημαντικό να μην χάσετε κάθετο.

Σε απόκριση στη συμπληρωμένη φόρμα, το GitHub θα δημιουργήσει Client ID и Client secret, αποθηκεύστε τα σε ασφαλές μέρος, θα μας φανούν χρήσιμα (για παράδειγμα, χρησιμοποιούμε Θόλος για την τήρηση μυστικών):

Client ID: 1ab2c3d4e5f6g7h8
Client secret: 98z76y54x32w1

Προετοιμάστε εγγραφές DNS για υποτομείς login.k8s.example.com и dex.k8s.example.com, καθώς και πιστοποιητικά SSL για εισόδους.

Ας δημιουργήσουμε πιστοποιητικά 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

ClusterEssuer με τίτλο le-clusterissuer θα πρέπει να υπάρχει ήδη, αν όχι, δημιουργήστε το χρησιμοποιώντας το 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: [email protected]
    privateKeySecretRef:
      name: le-clusterissuer
    http01: {}
EOF

Διαμόρφωση KubeAPIServer

Για να λειτουργήσει ο kubeAPIServer, πρέπει να διαμορφώσετε το OIDC και να αναβαθμίσετε το σύμπλεγμα:

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

Χρησιμοποιούμε λάκτισμα για επέκταση συμπλεγμάτων, αλλά λειτουργεί με τον ίδιο τρόπο για άλλους διαχειριστές συστάδων.

Διαμόρφωση Dex και dex-k8s-authenticator

Για να λειτουργήσει το Dex, πρέπει να έχετε ένα πιστοποιητικό και ένα κλειδί από τον κύριο του Kubernetes, θα το βγάλουμε από εκεί:

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

Κλωνοποιήστε το αποθετήριο dex-k8s-authenticator:

git clone [email protected]:mintel/dex-k8s-authenticator.git
cd dex-k8s-authenticator/

Με τη βοήθεια των τιμών-αρχείων, μπορούμε να ρυθμίσουμε με ευελιξία μεταβλητές για το δικό μας Διαγράμματα HELM.

Ας περιγράψουμε τη διαμόρφωση για το 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

Και για το 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
EOF

Εγκαταστήστε το Dex και το 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

Ας ελέγξουμε τη δυνατότητα συντήρησης των υπηρεσιών (το Dex θα πρέπει να επιστρέψει τον κωδικό 400 και το dex-k8s-authenticator θα πρέπει να επιστρέψει τον κωδικό 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

Διαμόρφωση RBAC

Δημιουργήστε ένα ClusterRole για την ομάδα, στην περίπτωσή μας με πρόσβαση μόνο για ανάγνωση:

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

Ας δημιουργήσουμε μια διαμόρφωση για το 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

Τώρα είμαστε έτοιμοι για δοκιμή.

Δοκιμές

Μεταβείτε στη σελίδα σύνδεσηςhttps://login.k8s.example.com) και συνδεθείτε με έναν λογαριασμό GitHub:

Έλεγχος ταυτότητας Kubernetes με GitHub OAuth και Dex
Σελίδα εξουσιοδότησης

Έλεγχος ταυτότητας Kubernetes με GitHub OAuth και Dex
Η σελίδα εξουσιοδότησης ανακατευθυνθεί στο GitHub

Έλεγχος ταυτότητας Kubernetes με GitHub OAuth και Dex
 Ακολουθήστε τις δημιουργημένες οδηγίες για να αποκτήσετε πρόσβαση

Μετά την αντιγραφή από την ιστοσελίδα, μπορούμε να χρησιμοποιήσουμε το kubectl για να διαχειριστούμε τους πόρους του συμπλέγματός μας:

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 "[email protected]" cannot delete pods in the namespace "default"

Και λειτουργεί, όλοι οι χρήστες του GitHub στον οργανισμό μας μπορούν να δουν πόρους και να συνδεθούν σε ομάδες, αλλά δεν έχουν άδεια να τους αλλάξουν.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο