Thibitisha katika Kubernetes ukitumia GitHub OAuth na Dex

Ninawasilisha kwa usikivu wako mafunzo ya kutoa ufikiaji wa nguzo ya Kubernetes kwa kutumia Dex, dex-k8s-authenticator na GitHub.

Thibitisha katika Kubernetes ukitumia GitHub OAuth na Dex
Meme ya ndani kutoka Kubernetes ya lugha ya Kirusi hupiga gumzo ndani telegram

Utangulizi

Tunatumia Kubernetes kuunda mazingira thabiti kwa ajili ya maendeleo na timu ya QA. Kwa hivyo tunataka kuwapa ufikiaji wa nguzo ya dashibodi na kubectl. Tofauti na OpenShift, vanilla Kubernetes haina uthibitishaji asilia, kwa hivyo tunatumia zana za wahusika wengine kwa hili.

Katika usanidi huu tunatumia:

  • dex-k8s-kithibitishaji  - programu ya wavuti ya kutengeneza usanidi wa kubectl
  • Dex — Mtoa huduma wa OpenID Connect
  • GitHub - kwa sababu tu tunatumia GitHub katika kampuni yetu

Tulijaribu kutumia Google OIDC, lakini kwa bahati mbaya sisi imeshindwa kuwaanzisha na vikundi, kwa hivyo ujumuishaji na GitHub ulitufaa vizuri. Bila ramani ya kikundi, haitawezekana kuunda sera za RBAC kulingana na vikundi.

Kwa hivyo, mchakato wetu wa idhini ya Kubernetes hufanyaje kazi katika uwakilishi wa kuona:

Thibitisha katika Kubernetes ukitumia GitHub OAuth na Dex
Mchakato wa idhini

Maelezo kidogo zaidi na hatua kwa hatua:

  1. Mtumiaji anaingia kwenye dex-k8s-authenticator (login.k8s.example.com)
  2. dex-k8s-kithibitishaji hutuma ombi kwa Dex (dex.k8s.example.com)
  3. Dex inaelekeza kwenye ukurasa wa kuingia wa GitHub
  4. GitHub hutoa habari muhimu ya uidhinishaji na kuirudisha kwa Dex
  5. Dex hupitisha taarifa iliyopokelewa kwa dex-k8s-kithibitishaji
  6. Mtumiaji hupokea tokeni ya OIDC kutoka GitHub
  7. dex-k8s-authenticator huongeza tokeni kwa kubeconfig
  8. kubectl hupitisha ishara kwa KubeAPIServer
  9. KubeAPIServer inarudisha ufikiaji kwa kubectl kulingana na tokeni iliyopitishwa
  10. Mtumiaji anapata ufikiaji kutoka kwa kubectl

Vitendo vya maandalizi

Kwa kweli, tayari tunayo nguzo ya Kubernetes iliyosanikishwa (k8s.example.com), na pia inakuja na HELM iliyosakinishwa awali. Pia tuna shirika kwenye GitHub (super-org).
Ikiwa huna HELM, isakinishe rahisi sana.

Kwanza tunahitaji kusanidi GitHub.

Nenda kwenye ukurasa wa mipangilio ya shirika, (https://github.com/organizations/super-org/settings/applications) na unda programu mpya (Programu ya OAuth Iliyoidhinishwa):
Thibitisha katika Kubernetes ukitumia GitHub OAuth na Dex
Kuunda programu mpya kwenye GitHub

Jaza sehemu na URL zinazohitajika, kwa mfano:

  • URL ya ukurasa wa nyumbani: https://dex.k8s.example.com
  • URL ya uidhinishaji wa kupiga simu tena: https://dex.k8s.example.com/callback

Jihadharini na viungo, ni muhimu si kupoteza slashes.

Kwa kujibu fomu iliyokamilishwa, GitHub itatoa Client ID и Client secret, ziweke mahali salama, zitakuwa na manufaa kwetu (kwa mfano, tunatumia Vault kwa kuhifadhi siri):

Client ID: 1ab2c3d4e5f6g7h8
Client secret: 98z76y54x32w1

Tayarisha rekodi za DNS za vikoa vidogo login.k8s.example.com и dex.k8s.example.com, pamoja na vyeti vya SSL kwa ingress.

Wacha tuunde vyeti vya 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 yenye kichwa le-clusterissuer inapaswa kuwa tayari kuwepo, lakini ikiwa sivyo, iunde kwa kutumia 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

Usanidi wa KubeAPIServer

Ili kubeAPIServer ifanye kazi, unahitaji kusanidi OIDC na kusasisha nguzo:

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

Tunatumia teke kwa kupeleka nguzo, lakini hii inafanya kazi vivyo hivyo kwa wasimamizi wengine wa nguzo.

Usanidi wa Dex na kithibitishaji cha dex-k8s

Ili Dex afanye kazi, unahitaji kuwa na cheti na ufunguo kutoka kwa bwana wa Kubernetes, wacha tuipate kutoka hapo:

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

Wacha tutengeneze hazina ya dex-k8s-kithibitishaji:

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

Kwa kutumia maadili ya faili, tunaweza kusanidi vigeu kwa urahisi kwa yetu chati za HELM.

Wacha tueleze usanidi wa 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

Na kwa dex-k8s-kithibitishaji:

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

Sakinisha Dex na dex-k8s-kithibitishaji:

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

Wacha tuangalie utendakazi wa huduma (Dex inapaswa kurudisha nambari 400, na dex-k8s-authenticator inapaswa kurudisha nambari 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

Mpangilio wa RBAC

Tunaunda ClusterRole ya kikundi, kwa upande wetu na ufikiaji wa kusoma tu:

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

Wacha tuunde usanidi wa 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

Sasa tuko tayari kwa majaribio.

Majaribio

Nenda kwenye ukurasa wa kuingia (https://login.k8s.example.com) na uingie kwa kutumia akaunti yako ya GitHub:

Thibitisha katika Kubernetes ukitumia GitHub OAuth na Dex
Ukurasa wa kuingia

Thibitisha katika Kubernetes ukitumia GitHub OAuth na Dex
Ukurasa wa kuingia umeelekezwa kwa GitHub

Thibitisha katika Kubernetes ukitumia GitHub OAuth na Dex
 Fuata maagizo yaliyotolewa ili kupata ufikiaji

Baada ya kunakili-kubandika kutoka kwa ukurasa wa wavuti, tunaweza kutumia kubectl kudhibiti rasilimali zetu za nguzo:

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"

Na inafanya kazi, watumiaji wote wa GitHub katika shirika letu wanaweza kuona rasilimali na kuingia kwenye maganda, lakini hawana haki ya kuzibadilisha.

Chanzo: mapenzi.com

Kuongeza maoni