GitHub OAuth және Dex көмегімен Kubernetes-те аутентификация

Мен сіздердің назарларыңызға Dex, dex-k8s-authenticator және GitHub көмегімен Kubernetes кластеріне кіруге арналған оқулықты ұсынамын.

GitHub OAuth және Dex көмегімен Kubernetes-те аутентификация
Орыс тілді Kubernetes жергілікті мем чатта Telegram

Кіріспе

Біз Кубернеттерді әзірлеу және QA тобы үшін динамикалық орталар жасау үшін пайдаланамыз. Сондықтан біз оларға бақылау тақтасы мен kubectl үшін кластерге кіруге рұқсат бергіміз келеді. OpenShift-тен айырмашылығы, ваниль Кубернетестің түпнұсқалық аутентификациясы жоқ, сондықтан біз бұл үшін үшінші тарап құралдарын пайдаланамыз.

Бұл конфигурацияда біз пайдаланамыз:

  • dex-k8s-аутентификация  — kubectl конфигурациясын жасауға арналған веб-қосымша
  • Dex — OpenID Connect провайдері
  • GitHub - жай ғана компаниямызда GitHub-ті пайдаланатындықтан

Біз Google OIDC қолдануға тырыстық, бірақ өкінішке орай сәтсіз болды оларды топтардан бастау үшін, сондықтан GitHub-пен интеграция бізге өте қолайлы болды. Топтық салыстырусыз топтарға негізделген RBAC саясаттарын жасау мүмкін болмайды.

Сонымен, біздің Kubernetes авторизациялау процесі визуалды көріністе қалай жұмыс істейді:

GitHub OAuth және Dex көмегімен Kubernetes-те аутентификация
Авторизациялау процесі

Толығырақ және нүкте бойынша:

  1. Пайдаланушы dex-k8s-authenticator жүйесіне кіреді (login.k8s.example.com)
  2. dex-k8s-аутентификатор сұрауды Dex-ке жібереді (dex.k8s.example.com)
  3. Dex GitHub кіру бетіне қайта бағыттайды
  4. GitHub қажетті рұқсат ақпаратын жасайды және оны Dex-ке қайтарады
  5. Dex алынған ақпаратты dex-k8s-аутентификаторға береді
  6. Пайдаланушы GitHub жүйесінен OIDC таңбалауышын алады
  7. dex-k8s-аутентификаторы kubeconfig-ге таңбалауыш қосады
  8. kubectl таңбалауышты KubeAPIServer қызметіне жібереді
  9. KubeAPIServer берілген таңбалауыш негізінде kubectl қатынасуларын қайтарады
  10. Пайдаланушы kubectl арқылы қол жеткізе алады

Дайындық әрекеттері

Әрине, бізде Kubernetes кластері орнатылған (k8s.example.com), сонымен қатар алдын ала орнатылған HELM бағдарламасымен бірге жеткізіледі. Бізде GitHub (super-org) сайтында да ұйым бар.
Егер сізде HELM жоқ болса, оны орнатыңыз өте оңай.

Алдымен GitHub орнатуымыз керек.

Ұйым параметрлері бетіне өтіңіз, (https://github.com/organizations/super-org/settings/applications) және жаңа қолданбаны жасаңыз (Authorized OAuth App):
GitHub OAuth және Dex көмегімен Kubernetes-те аутентификация
GitHub жүйесінде жаңа қолданба жасау

Өрістерді қажетті URL мекенжайларымен толтырыңыз, мысалы:

  • Негізгі бет URL: https://dex.k8s.example.com
  • Авторизацияның кері шақыру URL мекенжайы: https://dex.k8s.example.com/callback

Сілтемелермен абай болыңыз, қиғаш сызықтарды жоғалтпау маңызды.

Толтырылған пішінге жауап ретінде GitHub жасайды Client ID и Client secret, оларды қауіпсіз жерде сақтаңыз, олар бізге пайдалы болады (мысалы, біз қолданамыз Қойма құпияларды сақтау үшін):

Client ID: 1ab2c3d4e5f6g7h8
Client secret: 98z76y54x32w1

Ішкі домендер үшін DNS жазбаларын дайындаңыз login.k8s.example.com и dex.k8s.example.com, сонымен қатар кіру үшін SSL сертификаттары.

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 le-clusterissuer бұрыннан бар болуы керек, бірақ егер жоқ болса, оны 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

KubeAPIServer конфигурациясы

kubeAPIServer жұмыс істеуі үшін OIDC конфигурациялау және кластерді жаңарту қажет:

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

Біз қолданамыз коп кластерлерді орналастыру үшін, бірақ бұл үшін бірдей жұмыс істейді басқа кластер менеджерлері.

Dex конфигурациясы және dex-k8s-аутентификация

Dex жұмыс істеуі үшін сізде Kubernetes шеберінің сертификаты мен кілті болуы керек, оны сол жерден алайық:

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

dex-k8s-аутентификатор репозиторийін клондаймыз:

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

Мәндер файлдарын пайдалана отырып, біз айнымалы мәндерді икемді түрде конфигурациялай аламыз HELM диаграммалары.

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

Ал dex-k8s-аутентификаторы үшін:

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 және dex-k8s-аутентификаторын орнатыңыз:

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

Қызметтердің функционалдығын тексерейік (Dex 400 кодын, ал dex-k8s-аутентификаторы 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

RBAC конфигурациясы

Біз топ үшін ClusterRole жасаймыз, біздің жағдайда тек оқуға рұқсаты бар:

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

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

Енді біз тестілеуге дайынбыз.

Тесттер

Жүйеге кіру бетіне өтіңіз (https://login.k8s.example.com) және GitHub тіркелгіңізді пайдаланып жүйеге кіріңіз:

GitHub OAuth және Dex көмегімен Kubernetes-те аутентификация
Жүйеге кіру беті

GitHub OAuth және Dex көмегімен Kubernetes-те аутентификация
Жүйеге кіру беті GitHub қызметіне қайта бағытталды

GitHub OAuth және Dex көмегімен Kubernetes-те аутентификация
 Қол жеткізу үшін жасалған нұсқауларды орындаңыз

Веб-беттен көшіру-қоюдан кейін біз кластер ресурстарын басқару үшін kubectl пайдалана аламыз:

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"

Және ол жұмыс істейді, ұйымымыздағы барлық GitHub пайдаланушылары ресурстарды көріп, подкасттарға кіре алады, бірақ оларды өзгертуге құқықтары жоқ.

Ақпарат көзі: www.habr.com

пікір қалдыру