Задача – создать пользователя, у которого будет возможность проверять состояние подов и читать их логи – ко всем другим операциям доступа быть не должно.
AWS EKS использует AWS IAM для аутентификации в в Kubernetes-кластере (см. пост Kubernetes: знакомство, часть 4 — аутентификация в AWS EKS, aws-iam-authenticator и AWS IAM), но для авторизации, т.е. определения конкретных прав доступа – используется встроенный RBAC-механизм самого Kubernetes.
Предыдущие части:
- Kubernetes: знакомство, часть 1 — архитектура и основные компоненты, обзор
- Kubernetes: знакомство, часть 2 — создание кластера с AWS cloud-provider и AWS LoadBalancer
- Kubernetes: знакомство, часть 3 — обзор AWS EKS и ручное создание кластера
- Kubernetes: знакомство, часть 4 — аутентификация в AWS EKS, aws-iam-authenticator и AWS IAM
Рассмотрим общие понятия RBAC, а затем создадим пользователя с нужными правами.
Содержание
Обзор Kubernetes RBAC
Документация – Authorization Overview и Using RBAC Authorization.
RBAC модель в Kubernetes состоит из трёх компонентов:
- Роли: определение разрешений
- Субъекты: Пользователи (люди или приложения), или группы пользователей
- RoleBingdings: указывает, какие Пользователи имеют какие Роли
RBAC Role
Пример роли с именем example-role для доступа к подам в неймспейсе mynamespace, которая разрешает выполнять get
, watch
и list
операции:
kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: mynamespace name: example-role rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"]
Для получения списка Kubernetes apiGroups
используем kubectl api-resources
:
[simterm]
$ kubectl api-resources -o wide NAME SHORTNAMES APIGROUP NAMESPACED KIND VERBS ... pods po true Pod [create delete deletecollection get list patch update watch] ...
[/simterm]
В rules
примера выше мы:
apiGroups: [""]
– указываем core API groupresources: ["pods"]
– к ресурсам какого типа разрешено обращение["get", "watch", "list"]
– какие actions разрешены над этими ресурсами
RBAC RoleBingding
Для того, что бы пользователь получил эти разрешения – создаётся RoleBingding
, который в неймспейсе mynamespace связывает роль example-role с пользователем example-user:
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: example-rolebinding namespace: mynamespace subjects: - kind: User name: example-user apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: example-role apiGroup: rbac.authorization.k8s.io
Тут:
subjects
:kind: User
– тип объекта, которому разрешён доступ, в нашем случае это будет обычный пользовательname: example-user
– имя пользователя, которому подключаем права
roleRef
:kind: Role
– что именно подключаем пользователю, в этом случае объект типаRole
name: example-role
– собственно имя роли, как мы её задали вname: example-role
в примере самой роли выше
Role
vs ClusterRole
Role
и ClusterRole
представляют собой набор правил, которые описывают доступы, аналогично имеются RoleBinding
и ClusterRoleBinding
.
Разница между ними в том, что Role
задаёт права доступа в определённом неймспейсе, тогда как ClusterRole
– на уровне всего кластера, например:
- к ресурсам типа ноды кластера
- ресурсы по всем неймспейсам кластера
- доступ к ендпоинтам типа
/healthz
Выглядит ClusterRole
аналогично, с той разницей, что kind
указывается ClusterRole
:
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: example-clusterrole rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"]
И пример ClusterRoleBinding
:
kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: example-clusterrolebinding subjects: - kind: User name: example-user apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: example-clusterrole apiGroup: rbac.authorization.k8s.io
Имейти ввиду, что после создания Binding у вас не будет возможности изменить roleRef
– для этого биндинг треубется удалить, и создать заново.
EKS аутентификация и авторизация
Вкратце, аутентификация и авторизация происходит в следующем порядке:
- Аутентификация
- клиент выполняет запрос к Kubernetes-кластеру, передавая токен аутентификации, в котором включён ID пользователя
- Kubernetes, используя
aws-iam-authenticator
обращается к AWS IAM, и проверяет – имеется ли пользователь в системе, и является ли он тем, за кого себя выдаёт
- Авторизация
- если пользователь прошёл Аутентификацию – то Kubernetes передёт его в свой механизм RBAC вместе со всеми запрошенными действиями и ресурсами
- в RBAC ищется
RoleBinding
, которая связывает пользователя с определённой ролью - по имени роли проверяются разрешения на доступ к ресурсам и действиям
- принимается решение о разрешении или запрете действий
Далее выполним:
- создадим IAM пользователя
- настроим AWS CLI
- создадим RBAC Role с правами read-only на поды
- создадим RBAC RoleBinding, которая свяжет пользователя и роль
IAM пользователь
Начнём с создания IAM-юзера.
Добавляем пользователя с Programmatic Access:
Получаем его ключи доступа:
IAM policy
Если пользователю потребуются права на выполнение запросов к самому AWS EKS сервису, например – kubectl get nodes
– то отдельно добавляем политику с разрешениями на API-вызовы к ядру AWS.
Переходим в Policies – Add Policy:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "eks:DescribeCluster", "eks:ListClusters" ], "Resource": "*" } ] }
Тут разрешаем всего два действия – eks:DescribeCluster
и eks:ListClusters
, во всех регионах для всех кластеров EKS.
Сохраняем её, и подключаем политику к пользователю:
AWS CLI config
Что бы настроить kubectl
– сначала настраиваем AWS CLI под отдельный профиль, см. AWS: именованные профили доступа:
[simterm]
$ aws configure --profile eks-ro-user AWS Access Key ID [None]: AKI***FYC AWS Secret Access Key [None]: SzH***VGi Default region name [None]: eu-north-1 Default output format [None]: json
[/simterm]
Проверяем доступ к AWS:
[simterm]
$ aws --profile eks-ro-user sts get-caller-identity { "UserId": "AID***XGK", "Account": "534***385", "Arn": "arn:aws:iam::534***385:user/eks-ro-user" }
[/simterm]
И проверяем доступ к EKS-кластерам (вернее – к AWS API):
[simterm]
$ aws --profile eks-ro-user eks list-clusters --output text CLUSTERS eks-alb-testing-3 CLUSTERS eks-alb-testing-2
[/simterm]
Kubernetes RBAC – пример
Role
Создаём роль – указываем доступ только к pods, их логам и на создание port-forwading, и только на операции get
, list
, create
:
kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: eks-ro-role rules: - apiGroups: [""] resources: ["pods", "pods/log", "pods/portforward"] verbs: ["get", "list", "create"]
Применяем:
[simterm]
$ kubectl apply -f rbac-role.yml role.rbac.authorization.k8s.io/eks-ro-role created
[/simterm]
Проверяем:
[simterm]
$ kubectl get roles -o yaml apiVersion: v1 items: - apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"Role","metadata":{"annotations":{},"name":"eks-ro-role","namespace":"default"},"rules":[{"apiGroups":[""],"resources":["pods","pods/log"],"verbs":["get","list"]}]} creationTimestamp: "2020-03-24T10:34:27Z" name: eks-ro-role namespace: default resourceVersion: "681997" selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/default/roles/eks-ro-role uid: 09a78b6f-6dbb-11ea-827f-0a9eb3e1782e rules: - apiGroups: - "" resources: - pods - pods/log verbs: - get - list kind: List metadata: resourceVersion: "" selfLink: ""
[/simterm]
RoleBinding
Добавляем биндинг – связываем нашу роль и пользователя:
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: eks-ro-role-binding subjects: - kind: User name: eks-ro-user apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: eks-ro-role apiGroup: rbac.authorization.k8s.io
Применяем:
[simterm]
$ kubectl apply -f rbac-rolebinding.yml rolebinding.rbac.authorization.k8s.io/eks-ro-role-binding created
[/simterm]
aws-auth ConfigMap
Редактируем aws-auth ConfigMap
(см. AWS EKS aws-auth ConfigMap):
[simterm]
$ kubectl edit configmap aws-auth -n kube-system
[/simterm]
Добавляем mapUsers
– указываем ARN пользователя, его имя и его группу(ы):
apiVersion: v1 data: mapRoles: | - groups: - system:bootstrappers - system:nodes rolearn: arn:aws:iam::534***385:role/eksctl-eks-alb-testing-2-nodegrou-NodeInstanceRole-M6BS1WV48RLR username: system:node:{{EC2PrivateDNSName}} mapUsers: | - userarn: arn:aws:iam::534***385:user/eks-ro-user username: eks-ro-user groups: eks-ro-role
Проверяем:
[simterm]
$ kubectl get pods --as eks-ro-user NAME READY STATUS RESTARTS AGE nginx-7db9fccd9b-7d4rq 1/1 Running 0 58m
[/simterm]
Попробуем получить список Worker Nodes – к ним доступа мы не давали:
[simterm]
$ kubectl get nodes --as eks-ro-user Error from server (Forbidden): nodes is forbidden: User "eks-ro-user" cannot list resource "nodes" in API group "" at the cluster scope
[/simterm]
Отлично.
Проверим логи – запускаем порт-форвардинг на под с NGINX:
[simterm]
$ kubectl --as eks-ro-user port-forward nginx-7db9fccd9b-7d4rq 8000:80 Forwarding from 127.0.0.1:8000 -> 80 Forwarding from [::1]:8000 -> 80
[/simterm]
Выполняем запрос к поду:
[simterm]
$ curl -I localhost:8000 HTTP/1.1 200 OK
[/simterm]
Логи:
[simterm]
$ kubectl --as eks-ro-user logs -f nginx-7db9fccd9b-7d4rq 127.0.0.1 - - [25/Mar/2020:07:29:06 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.69.1" "-"
[/simterm]
Готово.
Ссылки по теме
- Authentication and Authorization in Kubernetes
- Privilege escalation via pod creation
- Authenticating Across Clusters with kubeconfig
- Granting User Access to Your Kubernetes Cluster
- How to Add Limited Access IAM Users to an EKS Cluster
- Managing Users or IAM Roles for your Cluster
- Kubernetes Authorization
- How do I provide access to other users and roles after cluster creation in Amazon EKS?
- How do I manage permissions across namespaces for my IAM users in an Amazon EKS cluster?
- Amazon EKS Identity-Based Policy Examples
- Kubernetes RBAC — giving permissions for logging and port-forwarding
- Add new user to manage AWS EKS
- Configuring permissions in Kubernetes with RBAC