ArgoCD использует два типа пользователей – локальные, заданные в argocd-cm
ConfigMap, и SSO.
Ниже рассмотрим работу с локальными пользователями, а позже добавим SSO и группы, так как для локальных пользователей нельзя создавать группы, см. Local users/accounts.
Разделение доступов выполняется с помощью ролей, которым подключаются политики, описывающие к чему есть доступ, и на какие операции.
При этом доступы можно выдавать как глобально, так и с разделением на отдельные Projects.
Начнём с добавления простого пользователя, и понемногу разберёмся с остальным.
Содержание
Пользователи и роли ArgoCD
Добавление локального пользователя
Тут всё просто – редактируем argocd-cm
ConfigMap, и добавляем пользователя:
apiVersion: v1 data: accounts.testuser: apiKey,login ...
В apiKey
указываем права на генерацию JWT-токенов для аутентификации, см. Security, login
– разрешение на логин через WebUI.
Сохраняем, и проверяем список пользователей:
[simterm]
$ argocd account list NAME ENABLED CAPABILITIES admin true login testuser true apiKey, login
[/simterm]
Пользователь admin создан при деплое ArgoCD, и у него нет прав на создание токена (можно перееопределить, добавив его в argocd-cm
, хотя его рекомендуется вообще отключить после создания новых пользователей).
Вообще общая идея, как мне кажется – это использовать пользователей для доступа к WebUI, а роли проектов – для получения токенов, а потом эти токены уже использовать в CI/CD пайплайнах.
testuser – создан нами только что, но сейчас он без пароля, и логин с ним не пройдёт.
Что бы создать пароль новому пользователю – вам нужен пароль текущего пользователя admin:
[simterm]
$ argocd account update-password --account testuser --new-password 1234 --current-password admin-p@ssw0rd Password updated
[/simterm]
Бредовенько, конечно, но как есть. См. Unable to change the user’s password via argocd CLI.
Логинимся с новым юзером:
[simterm]
$ argocd login dev-1-18.argocd.example.com --username testuser --name [email protected] Password: 'testuser' logged in successfully Context '[email protected]' updated
[/simterm]
Проверяем локальные контексты:
[simterm]
$ argocd login dcontext CURRENT NAME SERVER [email protected] dev-1-18.argocd.example.com * [email protected] dev-1-18.argocd.example.com
[/simterm]
Окей – сейчас под testuser.
Роли и RBAC
По-умолчанию, все новые пользователи используют policy.default
из argocd-rbac-cm
ConfigMap:
[simterm]
$ kubectl -n dev-1-18-devops-argocd-ns get configmap argocd-rbac-cm -o yaml apiVersion: v1 data: policy.default: role:readonly ...
[/simterm]
Для Argo имеется две дефолтных роли – role:readonly
и role:admin
. Кроме того, policy.default
можно задать в role: ''
, что бы отключить доступ вообще, т.к. если для пользователя не находится ролей/доступов – то будет применена именно policy.default
.
Сейчас наш новый юзер может только просматривать ресурсы:
[simterm]
$ argocd cluster list SERVER NAME VERSION STATUS MESSAGE https://kubernetes.default.svc in-cluster 1.18+ Successful
[/simterm]
Но не создавать новые, например попробуем добавить новый кластер:
[simterm]
$ argocd cluster add config-aws-china-eks-account@aws-china-eks-account --kubeconfig ~/.kube/config-aws-china-eks-account@aws-china-eks-account INFO[0002] ServiceAccount "argocd-manager" already exists in namespace "kube-system" INFO[0003] ClusterRole "argocd-manager-role" updated INFO[0004] ClusterRoleBinding "argocd-manager-role-binding" updated FATA[0006] rpc error: code = PermissionDenied desc = permission denied: clusters, create, https://21D***ECD.gr7.cn-northwest-1.eks.amazonaws.com.cn, sub: testuser, iat: 2021-05-12T14:03:12Z
[/simterm]
“permission denied: clusters, create” – ага.
Что бы дать права на создание кластера – редактируем argocd-rbac-cm
CondfigMap, добавлям роль role:test-role
с правами clusters, create
:
... data: policy.default: role:readonly policy.csv: | p, role:test-role, clusters, create, *, allow g, testuser, role:test-role ...
Проверяем:
[simterm]
$ argocd account can-i create clusters '*' yes
[/simterm]
Создаём:
[simterm]
$ argocd cluster add config-aws-china-eks-account@aws-china-eks-account --kubeconfig ~/.kube/config-aws-china-eks-account@aws-china-eks-account INFO[0001] ServiceAccount "argocd-manager" already exists in namespace "kube-system" INFO[0002] ClusterRole "argocd-manager-role" updated INFO[0003] ClusterRoleBinding "argocd-manager-role-binding" updated Cluster 'https://21D***ECD.gr7.cn-northwest-1.eks.amazonaws.com.cn' added
[/simterm]
Но что делать, если хочется задать ограничения по неймспейсам? Ведь RBAC в ConfigMap не поддерживает их.
К примеру, у нас есть Web-разработчики, есть backend-разработчики, и у них разные приложения, которые деплоятся в разные неймспейсы, и хочется отделить их – что бы Веб-команда не видела и не трогала ресурсы Бекенда, а Бекенда-команда – не затрагивала ресурсы Веб-команды.
ArgoCD Projects
И тут “Projects comes to the rescue“!
Project позволяет задать доступы для неймпейсов, репозиториев, кластеров и так далее. А затем мы сможем ограничить каждую группу девелоперов доступом к определённому проекту и, соответсвенно, ограничим доступ к неймспейсам.
Посмотрим, как это работает.
При установке, ArgoCD создаёт проект default:
[simterm]
$ argocd proj list NAME DESCRIPTION DESTINATIONS SOURCES CLUSTER-RESOURCE-WHITELIST NAMESPACE-RESOURCE-BLACKLIST SIGNATURE-KEYS ORPHANED-RESOURCES default *,* * */* <none> <none> disabled
[/simterm]
Проекты являются Kubernetes Custom Resource с типом appproject
:
[simterm]
$ kubectl -n dev-1-18-devops-argocd-ns get appproject NAME AGE default 166d
[/simterm]
И могут бысть созданы из манифеста (declarative setup ArgoCD рассмотрим в следующих постах):
kind: AppProject metadata: name: example-project namespace: dev-1-18-devops-argocd-ns spec: clusterResourceWhitelist: - group: '*' kind: '*' destinations: - namespace: argo-test-ns server: https://kubernetes.default.svc orphanedResources: warn: false sourceRepos: - '*'
Или с помощью ArgoCD CLI:
[simterm]
$ argocd proj create test-project -d https://kubernetes.default.svc,argo-test-ns -s https://github.com/argoproj/argocd-example-apps.git
[/simterm]
Проверяем:
[simterm]
$ argocd proj list NAME DESCRIPTION DESTINATIONS SOURCES CLUSTER-RESOURCE-WHITELIST NAMESPACE-RESOURCE-BLACKLIST SIGNATURE-KEYS ORPHANED-RESOURCES default *,* * */* <none> <none> disabled test-project https://kubernetes.default.svc,argo-test-ns https://github.com/argoproj/argocd-example-apps.git <none> <none> <none> disabled
[/simterm]
Теперь перенесём в этот проект уже имеющееся тестовое приложение guestbook из неймспейса argo-test-ns
:
[simterm]
$ argocd app set guestbook --project test-project
[/simterm]
Проверяем:
[simterm]
$ argocd app get guestbook Name: guestbook Project: test-project Server: https://kubernetes.default.svc Namespace: argo-test-ns URL: https://dev-1-18.argocd.example.com/applications/guestbook Repo: https://github.com/argoproj/argocd-example-apps.git ...
[/simterm]
А дальше – проверим, как работает ограничение на неймспейсы.
Для нашего проекта при создании был задан один destination – https://kubernetes.default.svc,argo-test-ns
.
Попробуем создать в этом проекте новое приложение, но namespace укажем argo-test-2-ns:
[simterm]
$ argocd app create guestbook-2 --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace argo-test-2-ns --project test-project FATA[0001] rpc error: code = InvalidArgument desc = application spec is invalid: InvalidSpecError: application destination {https://kubernetes.default.svc argo-test-2-ns} is not permitted in project 'test-project'
[/simterm]
“application destination {https://kubernetes.default.svc argo-test-2-ns} is not permitted in project ‘test-project‘” – отлично!
Обновим проект, добавим ещё один destination – тот же кластер, но неймспейс argo-test-2-ns:
[simterm]
$ argocd proj add-destination test-project https://kubernetes.default.svc argo-test-2-ns
[/simterm]
Проверяем:
[simterm]
$ argocd proj get test-project Name: test-project Description: Destinations: https://kubernetes.default.svc,argo-test-ns https://kubernetes.default.svc,argo-test-2-ns ...
[/simterm]
Повторяем создание приложения:
[simterm]
$ argocd app create guestbook-2 --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace argo-test-2-ns --project test-project application 'guestbook-2' created
[/simterm]
Теперь работает.
Соответсвенно, на Dev-кластере можно будет задать destination в виде '*'
, так как неймспейсы там динамические – девелоперы деплоят приложения из разных бранчей в разные неймспейсы, а вот для Production кластера – зададим жёсткое ограничение.
Projects и роли
Глобальные роли
Доступ к проектам можно задать как через глобальные настройки в argocd-rbac-cm
ConfigMap, так и локально для проекта.
Например, вернёмся к нашей глобальной роли role:test-role
, и добавим политику, разрешив доступ к приложениям только из проекта test-project
, а в policy.default
отключаем read-only доступ ко всем ресурсам, указав role: ''
:
... policy.csv: | p, role:test-role, clusters, create, *, allow p, role:test-role, applications, *, test-project/*, allow g, testuser, role:test-role policy.default: role:'' ...
Переключаемся на тестового юзера:
[simterm]
$ argocd context [email protected] Switched to context '[email protected]'
[/simterm]
Проверяем список доступных приложений:
[simterm]
$ argocd app list NAME CLUSTER NAMESPACE PROJECT STATUS HEALTH SYNCPOLICY CONDITIONS REPO PATH TARGET guestbook https://kubernetes.default.svc argo-test-ns test-project OutOfSync Missing <none> <none> https://github.com/argoproj/argocd-example-apps.git helm-guestbook HEAD
[/simterm]
Роли проекта и токены аутентификации
Другой вариант – создать отдельную роль в самом проекте – тогда будет возможность создать токен для этой роли, как для обычного пользователя.
Создаём роль test-role проекта test-project:
[simterm]
$ argocd proj role create test-project test-role
[/simterm]
Добавляем политику доступа – любые действия с приложением guestbook:
[simterm]
$ argocd proj role add-policy test-project test-role --action '*' --permission allow --object guestbook
[/simterm]
Политика будет включена в RBAC-роль этого проекта:
[simterm]
$ kubectl -n dev-1-18-devops-argocd-ns get appproject test-project -o jsonpath='{.spec.roles[].policies}' [p, proj:test-project:test-role, applications, *, test-project/guestbook, allow]
[/simterm]
Получаем токен:
[simterm]
$ argocd proj role create-token test-project test-role eyJ***sCA
[/simterm]
Или сразу в переменную:
[simterm]
$ token=$(argocd proj role create-token test-project test-role)
[/simterm]
И с его помощью проверяем права, например на синхронизацию приложения:
[simterm]
$ argocd account can-i sync applications test-project/guestbook --auth-token $token yes
[/simterm]
А вот на добавление кластера прав с этим токеном нет:
[simterm]
$ argocd account can-i create clusters '*' --auth-token $token no
[/simterm]
Но эти права есть у юзера, так как мы их задавали глобально в argocd-rbac-cm
через политику роли test-role – p, role:test-role, clusters, create, *, allow
:
[simterm]
$ argocd account can-i create projects '*' yes
[/simterm]
Группы
В RBAC так же можно объединять роли в группы (но не пользователей), например:
... policy.csv: | g, argocd-admins, role:admin ...
Затем, используя SSO, в нашем случае это будет Okta, мы замапим группы пользователей на нужные нам роли.
И всё вместе…
“А теперь со всей этой хернёй на борту мы попробуем взлететь!” (с)
Окей, всё это хорошо – но как можно все эти доступы использовать?
Что у нас будет?
Два проекта – web и backend.
У каждого – свои приложения.
Из глобальных пользователей нам нужна будет только рутовая учётка для девопсоадминов.
Дальше – с делением по проектам: один админ на проект, один read-only. Делать ли отдельную учётку для CI/CD? Пока не вижу смысла – Github Actions/Jenkins должны будут и создавать новые аппки в проектах, и удалять, так что подойдёт админ-учётка проекта. А для QA – будет read-only доступ, так им кроме логов подов особо ничего не надо – триггерить деплой они будут через Gitub.
Позже настроим Okta и SSO, и юзеры будут в веб-интерфейс ходить под своими учётками, которым дадим админа на приложения в проекте в зависимости от группы в Окте: бекенду – бекендово, вебу – вебово, а нам фиолетово.
В целом, на этом всё.
Дальше – настроим Okta, потом declarative setup, и можно настраивать Github Actions.
См. продолжение в ArgoCD: интеграция с Okta и группы пользователей.