I-authenticate sa Kubernetes gamit ang GitHub OAuth at Dex

Nagpapakita ako sa iyong atensyon ng isang tutorial para sa pagbuo ng access sa isang Kubernetes cluster gamit ang Dex, dex-k8s-authenticator at GitHub.

I-authenticate sa Kubernetes gamit ang GitHub OAuth at Dex
Lokal na meme mula sa Russian-language Kubernetes chat in Telegrama

Pagpapakilala

Ginagamit namin ang Kubernetes upang lumikha ng mga dynamic na kapaligiran para sa pagbuo at QA team. Kaya gusto naming bigyan sila ng access sa cluster para sa parehong dashboard at kubectl. Hindi tulad ng OpenShift, walang native na pagpapatotoo ang vanilla Kubernetes, kaya gumagamit kami ng mga tool ng third-party para dito.

Sa pagsasaayos na ito ginagamit namin ang:

  • dex-k8s-authenticatorβ€Š β€” web application para sa pagbuo ng kubectl config
  • Dex β€” Provider ng OpenID Connect
  • GitHub - dahil lang ginagamit namin ang GitHub sa aming kumpanya

Sinubukan naming gamitin ang Google OIDC, ngunit sa kasamaang palad kami nabigo upang simulan ang mga ito sa mga grupo, kaya ang pagsasama sa GitHub ay angkop sa amin. Kung walang group mapping, hindi posibleng gumawa ng mga patakaran ng RBAC batay sa mga grupo.

Kaya, paano gumagana ang aming proseso ng awtorisasyon sa Kubernetes sa isang visual na representasyon:

I-authenticate sa Kubernetes gamit ang GitHub OAuth at Dex
Proseso ng awtorisasyon

Kaunting detalye at punto sa punto:

  1. Nagla-log in ang user sa dex-k8s-authenticator (login.k8s.example.com)
  2. Ipinapasa ng dex-k8s-authenticator ang kahilingan kay Dex (dex.k8s.example.com)
  3. Nagre-redirect si Dex sa pahina ng pag-login sa GitHub
  4. Binubuo ng GitHub ang kinakailangang impormasyon ng awtorisasyon at ibinabalik ito sa Dex
  5. Ipinapasa ni Dex ang natanggap na impormasyon sa dex-k8s-authenticator
  6. Nakatanggap ang user ng OIDC token mula sa GitHub
  7. Ang dex-k8s-authenticator ay nagdaragdag ng token sa kubeconfig
  8. Ipinapasa ng kubectl ang token sa KubeAPIServer
  9. Nagbabalik ang KubeAPIServer ng mga access sa kubectl batay sa ipinasang token
  10. Ang gumagamit ay nakakakuha ng access mula sa kubectl

Mga aksyong paghahanda

Siyempre, mayroon na tayong naka-install na Kubernetes cluster (k8s.example.com), at mayroon ding HELM na paunang naka-install. Mayroon din kaming organisasyon sa GitHub (super-org).
Kung wala kang HELM, i-install ito napaka-simple.

Una kailangan nating i-set up ang GitHub.

Pumunta sa page ng mga setting ng organisasyon, (https://github.com/organizations/super-org/settings/applications) at lumikha ng bagong application (Awtorisadong OAuth App):
I-authenticate sa Kubernetes gamit ang GitHub OAuth at Dex
Paglikha ng bagong application sa GitHub

Punan ang mga patlang ng mga kinakailangang URL, halimbawa:

  • URL ng homepage: https://dex.k8s.example.com
  • URL ng authorization callback: https://dex.k8s.example.com/callback

Mag-ingat sa mga link, mahalaga na huwag mawala ang mga slash.

Bilang tugon sa isang nakumpletong form, bubuo ang GitHub Client ID ΠΈ Client secret, panatilihin ang mga ito sa isang ligtas na lugar, sila ay magiging kapaki-pakinabang sa amin (halimbawa, ginagamit namin Vault para sa pagtatago ng mga lihim):

Client ID: 1ab2c3d4e5f6g7h8
Client secret: 98z76y54x32w1

Maghanda ng mga tala ng DNS para sa mga subdomain login.k8s.example.com ΠΈ dex.k8s.example.com, pati na rin ang mga SSL certificate para sa pagpasok.

Gumawa tayo ng mga SSL certificate:

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 na may pamagat le-clusterissuer dapat mayroon na, ngunit kung hindi, gawin ito gamit ang 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

Configuration ng KubeAPIServer

Para gumana ang kubeAPIServer, kailangan mong i-configure ang OIDC at i-update ang cluster:

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

Gumagamit kami sipa para sa pag-deploy ng mga kumpol, ngunit ito ay gumagana nang katulad para sa iba pang mga cluster manager.

Dex configuration at dex-k8s-authenticator

Para gumana si Dex, kailangan mong magkaroon ng certificate at key mula sa Kubernetes master, kunin natin ito mula doon:

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

I-clone natin ang dex-k8s-authenticator repository:

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

Gamit ang mga value ng file, maaari naming madaling i-configure ang mga variable para sa aming HELM chart.

Ilarawan natin ang pagsasaayos para kay 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

At para sa 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

I-install ang Dex at 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

Suriin natin ang functionality ng mga serbisyo (Dex dapat magbalik ng code 400, at ang dex-k8s-authenticator ay dapat magbalik ng code 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

configuration ng RBAC

Gumagawa kami ng ClusterRole para sa grupo, sa aming kaso na may read-only na access:

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

Gumawa tayo ng configuration para sa 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

Ngayon ay handa na kami para sa pagsubok.

Mga Pagsubok

Pumunta sa login page (https://login.k8s.example.com) at mag-log in gamit ang iyong GitHub account:

I-authenticate sa Kubernetes gamit ang GitHub OAuth at Dex
Pahina sa pag-login

I-authenticate sa Kubernetes gamit ang GitHub OAuth at Dex
Na-redirect ang pahina sa pag-login sa GitHub

I-authenticate sa Kubernetes gamit ang GitHub OAuth at Dex
 Sundin ang mga nabuong tagubilin upang makakuha ng access

Pagkatapos ng copy-paste mula sa web page, maaari naming gamitin ang kubectl upang pamahalaan ang aming mga mapagkukunan ng cluster:

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"

At ito ay gumagana, lahat ng mga user ng GitHub sa aming organisasyon ay maaaring makakita ng mga mapagkukunan at mag-log in sa mga pod, ngunit wala silang karapatan na baguhin ang mga ito.

Pinagmulan: www.habr.com

Magdagdag ng komento