Otentikasi di Kubernetes menggunakan GitHub OAuth dan Dex

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

Otentikasi di Kubernetes menggunakan GitHub OAuth dan Dex
Meme lokal dari obrolan Kubernetes berbahasa Rusia Telegram

pengenalan

Kami menggunakan Kubernetes untuk menciptakan lingkungan dinamis untuk tim pengembangan dan QA. Jadi kami ingin memberi mereka akses ke cluster untuk dashboard dan kubectl. Tidak seperti OpenShift, vanilla Kubernetes tidak memiliki autentikasi 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, tapi sayangnya kami gagal untuk memulainya dengan grup, jadi integrasi dengan GitHub cocok untuk kami. Tanpa pemetaan kelompok, tidak mungkin tercipta kebijakan RBAC yang berbasis kelompok.

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

Otentikasi di Kubernetes menggunakan GitHub OAuth dan Dex
Proses otorisasi

Sedikit lebih detail dan poin demi poin:

  1. Pengguna masuk ke dex-k8s-authenticator (login.k8s.example.com)
  2. dex-k8s-authenticator meneruskan 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 menerima token OIDC dari GitHub
  7. dex-k8s-authenticator menambahkan token ke kubeconfig
  8. kubectl meneruskan token ke KubeAPIServer
  9. KubeAPIServer mengembalikan akses ke kubectl berdasarkan token yang diteruskan
  10. Pengguna mendapat akses dari kubectl

Tindakan persiapan

Tentu saja, kami sudah menginstal cluster Kubernetes (k8s.example.com), dan juga dilengkapi dengan HELM yang sudah diinstal sebelumnya. Kami juga memiliki organisasi di GitHub (super-org).
Jika Anda tidak memiliki HELM, instal sangat sederhana.

Pertama kita perlu menyiapkan GitHub.

Buka halaman pengaturan organisasi, (https://github.com/organizations/super-org/settings/applications) dan buat aplikasi baru (Aplikasi OAuth Resmi):
Otentikasi di Kubernetes menggunakan GitHub OAuth dan Dex
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 sudah diisi, GitHub akan menghasilkan Client ID ΠΈ Client secret, simpanlah di tempat yang aman, karena akan berguna bagi kita (misalnya kita gunakan Kubah untuk menyimpan rahasia):

Client ID: 1ab2c3d4e5f6g7h8
Client secret: 98z76y54x32w1

Siapkan catatan DNS untuk subdomain login.k8s.example.com ΠΈ dex.k8s.example.com, serta sertifikat SSL untuk masuknya.

Mari membuat 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

ClusterIssuer dengan judul le-clusterissuer seharusnya sudah ada, namun jika belum, buatlah 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

Agar kubeAPIServer dapat berfungsi, Anda perlu mengkonfigurasi 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

Kita gunakan tendangan untuk menyebarkan cluster, tetapi cara kerjanya serupa manajer cluster lainnya.

Konfigurasi Dex dan dex-k8s-authenticator

Agar Dex dapat berfungsi, Anda harus memiliki sertifikat dan kunci dari master Kubernetes, mari kita ambil 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 kloning repositori dex-k8s-authenticator:

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

Dengan menggunakan file nilai, kita dapat secara fleksibel mengonfigurasi variabel untuk file kita grafik HELM.

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 fungsionalitas layanan (Dex harus mengembalikan kode 400, dan dex-k8s-authenticator harus mengembalikan 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

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

Uji

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

Otentikasi di Kubernetes menggunakan GitHub OAuth dan Dex
Halaman masuk

Otentikasi di Kubernetes menggunakan GitHub OAuth dan Dex
Halaman login dialihkan ke GitHub

Otentikasi di Kubernetes menggunakan GitHub OAuth dan Dex
 Ikuti instruksi yang dihasilkan untuk mendapatkan akses

Setelah menyalin-menempelkan halaman web, kita dapat menggunakan kubectl untuk mengelola sumber daya cluster kita:

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 ini berhasil, semua pengguna GitHub di organisasi kami dapat melihat sumber daya dan masuk ke pod, tetapi mereka tidak memiliki hak untuk mengubahnya.

Sumber: www.habr.com

Tambah komentar