GitHub OAuth va Dex yordamida Kubernetesda autentifikatsiya qiling

Men sizning e'tiboringizga Dex, dex-k8s-authenticator va GitHub yordamida Kubernetes klasteriga kirishni yaratish bo'yicha qo'llanmani taqdim etaman.

GitHub OAuth va Dex yordamida Kubernetesda autentifikatsiya qiling
Rus tilidagi Kubernetesning mahalliy memlari suhbatda Telegram

kirish

Biz Kubernetes-dan ishlab chiqish va QA jamoasi uchun dinamik muhit yaratish uchun foydalanamiz. Shunday qilib, biz ularga asboblar paneli va kubectl uchun klasterga kirish huquqini bermoqchimiz. OpenShift-dan farqli o'laroq, vanil Kubernetesda mahalliy autentifikatsiya yo'q, shuning uchun biz buning uchun uchinchi tomon vositalaridan foydalanamiz.

Ushbu konfiguratsiyada biz foydalanamiz:

  • dex-k8s-autentifikatsiyaβ€Š β€” kubectl konfiguratsiyasini yaratish uchun veb-ilova
  • Dex β€” OpenID Connect provayderi
  • GitHub - shunchaki kompaniyamizda GitHub-dan foydalanganimiz uchun

Biz Google OIDC dan foydalanishga harakat qildik, lekin afsuski, biz bajarilmadi ularni guruhlar bilan boshlash uchun, shuning uchun GitHub bilan integratsiya bizga juda mos keldi. Guruh xaritasisiz, guruhlarga asoslangan RBAC siyosatlarini yaratish mumkin bo'lmaydi.

Shunday qilib, bizning Kubernetes avtorizatsiya jarayoni vizual tasvirda qanday ishlaydi:

GitHub OAuth va Dex yordamida Kubernetesda autentifikatsiya qiling
Avtorizatsiya jarayoni

Bir oz ko'proq tafsilot va nuqta bo'yicha:

  1. Foydalanuvchi dex-k8s-authenticator tizimiga kiradi (login.k8s.example.com)
  2. dex-k8s-authenticator so'rovni Dexga yuboradi (dex.k8s.example.com)
  3. Dex GitHub kirish sahifasiga yo'naltiradi
  4. GitHub kerakli avtorizatsiya ma'lumotlarini ishlab chiqaradi va uni Dex-ga qaytaradi
  5. Dex olingan ma'lumotni dex-k8s-authenticatorga uzatadi
  6. Foydalanuvchi GitHub'dan OIDC tokenini oladi
  7. dex-k8s-authenticator kubeconfig-ga token qo'shadi
  8. kubectl tokenni KubeAPIServerga uzatadi
  9. KubeAPIServer o'tkazilgan token asosida kubectl-ga kirishlarni qaytaradi
  10. Foydalanuvchi kubectl-dan ruxsat oladi

Tayyorgarlik harakatlari

Albatta, bizda allaqachon Kubernetes klasteri o'rnatilgan (k8s.example.com), shuningdek, oldindan o'rnatilgan HELM bilan birga keladi. GitHub (super-org) da bizning tashkilotimiz ham bor.
Agar sizda HELM bo'lmasa, uni o'rnating juda oddiy.

Avval GitHub-ni sozlashimiz kerak.

Tashkilot sozlamalari sahifasiga o'ting, (https://github.com/organizations/super-org/settings/applications) va yangi ilova yarating (Authorized OAuth App):
GitHub OAuth va Dex yordamida Kubernetesda autentifikatsiya qiling
GitHub-da yangi dastur yaratish

Maydonlarni kerakli URL manzillari bilan to'ldiring, masalan:

  • Bosh sahifa URL: https://dex.k8s.example.com
  • Avtorizatsiya uchun qayta qo'ng'iroq qilish URL manzili: https://dex.k8s.example.com/callback

Havolalar bilan ehtiyot bo'ling, slashlarni yo'qotmaslik muhimdir.

To'ldirilgan shaklga javoban GitHub yaratadi Client ID ΠΈ Client secret, ularni xavfsiz joyda saqlang, ular biz uchun foydali bo'ladi (masalan, biz foydalanamiz bank seyfi sirlarni saqlash uchun):

Client ID: 1ab2c3d4e5f6g7h8
Client secret: 98z76y54x32w1

Subdomenlar uchun DNS yozuvlarini tayyorlang login.k8s.example.com ΠΈ dex.k8s.example.com, shuningdek kirish uchun SSL sertifikatlari.

Keling, SSL sertifikatlarini yarataylik:

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

Sarlavhali ClusterIssuer le-clusterissuer allaqachon mavjud bo'lishi kerak, lekin agar bo'lmasa, uni HELM yordamida yarating:

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

KubeAPIServer konfiguratsiyasi

KubeAPIServer ishlashi uchun siz OIDC ni sozlashingiz va klasterni yangilashingiz kerak:

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

Biz foydalanamiz tepmoq klasterlarni joylashtirish uchun, lekin bu xuddi shunday ishlaydi boshqa klaster menejerlari.

Dex konfiguratsiyasi va dex-k8s-authenticator

Dex ishlashi uchun sizda Kubernetes ustasidan sertifikat va kalit bo'lishi kerak, keling, uni u yerdan olamiz:

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

Keling, dex-k8s-authenticator omborini klonlaylik:

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

Qiymatlar fayllaridan foydalanib, biz o'zgaruvchilarimiz uchun moslashuvchan tarzda sozlashimiz mumkin HELM diagrammalari.

Dex uchun konfiguratsiyani tasvirlab beraylik:

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

Va dex-k8s-authenticator uchun:

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

Dex va dex-k8s-authenticatorni o'rnating:

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

Xizmatlarning funksionalligini tekshiramiz (Dex 400 kodini, dex-k8s-authenticator esa 200 kodini qaytarishi kerak):

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

RBAC konfiguratsiyasi

Biz guruh uchun ClusterRole yaratamiz, bizning holatlarimizda faqat o'qish uchun ruxsat mavjud:

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

Keling, ClusterRoleBinding uchun konfiguratsiya yarataylik:

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

Endi biz sinovga tayyormiz.

Sinovlar

Kirish sahifasiga o'ting (https://login.k8s.example.com) va GitHub hisobingizdan foydalanib tizimga kiring:

GitHub OAuth va Dex yordamida Kubernetesda autentifikatsiya qiling
Kirish sahifasi

GitHub OAuth va Dex yordamida Kubernetesda autentifikatsiya qiling
Kirish sahifasi GitHub-ga yo'naltirildi

GitHub OAuth va Dex yordamida Kubernetesda autentifikatsiya qiling
 Kirish uchun yaratilgan ko'rsatmalarga amal qiling

Veb-sahifadan nusxa ko'chirgandan so'ng, biz kubectl dan klaster resurslarimizni boshqarish uchun foydalanishimiz mumkin:

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"

Va u ishlaydi, tashkilotimizdagi barcha GitHub foydalanuvchilari resurslarni ko'rishlari va podlarga kirishlari mumkin, ammo ularni o'zgartirish huquqiga ega emaslar.

Manba: www.habr.com

a Izoh qo'shish