User Tools

Site Tools


управление_доступом_в_kubernetes

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
управление_доступом_в_kubernetes [2025/12/18 12:36]
val [Демонстрация OIDC]
управление_доступом_в_kubernetes [2026/01/13 09:39] (current)
val [Шаг 7. Использование OpenID Connect]
Line 15: Line 15:
   * [[https://​medium.com/​@subhampradhan966/​implementing-and-verifying-kubernetes-service-accounts-a-step-by-step-guide-c43b727260b2|Implementing and Verifying Kubernetes Service Accounts: A Step-by-Step Guide]]   * [[https://​medium.com/​@subhampradhan966/​implementing-and-verifying-kubernetes-service-accounts-a-step-by-step-guide-c43b727260b2|Implementing and Verifying Kubernetes Service Accounts: A Step-by-Step Guide]]
  
- +  * [[https://​medium.com/​@amirhosseineidy/​kubernetes-authentication-with-keycloak-oidc-63571eaeed61|Kubernetes authentication with keycloak oidc]] 
 +  * [[https://​vlasov.pro/​ru/​p/​kubernetes-oidc/​|Kubernetes авторизация через OIDC]] 
 +  * [[https://​timeweb.cloud/​docs/​k8s/​connect-oidc-provider-to-cluster|Подключение OIDC-провайдера к кластеру]] 
 +  * [[https://​www.talkingquickly.co.uk/​setting-up-oidc-login-kubernetes-kubectl-with-keycloak|OIDC Login to Kubernetes and Kubectl with Keycloak]] 
 +  * [[https://​github.com/​int128/​kubelogin|kubelogin - This is a kubectl plugin for Kubernetes OpenID Connect]]
  
 ===== Реклама ===== ===== Реклама =====
Line 101: Line 104:
  
 kube1:​~/​users#​ kubectl delete serviceaccounts admin-user kube1:​~/​users#​ kubectl delete serviceaccounts admin-user
 +
 +user1@client1:​~$ rm -rf .kube/
 </​code>​ </​code>​
 ===== Шаг 6. Использование Service Accounts в приложениях ===== ===== Шаг 6. Использование Service Accounts в приложениях =====
Line 145: Line 150:
 </​code>​ </​code>​
  
-===== Вопросы? =====+===== Шаг 7. Использование OpenID Connect ​=====
  
-===== Домашнее задание ===== +  * Сервис Keycloak [[Сервис Keycloak#​Аутентификация пользователей WEB приложения]] 
- +  * !!! в конфигурации kube-apiserver ​параметра client-secret нет ​и не требуется !!!
-  - Куда и через сколько исчезает "​kubectl get csr" ​после "​approve"​ ?  +
- +
-===== Перезапуск вебинара =====+
 <​code>​ <​code>​
-user1@client1:​~$ rm -v user1* 
- 
-user1@client1:​~$ rm -rfv .kube/ 
- 
-kube1:~# rm -rfv users/ 
-</​code>​ 
- 
-===== Дополнительные материалы ===== 
- 
-==== Демонстрация OIDC ==== 
- 
-<​code>​ 
-user1@client1:​~$ cp -rv .kube.iodc/ .kube/ 
-</​code>​ 
- 
-  * Открываем браузер 
-  * Подколючемся к giltab через keycloak 
-<​code>​ 
-user1@client1:​~$ kubelogin 
- 
-user1@client1:​~$ kubectl auth whoami 
-</​code>​ 
- 
-  * [[Система Kubernetes#​Предоставление полного доступа к Kubernetes Cluster]] 
- 
- 
-==== Черновик OIDC ==== 
-<​code>​ 
-https://​medium.com/​@amirhosseineidy/​kubernetes-authentication-with-keycloak-oidc-63571eaeed61 
- 
-https://​vlasov.pro/​ru/​p/​kubernetes-oidc/​ 
- 
-https://​github.com/​int128/​kubelogin 
- 
-https://​timeweb.cloud/​docs/​k8s/​connect-oidc-provider-to-cluster 
- 
-? https://​www.talkingquickly.co.uk/​setting-up-oidc-login-kubernetes-kubectl-with-keycloak 
- 
-Email verified 
- 
 kube1:​~/​users#​ vim /​etc/​kubernetes/​manifests/​kube-apiserver.yaml kube1:​~/​users#​ vim /​etc/​kubernetes/​manifests/​kube-apiserver.yaml
 +</​code><​code>​
 ... ...
 spec: spec:
Line 199: Line 162:
   - command:   - command:
     - kube-apiserver     - kube-apiserver
-    - --oidc-issuer-url=https://​keycloak.corp13.un/realms/corp13+    - --oidc-issuer-url=https://​keycloak.corpX.un/realms/corpX
     #- --oidc-client-id=account     #- --oidc-client-id=account
     - --oidc-client-id=any-client     - --oidc-client-id=any-client
Line 206: Line 169:
     - --oidc-groups-claim=groups     - --oidc-groups-claim=groups
 ... ...
 +</​code><​code>​
 +kube1:~# ps ax | grep kube-apiserver
  
-kube1:~/users# kubectl -n kube-system logs Pod/​kube-apiserver-kube1+kube1:~# journalctl -f | grep kube-apiserver 
 + 
 +kube1/2:~# kubectl -n kube-system logs Pod/​kube-apiserver-kube1 
 +... 
 +Error: unknown flag: --oidc-client-secret
 ... ...
 E1203 05:​22:​46.412571 ​      1 authentication.go:​73] "​Unable to authenticate the request"​ err="​[invalid bearer token, oidc: verify token: oidc: expected audience \"​any-client\"​ got [\"​account\"​]]"​ E1203 05:​22:​46.412571 ​      1 authentication.go:​73] "​Unable to authenticate the request"​ err="​[invalid bearer token, oidc: verify token: oidc: expected audience \"​any-client\"​ got [\"​account\"​]]"​
 ... ...
 +E1218 10:​36:​21.105422 ​      1 authentication.go:​75] "​Unable to authenticate the request"​ err="​[invalid bearer token, oidc: email not verified]"​
 +...
 +</​code>​
 +
 +  * [[Сервис Keycloak#​Проверка получения токена]] Keycloak ​
 +  * [[Система Kubernetes#​Создание файла конфигурации kubectl]] c полученным токеном
 +
 +<​code>​
 +client1:~# wget https://​github.com/​int128/​kubelogin/​releases/​download/​v1.35.0/​kubelogin_linux_amd64.zip
 +
 +client1:~# unzip kubelogin_linux_amd64.zip
 +
 +client1:~# mv kubelogin /​usr/​local/​bin/​
  
 user1@client1:​~$ cat .kube/​config user1@client1:​~$ cat .kube/​config
-apiVersion: v1 +</​code><​code>​ 
-clusters: +...
-- cluster: +
-    certificate-authority-data: ​... +
-    server: https://​192.168.13.221:​6443 +
-  name: cluster.local +
-contexts: +
-- context: +
-    cluster: cluster.local +
-    user: user1 +
-  name: default-context +
-current-context:​ default-context +
-kind: Config +
-preferences:​ {}+
 users: users:
 - name: user1 - name: user1
Line 239: Line 209:
         #​refresh-token: ​         #​refresh-token: ​
       name: oidc       name: oidc
 +</​code><​code>​
 +user1@client1:​~$ kubelogin
  
 +user1@client1:​~$ kubectl auth whoami
 </​code>​ </​code>​
 +
 +  * [[Система Kubernetes#​Предоставление полного доступа к Kubernetes Cluster]]
 +
 +===== Вопросы?​ =====
 +
 +===== Домашнее задание =====
 +
 +  - Куда и через сколько исчезает "​kubectl get csr" после "​approve"​ ? 
 +
 +===== Перезапуск вебинара =====
 +<​code>​
 +user1@client1:​~$ rm -v user1*
 +
 +user1@client1:​~$ rm -rfv .kube/
 +
 +kube1:~# rm -rfv users/
 +</​code>​
 +
 +===== Дополнительные материалы =====
 +
 ==== Черновик Auditing ==== ==== Черновик Auditing ====
 <​code>​ <​code>​
Line 296: Line 289:
  
 ==== Черновик DEX ==== ==== Черновик DEX ====
 +
 +=== Описание ===
 <​code>​ <​code>​
 Создаём группы и пользователей под Kubernetes Создаём группы и пользователей под Kubernetes
Line 631: Line 626:
  
 Применяем файл ​ test-pod.txt Применяем файл ​ test-pod.txt
- 
  
 И тестируем права И тестируем права
Line 638: Line 632:
  
 Если не пускает польз когда у него права только на один ns то надо дать права на просмотр. Если не пускает польз когда у него права только на один ns то надо дать права на просмотр.
 +</​code>​
 +
 +=== Файлы ===
 +<​code>​
 +=== role.txt ===
 +apiVersion: rbac.authorization.k8s.io/​v1
 +kind: ClusterRoleBinding
 +metadata:
 +  name: k8s-admins
 +subjects:
 +  - kind: Group
 +    name: k8s-cluster-admins ​        # ИМЯ ГРУППЫ из FreeIPA
 +    apiGroup: rbac.authorization.k8s.io
 +roleRef:
 +  kind: ClusterRole
 +  name: cluster-admin
 +  apiGroup: rbac.authorization.k8s.io
 +---
 +# 1) Админы НС core-test-admin
 +apiVersion: rbac.authorization.k8s.io/​v1
 +kind: RoleBinding
 +metadata:
 +  name: core-test-admin-admins
 +  namespace: core-test-admin
 +subjects:
 +  - kind: Group
 +    name: k8s-ns-core-test-admin ​         # ГРУППА из токена Dex / FreeIPA
 +    apiGroup: rbac.authorization.k8s.io
 +roleRef:
 +  kind: ClusterRole
 +  name: admin                             # встроенная роль с полным доступом в ns
 +  apiGroup: rbac.authorization.k8s.io
 +---
 +# 2) Вьюеры НС core-test-view
 +apiVersion: rbac.authorization.k8s.io/​v1
 +kind: RoleBinding
 +metadata:
 +  name: core-test-view-viewers
 +  namespace: core-test-view
 +subjects:
 +  - kind: Group
 +    name: k8s-ns-core-test-view ​          # ГРУППА для read-only в этом ns
 +    apiGroup: rbac.authorization.k8s.io
 +roleRef:
 +  kind: ClusterRole
 +  name: view                              # встроенная read-only роль для ns
 +  apiGroup: rbac.authorization.k8s.io
 +---
 +# 3) Read-only по всему кластеру для группы k8s-ns
 +apiVersion: rbac.authorization.k8s.io/​v1
 +kind: ClusterRoleBinding
 +metadata:
 +  name: k8s-ns-read-all
 +subjects:
 +  - kind: Group
 +    name: k8s-ns ​                          # ГРУППА "​общие зрители k8s"
 +    apiGroup: rbac.authorization.k8s.io
 +roleRef:
 +  kind: ClusterRole
 +  name: view                               # cluster-wide view
 +  apiGroup: rbac.authorization.k8s.io
 +
 +
 +kubectl apply -f k8s-admins-rbac.yaml
 +kubectl get clusterrolebinding k8s-admins -o yaml
 +
 +=== issuer.txt ===
 +apiVersion: cert-manager.io/​v1
 +kind: ClusterIssuer
 +metadata:
 +  name: freeipa-acme
 +spec:
 +  acme:
 +    email: admin@teach.local
 +    server: https://​ipa-server-1.teach.local/​acme/​directory
 +    privateKeySecretRef:​
 +      name: freeipa-acme-account-key
 +
 +    # ВАЖНО: одна длинная строка из ipa-ca.b64
 +    caBundle: ПОДСТАВЬ_ЗДЕСЬ_СТРОКУ_ИЗ_ipa-ca.b64
 +
 +    solvers:
 +      - http01:
 +          ingress:
 +            ingressClassName:​ nginx
 +
 +=== dex-auth-values.txt ===
 +global:
 +  deployEnv: dev
 +
 +image:
 +  repository: mintel/​dex-k8s-authenticator
 +  tag: 1.4.0
 +  pullPolicy: Always
 +
 +dexK8sAuthenticator:​
 +  port: 5555
 +  debug: true
 +  web_path_prefix:​ /
 +  clusters:
 +    - name: teach-cluster
 +      short_description:​ "​Учебный кластер"​
 +      description:​ "​Kubespray кластер teach.local"​
 +
 +      # ДОЛЖНО совпадать с issuer у Dex и --oidc-issuer-url у kube-apiserver
 +      issuer: https://​dex.teach.local/​dex
 +
 +      # Адрес API-сервера кластера
 +      k8s_master_uri:​ https://​192.168.100.230:​6443
 +
 +      # Те же client_id / secret, что в staticClients Dex
 +      client_id: dex-k8s-authenticator
 +      client_secret:​ 9f3b2e3a7a8d14d0a5ff4b1b8e92c3de0b6b7f21a4e59bd8c1f3d2e7c8a9b0c1
 +
 +      # ДОЛЖНО 1-в-1 совпадать с redirectURIs в Dex для этого клиента
 +  ​
 +      redirect_uri:​ https://​auth.teach.local/​callback
 +
 +      k8s_ca_pem: |
 +        -----BEGIN CERTIFICATE-----
 +        ТУТ ЦЕЛИКОМ СОДЕРЖИМОЕ /​etc/​kubernetes/​ssl/​ca.crt
 +        БЕЗ base64, как есть
 +        -----END CERTIFICATE-----
 +
 +service:
 +  type: ClusterIP
 +  port: 5555
 +
 +ingress:
 +  enabled: true
 +  ingressClassName:​ nginx
 +  annotations:​ {}
 +  labels: {}
 +
 +  # В ЭТОМ чарте path один, для всех хостов:​
 +  path: /
 +
 +  # hosts — это СПИСОК СТРОК, а не объектов:​
 +  hosts:
 +    - auth.teach.local
 +
 +  tls:
 +    - secretName: dex-auth-tls
 +      hosts:
 +        - auth.teach.local
 +
 +# Чтобы убрать x509: unknown authority для Dex (FreeIPA CA)
 +caCerts:
 +  enabled: true
 +  secrets:
 +    - name: ipa-ca
 +      filename: ipa-ca.crt
 +      value: |-
 +        ТУТ_ОДНА_СТРОКА_BASE64_ОТ /​etc/​ipa/​ca.crt
 +   
 +=== config.txt ===
 +replicaCount:​ 1
 +
 +image:
 +  repository: ghcr.io/​dexidp/​dex
 +  tag: v2.44.0
 +  pullPolicy: IfNotPresent
 +
 +service:
 +  type: ClusterIP
 +  ports:
 +    http:
 +      port: 5556
 +
 +https:
 +  enabled: false
 +
 +grpc:
 +  enabled: false
 +
 +rbac:
 +  create: true
 +
 +podDisruptionBudget:​
 +  enabled: false
 +
 +networkPolicy:​
 +  enabled: false
 +
 +autoscaling:​
 +  enabled: false
 +
 +ingress:
 +  enabled: true
 +  className: nginx
 +  hosts:
 +    - host: dex.teach.local
 +      paths:
 +        - path: /dex/
 +          pathType: ImplementationSpecific
 +  tls:
 +    - secretName: dex-tls ​         # СЕКРЕТ,​ который делает cert-manager/​FreeIPA
 +      hosts:
 +        - dex.teach.local
 +
 +configSecret:​
 +  create: true
 +
 +serviceMonitor:​
 +  enabled: false
 +
 +serviceAccount:​
 +  create: true        # или false, если не нужен отдельный SA
 +  name: "" ​           # пусто = helm сам сгенерит имя по release
 +  annotations:​ {}
 +
 +config:
 +  issuer: https://​dex.teach.local/​dex
 +
 +  storage:
 +    type: kubernetes
 +    config:
 +      inCluster: true
 +    type: memory
 +
 +  web:
 +    http: 0.0.0.0:​5556
 +
 +  logger:
 +    level: debug
 +    format: text
 +
 +  oauth2:
 +    skipApprovalScreen:​ true
 +
 +  staticClients:​
 +    - id: example-app
 +      name: Example App
 +      secret: example-app-secret
 +      redirectURIs:​
 +        - http://​127.0.0.1:​5555/​callback
 +    - id: dex-k8s-authenticator
 +      name: Dex K8s Authenticator
 +      secret: SUPER-SECRET-STRING ​
 +      redirectURIs:​
 +        - https://​auth.teach.local/​callback
 +
 +
 +  connectors:
 +    - type: ldap
 +      id: freeipa
 +      name: FreeIPA
 +      config:
 +        host: 192.168.100.252:​389
 +        insecureNoSSL:​ true
 +        startTLS: false
 +
 +        bindDN: "​uid=dex-bind,​cn=users,​cn=accounts,​dc=teach,​dc=local"​
 +        bindPW: "​123456"​
 +
 +        userSearch:
 +          baseDN: "​cn=users,​cn=accounts,​dc=teach,​dc=local"​
 +          filter: "​(objectClass=person)"​
 +          emailAttr: "​mail"​
 +          idAttr: "​uid"​
 +          nameAttr: "​cn"​
 +          username: "​uid"​
 +
 +        groupSearch:​
 +          baseDN: "​cn=groups,​cn=accounts,​dc=teach,​dc=local"​
 +          filter: "​(objectClass=groupofnames)"​
 +          userAttr: "​dn"​
 +          groupAttr: "​member"​
 +          nameAttr: "​cn"​
 +
 +
 +=== certificate-auth.txt ===
 +apiVersion: cert-manager.io/​v1
 +kind: Certificate
 +metadata:
 +  name: dex-auth-cert
 +  namespace: dex-auth
 +spec:
 +  secretName: dex-auth-tls
 +  dnsNames:
 +    - auth.teach.local
 +  issuerRef:
 +    name: freeipa-acme
 +    kind: ClusterIssuer
 +
 +=== certificate.txt ===
 +apiVersion: cert-manager.io/​v1
 +kind: Certificate
 +metadata:
 +  name: dex-cert
 +  namespace: dex
 +spec:
 +  secretName: dex-tls
 +  dnsNames:
 +    - dex.teach.local
 +  issuerRef:
 +    name: freeipa-acme
 +    kind: ClusterIssuer
 +
 +=== test-pod.txt ===
 +apiVersion: v1
 +kind: Pod
 +metadata:
 +  name: admin-nginx
 +  namespace: core-test-admin
 +  labels:
 +    app: admin-nginx
 +spec:
 +  containers:
 +    - name: nginx
 +      image: nginx:1.27
 +      ports:
 +        - containerPort:​ 80
 +---
 +apiVersion: v1
 +kind: Pod
 +metadata:
 +  name: view-nginx
 +  namespace: core-test-view
 +  labels:
 +    app: view-nginx
 +spec:
 +  containers:
 +    - name: nginx
 +      image: nginx:1.27
 +      ports:
 +        - containerPort:​ 80
 </​code>​ </​code>​
управление_доступом_в_kubernetes.1766050581.txt.gz · Last modified: 2025/12/18 12:36 by val