Хостинг
VDS
Аренда серверов
Домены
Почта
SSL
Хранилище
Сайты
Обзоры
Регламенты
AI Studio
Kubernetes
Архив
Создание сервисного аккаунта и постоянного токена доступа

Сервисный аккаунт (ServiceAccount) — это учётная запись для программных клиентов Kubernetes: подов, CI/CD-пайплайнов, скриптов, kubectl на другой машине, внешних инструментов мониторинга.

Для подов Kubernetes автоматически создаёт токен сервисного аккаунта и пробрасывает его в под. Этот токен ограничен по времени действия и периодически обновляется: он удобен для работы внутри кластера, но не подходит для внешних клиентов, которым нужнен постоянный не изменяемый доступ.

Токен, выданный через секрет, не имеет срока действия — он валиден, пока существует сам секрет. Это удобно, когда клиенту нужен постоянные токен, который не нужно регулярно перевыпускать.

В данной статье рассмотрим создание сервисного аккаунта с полным доступом к кластеру и постоянного токена для него, а также то, как отозвать токен и изменить права доступа.

Для начала работы

Перед началом работы вам понадобится:

  • Кластер Kubernetes в NetAngels

  • Установленная утилита kubectl с настроенным доступом (конфигурационный файл кластера)

1. Создание сервисного аккаунта, секрета и привязки прав

Создадим сервисный аккаунт admin в неймспейсе kube-system, секрет для постоянного токена и привязку к встроенной роли cluster-admin (полный доступ к кластеру):

kubectl apply -f - <<EOF
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin
  namespace: kube-system
---
apiVersion: v1
kind: Secret
metadata:
  name: admin-token-secret
  namespace: kube-system
  annotations:
    kubernetes.io/service-account.name: "admin"
type: kubernetes.io/service-account-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin
  namespace: kube-system
EOF
serviceaccount/admin created
secret/admin-token-secret created
clusterrolebinding.rbac.authorization.k8s.io/admin created

Проверим созданные ресурсы:

kubectl get sa/admin secret/admin-token-secret -n kube-system
NAME                   SECRETS   AGE
serviceaccount/admin   0         0s

NAME                        TYPE                                  DATA   AGE
secret/admin-token-secret   kubernetes.io/service-account-token   3      0s

Секрет уже содержит три поля — ca.crt, namespace и token. Токен генерируется Kubernetes сразу после создания секрета: его нельзя задать самому, только получить.

Обратите внимание: роль cluster-admin даёт полный доступ к кластеру, и утечка такого токена означает потерю контроля над всем кластером. В рабочих сценариях выдавайте сервисным аккаунтам минимально необходимые права — как показано в разделе 5.

2. Получение токена

kubectl get secret admin-token-secret -n kube-system -o jsonpath='{.data.token}' | base64 -d
<токен>

Это JWT без срока действия (в payload нет поля exp). Токен можно сохранить в переменную окружения, файл или сразу подставить в конфигурацию клиента.

3. Использование токена

Для работы с кластером сформируем конфигурационный файл для kubectl, в котором пользователь описан токеном, а не сертификатом. Сформировать его можно командами kubectl config: из конфига администратора берём только описание кластера — адрес API-сервера и CA-сертификат, — а пользователя создаем с токеном из секрета.

Сначала сохраним CA-сертификат из конфига администратора в файл. Без флага --flatten команда kubectl config view заменяет данные сертификатов плейсхолдером DATA+OMITTED, поэтому флаг обязателен:

kubectl config view --flatten -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 -d > ca.crt

Теперь создаём sa-cluster.yaml: описываем кластер, встраиваем в него CA-сертификат, добавляем пользователя с токеном и контекст, связывающий их. Значение --server — адрес API-сервера из вашего конфига администратора:

KUBECONFIG=sa-cluster.yaml kubectl config set-cluster my-cluster --server=https://<адрес API-сервера>:6443 --certificate-authority=ca.crt --embed-certs
KUBECONFIG=sa-cluster.yaml kubectl config set-credentials sa-admin --token=<токен>
KUBECONFIG=sa-cluster.yaml kubectl config set-context sa-cluster --cluster=my-cluster --user=sa-admin
KUBECONFIG=sa-cluster.yaml kubectl config use-context sa-cluster
Cluster "my-cluster" set.
User "sa-admin" set.
Context "sa-cluster" created.
Switched to context "sa-cluster".

Флаг --embed-certs встраивает содержимое ca.crt прямо в файл, поэтому sa-cluster.yaml самодостаточен и может быть перенесён на другую машину; сам ca.crt можно удалить.

Результат:

KUBECONFIG=sa-cluster.yaml kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://<адрес API-сервера>:6443
  name: my-cluster
contexts:
- context:
    cluster: my-cluster
    user: sa-admin
  name: sa-cluster
current-context: sa-cluster
kind: Config
users:
- name: sa-admin
  user:
    token: REDACTED

Поля certificate-authority-data и token в выводе маскируются самим kubectl — в файле хранятся настоящий сертификат и токен.

Теперь можно обращаться к API по токену:

KUBECONFIG=sa-cluster.yaml kubectl get nodes
NAME       STATUS   ROLES    AGE     VERSION
worker-1   Ready    <none>   7d21h   v1.33.8+k0s

