Kubernetes - пример использования RBAC

Thank you for reading this post, don't forget to subscribe!

Начи­ная с Kubernetes 1.6, поли­ти­ки RBAC вклю­ча­ют­ся по умол­ча­нию. Поли­ти­ки RBAC име­ют жиз­нен­но важ­ное зна­че­ние для пра­виль­но­го управ­ле­ния вашим кла­сте­ром, посколь­ку они поз­во­ля­ют вам ука­зы­вать, какие типы дей­ствий раз­ре­ше­ны для кон­крет­но­го поль­зо­ва­те­ля и его роли в вашей организации.

При­ме­ры включают:

  • Защи­ту кла­сте­ра путем раз­ре­ше­ния при­ви­ле­ги­ро­ван­ные дей­ствий (напри­мер, доступ к сек­ре­там) толь­ко администраторам.
  • Вклю­че­ние при­ну­ди­тель­ной аутен­ти­фи­ка­ции поль­зо­ва­те­лей в вашем кластере.
  • Огра­ни­че­ние созда­ния ресур­сов (т.к. кон­тей­не­ры, посто­ян­ные дис­ки, раз­вер­ты­ва­ния) для кон­крет­ных про­странств имен. Вы так­же може­те исполь­зо­вать кво­ты, что­бы гаран­ти­ро­вать, что исполь­зо­ва­ние ресур­сов огра­ни­че­но и нахо­дит­ся под контролем.
  • Раз­ре­ше­ние поль­зо­ва­те­лям про­смат­ри­вать ресур­сы толь­ко в сво­ем авто­ри­зо­ван­ном про­стран­стве имен, что поз­во­ля­ет изо­ли­ро­вать ресур­сы внут­ри вашей орга­ни­за­ции (напри­мер, меж­ду отде­ла­ми или департаментами).

В след­ствие того, что в послед­них вер­си­ях Kubernetes RBAC вклю­чен по умол­ча­нию, вы, воз­мож­но, уже обна­ру­жи­ли спе­ци­фи­че­ские ошиб­ки при настрой­ке реше­ний по сете­вой вир­ту­а­ли­за­ции (напри­мер, flunneld) или деп­лое Helm в вашем кла­сте­ре. Обыч­но такие ошиб­ки выгля­дят сле­ду­ю­щим образом:

the server does not allow access to the requested resource

ща рас­смот­рим как пра­виль­но рабо­тать с RBAC, что­бы вы мог­ли решать тако­го рода проблемы.

API объ­ек­ты RBAC

Одной из основ­ных функ­ций Kubernetes явля­ет­ся то, что все его ресур­сы пред­став­ля­ют собой моде­ли­ру­е­мые API объ­ек­ты, кото­рые поз­во­ля­ют выпол­нять с ними опе­ра­ции CRUD (Create, Read, Update, Delete). При­ме­ра­ми ресур­сов являются:

  • Pods
  • Deployments
  • Namespaces
  • Secrets
  • Replicasets
  • PersistentVolumes
  • ConfigMaps
  • Nodes

При­ме­ры воз­мож­ных опе­ра­ций над эти­ми ресурсами:

  • create
  • get
  • delete
  • list
  • update
  • edit
  • watch
  • exec

Высо­ко­уров­не­вые ресур­сы свя­за­ны с груп­па­ми API (напри­мер, Pod отно­сит­ся к core груп­пе API, а Deployments отно­сят­ся к груп­пе API apps). Допол­ни­тель­ные све­де­ния обо всех доступ­ных ресур­сах, опе­ра­ци­ях и груп­пах API см. в офи­ци­аль­ном спра­воч­ни­ке API Kubernetes.

