Kubernetes Authentication kun GitHub OAuth kaj Dex

Mi prezentas al via atento lernilon por generi aliron al Kubernetes-grupo uzante Dex, dex-k8s-authenticator kaj GitHub.

Kubernetes Authentication kun GitHub OAuth kaj Dex
Loka memo de la ruslingva Kubernetes babilado Telegramo

Enkonduko

Ni uzas Kubernetes por krei dinamikajn mediojn por la evolua teamo kaj QA. Do ni volas doni al ili aliron al la areto por ambaŭ la panelo kaj kubectl. Male al la sama OpenShift, vanilo Kubernetes ne havas denaskan aŭtentikigon, do ni uzas triajn ilojn por tio.

En ĉi tiu agordo ni uzas:

  • dex-k8s-authenticator  - TTT-apliko por generi kubectl-agordon
  • Dex - Provizanto de OpenID Connect
  • GitHub - simple ĉar ni uzas GitHub en nia kompanio

Ni provis uzi Google OIDC, sed bedaŭrinde ni malsukcesis komenci ilin per grupoj, do la integriĝo kun GitHub ĝuste konvenis al ni. Sen grupa mapado, ne estos eble krei grup-bazitajn RBAC-politikojn.

Do, kiel funkcias nia procezo de rajtigo de Kubernetes en vida reprezentado:

Kubernetes Authentication kun GitHub OAuth kaj Dex
Procezo de rajtigo

Iom pli da detaloj kaj punkto post punkto:

  1. Uzanto ensalutas en dex-k8s-authenticator (login.k8s.example.com)
  2. dex-k8s-authenticator redirektas la peton al Dex (dex.k8s.example.com)
  3. Dex alidirektas al GitHub-ensalutpaĝo
  4. GitHub generas la bezonatajn rajtigajn informojn kaj resendas ĝin al Dex
  5. Dex pasas la ricevitajn informojn al dex-k8s-authenticator
  6. Uzanto ricevas OIDC-ĵetonon de GitHub
  7. dex-k8s-authenticator aldonas ĵetonon al kubeconfig
  8. kubectl pasas ĵetonon al KubeAPIServer
  9. KubeAPIServer bazita sur la preterpasita ĵetono resendas aliron al kubectl
  10. Uzantaj aliroj de kubectl

Preparaj agoj

Kompreneble, ni jam havas instalitan Kubernetes-grupon (k8s.example.com), same kiel HELM antaŭinstalita. Ni ankaŭ havas organizon en GitHub (super-org).
Se vi ne havas HELM, instalu ĝin tre simpla.

Unue ni devas agordi GitHub.

Iru al la paĝo de agordoj de la organizo, (https://github.com/organizations/super-org/settings/applications) kaj kreu novan aplikaĵon (aŭtorizita OAuth Apo):
Kubernetes Authentication kun GitHub OAuth kaj Dex
Kreu novan apon en GitHub

Plenigu la kampojn kun la postulataj URL-oj, ekzemple:

  • Hejmpaĝo URL: https://dex.k8s.example.com
  • Rajtigo-revoka URL: https://dex.k8s.example.com/callback

Atentu kun ligiloj, gravas ne perdi obliklojn.

Responde al la kompletigita formularo, GitHub generos Client ID и Client secret, konservu ilin en sekura loko, ili estos utilaj al ni (ekzemple, ni uzas volbo por konservi sekretojn):

Client ID: 1ab2c3d4e5f6g7h8
Client secret: 98z76y54x32w1

Preparu DNS-rekordojn por subdomajnoj login.k8s.example.com и dex.k8s.example.com, same kiel SSL-atestiloj por eniroj.

Ni kreu SSL-atestilojn:

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 kun titolo le-clusterissuer devus jam ekzisti, se ne, kreu ĝin uzante 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-agordo

Por ke kubeAPIServer funkciu, vi devas agordi OIDC kaj ĝisdatigi la areton:

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

Ni uzas kops por vastigi aretojn, sed ĝi funkcias same por aliaj clustermanaĝeroj.

Dex-agordo kaj dex-k8s-authenticator

Por ke Dex funkciu, vi devas havi atestilon kaj ŝlosilon de la majstro Kubernetes, ni eltiros ĝin de tie:

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

Klonu la deponejon dex-k8s-authenticator:

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

Helpe de valor-dosieroj, ni povas flekseble agordi variablojn por nia HELM-diagramoj.

Ni priskribu la agordon por 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

Kaj por 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

Instalu Dex kaj 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

Ni kontrolu la servadon de la servoj (Dex devas resendi kodon 400, kaj dex-k8s-authenticator devas resendi kodon 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-agordo

Kreu ClusterRole por la grupo, en nia kazo kun nurlegebla aliro:

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

Ni kreu agordon por 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

Nun ni estas pretaj por testado.

Provoj

Iru al ensaluta paĝohttps://login.k8s.example.com) kaj ensalutu per GitHub-konto:

Kubernetes Authentication kun GitHub OAuth kaj Dex
Paĝo pri rajtigo

Kubernetes Authentication kun GitHub OAuth kaj Dex
Rajtpaĝo alidirektita al GitHub

Kubernetes Authentication kun GitHub OAuth kaj Dex
 Sekvu la generitajn instrukciojn por akiri aliron

Post kopii-alglui de la retpaĝo, ni povas uzi kubectl por administri niajn amasrimedojn:

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"

Kaj ĝi funkcias, ĉiuj uzantoj de GitHub en nia organizo povas vidi rimedojn kaj ensaluti en podojn, sed ili ne havas permeson ŝanĝi ilin.

fonto: www.habr.com

Aldoni komenton