Autentisering i Kubernetes med GitHub OAuth och Dex

HÀr presenterar jag en tutorial för att generera Ätkomster till Kubernetes-klustret med hjÀlp av Dex, dex-k8s-authenticator och GitHub.

Autentisering i Kubernetes med GitHub OAuth och Dex
Ett lokalt meme frÄn den rysksprÄkiga Kubernetes-chatten i Telegram

Introduktion

Vi anvÀnder Kubernetes för att skapa dynamiska miljöer för utvecklar- och QA-teamet. PÄ sÄ sÀtt vill vi ge dem Ätkomst till klustret bÄde för dashboard och kubectl. Till skillnad frÄn OpenShift har vanilj Kubernetes inget inbyggt autentisering, sÄ vi anvÀnder tredjepartsverktyg för detta.

I denna konfiguration anvÀnder vi:

  • dex-k8s-authenticator  — en webbapplikation för att generera kubectl-konfiguration
  • Dex — en OpenID Connect-leverantör
  • GitHub — helt enkelt för att vi anvĂ€nder GitHub i vĂ„rt företag.

Vi försökte anvÀnda Google OIDC, men tyvÀrr lyckades vi inte fÄ det att fungera med grupper, sÄ integrationen med GitHub passade oss bra. Utan grupplÀnkning gÄr det inte att skapa RBAC-policyer baserade pÄ grupper.

SÄ hur fungerar vÄr autentiseringsprocess i Kubernetes visuellt:

Autentisering i Kubernetes med GitHub OAuth och Dex
Autentiseringsprocessen

Lite mer i detalj, punkt för punkt:

  1. AnvÀndaren loggar in pÄ dex-k8s-authenticator (login.k8s.example.com)
  2. dex-k8s-authenticator vidarebefordrar begÀran till Dex (dex.k8s.example.com)
  3. Dex vidarebefordrar till GitHubs inloggningssida
  4. GitHub genererar nödvÀndig autentiseringsinformation och ÄtervÀnder den till Dex
  5. Dex vidarebefordrar den mottagna informationen till dex-k8s-authenticator
  6. AnvÀndaren fÄr en OIDC-token frÄn GitHub
  7. dex-k8s-authenticator lÀgger till token i kubeconfig
  8. kubectl skickar token till KubeAPIServer
  9. KubeAPIServer returnerar Ätkomst till kubectl baserat pÄ den angivna token
  10. AnvÀndaren fÄr Ätkomst frÄn kubectl

Förberedande ÄtgÀrder

Naturligtvis har vi redan en installerad Kubernetes-kluster (k8s.example.com), och HELM Àr ocksÄ förinstallerat. Vi har Àven en organisation pÄ GitHub (super-org).
Om du inte har HELM, installeras det vÀldigt enkelt.

Först mÄste vi konfigurera GitHub.

GÄ till organisationsinstÀllningssidan, (https://github.com/organizations/super-org/settings/applications) och skapa en ny applikation (Authorized OAuth App):
Autentisering i Kubernetes med GitHub OAuth och Dex
Skapa en ny applikation i GitHub

Fyll i fÀlten med nödvÀndiga URL:er, exempelvis:

  • Huvud-URL: https://dex.k8s.example.com
  • AutoriseringsĂ„terkopplings-URL: https://dex.k8s.example.com/callback

Var försiktig med lÀnkarna, det Àr viktigt att inte tappa bort snedstrecken.

Som svar pÄ det ifyllda formulÀret kommer GitHub att generera Klient-ID och Klienthemlighet, spara dem pÄ en sÀker plats, vi kommer att behöva dem (vi anvÀnder exempelvis Vault för att lagra hemligheter):

Klient-ID: 1ab2c3d4e5f6g7h8
Klienthemlighet: 98z76y54x32w1

Förbered DNS-poster för subdomÀner login.k8s.example.com och dex.k8s.example.com, samt SSL-certifikat för ingress.

Skapa SSL-certifikat:

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 med namnet le-clusterissuer mĂ„ste redan finnas, om den inte gör det — lĂ„t oss skapa den med 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

KubeAPIServer-konfiguration

För att fÄ kubeAPIServer att fungera mÄste OIDC konfigureras och klustret uppdateras:

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 anvÀnder kops för att distribuera kluster, men detta fungerar pÄ liknande sÀtt för andra klusterhanterare.

Dex och dex-k8s-authenticator-konfiguration

För att fÄ Dex att fungera mÄste vi ha ett certifikat och en nyckel frÄn Kubernetes-mastern, vi hÀmtar det dÀrifrÄn:

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

Klonar dex-k8s-authenticator-repo:

git clone git@github.com:mintel/dex-k8s-authenticator.git
cd dex-k8s-authenticator/

Med hjÀlp av values-filer kan vi flexibelt konfigurera variabler för vÄra HELM-diagram.

LÄt oss beskriva konfigurationen 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

Och 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
EOF

LÄt oss installera Dex och 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

Vi kontrollerar att tjÀnsterna fungerar (Dex ska returnera kod 400, och dex-k8s-authenticator ska returnera kod 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-konfiguration

Vi skapar en ClusterRole för gruppen, i vÄrt fall med read-only behörigheter:

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

Vi skapar en konfiguration för 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

Nu Àr vi redo för testning.

Tester

Vi gÄr till inloggningssidan (https://login.k8s.example.com) och loggar in med vÄrt GitHub-konto:

Autentisering i Kubernetes med GitHub OAuth och Dex
Inloggningssidan

Autentisering i Kubernetes med GitHub OAuth och Dex
Inloggningssidan omdirigeras till GitHub

Autentisering i Kubernetes med GitHub OAuth och Dex
 Följ de genererade instruktionerna för att fÄ Ätkomst

Efter att ha kopierat och klistrat in frÄn webbsidan kan vi anvÀnda kubectl för att hantera resurserna i vÄr kluster:

kubectl get po
NAMN                KLAR   STATUS    OMSTARTAR   ÅLDER
mypod               1/1     Körning   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"

Och det fungerar, alla GitHub-anvÀndare i vÄr organisation kan se resurserna och gÄ in i poddar, men de har inte rÀtt att Àndra dem.

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster