Управління службовими обліковими записами
Службовий обліковий запис (ServiceAccount) надає ідентифікацію для процесів, що виконуються в Pod.
Процес всередині Pod може використовувати ідентифікацію свого повʼязаного службового облікового запису для автентифікації у API сервері кластера.
Для ознайомлення зі службовими обліковими записами, прочитайте про конфігурування службових облікових записів.
Цей посібник пояснює деякі концепції, повʼязані зі ServiceAccount. Також у посібнику розглядається, як отримати або відкликати токени, що представляють ServiceAccounts.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Щоб точно виконати ці кроки, переконайтеся, що у вас є простір імен під назвою examplens
. Якщо ні, створіть його, виконавши команду:
kubectl create namespace examplens
Облікові записи користувачів та службові облікові записи
Kubernetes розрізняє поняття облікового запису користувача та службового облікового запису з кількох причин:
- Облікові записи користувачів призначені для людей. Службові облікові записи призначені для процесів застосунків, які (для Kubernetes) виконуються в контейнерах, що є частиною Pod.
- Облікові записи користувачів мають бути глобальними: імена повинні бути унікальними у всіх просторах імен кластера. Незалежно від того, який простір імен ви розглядаєте, певний обліковий запис користувача представляє того самого користувача. У Kubernetes службові облікові записи є привʼязаними до простору імен: два різні простори імен можуть містити ServiceAccountʼи з однаковими іменами.
- Як правило, облікові записи користувачів кластера можуть синхронізуватися з корпоративною базою даних, де створення нового облікового запису користувача вимагає спеціальних привілеїв і повʼязане зі складними бізнес-процесами. Навпаки, створення службових облікових записів повинно бути легшим, дозволяючи користувачам кластера створювати службові облікові записи для конкретних завдань за запитом. Відділення створення ServiceAccount від кроків для реєстрації користувачів полегшує дотримання принципу найменших привілеїв для робочих навантажень.
- Вимоги до аудиту для облікових записів користувачів (людей) та службових облікових записів можуть відрізнятися; розділення полегшує досягнення цих вимог.
- Конфігураційний пакет для складної системи може містити визначення різних службових облікових записів для компонентів цієї системи. Оскільки службові облікові записи можуть створюватися без багатьох обмежень і мають імена, привʼязані до простору імен, така конфігурація зазвичай є переносимою.
Привʼязані токени службових облікових записів
Токени ServiceAccount можуть бути привʼязані до API обʼєктів, що існують у kube-apiserver. Їх можна використовувати для звʼязування дійсності токена з існуванням іншого API обʼєкта. Підтримувані типи обʼєктів наступні:
- Pod (використовується для projected томів, див. нижче)
- Secret (може використовуватися для відкликання токена шляхом видалення Secret)
- Node (у версії v1.30 створення нових токенів, привʼязаних до вузлів, є альфа-функцією, використання наявних токенів, привʼязаних до вузлів, є бета-функцією)
Коли токен привʼязаний до обʼєкта, metadata.name
і metadata.uid
цього обʼєкта зберігаються як додаткові "приватні заявки" у виданому JWT.
Коли привʼязаний токен представляється kube-apiserver, автентифікатор службового облікового запису витягне і перевірить ці заявки. Якщо вказаний обʼєкт або ServiceAccount знаходяться в процесі видалення (наприклад, через завершувач), то протягом будь-якого моменту, через 60 секунд (або більше) після дати .metadata.deletionTimestamp
, автентифікація з використанням цього токена буде неуспішною. Якщо обʼєкт, на який він посилається, більше не існує (або його metadata.uid
не збігається), запит не буде автентифікований.
Додаткові метадані в токенах, повʼязаних з Pod
Kubernetes v1.30 [beta]
(стандартно увімкнено: true)Коли токен службового облікового запису привʼязаний до обʼєкта Pod, додаткові метадані також вбудовуються в токен, що вказує на значення поля spec.nodeName
повʼязаного Pod і uid цього вузла, якщо це можливо.
Ця інформація про вузол не перевіряється kube-apiserver, коли токен використовується для автентифікації. Вона включена, щоб інтегратори не повинні були отримувати обʼєкти API Pod або Node для перевірки повʼязаного імені вузла та uid при інспекції JWT.
Перевірка та інспекція приватних заявок
API TokenReview
може використовуватися для перевірки та вилучення приватних заявок з токена:
Спочатку припустимо, що у вас є Pod з назвою
test-pod
і службовий обліковий запис з назвоюmy-sa
.Створіть токен, привʼязаний до цього Pod:
kubectl create token my-sa --bound-object-kind="Pod" --bound-object-name="test-pod"
Скопіюйте цей токен у новий файл з назвою
tokenreview.yaml
:apiVersion: authentication.k8s.io/v1 kind: TokenReview spec: token: <токен з кроку 2>
Надішліть цей ресурс до apiserver для перевірки:
kubectl create -o yaml -f tokenreview.yaml # ми використовуємо '-o yaml', щоб можна було перевірити вихідні дані
Ви повинні побачити вихідні дані, подібні до наведених нижче:
apiVersion: authentication.k8s.io/v1
kind: TokenReview
metadata:
creationTimestamp: null
spec:
token: <token>
status:
audiences:
- https://kubernetes.default.svc.cluster.local
authenticated: true
user:
extra:
authentication.kubernetes.io/credential-id:
- JTI=7ee52be0-9045-4653-aa5e-0da57b8dccdc
authentication.kubernetes.io/node-name:
- kind-control-plane
authentication.kubernetes.io/node-uid:
- 497e9d9a-47aa-4930-b0f6-9f2fb574c8c6
authentication.kubernetes.io/pod-name:
- test-pod
authentication.kubernetes.io/pod-uid:
- e87dbbd6-3d7e-45db-aafb-72b24627dff5
groups:
- system:serviceaccounts
- system:serviceaccounts:default
- system:authenticated
uid: f8b4161b-2e2b-11e9-86b7-2afc33b31a7e
username: system:serviceaccount:default:my-sa
Примітка:
Попри використанняkubectl create -f
для створення цього ресурсу, і визначення його схожим чином з іншими типами ресурсів у Kubernetes, TokenReview є спеціальним типом і kube-apiserver насправді не зберігає обʼєкт TokenReview в etcd. Тому kubectl get tokenreview
не є допустимою командою.Механізм томів привʼязаного токена службового облікового запису
Kubernetes v1.22 [stable]
(стандартно увімкнено: true)Стандартно, панель управління Kubernetes (зокрема, ServiceAccount admission controller) додає projected том до Pod, і цей том містить токен для доступу до API Kubernetes.
Ось приклад, як це виглядає для запущеного Pod:
...
- name: kube-api-access-<random-suffix>
projected:
sources:
- serviceAccountToken:
path: token # має збігатися з шляхом, який очікує застосунок
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
Цей фрагмент маніфесту визначає projected том, що складається з трьох джерел. У цьому випадку, кожне джерело також представляє один шлях у цьому томі. Три джерела такі:
- Джерело
serviceAccountToken
, яке містить токен, який kubelet отримує з kube-apiserver. Kubelet отримує токени з обмеженим терміном дії за допомогою API TokenRequest. Токен, наданий для TokenRequest, закінчується або при видаленні Pod, або після визначеного терміну дії (стандартно, це 1 година). Kubelet також оновлює цей токен перед тим, як термін його дії закінчиться. Токен привʼязаний до конкретного Pod і має kube-apiserver як свою аудиторію. Цей механізм замінив попередній механізм, який додавав том на основі Secret, де Secret представляв ServiceAccount для Pod, але не мав терміну дії. - Джерело
configMap
. ConfigMap містить набір даних центру сертифікації. Pod можуть використовувати ці сертифікати, щоб упевнитись, що вони підключаються до kube-apiserver вашого кластера (а не до проміжного блоку або випадково неправильно налаштованого колеги). - Джерело
downwardAPI
, яке шукає імʼя простору імен, що містить Pod, і надає цю інформацію про імʼя для коду застосунку, що виконується всередині Pod.
Будь-який контейнер у Pod, який монтує цей том, може отримати доступ до вищевказаної інформації.
Примітка:
Не існує якогось окремого механізму для анулювання токена, виданого через TokenRequest. Якщо ви більше не довіряєте привʼязаному токену службового облікового запису для Pod, ви можете видалити цей Pod. Видалення Pod анулює його привʼязані токени службових облікових записів.Ручне управління Secret для ServiceAccounts
Версії Kubernetes до v1.22 автоматично створювали облікові дані для доступу до API Kubernetes. Цей старіший механізм був заснований на створенні токенів Secret, які потім могли бути змонтовані в запущені Podʼи.
У новіших версіях, включаючи Kubernetes v1.31, API облікові дані отримуються безпосередньо за допомогою TokenRequest, і монтуються в Podʼи за допомогою projected тому. Токени, отримані за допомогою цього методу, мають обмежений термін дії та автоматично анулюються, коли Pod, в який вони змонтовані, видаляється.
Ви все ще можете створити вручну Secret для збереження токена службового облікового запису; наприклад, якщо вам потрібен токен, який ніколи не закінчується.
Після того, як ви вручну створите Secret і звʼяжете його зі службовим обліковим записом, панель управління Kubernetes автоматично заповнює токен у цьому Secret.
Примітка:
Хоча існує ручний механізм для створення токена службового облікового запису з тривалим терміном дії, рекомендується використовувати TokenRequest для отримання токенів доступу до API з коротким терміном дії.Автоматичне очищення застарілих токенів ServiceAccount
До версії 1.24 Kubernetes автоматично генерував токени на основі Secret для ServiceAccount. Щоб розрізнити автоматично згенеровані токени та створені вручну, Kubernetes перевіряє посилання з поля секретів ServiceAccount. Якщо Secret згадується в полі secrets
, він вважається автоматично згенерованим застарілим токеном. В іншому випадку він вважається вручну створеним застарілим токеном. Наприклад:
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-robot
namespace: default
secrets:
- name: build-robot-secret # зазвичай НЕ присутній для вручну створеного токена
Починаючи з версії 1.29, застарілі токени службових облікових записів, які були згенеровані автоматично, будуть позначені як недійсні, якщо вони залишатимуться невикористаними протягом певного періоду часу (стандартно один рік). Токени, які продовжують залишатися невикористаними протягом цього визначеного періоду (знову ж таки, стандартно один рік), будуть згодом видалені панеллю управління.
Якщо користувачі використовують анульований автоматично згенерований токен, валідатор токенів:
- додасть анотацію аудиту для пари ключ-значення
authentication.k8s.io/legacy-token-invalidated: <secret name>/<namespace>
, - збільшить лічильник метрики
invalid_legacy_auto_token_uses_total
, - оновить мітку Secret
kubernetes.io/legacy-token-last-used
з новою датою, - поверне помилку, вказуючи, що токен був анульований.
При отриманні цієї помилки валідації користувачі можуть оновити Secret, щоб видалити мітку kubernetes.io/legacy-token-invalid-since
, щоб тимчасово дозволити використання цього токена.
Ось приклад автоматично згенерованого застарілого токена, який був позначений мітками kubernetes.io/legacy-token-last-used
і kubernetes.io/legacy-token-invalid-since
:
apiVersion: v1
kind: Secret
metadata:
name: build-robot-secret
namespace: default
labels:
kubernetes.io/legacy-token-last-used: 2022-10-24
kubernetes.io/legacy-token-invalid-since: 2023-10-25
annotations:
kubernetes.io/service-account.name: build-robot
type: kubernetes.io/service-account-token
Деталі панелі управління
Контролер ServiceAccount
Контролер ServiceAccount керує ServiceAccount всередині просторів імен та забезпечує наявність ServiceAccount з іменем "default" у кожному активному просторі імен.
Контролер токенів
Контролер токенів службових облікових записів працює як частина kube-controller-manager
. Цей контролер діє асинхронно. Він:
- відстежує видалення ServiceAccount та видаляє всі відповідні Secretʼи токенів ServiceAccount.
- відстежує додавання Secretʼу токенів ServiceAccount та забезпечує наявність відповідного ServiceAccount, додає токен до Secretʼу за потреби.
- відстежує видалення Secretʼу та видаляє посилання з відповідного ServiceAccount за потреби.
Необхідно передати файл приватного ключа службового облікового запису контролеру токенів у kube-controller-manager
, використовуючи прапорець --service-account-private-key-file
. Приватний ключ використовується для підпису згенерованих токенів службових облікових записів. Аналогічно, необхідно передати відповідний публічний ключ у kube-apiserver
, використовуючи прапорець --service-account-key-file
. Публічний ключ буде використовуватися для перевірки токенів під час автентифікації.
Контролер допуску ServiceAccount
Зміна Podʼів здійснюється через втулок, що викликається Контролером допуску. Він є частиною сервера API. Цей контролер допуску діє синхронно для зміни Podʼів під час їх створення. Коли цей втулок активний (а він є стандартно активним у більшості дистрибутивів), то під час створення Pod він виконує наступні дії:
- Якщо у Pod не встановлено значення
.spec.serviceAccountName
, контролер допуску встановлює імʼя ServiceAccountdefault
для цього Pod. - Контролер допуску забезпечує наявність ServiceAccount, на який посилається Pod. Якщо не існує ServiceAccount з відповідним імʼям, контролер допуску відхиляє Pod. Ця перевірка застосовується навіть для
default
ServiceAccount. - Якщо поле
automountServiceAccountToken
у ServiceAccount або в Podʼі не встановлено вfalse
:- контролер допуску змінює Pod, додаючи додатковий том, що містить токен для доступу до API.
- контролер допуску додає
volumeMount
до кожного контейнера в Podʼі, пропускаючи контейнери, які вже мають визначений шлях для монтування тому/var/run/secrets/kubernetes.io/serviceaccount
. Для Linux-контейнерів цей том монтується за адресою/var/run/secrets/kubernetes.io/serviceaccount
; на Windows-вузлах монтування знаходиться ну еквівалентному шляху.
- Якщо в специфікації Pod не містяться жодні
imagePullSecrets
, контролер допуску додаєimagePullSecrets
, копіюючи їх зServiceAccount
.
Контролер відстеження токенів застарілих ServiceAccount
Kubernetes v1.28 [stable]
(стандартно увімкнено: true)Цей контролер створює ConfigMap з назвою kube-system/kube-apiserver-legacy-service-account-token-tracking
у просторі імен kube-system
. ConfigMap фіксує мітку часу, коли система почала відстежувати застарілі токени службових облікових записів.
Очищувач токенів застарілих ServiceAccount
Kubernetes v1.30 [stable]
(стандартно увімкнено: true)Очищувач токенів застарілих ServiceAccount працює як частина kube-controller-manager
і перевіряє кожні 24 години, чи не використовувався будь-який автоматично згенерований застарілий токен службового облікового запису протягом визначеного часу. Якщо так, очищувач позначає ці токени як недійсні.
Очищувач працює, спершу перевіряючи ConfigMap, створений панеллю управління (за умови, що LegacyServiceAccountTokenTracking
увімкнено). Якщо поточний час перевищує визначений час після дати в ConfigMap, очищувач переглядає список Secretʼів у кластері та оцінює кожен Secret, що має тип kubernetes.io/service-account-token
.
Якщо Secret відповідає всім наступним умовам, очищувач позначає його як недійсний:
- Secret створено автоматично, що означає що він двонаправлено згадується ServiceAccount.
- Secret не змонтовано жодним Podʼом.
- Secret не використовувався протягом визначеного часу з моменту створення або останнього використання.
Очищувач позначає Secret як недійсний, додаючи мітку kubernetes.io/legacy-token-invalid-since
до Secret, з поточною датою. Якщо недійсний Secret не використовується протягом визначеного часу, очищувач видаляє його.
Примітка:
Усі визначені часи стандартно становлять один рік. Адміністратор кластера може налаштувати це значення через аргумент командного рядка--legacy-service-account-token-clean-up-period
для компонента kube-controller-manager
.API TokenRequest
Kubernetes v1.22 [stable]
Ви використовуєте субресур TokenRequest з ServiceAccount, щоб отримати токен з обмеженим часом дії для цього ServiceAccount. Вам не потрібно викликати його для отримання API-токена для використання в контейнері, оскільки kubelet налаштовує це для вас, використовуючи projected том.
Якщо ви хочете використовувати API TokenRequest через kubectl
, див. Ручне створення API-токена для ServiceAccount.
Панель управління Kubernetes (зокрема, контролер допуску ServiceAccount) додає projected том до Podʼів, а kubelet забезпечує, що цей том містить токен, який дозволяє контейнерам автентифікуватися як відповідний ServiceAccount.
(Цей механізм замінив попередній механізм, який додавав том на основі Secret, де Secret представляв ServiceAccount для Pod, але не мав терміну дії.)
Ось приклад того, як це виглядає для запущеного Pod:
...
- name: kube-api-access-<random-suffix>
projected:
defaultMode: 420 # десятичний еквівалент вісімкового 0644
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
Цей фрагмент маніфесту визначає projected том, який обʼєднує інформацію з трьох джерел:
- Джерело
serviceAccountToken
, що містить токен, який kubelet отримує від kube-apiserver. Kubelet отримує токени з обмеженим часом дії, використовуючи API TokenRequest. Токен, виданий для TokenRequest, спливає або коли Pod видаляється, або через визначений термін життя (стандартно — 1 година). Токен привʼязаний до конкретного Podʼа та має kube-apiserver як свою аудиторію. - Джерело
configMap
. ConfigMap містить пакет даних сертифікаційного центру. Podʼи можуть використовувати ці сертифікати, щоб переконатися, що вони підключаються до kube-apiserver вашого кластера (а не до проміжного блоку або випадково неправильно налаштованого колеги). - Джерело
downwardAPI
. Цей томdownwardAPI
робить імʼя простору імен, що містить Pod, доступним для коду програми, що працює всередині Podʼа.
Будь-який контейнер у Podʼі, що монтує цей том, може отримати доступ до вищезазначеної інформації.
Створення додаткових API токенів
Увага:
Створюйте довгострокові API токени тільки якщо механізм запиту токенів не підходить. Механізм запиту токенів надає токени з обмеженим часом дії; оскільки вони спливають, вони представляють менший ризик для інформаційної безпеки.Для створення постійного API токена для ServiceAccount, створіть Secret типу kubernetes.io/service-account-token
з анотацією, що посилається на ServiceAccount. Панель управління потім генерує довгостроковий токен і оновлює цей Secret з даними згенерованого токена.
Ось приклад маніфесту для такого Secret:
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
name: mysecretname
annotations:
kubernetes.io/service-account.name: myserviceaccount
Для створення Secret на основі цього прикладу, виконайте:
kubectl -n examplens create -f https://k8s.io/examples/secret/serviceaccount/mysecretname.yaml
Для перегляду деталей цього Secret, виконайте:
kubectl -n examplens describe secret mysecretname
Результат буде подібним до:
Name: mysecretname
Namespace: examplens
Labels: <none>
Annotations: kubernetes.io/service-account.name=myserviceaccount
kubernetes.io/service-account.uid=8a85c4c4-8483-11e9-bc42-526af7764f64
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1362 bytes
namespace: 9 bytes
token: ...
Якщо ви запустите новий Pod у просторі імен examplens
, він може використовувати Secret токену службового облікового запису myserviceaccount
, який ви щойно створили.
Увага:
Не посилайтеся на вручну створені Secretʼи в поліsecrets
ServiceAccount. Вручну створені Secret будуть очищені, якщо вони не використовуватимуться протягом тривалого часу. Будь ласка, зверніться до очищення автоматично згенерованих токенів застарілих ServiceAccount.Видалення/деактивація токена ServiceAccount
Якщо ви знаєте назву Secret, що містить токен, який ви хочете видалити:
kubectl delete secret name-of-secret
Інакше спочатку знайдіть Secret для ServiceAccount.
# Це передбачає, що у вас вже є простір імен 'examplens'
kubectl -n examplens get serviceaccount/example-automated-thing -o yaml
Результат буде подібним до:
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"example-automated-thing","namespace":"examplens"}}
creationTimestamp: "2019-07-21T07:07:07Z"
name: example-automated-thing
namespace: examplens
resourceVersion: "777"
selfLink: /api/v1/namespaces/examplens/serviceaccounts/example-automated-thing
uid: f23fd170-66f2-4697-b049-e1e266b7f835
secrets:
- name: example-automated-thing-token-zyxwv
Потім видаліть Secret, назву якого ви тепер знаєте:
kubectl -n examplens delete secret/example-automated-thing-token-zyxwv
Прибирання
Якщо ви створили простір імен examplens
для експериментів, ви можете його видалити:
kubectl delete namespace examplens
Що далі
- Прочитайте більше деталей про projected томи.