Для управ­ле­ния RBAC в Kubernetes, поми­мо ресур­сов и опе­ра­ций, нам нуж­ны сле­ду­ю­щие элементы:

  • Rules. Пра­ви­ла пред­став­ля­ют собой набор опе­ра­ций, кото­рые могут выпол­нять­ся груп­пой ресур­сов, при­над­ле­жа­щих раз­лич­ным груп­пам API.
  • Roles и ClusterRoles. Оба состо­ят из пра­вил. Раз­ни­ца меж­ду Role и ClusterRole – это область при­ме­ни­мо­сти: в Role пра­ви­ла при­ме­ни­мы к одно­му про­стран­ству имен, тогда как ClusterRole пра­ви­ла рас­про­стра­ня­ют­ся на весь кла­стер, поэто­му пра­ви­ла при­ме­ня­ют­ся к несколь­ким про­стран­ствам имен. ClusterRoles так­же могут опре­де­лять пра­ви­ла для ресур­сов уров­ня кла­сте­ра (напри­мер, узлы). Roles и ClusterRoles мапят­ся на API ресур­сы внут­ри наше­го кластера.
  • Subjects. Субъ­ек­ты соот­вет­ству­ют объ­ек­там, кото­рые пыта­ют­ся выпол­нить опе­ра­ции в кла­сте­ре. Суще­ству­ет три типа субъектов:
  • User Accounts (учет­ные запи­си поль­зо­ва­те­лей): гло­баль­ны и пред­на­зна­че­ны для людей или про­цес­сов, живу­щих вне кла­сте­ра. В кла­сте­ре Kubernetes нет свя­зан­но­го с этим субъ­ек­том объ­ек­та API ресурса.
  • Service Accounts (учет­ные запи­си служб). Этот вид учет­ной запи­си пред­на­зна­чен для внут­ри­кла­стер­ных про­цес­сов, запу­щен­ных в Pod-ах ваше­го кла­сте­ра, кото­рым необ­хо­ди­мо полу­чить доступ к API кластера.
  • Groups (груп­пы). Груп­пы исполь­зу­ет­ся для ссыл­ки на сра­зу несколь­ко учет­ных записей.Некоторые груп­пы, такие как cluster-admin (объ­яс­ня­ет­ся в после­ду­ю­щих раз­де­лах), созда­ют­ся по умолчанию.
  • RoleBindings (свя­зи ролей) и ClusterRoleBindings (свя­зи кла­стер­ных ролей): как вид­но из назва­ния сущ­но­стей, они свя­зы­ва­ют субъ­ек­ты с роля­ми (т.е. опе­ра­ци­я­ми, кото­рые может выпол­нять кон­крет­ный поль­зо­ва­тель). Что каса­ет­ся их раз­ни­цы с ClusterRoles, раз­ни­ца заклю­ча­ет­ся в обла­сти при­ме­ни­мо­сти: RoleBinding при­ме­ня­ет пра­ви­ла внут­ри одно­го про­стран­ства имен, тогда как ClusterRoleBinding при­ме­ня­ет их во всех про­стран­ствах имен кластера.

Вы може­те най­ти при­ме­ры каж­до­го эле­мен­та API в офи­ци­аль­ной доку­мен­та­ции Kubernetes.

 

Создание пользователя с ограничениями по пространству имен

В этом при­ме­ре мы созда­дим сле­ду­ю­щую учет­ную запись пользователя:

  • Имя поль­зо­ва­те­ля: user1
  • Груп­па: deparment1

Мы доба­вим необ­хо­ди­мые поли­ти­ки RBAC, что­бы этот поль­зо­ва­тель мог пол­но­стью управ­лять раз­вер­ты­ва­ни­я­ми (т.е. исполь­зо­вать коман­ду kubectl run) толь­ко внут­ри про­стран­ства имен office. В кон­це мы про­ве­рим создан­ные поли­ти­ки, что­бы убе­дить­ся, что они рабо­та­ют так, как мы их определили.

Создание пространства имен

Выпол­ни­те коман­ду kubectl create для созда­ния про­стран­ства имен office. Коман­ду необ­хо­ди­мо запу­стить от поль­зо­ва­те­ля Kubernetes admin:

[root@kub-master-1 ~]# kubectl create namespace office

 

Создание пользователя

Как уже упо­ми­на­лось ранее, в Kubernetes нет объ­ек­тов API для управ­ле­ния учет­ны­ми запи­ся­ми поль­зо­ва­те­лей. Из доступ­ных спо­со­бов управ­ле­ния аутен­ти­фи­ка­ци­ей (см. офи­ци­аль­ную доку­мен­та­цию Kubernetes) для про­сто­ты мы будем исполь­зо­вать сер­ти­фи­ка­ты OpenSSL. Необ­хо­ди­мые шаги:

  • Создай­те закры­тый ключ для сво­е­го поль­зо­ва­те­ля. В этом при­ме­ре мы назо­вем файл user1.key[root@kub-master-1 ~]# openssl genrsa -out user1.key 2048
  • Создай­те запрос сер­ти­фи­ка­та user1.csr, исполь­зуя толь­ко что создан­ный вами закры­тый ключ (user1.key). Убе­ди­тесь, что вы ука­за­ли свое имя поль­зо­ва­те­ля и груп­пу в раз­де­ле -subj(CN для име­ни поль­зо­ва­те­ля и O для груп­пы). Как упо­ми­на­лось ранее, мы будем исполь­зо­вать имя user1 и deparment1 в каче­стве группы:

[root@kub-master-1 ~]# openssl req -new -key user1.key -out user1.csr -subj "/CN=user1/O=deparment1"

  • Най­ди­те свой центр сер­ти­фи­ка­ции кла­сте­ра Kubernetes (CA). Он будет отве­чать за утвер­жде­ние запро­са и полу­че­ние необ­хо­ди­мо­го сер­ти­фи­ка­та для досту­па к API кла­сте­ра. Обыч­но он рас­по­ла­га­ет­ся в дирек­то­рии /etc/kubernetes/pki/. В слу­чае Minikube это будет ~/.minikube/. Убе­ди­тесь, что фай­лы ca.crt и ca.key суще­ству­ют в соот­вет­ству­ю­щей директории.

 

  • Создай­те сер­ти­фи­кат user1.crt, одоб­рив запрос на под­пись сер­ти­фи­ка­та, user1.csr, сде­лан­ный ранее. Убе­ди­тесь, что вы заме­ни­ли CA_LOCATION в при­ме­ре коман­ды ниже на место­по­ло­же­ние ваше­го акту­аль­но­го CA кла­сте­ра. Сер­ти­фи­кат будет дей­стви­те­лен в тече­ние 500 дней:

