Sahkan dalam Kubernetes menggunakan GitHub OAuth dan Dex

Saya menyampaikan kepada perhatian anda tutorial untuk menjana akses kepada gugusan Kubernetes menggunakan Dex, dex-k8s-authenticator dan GitHub.

Sahkan dalam Kubernetes menggunakan GitHub OAuth dan Dex
Meme tempatan daripada sembang Kubernetes berbahasa Rusia masuk Telegram

Pengenalan

Kami menggunakan Kubernetes untuk mencipta persekitaran dinamik untuk pembangunan dan pasukan QA. Jadi kami ingin memberi mereka akses kepada kluster untuk kedua-dua papan pemuka dan kubectl. Tidak seperti OpenShift, vanilla Kubernetes tidak mempunyai pengesahan asli, jadi kami menggunakan alat pihak ketiga untuk ini.

Dalam konfigurasi ini kami menggunakan:

  • dex-k8s-authenticatorβ€Š β€” aplikasi web untuk menjana konfigurasi kubectl
  • Dex β€” Pembekal OpenID Connect
  • GitHub - semata-mata kerana kami menggunakan GitHub dalam syarikat kami

Kami cuba menggunakan Google OIDC, tetapi malangnya kami gagal untuk memulakannya dengan kumpulan, jadi penyepaduan dengan GitHub sangat sesuai untuk kami. Tanpa pemetaan kumpulan, dasar RBAC tidak akan dapat dibuat berdasarkan kumpulan.

Jadi, bagaimanakah proses kebenaran Kubernetes kami berfungsi dalam perwakilan visual:

Sahkan dalam Kubernetes menggunakan GitHub OAuth dan Dex
Proses kebenaran

Sedikit lebih terperinci dan titik demi titik:

  1. Pengguna log masuk ke dex-k8s-authenticator (login.k8s.example.com)
  2. dex-k8s-authenticator memajukan permintaan kepada Dex (dex.k8s.example.com)
  3. Dex mengubah hala ke halaman log masuk GitHub
  4. GitHub menjana maklumat kebenaran yang diperlukan dan mengembalikannya kepada Dex
  5. Dex menghantar maklumat yang diterima kepada dex-k8s-authenticator
  6. Pengguna menerima token OIDC daripada GitHub
  7. dex-k8s-authenticator menambah token ke kubeconfig
  8. kubectl menghantar token kepada KubeAPIServer
  9. KubeAPIServer mengembalikan akses kepada kubectl berdasarkan token yang diluluskan
  10. Pengguna mendapat akses daripada kubectl

Tindakan persediaan

Sudah tentu, kami sudah memasang kluster Kubernetes (k8s.example.com), dan turut disertakan dengan HELM yang diprapasang. Kami juga mempunyai organisasi di GitHub (super-org).
Jika anda tidak mempunyai HELM, pasangkannya sangat mudah.

Mula-mula kita perlu menyediakan GitHub.

Pergi ke halaman tetapan organisasi, (https://github.com/organizations/super-org/settings/applications) dan buat aplikasi baharu (Apl OAuth Dibenarkan):
Sahkan dalam Kubernetes menggunakan GitHub OAuth dan Dex
Mencipta aplikasi baharu pada GitHub

Isikan medan dengan URL yang diperlukan, contohnya:

  • URL halaman utama: https://dex.k8s.example.com
  • URL panggilan balik kebenaran: https://dex.k8s.example.com/callback

Berhati-hati dengan pautan, adalah penting untuk tidak kehilangan garis miring.

Sebagai tindak balas kepada borang yang lengkap, GitHub akan menjana Client ID ΠΈ Client secret, simpan di tempat yang selamat, ia akan berguna kepada kita (contohnya, kita gunakan Bilik Kebal untuk menyimpan rahsia):

Client ID: 1ab2c3d4e5f6g7h8
Client secret: 98z76y54x32w1

Sediakan rekod DNS untuk subdomain login.k8s.example.com ΠΈ dex.k8s.example.com, serta sijil SSL untuk kemasukan.

Mari buat sijil 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

KlusterIsuer dengan tajuk le-clusterissuer sepatutnya sudah wujud, tetapi jika tidak, ciptakannya menggunakan 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

Konfigurasi KubeAPIServer

Untuk kubeAPIServer berfungsi, anda perlu mengkonfigurasi OIDC dan mengemas kini kluster:

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

Kami guna tendang untuk menggunakan kluster, tetapi ini berfungsi sama untuk pengurus kluster lain.

Konfigurasi dex dan dex-k8s-authenticator

Untuk Dex berfungsi, anda perlu mempunyai sijil dan kunci daripada tuan Kubernetes, mari dapatkannya dari sana:

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

Mari kita klon repositori dex-k8s-authenticator:

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

Menggunakan fail nilai, kami boleh mengkonfigurasi pembolehubah secara fleksibel untuk kami Carta HELM.

Mari kita terangkan konfigurasi untuk 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

Dan untuk 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

Pasang Dex dan 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

Mari semak kefungsian perkhidmatan (Dex harus mengembalikan kod 400 dan dex-k8s-authenticator harus mengembalikan 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

Konfigurasi RBAC

Kami mencipta ClusterRole untuk kumpulan, dalam kes kami dengan akses baca sahaja:

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

Mari buat konfigurasi untuk 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

Sekarang kami bersedia untuk ujian.

Ujian

Pergi ke halaman log masuk (https://login.k8s.example.com) dan log masuk menggunakan akaun GitHub anda:

Sahkan dalam Kubernetes menggunakan GitHub OAuth dan Dex
Halaman log masuk

Sahkan dalam Kubernetes menggunakan GitHub OAuth dan Dex
Halaman log masuk diubah hala ke GitHub

Sahkan dalam Kubernetes menggunakan GitHub OAuth dan Dex
 Ikuti arahan yang dijana untuk mendapatkan akses

Selepas menyalin-tampal daripada halaman web, kami boleh menggunakan kubectl untuk mengurus sumber kluster kami:

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"

Dan ia berfungsi, semua pengguna GitHub dalam organisasi kami boleh melihat sumber dan log masuk ke pod, tetapi mereka tidak mempunyai hak untuk mengubahnya.

Sumber: www.habr.com

Tambah komen