Autentiser i Kubernetes med GitHub OAuth og Dex

Jeg presenterer for din oppmerksomhet en veiledning for å generere tilgang til en Kubernetes-klynge ved hjelp av Dex, dex-k8s-autenticator og GitHub.

Autentiser i Kubernetes med GitHub OAuth og Dex
Lokal meme fra den russiskspråklige Kubernetes chatter inn Telegram

Innledning

Vi bruker Kubernetes for å skape dynamiske miljøer for utviklings- og QA-teamet. Så vi ønsker å gi dem tilgang til klyngen for både dashbordet og kubectl. I motsetning til OpenShift har ikke vanilla Kubernetes innebygd autentisering, så vi bruker tredjepartsverktøy for dette.

I denne konfigurasjonen bruker vi:

  • dex-k8s-autentisering  — webapplikasjon for å generere kubectl-konfig
  • Dex — OpenID Connect-leverandør
  • GitHub – rett og slett fordi vi bruker GitHub i selskapet vårt

Vi prøvde å bruke Google OIDC, men dessverre mislyktes å starte dem med grupper, så integrasjonen med GitHub passet oss ganske bra. Uten gruppekartlegging vil det ikke være mulig å lage RBAC-policyer basert på grupper.

Så hvordan fungerer Kubernetes-autorisasjonsprosessen vår i en visuell representasjon:

Autentiser i Kubernetes med GitHub OAuth og Dex
Autorisasjonsprosess

Litt mer detaljert og punkt for punkt:

  1. Bruker logger på dex-k8s-autenticator (login.k8s.example.com)
  2. dex-k8s-authenticator videresender forespørselen til Dex (dex.k8s.example.com)
  3. Dex omdirigerer til GitHub-påloggingssiden
  4. GitHub genererer nødvendig autorisasjonsinformasjon og returnerer den til Dex
  5. Dex sender den mottatte informasjonen til dex-k8s-authenticator
  6. Brukeren mottar et OIDC-token fra GitHub
  7. dex-k8s-authenticator legger til token til kubeconfig
  8. kubectl sender tokenet til KubeAPIServer
  9. KubeAPIServer returnerer tilganger til kubectl basert på det passerte tokenet
  10. Brukeren får tilgang fra kubectl

Forberedende handlinger

Selvfølgelig har vi allerede en Kubernetes-klynge installert (k8s.example.com), og leveres også med HELM forhåndsinstallert. Vi har også en organisasjon på GitHub (super-org).
Hvis du ikke har HELM, installer det meget enkel.

Først må vi sette opp GitHub.

Gå til siden for organisasjonsinnstillinger, (https://github.com/organizations/super-org/settings/applications) og opprett en ny applikasjon (Autorisert OAuth-app):
Autentiser i Kubernetes med GitHub OAuth og Dex
Opprette en ny applikasjon på GitHub

Fyll ut feltene med de nødvendige nettadressene, for eksempel:

  • Hjemmeside-URL: https://dex.k8s.example.com
  • Nettadresse for tilbakeringing av autorisasjon: https://dex.k8s.example.com/callback

Vær forsiktig med lenker, det er viktig å ikke miste skråstreker.

Som svar på et utfylt skjema vil GitHub generere Client ID и Client secret, oppbevar dem på et trygt sted, vil de være nyttige for oss (for eksempel bruker vi Vault for lagring av hemmeligheter):

Client ID: 1ab2c3d4e5f6g7h8
Client secret: 98z76y54x32w1

Forbered DNS-poster for underdomener login.k8s.example.com и dex.k8s.example.com, samt SSL-sertifikater for ingress.

La oss lage SSL-sertifikater:

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

Klyngeutsteder med tittel le-clusterissuer burde allerede eksistere, men hvis ikke, lag det ved å bruke 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-konfigurasjon

For at kubeAPIServer skal fungere, må du konfigurere OIDC og oppdatere klyngen:

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

Vi bruker sparke for distribusjon av klynger, men dette fungerer på samme måte for andre klyngeledere.

Dex-konfigurasjon og dex-k8s-autentisering

For at Dex skal fungere, må du ha et sertifikat og en nøkkel fra Kubernetes-mesteren, la oss hente det derfra:

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

La oss klone dex-k8s-autenticator-depotet:

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

Ved å bruke verdifiler kan vi fleksibelt konfigurere variabler for våre HELM-diagrammer.

La oss beskrive konfigurasjonen for 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

Og for dex-k8s-autenticator:

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

Installer Dex og dex-k8s-autenticator:

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

La oss sjekke funksjonaliteten til tjenestene (Dex skal returnere kode 400, og dex-k8s-authenticator skal returnere kode 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-konfigurasjon

Vi oppretter en ClusterRole for gruppen, i vårt tilfelle med skrivebeskyttet tilgang:

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

La oss lage en konfigurasjon for 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

Nå er vi klare for testing.

Tester

Gå til påloggingssiden (https://login.k8s.example.com) og logg på med GitHub-kontoen din:

Autentiser i Kubernetes med GitHub OAuth og Dex
Påloggingsside

Autentiser i Kubernetes med GitHub OAuth og Dex
Påloggingsside omdirigert til GitHub

Autentiser i Kubernetes med GitHub OAuth og Dex
 Følg de genererte instruksjonene for å få tilgang

Etter å ha kopiert og limt inn fra nettsiden, kan vi bruke kubectl til å administrere klyngressursene våre:

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"

Og det fungerer, alle GitHub-brukere i organisasjonen vår kan se ressurser og logge på pods, men de har ikke rettigheter til å endre dem.

Kilde: www.habr.com

Legg til en kommentar