Для проверки доступа без kubectl можно обратиться к API-серверу напрямую с заголовком Authorization: Bearer:

curl -sk https://<адрес API-сервера>:6443/api/v1/namespaces/default -H "Authorization: Bearer <токен>"
{
  "kind": "Namespace",
  "apiVersion": "v1",
  "metadata": {
    "name": "default",
    "uid": "984052be-d563-4f82-ae69-9269d695e4f1",
    "resourceVersion": "8",
    "creationTimestamp": "2026-08-26T12:36:39Z",
    "labels": {
      "kubernetes.io/metadata.name": "default"
    },
    "managedFields": [
      {
        "manager": "kube-apiserver",
        "operation": "Update",
        "apiVersion": "v1",
        "time": "2026-08-26T12:36:39Z",
        "fieldsType": "FieldsV1",
        "fieldsV1": {
          "f:metadata": {
            "f:labels": {
              ".": {},
              "f:kubernetes.io/metadata.name": {}
            }
          }
        }
      }
    ]
  },
  "spec": {
    "finalizers": [
      "kubernetes"
    ]
  },
  "status": {
    "phase": "Active"
  }
}

4. Проверка прав

Права аккаунта можно проверить командой kubectl auth can-i, используя конфиг с токеном из предыдущего раздела:

KUBECONFIG=sa-cluster.yaml kubectl auth can-i get pods
yes
KUBECONFIG=sa-cluster.yaml kubectl auth can-i create deployments
yes
KUBECONFIG=sa-cluster.yaml kubectl auth can-i get nodes
Warning: resource 'nodes' is not namespace scoped

yes

Аккаунт имеет полный доступ — cluster-admin разрешает любые операции с любыми ресурсами.

5. Изменение прав доступа

Права конфигурируются связями сервисных аккаунтов с ролями (ClusterRoleBinding/RoleBinding) на момент каждого запроса, поэтому изменение прав отражается на действующих токенах сразу.

Изменить права доступа — значит удалить связь и/или создать новую. Например, ограничим аккаунт до чтения подов и сервисов:

kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: sa-restricted
rules:
- apiGroups: [""]
  resources: ["pods", "services"]
  verbs: ["get", "list"]
EOF
clusterrole.rbac.authorization.k8s.io/sa-restricted created
kubectl delete clusterrolebinding admin
clusterrolebinding.rbac.authorization.k8s.io "admin" deleted
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: sa-restricted
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: sa-restricted
subjects:
- kind: ServiceAccount
  name: admin
  namespace: kube-system
EOF
clusterrolebinding.rbac.authorization.k8s.io/sa-restricted created

Проверим права после:

KUBECONFIG=sa-cluster.yaml kubectl auth can-i get pods
yes
KUBECONFIG=sa-cluster.yaml kubectl auth can-i create deployments
no
KUBECONFIG=sa-cluster.yaml kubectl auth can-i get nodes
Warning: resource 'nodes' is not namespace scoped

no

Токен при этом не меняется — запросы с тем же токеном к ранее разрешённым операциям теперь завершаются отказом в доступе (код 403):

curl -sk https://<адрес API-сервера>:6443/api/v1/nodes -H "Authorization: Bearer <токен>"
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "nodes is forbidden: User \"system:serviceaccount:kube-system:admin\" cannot list resource \"nodes\" in API group \"\" at the cluster scope",
  "reason": "Forbidden",
  "details": {
    "kind": "nodes"
  },
  "code": 403
}

6. Отзыв токена

Постоянный токен отзывается удалением секрета, в котором он хранится:

kubectl delete secret admin-token-secret -n kube-system
secret "admin-token-secret" deleted from kube-system namespace

Проверим доступ к API с использованием удаленного токена:

curl -sk https://<адрес API-сервера>:6443/api/v1/pods -H "Authorization: Bearer <токен>"
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "Unauthorized",
  "reason": "Unauthorized",
  "code": 401
}

Если вместе с токеном не нужен и сам аккаунт, достаточно удалить ServiceAccount — все связанные с ним токены перестанут работать. Если же действующий токен понадобится снова, секрет можно создать заново — Kubernetes сгенерирует новый токен.

Удаление ресурсов

Секрет с токеном уже удалён в разделе 6, удаляем оставшиеся ресурсы:

kubectl delete clusterrolebinding sa-restricted
kubectl delete clusterrole sa-restricted
kubectl delete sa admin -n kube-system
clusterrolebinding.rbac.authorization.k8s.io "sa-restricted" deleted
clusterrole.rbac.authorization.k8s.io/sa-restricted deleted
serviceaccount "admin" deleted from kube-system namespace

Нам доверяют тысячи компаний и разработчиков

22 года
Предоставляем услуги профессионального хостинга
35 000+
Клиентов доверяют нам размещение своих сайтов
99.99%
Подтвержденный uptime наших серверов хостинга
Callibri
Крылья
Tele-Club
Linline
Премьер зал
УГМК-Здоровье
Магнум
Алатырь
Туристер
Callibri
Крылья
Tele-Club
Linline
Премьер зал
УГМК-Здоровье
Магнум
Алатырь
Туристер
ВК49865