Налаштування службових облікових записів для Podʼів
Kubernetes пропонує два відмінні способи автентифікації для клієнтів, які працюють у межах вашого кластера або мають взаємозвʼязок з панеллю управління вашого кластера для автентифікації в API-сервері.
Службовий обліковий запис надає ідентичність процесам, які працюють у Podʼі, і відповідає обʼєкту ServiceAccount. Коли ви автентифікуєтеся в API-сервері, ви ідентифікуєте себе як певного користувача. Kubernetes визнає поняття користувача, але сам Kubernetes не має API User.
Це завдання стосується Службових облікових записів, які існують в API Kubernetes. Керівництво показує вам деякі способи налаштування Службових облікових записів для Podʼів.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Використання стандартного службового облікового запису для доступу до API-сервера
Коли Podʼи звертаються до API-сервера, вони автентифікуються як певний Службовий обліковий запис (наприклад, default
). В кожному просторі імен завжди є принаймні один Службовий обліковий запис.
У кожному просторі імен Kubernetes завжди міститься принаймні один Службовий обліковий запис: стандартний службовий обліковий запис для цього простору імен, з назвою default
. Якщо ви не вказуєте Службовий обліковий запис при створенні Podʼа, Kubernetes автоматично призначає Службовий обліковий запис з назвою default
у цьому просторі імен.
Ви можете отримати деталі для Podʼа, який ви створили. Наприклад:
kubectl get pods/<імʼя_пода> -o yaml
У виводі ви побачите поле spec.serviceAccountName
. Kubernetes автоматично встановлює це значення, якщо ви не вказали його при створенні Podʼа.
Застосунок, який працює усередині Podʼа, може отримати доступ до API Kubernetes, використовуючи автоматично змонтовані облікові дані службового облікового запису. Для отримання додаткової інформації див. доступ до кластера.
Коли Pod автентифікується як Службовий обліковий запис, його рівень доступу залежить від втулка авторизації та політики, які використовуються.
Облікові дані API автоматично відкликаються, коли Pod видаляється, навіть якщо є завершувачі. Зокрема, облікові дані API відкликаються через 60 секунд після встановленого на Pod значення .metadata.deletionTimestamp
(час видалення зазвичай дорівнює часу, коли запит на видалення був прийнятий плюс період належного завершення роботи Pod).
Відмова від автоматичного монтування облікових даних API
Якщо ви не бажаєте, щоб kubelet автоматично монтував облікові дані API ServiceAccount, ви можете відмовитися від такої стандартної поведінки. Ви можете відмовитися від автоматичного монтування облікових даних API у /var/run/secrets/kubernetes.io/serviceaccount/token
для службового облікового запису, встановивши значення automountServiceAccountToken: false
у ServiceAccount:
Наприклад:
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-robot
automountServiceAccountToken: false
...
Ви також можете відмовитися від автоматичного монтування облікових даних API для певного Podʼа:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
serviceAccountName: build-robot
automountServiceAccountToken: false
...
Якщо як ServiceAccount, так і .spec
Podʼа вказують значення для automountServiceAccountToken
, специфікація Podʼа має перевагу.
Використання більше ніж одного ServiceAccount
У кожному просторі імен є принаймні один ServiceAccount: типовий ServiceAccount, який називається default
. Ви можете переглянути всі ресурси ServiceAccount у вашому поточному просторі імен за допомогою:
kubectl get serviceaccounts
Вихідні дані схожі на наступні:
NAME SECRETS AGE
default 1 1d
Ви можете створити додаткові обʼєкти ServiceAccount таким чином:
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-robot
EOF
Імʼя обʼєкта ServiceAccount повинно бути дійсним DNS-піддоменним імʼям.
Якщо ви отримуєте повний дамп обʼєкта ServiceAccount, подібний до цього:
kubectl get serviceaccounts/build-robot -o yaml
Вихідні дані схожі на наступні:
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: 2019-06-16T00:12:34Z
name: build-robot
namespace: default
resourceVersion: "272500"
uid: 721ab723-13bc-11e5-aec2-42010af0021e
Ви можете використовувати розширення дозволів для встановлення дозволів на облікові записи служб.
Щоб використовувати не-стандартний обліковий запис, встановіть поле spec.serviceAccountName
Podʼа на імʼя ServiceAccount, який ви хочете використовувати.
Ви можете встановити лише поле serviceAccountName
при створенні Podʼа або в шаблоні для нового Podʼа. Ви не можете оновлювати поле .spec.serviceAccountName
Podʼа, який вже існує.
Примітка:
Поле.spec.serviceAccount
є застарілою альтернативою для .spec.serviceAccountName
. Якщо ви хочете видалити поля з ресурсу робочого навантаження, встановіть обидва поля явно пустими у шаблоні Pod.Очищення
Якщо ви спробували створити ServiceAccount build-robot
з прикладу вище, ви можете видалити його виконавши:
kubectl delete serviceaccount/build-robot
Вручну створіть API-токен для ServiceAccount
Припустимо, у вас вже є службовий обліковий запис з назвою "build-robot", як зазначено вище.
Ви можете отримати тимчасовий API-токен для цього ServiceAccount за допомогою kubectl
:
kubectl create token build-robot
Вихідні дані з цієї команди — це токен, який ви можете використовувати для автентифікації цього ServiceAccount. Ви можете запросити певний час дії токена, використовуючи аргумент командного рядка --duration
для kubectl create token
(фактичний час дії виданого токену може бути коротшим або навіть довшим).
Kubernetes v1.31 [beta]
(стандартно увімкнено: true)Використовуючи kubectl
v1.31 або новішу версію, можна створити токен службового облікового запису, який буде безпосередньо привʼязано до вузла:
kubectl create token build-robot --bound-object-kind Node --bound-object-name node-001 --bound-object-uid 123...456
Токен буде чинний до закінчення його терміну дії або до видалення відповідного вузла чи службового облікового запису.
Примітка:
У версіях Kubernetes до v1.22 автоматично створювалися довгострокові облікові дані для доступу до API Kubernetes. Цей старий механізм базувався на створенні Secret токенів, які потім можна було монтувати в запущені контейнери. У більш пізніх версіях, включаючи Kubernetes v1.32, облікові дані API отримуються безпосередньо за допомогою TokenRequest API, і вони монтуються в контейнери за допомогою projected тому. Токени, отримані за допомогою цього методу, мають обмежений термін дії та автоматично анулюються, коли контейнер, у який вони монтувалися, видаляється.
Ви все ще можете вручну створити Secret токен службового облікового запису; наприклад, якщо вам потрібен токен, який ніколи не закінчується. Однак рекомендується використовувати TokenRequest для отримання токена для доступу до API.
Вручну створіть довговічний API-токен для ServiceAccount
Якщо ви бажаєте отримати API-токен для службового облікового запису, ви створюєте новий Secret з особливою анотацією kubernetes.io/service-account.name
.
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: build-robot-secret
annotations:
kubernetes.io/service-account.name: build-robot
type: kubernetes.io/service-account-token
EOF
Якщо ви переглянете Secret використовуючи:
kubectl get secret/build-robot-secret -o yaml
ви побачите, що тепер Secret містить API-токен для ServiceAccount "build-robot".
Через анотацію, яку ви встановили, панель управління автоматично генерує токен для цього службового облікового запису і зберігає їх у відповідному Secret. Крім того, панель управління також очищає токени для видалених облікових записів служб.
kubectl describe secrets/build-robot-secret
Вивід схожий на такий:
Name: build-robot-secret
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: build-robot
kubernetes.io/service-account.uid: da68f9c6-9d26-11e7-b84e-002dc52800da
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1338 байтів
namespace: 7 байтів
token: ...
Примітка:
Зміст token
тут пропущений.
При здійсненні перегляду вмісту Secret kubernetes.io/service-account-token
уважно відносьтеся, щоб не відображати його будь-де, де його може побачити сторонній спостерігач.
При видаленні ServiceAccount, який має відповідний Secret, панель управління Kubernetes автоматично очищає довговічний токен з цього Secret.
Примітка:
Якщо ви переглянете ServiceAccount використовуючи:
kubectl get serviceaccount build-robot -o yaml
Ви не побачите Secret build-robot-secret
у полях API-обʼєктів службового облікового запису .secrets
, оскільки це поле заповнюється лише автоматично згенерованими Secret.
Додайте ImagePullSecrets до ServiceAccount
Спочатку створіть imagePullSecret. Потім перевірте, чи він був створений. Наприклад:
Створіть imagePullSecret, як описано в Вказування ImagePullSecrets в контейнері.
kubectl create secret docker-registry myregistrykey --docker-server=<імʼя реєстру> \ --docker-username=ІМ'Я_КОРИСТУВАЧА --docker-password=ПАРОЛЬ_ДЛЯ_DOCKER \ --docker-email=ЕЛЕКТРОННА_ПОШТА_ДЛЯ_DOCKER
Перевірте, чи він був створений.
kubectl get secrets myregistrykey
Вивід схожий на такий:
NAME TYPE DATA AGE myregistrykey kubernetes.io/.dockerconfigjson 1 1д
Додайте imagePullSecret до ServiceAccount
Далі, змініть типовий обліковий запис служби для цього простору імен так, щоб він використовував цей Secret як imagePullSecret.
kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'
Ви можете досягти того ж самого результату, відредагувавши обʼєкт вручну:
kubectl edit serviceaccount/default
Вивід файлу sa.yaml
буде схожий на такий:
Вибраний вами текстовий редактор відкриється з конфігурацією, що схожа на цю:
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: 2021-07-07T22:02:39Z
name: default
namespace: default
resourceVersion: "243024"
uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6
За допомогою вашого редактора видаліть рядок з ключем resourceVersion
, додайте рядки для imagePullSecrets:
та збережіть це. Залиште значення uid
таким же, як ви його знайшли.
Після внесення змін, відредагований ServiceAccount виглядатиме схоже на це:
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: 2021-07-07T22:02:39Z
name: default
namespace: default
uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6
imagePullSecrets:
- name: myregistrykey
Перевірте, що imagePullSecrets встановлені для нових Podʼів
Тепер, коли створюється новий Pod у поточному просторі імен і використовується типовий ServiceAccount, у новому Podʼі автоматично встановлюється поле spec.imagePullSecrets
:
kubectl run nginx --image=<імʼя реєстру>/nginx --restart=Never
kubectl get pod nginx -o=jsonpath='{.spec.imagePullSecrets[0].name}{"\n"}'
Вивід:
myregistrykey
Проєцювання токенів ServiceAccount
Kubernetes v1.20 [stable]
Примітка:
Для включення та використання проєкції запиту токена вам необхідно вказати кожен з наступних аргументів командного рядка для kube-apiserver
:
--service-account-issuer
- визначає ідентифікатор емітента токена службового облікового запису. Ви можете вказати аргумент
--service-account-issuer
аргумент кілька разів, це може бути корисно, щоб увімкнути зміну емітента без переривання роботи. Коли цей прапорець вказано кілька разів, перший використовується для генерації токенів та всі використовуються для визначення прийнятних емітентів. Вам потрібно використовувати Kubernetes v1.22 або пізніше, щоб мати можливість вказати--service-account-issuer
кілька разів. --service-account-key-file
- вказує шлях до файлу, який містить PEM-кодований X.509 приватний або публічний ключі (RSA або ECDSA), які використовуються для перевірки токенів ServiceAccount. Вказаний файл може містити кілька ключів, а прапорець може бути вказаний кілька разів з різними файлами. Якщо вказано кілька разів, токени, підписані будь-яким із вказаних ключів, вважаються сервером Kubernetes API дійсними.
--service-account-signing-key-file
- вказує шлях до файлу, який містить поточний приватний ключ емітента токенів службового облікового запису. Емітент підписує видані ID токени з цим приватним ключем.
--api-audiences
(може бути опущено)- визначає аудиторії для токенів ServiceAccount. Автентифікатор токенів службових облікових записів перевіряє, що токени, використані в API, привʼязані принаймні до однієї з цих аудиторій. Якщо
api-audiences
вказано кілька разів, токени для будь-якої з вказаних аудиторій вважаються сервером Kubernetes API дійсними. Якщо ви вказали аргумент командного рядка--service-account-issuer
, але не встановили--api-audiences
, панель управління типово має одноелементний список аудиторій, що містить лише URL емітента.
Kubelet також може проєцювати токен ServiceAccount в Pod. Ви можете вказати бажані властивості токена, такі як аудиторія та тривалість дії. Ці властивості не конфігуруються для типового токена ServiceAccount. Токен також стане недійсним щодо API, коли будь-який з Podʼів або ServiceAccount буде видалено.
Ви можете налаштувати цю поведінку для spec
Podʼа за допомогою типу projected тому, що називається ServiceAccountToken
.
Токен з цього projected тому — JSON Web Token (JWT). JSON-вміст цього токена слідує чітко визначеній схемі — приклад вмісту для токена, повʼязаного з Pod:
{
"aud": [ # відповідає запитаним аудиторіям або стандартним аудиторіям API-сервера, якщо явно не запитано
"https://kubernetes.default.svc"
],
"exp": 1731613413,
"iat": 1700077413,
"iss": "https://kubernetes.default.svc", # відповідає першому значенню, переданому прапорцю --service-account-issuer
"jti": "ea28ed49-2e11-4280-9ec5-bc3d1d84661a",
"kubernetes.io": {
"namespace": "kube-system",
"node": {
"name": "127.0.0.1",
"uid": "58456cb0-dd00-45ed-b797-5578fdceaced"
},
"pod": {
"name": "coredns-69cbfb9798-jv9gn",
"uid": "778a530c-b3f4-47c0-9cd5-ab018fb64f33"
},
"serviceaccount": {
"name": "coredns",
"uid": "a087d5a0-e1dd-43ec-93ac-f13d89cd13af"
},
"warnafter": 1700081020
},
"nbf": 1700077413,
"sub": "system:serviceaccount:kube-system:coredns"
}
Запуск Podʼа з використанням проєцювання токену службового облікового запису
Щоб надати Podʼу токен з аудиторією vault
та терміном дії дві години, ви можете визначити маніфест Podʼа, схожий на цей:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- mountPath: /var/run/secrets/tokens
name: vault-token
serviceAccountName: build-robot
volumes:
- name: vault-token
projected:
sources:
- serviceAccountToken:
path: vault-token
expirationSeconds: 7200
audience: vault
Створіть Pod:
kubectl create -f https://k8s.io/examples/pods/pod-projected-svc-token.yaml
Kubelet буде: запитувати та зберігати токен від імені Podʼа; робити токен доступним для Podʼа за налаштованим шляхом до файлу; і оновлювати токен поблизу його закінчення. Kubelet активно запитує ротацію для токена, якщо він старший, ніж 80% від загального часу життя (TTL), або якщо токен старший, ніж 24 години.
Застосунок відповідає за перезавантаження токена при його ротації. Зазвичай для застосунку достатньо завантажувати токен за розкладом (наприклад: один раз кожні 5 хвилин), без відстеження фактичного часу закінчення.
Виявлення емітента службового облікового запису
Kubernetes v1.21 [stable]
Якщо ви увімкнули проєцювання токенів для ServiceAccounts у вашому кластері, то ви також можете скористатися функцією виявлення. Kubernetes надає спосіб клієнтам обʼєднуватись як постачальник ідентифікаційних даних, щоб одна або кілька зовнішніх систем могли діяти як сторона, що їм довіряє.
Примітка:
URL емітента повинен відповідати Специфікації виявлення OIDC. На практиці це означає, що він повинен використовувати схему https
, і має обслуговувати конфігурацію постачальника OpenID за адресою {емітент-облікового-запису}/.well-known/openid-configuration
.
Якщо URL не відповідає, точки доступу виявлення емітента ServiceAccount не зареєстровані або недоступні.
Якщо увімкнено, Kubernetes API-сервер публікує документ конфігурації постачальника OpenID через HTTP. Документ конфігурації публікується за адресою /.well-known/openid-configuration
. Документ конфігурації OpenID постачальника іноді називається документом виявлення. Kubernetes API-сервер також публікує повʼязаний набір ключів JSON Web (JWKS), також через HTTP, за адресою /openid/v1/jwks
.
Примітка:
Відповіді, що обслуговуються за адресами/.well-known/openid-configuration
та /openid/v1/jwks
, призначені для сумісності з OIDC, але не є строго сумісними з OIDC. Ці документи містять лише параметри, необхідні для виконання перевірки токенів службових облікових записів Kubernetes.Кластери, які використовують RBAC, включають типову роль кластера з назвою system:service-account-issuer-discovery
. Типовий ClusterRoleBinding надає цю роль групі system:serviceaccounts
, до якої неявно належать всі ServiceAccounts. Це дозволяє Podʼам, які працюють у кластері, отримувати доступ до документа виявлення службового облікового запису через їх змонтований токен службового облікового запису. Адміністратори також можуть вибрати привʼязку ролі до system:authenticated
або system:unauthenticated
залежно від їх вимог до безпеки та зовнішніх систем, з якими вони мають намір обʼєднуватись.
Відповідь JWKS містить публічні ключі, які може використовувати залежна сторона для перевірки токенів службових облікових записів Kubernetes. Залежні сторони спочатку запитують конфігурацію постачальника OpenID, а потім використовують поле jwks_uri
у відповіді, щоб знайти JWKS.
У багатьох випадках API-сервери Kubernetes не доступні через глобальну мережу, але публічні точки доступу, які обслуговують кешовані відповіді від API-сервера, можуть бути доступні для користувачів або постачальників послуг. У таких випадках можливо перевизначити jwks_uri
в конфігурації постачальника OpenID, щоб вона вказувала на глобальну точку доступу, а не на адресу API-сервера, передаючи прапорець --service-account-jwks-uri
до API-сервера. Як і URL емітента, URI JWKS повинен використовувати схему https
.
Що далі
Дивіться також:
- Прочитайте Посібник адміністратора кластера щодо службових облікових записів
- Дізнайтеся про Авторизацію в Kubernetes
- Дізнайтеся про Secret
- або, як розподіляти облікові дані безпечно за допомогою Secret
- але також майте на увазі, що використання Secret для автентифікації як службового облікового запису є застарілим. Рекомендований альтернативний метод — проєціювання токенів службового облікового запису.
- Дізнайтеся про projected томи.
- Для ознайомлення з OIDC discovery, прочитайте Попередній перегляд пропозиції щодо підпису токена службового облікового запису щодо покращення Kubernetes
- Прочитайте Специфікацію виявлення OIDC