Аутентификация в Kubernetes может отличаться методами аутентификации, пользователями, правилами кластеров:
- сам
kubectl
может использовать различные способы аутентифицаии – сертификаты, логин-пароль - сами пользователи могут использовать различные способы – токены, логин-пароль и т.д.
- и, в конце-концов, мы можем захотеть хранить в настройках доступ к различным кластерам, но иметь возможность манипулировать ими из одного места
Для всего этого служит файл настроек kubectl
, в котором описываются механизмы аутентификации и данные подключения к кластерам.
В системе может присутствовать более одного такого файла настроек, а для определения того, какой использовать – kubectl
выполнит проверку по:
- опции
--kubeconfig
и пути к файлу - переменной окружения
$KUBECONFIG
- и файлу по-умолчанию –
$HOME/.kube/config
Применён будет первый обнаруженный, т.е. приоритет в списке выше идёт сверху вниз.
Например:
[simterm]
$ kubectl get pods --kubeconfig=/home/setevoy/new-config
[/simterm]
Впрочем, можно передать все нужные опции прямо аргументами к kubectl
, не используя файл вообще:
[simterm]
$ kubectl get nodes --server https://eks-api-server.com:6443 --user kube-username --client-certificate user-client.cert --client-key user-client --insecure-skip-tls-verify
[/simterm]
В этом посте рассмотрим из чего файл настроек состоит, как манипулировать данными в нём, и в конце – сгенерируем файл настроек kubectl
для своего AWS Elastic Kubernetes Service кластера для двух пользователейй – AWS IAM User и AWS IAM Role.
Содержание
kubectl
config file
Пример файла настроек kubectl
:
current-context: federal-context apiVersion: v1 clusters: - cluster: api-version: v1 server: http://cluster-1.com:8080 name: cluster-1 - cluster: certificate-authority: path/to/cafile server: https://cluster-2.com:4443 name: cluster-2 - cluster: insecure-skip-tls-verify: true server: https://cluster-3.com:443 name: cluster-3 contexts: - context: cluster: cluster-1 namespace: cluster-1-ns user: user-1 name: federal-context - context: cluster: cluster-2 namespace: cluster-1-ns user: user-2 name: queen-anne-context kind: Config preferences: colors: true users: - name: user-1 user: token: user-1-token - name: user-2 user: client-certificate: path/to/client/cert client-key: path/to/client/key
Для просмотра содержимого текущего файла настроек используем kubectl config view
, а для просмотра только текущего контекста – добавляем --minify
:
[simterm]
$ kubectl config view --minify apiVersion: v1 clusters: - cluster: certificate-authority-data: DATA+OMITTED server: https://example-cluster.yl4.us-east-2.eks.amazonaws.com name: arn:aws:eks:us-east-2:534***385:cluster/bttrm-eks-dev-0 contexts: - context: cluster: arn:aws:eks:us-east-2:534***385:cluster/bttrm-eks-dev-0 user: arn:aws:eks:us-east-2:534***385:cluster/bttrm-eks-dev-0 name: arn:aws:eks:us-east-2:534***385:cluster/bttrm-eks-dev-0 current-context: arn:aws:eks:us-east-2:534***385:cluster/bttrm-eks-dev-0 kind: Config preferences: {} users: - name: arn:aws:eks:us-east-2:534***385:cluster/bttrm-eks-dev-0 user: exec: apiVersion: client.authentication.k8s.io/v1alpha1 args: - --region - us-east-2 - eks - get-token - --cluster-name - bttrm-eks-dev-0 command: aws env: - name: AWS_PROFILE value: arseniy
[/simterm]
Процессы аутентификации и авторизации в AWS Elastic Kubernetes Service и процесс получения токенов см. в Kubernetes: знакомство, часть 4 — аутентификация в AWS EKS, aws-iam-authenticator и AWS IAM.
cluster
clusters: - cluster: certificate-authority: path/to/my/cafile server: https://horse.org:4443 name: horse-cluster - cluster: insecure-skip-tls-verify: true server: https://pig.org:443 name: pig-cluster
Блок cluster
содержит информацию об, внезапно, кластере – FQDN API-сервера для подключения, его Certificate Authority сертификат с публичным ключём (в base64), и имя.
Для добавления нового кластера используем kubectl config set-cluster
– передаём имя для сервера, как мы его хотим видеть, плюс URL API-сервера:
[simterm]
$ kubectl --kubeconfig=example-kubeconf config set-cluster example-cluster-1 --server=https://example-cluster.yl4.us-east-2.eks.amazonaws.com --insecure-skip-tls-verify=true Cluster "example-cluster-1" set.
[/simterm]
Проверяем содержимое example-kubeconf
:
apiVersion: v1 clusters: - cluster: insecure-skip-tls-verify: true server: https://example-cluster.yl4.us-east-2.eks.amazonaws.com name: example-cluster-1 contexts: [] current-context: "" kind: Config preferences: {} users: []
user
Блог user
определяет собственно пользователя для аутентифицикации.
Тут же указываются доступные пользвателю методы аутентифицикации, которые могут быть:
client-certificate
client-key
token
username/password
Добавляем пользователя, используя kubectl config set-credentials
:
[simterm]
$ kubectl --kubeconfig=example-kubeconf config set-credentials example-user-1 --token=SOMETOKEN User "example-user-1" set.
[/simterm]
В --token
пока передаём любую дичь – чуть позже, в Добавление user, посмотрим, как добавить аутентификацию через сертификат.
Проверяем конфиг:
apiVersion: v1 clusters: - cluster: insecure-skip-tls-verify: true server: https://example-cluster.yl4.us-east-2.eks.amazonaws.com name: example-cluster-1 contexts: [] current-context: "" kind: Config preferences: {} users: - name: example-user-1 user: token: SOMETOKEN
Появился блок users
– окей.
context
В блоке context
задаётся блок (в виде типа данных dictionary), в котором объединяются cluster
, user
и опционально namespace
.
Добавляем новый контекст с помощью kubectl config set-conext
– объединяем созданные ранее кластер и пользователя, плюс задаём дефолтный для юзера неймспейс в кластере:
[simterm]
$ kubectl --kubeconfig=example-kubeconf config set-context example-context-1 --cluster=example-cluster-1 --namespace=cluster-1-ns --user=example-user-1 Context "example-context-1" created.
[/simterm]
Проверяем:
apiVersion: v1 clusters: - cluster: insecure-skip-tls-verify: true server: https://example-cluster.yl4.us-east-2.eks.amazonaws.com name: example-cluster-1 contexts: - context: cluster: example-cluster-1 namespace: cluster-1-ns user: example-user-1 name: example-context-1 current-context: "" kind: Config preferences: {} users: - name: example-user-1 user: token: SOMETOKEN
current-context
Описывает текущий контекст, он же контекст по-умолчанию, который будет использоваться при вызове kubectl
без указания контекста.
Используем kubectl config use-context
:
[simterm]
$ kubectl --kubeconfig=example-kubeconf config use-context example-context-1 Switched to context "example-context-1".
[/simterm]
Соберём все шаги вместе – настроим второй кластер:
- создаём пользователя:
kubectl --kubeconfig=example-kubeconf-2 config set-credentials example-user-2 --username=user --password=pass
- добавляем новый API-сервер нужного кластера:
kubectl --kubeconfig=example-kubeconf-2 config set-cluster example-cluster-2 --server=http://1.1.1.1:80
- объединяем кластер и пользователя в контекст:
kubectl --kubeconfig=example-kubeconf-2 config set-context example-context-2 --cluster=example-cluster-2 --user=example-user-2
- переключаемся на этот контекст:
kubectl --kubeconfig=example-kubeconf-2 config use-context example-context-2
- меняем namespace по-умолчанию в этом кластере для этого пользователя:
kubectl --kubeconfig=example-kubeconf-2 config set contexts.example-context-2.namespace in-cluster-namespace-name
Результат:
apiVersion: v1 clusters: - cluster: server: http://1.1.1.1:8080 name: example-cluster-2 contexts: - context: cluster: example-cluster-2 namespace: in-cluster-namespace-name user: example-user-2 name: example-context-2 current-context: example-context-2 kind: Config preferences: {} users: - name: example-user-2 user: password: pass username: user
AWS IAM User и Elastic Kubernetes Service
А теперь создадим новый файл конфига с настройками для конкретного кластера – но для двух различных пользователей.
У нас используется AWS IAM, потому для аутентификации используем IAM пользователей и IAM роли, см. схемы тут – AWS Elastic Kubernetes Service: RBAC-авторизация через AWS IAM и RBAC группы.
Выполним:
- добавим существующий кластер
- добавим пользователя с аутентификацией через токен
- объединим пользователя и кластер в контекст
aws eks describe-cluster
и создание kubeconfig
Для настройки нам потребуются:
- URL API-сервера кластера
- его сертификат
- имя кластера
Добавление cluster
Получаем их с помощью aws eks describe-cluster
, сохраним в переменную $host
(| tr -d '"'
, что бы убрать кавычки):
[simterm]
$ host=$(aws --profile arseniy eks describe-cluster --name bttrm-eks-dev-0 --query cluster.endpoint | tr -d '"') $ echo $host https://example-cluster.yl4.us-east-2.eks.amazonaws.com
[/simterm]
Аналогично для сертификата:
[simterm]
$ cert=$(aws --profile arseniy eks describe-cluster --name bttrm-eks-dev-0 --query cluster.certificateAuthority.data | tr -d '"')
[/simterm]
Создаём файл настроек, добавляем туда блок cluster
.
Так как нет опции --certificate-authority-data
– делаем грязным хаком (хотя на Github вопрос поднимался ещё в 2018 году – #61572): вместо set-cluster
используем просто set
, а дальше передадим нужные параметры.
Сначала добавляем сам сервер:
[simterm]
$ kubectl --kubeconfig=newconfig config set-cluster bttrm-eks-dev-0 --server=$host Cluster "bttrm-eks-dev-0" set.
[/simterm]
А теперь через set
– добавляем тело сертификата:
[simterm]
$ kubectl --kubeconfig=newconfig config set clusters.bttrm-eks-dev-0.certificate-authority-data $cert Property "clusters.bttrm-eks-dev-0.certificate-authority-data" set.
[/simterm]
Проверяем:
apiVersion: v1 clusters: - cluster: certificate-authority-data: LS0***Qo= server: https://example-cluster.yl4.us-east-2.eks.amazonaws.com name: bttrm-eks-dev-0 contexts: [] current-context: "" kind: Config preferences: {} users: []
Добавление user
Теперь добавим пользователей.
У меня в AWS CLI настроен профиль arseniy – это рутовый юзер, кроме него есть пользователь iam-bttrm-web-user-1-kubectl, у которого доступы ограничены двумя неймспейсами, и который обращается к EKS, используя AWS IAM Role (см. AWS Elastic Kubernetes Service: RBAC-авторизация через AWS IAM и RBAC группы).
Добавим двух пользователей в конфиг.
Тут используем токен, который можно получить с помощью aws-iam-authenticator
, см. Kubernetes: знакомство, часть 4 — аутентификация в AWS EKS, aws-iam-authenticator и AWS IAM:
[simterm]
$ aws-iam-authenticator token -i bttrm-eks-dev-0
[/simterm]
Либо можем посмотреть – как выполняется получение токена сейчас (настроено через aws eks update-kubeconfig
):
[simterm]
$ kubectl config view --minify ... users: - name: arn:aws:eks:us-east-2:534***385:cluster/bttrm-eks-dev-0 user: exec: args: - --region - us-east-2 - eks - get-token - --cluster-name - bttrm-eks-dev-0 command: aws env: - name: AWS_PROFILE value: arseniy
[/simterm]
Т.е.:
[simterm]
$ aws --profile us-east-2 --profile arseniy eks get-token --cluster-name bttrm-eks-dev-0
[/simterm]
Теперь получаем сам токен, сохраняем в переменную $token
:
[simterm]
$ token=$(aws --profile us-east-2 --profile arseniy eks get-token --cluster-name bttrm-eks-dev-0 | jq .status.token | tr -d '"')
[/simterm]
Добавляем пользователя arseny-dev-0 в конфиг:
[simterm]
$ kubectl --kubeconfig=newconfig config set-credentials arseny-dev-0 --token=$token User "arseny-dev-0" set.
[/simterm]
Проверяем конфиг:
[simterm]
$ cat newconfig apiVersion: v1 clusters: - cluster: certificate-authority: LS0***LQo= server: https://example-cluster.yl4.us-east-2.eks.amazonaws.com name: bttrm-eks-dev-0 contexts: [] current-context: "" kind: Config preferences: {} users: - name: arseny-dev-0 user: token: k8s-aws-v1.aHR***DE0
[/simterm]
Создание context
И собираем кластер и пользователя в контекст с именем arseny@dev-0:
[simterm]
$ kubectl --kubeconfig=newconfig config set-context arseny@dev-0 --cluster=bttrm-eks-dev-0 --user=arseny-dev-0 Context "arseny@dev-0" created.
[/simterm]
Проверяем конфиг:
apiVersion: v1 clusters: - cluster: certificate-authority: LS0***LQo= server: https://example-cluster.yl4.us-east-2.eks.amazonaws.com name: bttrm-eks-dev-0 contexts: - context: cluster: bttrm-eks-dev-0 user: arseny-dev-0 name: arseny@dev-0 current-context: "" kind: Config preferences: {} users: - name: arseny-dev-0 user: token: k8s-aws-v1.aHR***DE0
Задаём этот контекст дефолтным:
[simterm]
$ kubectl --kubeconfig=newconfig config use-context arseny@dev-0 Switched to context "arseny@dev-0".
[/simterm]
И пробуем подключиться к кластеру:
[simterm]
$ kubectl --kubeconfig=newconfig get pod NAME READY STATUS RESTARTS AGE reloader-reloader-55448df76c-znst5 1/1 Running 0 4d4h testing-deployment-7b6964f774-cvhmw 1/1 Running 3 3d22h
[/simterm]
Готово.
Ссылки по теме
- Configure Access to Multiple Clusters
- Organizing Cluster Access Using kubeconfig Files
- Kubernetes Client Authentication on Amazon EKS
- Kubernetes Tips: Give Access To Your Cluster With A Client Certificate
- Kubernetes/docs/user-guide/kubeconfig-file.md
- Configure RBAC In Your Kubernetes Cluster
- Creating a kubeconfig file for a self-hosted Kubernetes cluster
- Mastering the KUBECONFIG file
- Kubernetes Tips: Give Access To Your Cluster With A Client Certificate
- The dark side of kubeconfig – вопросы безопасности при использовании kubeconfig