Otentikasi di Kubernetes dengan GitHub OAuth dan Dex

Saya menyajikan kepada Anda tutorial untuk menghasilkan akses ke kluster Kubernetes menggunakan Dex, dex-k8s-authenticator dan GitHub.

gambar

Meme lokal dari obrolan bahasa Rusia Kubernetes di Telegram

Pendahuluan


Kami menggunakan Kubernetes untuk menciptakan lingkungan yang dinamis untuk tim pengembangan dan QA. Jadi, kami ingin memberi mereka akses ke cluster untuk dasbor dan kubectl. Tidak seperti OpenShift, vanilla Kubernetes tidak memiliki otentikasi asli, jadi kami menggunakan alat pihak ketiga untuk ini.

Dalam konfigurasi ini, kami menggunakan:

  • dex-k8s-authenticator - aplikasi web untuk menghasilkan konfigurasi kubectl
  • Dex - Penyedia OpenID Connect
  • GitHub - hanya karena kami menggunakan GitHub di perusahaan kami

Kami mencoba menggunakan Google OIDC, tetapi sayangnya kami tidak dapat membuatnya dalam grup, jadi integrasi dengan GitHub baik-baik saja dengan kami. Tanpa pemetaan grup, Anda tidak dapat membuat kebijakan RBAC berbasis grup.

Jadi, bagaimana proses otorisasi kami di Kubernetes bekerja dalam representasi visual:

gambar
Proses otorisasi

Sedikit lebih detail dan poin:

  1. Pengguna masuk ke dex-k8s-authenticator ( login.k8s.example.com )
  2. dex-k8s-authenticator mengalihkan permintaan ke Dex ( dex.k8s.example.com )
  3. Dex mengalihkan ke halaman login GitHub
  4. GitHub menghasilkan informasi otorisasi yang diperlukan dan mengembalikannya ke Dex
  5. Dex meneruskan informasi yang diterima ke dex-k8s-authenticator
  6. Pengguna mendapat token OIDC dari GitHub
  7. dex-k8s-authenticator menambahkan token ke kubeconfig
  8. kubectl meneruskan token ke KubeAPIServer
  9. KubeAPIServer berdasarkan token yang dikembalikan mengakses di kubectl
  10. Pengguna mendapat akses dari kubectl

Kegiatan Persiapan


Tentu saja, kami sudah menginstal cluster k8s.example.com ( k8s.example.com ), serta BANTUAN. Kami juga memiliki organisasi di GitHub (super-org).
Jika Anda tidak memiliki BANTUAN, sangat mudah untuk menginstal.

Pertama kita perlu mengkonfigurasi GitHub.

Buka halaman pengaturan organisasi, ( https://github.com/organizations/super-org/settings/applications ) dan buat aplikasi baru (Aplikasi OAuth Resmi):
gambar
Membuat aplikasi baru di GitHub

Isi kolom dengan URL yang diperlukan, misalnya:

  • URL Beranda: https://dex.k8s.example.com
  • URL panggilan balik otorisasi: https://dex.k8s.example.com/callback

Hati-hati dengan tautan, penting untuk tidak kehilangan garis miring.

Menanggapi formulir yang telah diisi, GitHub akan menghasilkan Client ID dan Client secret , menyimpannya di tempat yang aman, mereka akan berguna bagi kami (misalnya, kami menggunakan Vault untuk menyimpan rahasia):

 Client ID: 1ab2c3d4e5f6g7h8 Client secret: 98z76y54x32w1 

Mempersiapkan data DNS untuk subdomain login.k8s.example.com dan dex.k8s.example.com , serta sertifikat SSL untuk ingress.

Buat sertifikat 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 

Seorang pengirim le-clusterissuer dengan nama le-clusterissuer seharusnya sudah ada, jika tidak, buat 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: k8s-admin@example.com privateKeySecretRef: name: le-clusterissuer http01: {} EOF 

Konfigurasi KubeAPIServer


Agar kubeAPIServer berfungsi, Anda harus mengonfigurasi OIDC dan memperbarui 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 

Kami menggunakan kops untuk menyebarkan cluster, tetapi berfungsi sama untuk manajer cluster lainnya .

Konfigurasi Dex dan dex-k8s-authenticator


Agar Dex berfungsi, Anda harus memiliki sertifikat dan kunci dari master Kubernetes, menariknya dari sana:

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

Klon repositori dex-k8s-authenticator:

 git clone git@github.com:mintel/dex-k8s-authenticator.git cd dex-k8s-authenticator/ 

Menggunakan nilai-file kita dapat secara fleksibel mengatur variabel untuk bagan HELM kami.

Mari kita jelaskan 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 

Instal 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 kita periksa kemudahan servis dari layanan (Dex harus mengembalikan kode 400, dan dex-k8s-authenticator - kode 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 membuat ClusterRole untuk grup, dalam kasus kami dengan akses hanya baca:

 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 

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 siap untuk pengujian.

Tes


Kami masuk ke halaman login ( https://login.k8s.example.com ) dan masuk menggunakan akun GitHub:

gambar
Halaman login

gambar
Halaman login dialihkan ke GitHub

gambar
Ikuti instruksi yang dihasilkan untuk akses

Setelah salin-tempel dari halaman web, kita dapat menggunakan kubectl untuk mengelola sumber daya cluster 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 "amet@example.com" cannot delete pods in the namespace "default" 

Dan itu berhasil, semua pengguna GitHub di organisasi kami dapat melihat sumber daya dan memasukkan pod, tetapi mereka tidak memiliki hak untuk mengubahnya.

Source: https://habr.com/ru/post/id436238/


All Articles