$ openssl x509 -req -in user1.csr -CA CA_LOCATION/ca.crt -CAkey CA_LOCATION/ca.key -CAcreateserial -out user1.crt -days 500

в моём слу­чае это команда:

[root@kub-master-1 ~]# openssl x509 -req -in user1.csr -CA /etc/kubernetes/pki/ca.pem -CAkey /etc/kubernetes/pki/ca-key.pem -CAcreateserial -out user1.crt -days 500
и её вывод:

  • Сохра­ни­те как user1.crt, так и user1.key где-нибудь в без­опас­ном месте (напри­мер, в дирек­то­рии ~/.kube/certs/):
    $ mkdir ~/.kube/certs
    $ cp user1.crt ~/.kube/certs
    $ cp user1.key ~/.kube/certs
  • добавь­те новый кон­текст с новы­ми учет­ны­ми дан­ны­ми для ваше­го кла­сте­ра Kubernetes.
    [root@kub-master-1 ~]# kubectl config set-credentials user1 --client-certificate=$HOME/.kube/certs/user1.crt --client-key=$HOME/.kube/certs/user1.keyСмотрим имя кластера:
    [root@kub-master-1 ~]# kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'

    [root@kub-master-1 ~]# kubectl config set-context user1-context --cluster=cluster.local --namespace=office --user=user1

 

доба­вим теперь поль­зо­ва­те­ля  под кото­рым будем работать:

[root@kub-master-1 ~]# adduser test
[root@kub-master-1 ~]# mkdir -p /home/test/.kube/certs
[root@kub-master-1 ~]# cp /root/.kube/certs/user1.* /home/test/.kube/certs/

смот­рим файл:
[root@kub-master-1 ~]# cat /root/.kube/config

нас инте­ре­су­ет:

certificate-authority-data
и
server

и созда­ём файл сле­ду­ю­ще­го вида:

[root@kub-master-1 ~]# cat /home/test/.kube/config

не забы­ва­ем ука­зать certificate-authority-data и server

Теперь при попыт­ке исполь­зо­вать kubectl с этим кон­фи­гу­ра­ци­он­ным фай­лом мы будем полу­чать отказ в досту­пе. Это ожи­да­е­мое пове­де­ние, посколь­ку мы не опре­де­ли­ли ника­ких раз­ре­шен­ных опе­ра­ций для толь­ко что создан­но­го поль­зо­ва­те­ля. Убе­ди­тесь в этом сами:

[test@kub-master-1 ~]$ kubectl get pod -n my-site
The connection to the server localhost:8080 was refused - did you specify the right host or port?
дан­ная ошиб­ка логич­на пото­му что мы не ука­за­ли context

[test@kub-master-1 ~]$ kubectl --context=user1-context get pods -n my-site
Error from server (Forbidden): pods is forbidden: User "user1" cannot list resource "pods" in API group "" in the namespace "my-site"

а вот эта как рас та ошиб­ка что и долж­на при­ле­тать Forbidden

Создание роли для управления развертываниями

Создай­те файл role-deployment-manager.yaml с при­ве­ден­ным ниже содер­жи­мым. В этом yaml-фай­ле мы созда­ем пра­ви­ло, кото­рое поз­во­ля­ет поль­зо­ва­те­лю выпол­нять несколь­ко опе­ра­ций с Deployments, Pods и ReplicaSets (необ­хо­ди­мых для созда­ния Deployment), кото­рые при­над­ле­жат к core (выде­ле­ны “” в yaml-фай­ле) extensions груп­пам API:

[root@kub-master-1 ~]# cat role-deployment-manager.yaml

[root@kub-master-1 ~]# kubectl create -f role-deployment-manager.yaml

 

Установление связи пользователь-роль

Создай­те файл rolebinding-deployment-manager.yaml так, как пока­за­но ниже. В этом фай­ле мы при­вя­зы­ва­ем Role deployment-manager к субъ­ек­ту User Account user1 внут­ри про­стран­ства имен office:

[root@kub-master-1 ~]# cat rolebinding-deployment-manager.yaml

[root@kub-master-1 ~]# kubectl create -f rolebinding-deployment-manager.yaml

Тестирование политик RBAC

Теперь вы може­те выпол­нять сле­ду­ю­щие коман­ды без каких-либо проблем:

[test@kub-master-1 ~]$ kubectl --context=user1-context get pods -n office
No resources found in office namespace.

запу­стим тесто­вое при­ло­же­ние и про­ве­рим что нам доступ­но из под наше­го пользователя:

[test@kub-master-1 ~]$ kubectl --context=user1-context get all -n office

как видим нам доступ­ны толь­ко сле­ду­ю­щие сущности:
deployments  replicasets   pods

как рас их мы и пере­чис­ли­ли в кон­фи­ге  role-deployment-manager.yaml  для наше­го namespace office

про­ве­рим удаление:

как видим всё ок.