Autentificați-vă în Kubernetes folosind GitHub OAuth și Dex

Vă prezint atenției un tutorial pentru generarea accesului la un cluster Kubernetes folosind Dex, dex-k8s-authenticator și GitHub.

Autentificați-vă în Kubernetes folosind GitHub OAuth și Dex
Meme locală din chatul Kubernetes în limba rusă Telegramă

Introducere

Folosim Kubernetes pentru a crea medii dinamice pentru echipa de dezvoltare și QA. Așa că vrem să le oferim acces la cluster atât pentru tabloul de bord, cât și pentru kubectl. Spre deosebire de OpenShift, vanilla Kubernetes nu are autentificare nativă, așa că folosim instrumente terțe pentru aceasta.

În această configurație folosim:

  • dex-k8s-authenticator  — aplicație web pentru generarea kubectl config
  • Dex — Furnizorul OpenID Connect
  • GitHub - pur și simplu pentru că folosim GitHub în compania noastră

Am încercat să folosim Google OIDC, dar, din păcate, noi nu a reușit pentru a le începe cu grupuri, așa că integrarea cu GitHub ni s-a potrivit destul de bine. Fără maparea grupului, nu va fi posibilă crearea politicilor RBAC bazate pe grupuri.

Deci, cum funcționează procesul nostru de autorizare Kubernetes într-o reprezentare vizuală:

Autentificați-vă în Kubernetes folosind GitHub OAuth și Dex
Procesul de autorizare

Mai multe detalii și punct cu punct:

  1. Utilizatorul se conectează la dex-k8s-authenticator (login.k8s.example.com)
  2. dex-k8s-authenticator trimite cererea către Dex (dex.k8s.example.com)
  3. Dex redirecționează către pagina de conectare GitHub
  4. GitHub generează informațiile de autorizare necesare și le returnează Dex
  5. Dex transmite informațiile primite către dex-k8s-authenticator
  6. Utilizatorul primește un token OIDC de la GitHub
  7. dex-k8s-authenticator adaugă un token la kubeconfig
  8. kubectl transmite jetonul către KubeAPIServer
  9. KubeAPIServer returnează acces la kubectl pe baza simbolului transmis
  10. Utilizatorul are acces de la kubectl

Activități pregătitoare

Desigur, avem deja instalat un cluster Kubernetes (k8s.example.com), și vine, de asemenea, cu HELM preinstalat. Avem și o organizație pe GitHub (super-org).
Dacă nu aveți HELM, instalați-l foarte simplu.

Mai întâi trebuie să setăm GitHub.

Accesați pagina cu setările organizației, (https://github.com/organizations/super-org/settings/applications) și creați o nouă aplicație (Aplicație OAuth autorizată):
Autentificați-vă în Kubernetes folosind GitHub OAuth și Dex
Crearea unei noi aplicații pe GitHub

Completați câmpurile cu adresele URL necesare, de exemplu:

  • Adresa URL a paginii de pornire: https://dex.k8s.example.com
  • Adresa URL de returnare a autorizării: https://dex.k8s.example.com/callback

Atenție la link-uri, este important să nu pierdeți barele oblice.

Ca răspuns la un formular completat, GitHub va genera Client ID и Client secret, păstrați-le într-un loc sigur, ne vor fi de folos (de exemplu, folosim Boltă pentru stocarea secretelor):

Client ID: 1ab2c3d4e5f6g7h8
Client secret: 98z76y54x32w1

Pregătiți înregistrări DNS pentru subdomenii login.k8s.example.com и dex.k8s.example.com, precum și certificate SSL pentru intrare.

Să creăm 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 titlu le-clusterissuer ar trebui să existe deja, dar dacă nu, creați-l folosind 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

Configurarea KubeAPIServer

Pentru ca kubeAPIServer să funcționeze, trebuie să configurați OIDC și să actualizați clusterul:

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

Folosim lovitură pentru implementarea clusterelor, dar aceasta funcționează în mod similar pentru alți manageri de cluster.

Configurare Dex și dex-k8s-authenticator

Pentru ca Dex să funcționeze, trebuie să aveți un certificat și o cheie de la masterul Kubernetes, să o luăm de acolo:

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

Să clonăm depozitul dex-k8s-authenticator:

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

Folosind fișierele de valori, putem configura în mod flexibil variabilele noastre diagrame HELM.

Să descriem configurația pentru 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

Și pentru 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

Instalați 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-authenticator

Să verificăm funcționalitatea serviciilor (Dex ar trebui să returneze codul 400, iar dex-k8s-authenticator ar trebui să returneze 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 200

Configurație RBAC

Creăm un ClusterRole pentru grup, în cazul nostru cu acces numai pentru citire:

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

Să creăm o configurație 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"
EOF

Acum suntem gata de testare.

teste

Accesați pagina de conectare (https://login.k8s.example.com) și conectați-vă folosind contul GitHub:

Autentificați-vă în Kubernetes folosind GitHub OAuth și Dex
Pagina de logare

Autentificați-vă în Kubernetes folosind GitHub OAuth și Dex
Pagina de conectare a fost redirecționată către GitHub

Autentificați-vă în Kubernetes folosind GitHub OAuth și Dex
 Urmați instrucțiunile generate pentru a obține acces

După copierea-lipirea de pe pagina web, putem folosi kubectl pentru a gestiona resursele clusterului:

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"

Și funcționează, toți utilizatorii GitHub din organizația noastră pot vedea resurse și se pot conecta la pod-uri, dar nu au drepturi să le modifice.

Sursa: www.habr.com

Adauga un comentariu