====== Управление доступом в Kubernetes ======
* [[https://kubernetes.io/docs/reference/access-authn-authz/authentication/|Kubernetes Documentation -> Reference -> API Access Control -> Authenticating]]
* [[https://habr.com/ru/articles/779190/|Как работает аутентификация в Kubernetes: ServiceAccount и RBAC]]
* [[https://medium.com/@muppedaanvesh/a-hand-on-guide-to-kubernetes-rbac-with-a-user-creation-%EF%B8%8F-1ad9aa3cafb1|A Hands-On Guide to Kubernetes RBAC With a User Creation]]
* [[https://kubernetes.io/docs/reference/kubectl/generated/kubectl_config/kubectl_config_set-credentials/|Kubernetes Documentation kubectl config set-credentials]]
* [[https://stackoverflow.com/questions/49396607/where-can-i-get-a-list-of-kubernetes-api-resources-and-subresources|Where can I get a list of Kubernetes API resources and subresources?]]
* [[https://www.container-security.site/security_research/node_proxy.html|Node/Proxy in Kubernetes RBAC]]
* [[https://stackoverflow.com/questions/60445336/how-to-grant-access-to-specify-namespace-in-kubernetes-dashboard|How to grant access to specify namespace in kubernetes dashboard?]]
* [[https://docs.sc.otc.t-systems.com/cloud-container-engine/umn/permissions_management/namespace_permissions_kubernetes_rbac-based.html|Namespace Permissions (Kubernetes RBAC-based)]]
* [[https://medium.com/@ManagedKube/kubernetes-rbac-port-forward-4c7eb3951e28|Kubernetes RBAC Port Forward]]
* [[https://medium.com/@subhampradhan966/implementing-and-verifying-kubernetes-service-accounts-a-step-by-step-guide-c43b727260b2|Implementing and Verifying Kubernetes Service Accounts: A Step-by-Step Guide]]
* [[https://medium.com/@reza.sadriniaa/automatic-kubernetes-certificate-renewal-a-step-by-step-guide-c4320192a74d|Automatic Kubernetes Certificate Renewal: A Step-by-Step Guide]]
* [[https://weng-albert.medium.com/updating-kubernetes-certificates-easy-peasy-en-139fc07f26c8|Updating Kubernetes Certificates: Easy Peasy!(En)]]
===== Реклама =====
* Kubernetes — это решение, превращающее Linux сервера в кластер, и, как Linux является многопользовательской, многозадачной операционной системой, так и Kubernetes позволяет множеству пользователей и приложений работать в одном кластере безопасно разделяя его ресурсы
* На нашем вебинаре Вы узнаете как настраивать права доступа в Kubernetes на примерах практических, полезных задач
===== Техническое задание =====
* Создать учетную запись и файл конфигурации с правами для подключения к приложениям, администрированию ресурсов выделенного Namespace и всего кластера Kubernetes
* Использовать учтёные записи приложений в Kubernetes для доступа к API
===== Запись вебинара =====
* Тэги: Kubernetes, ServiceAccout, RBAC
===== Подготовка к повтору вебинара =====
user1@client1:~$ rm user1*
user1@client1:~$ rm -r .kube/
kube1:~# rm -r users/
kube1:~# kubectl delete serviceaccounts admin-user
===== Шаг 1. Что у нас есть, для начала =====
* [[Система Kubernetes]]
* Cloud native distributed block storage for Kubernetes [[Сервис Keycloak#longhorn]]
* [[Сервис Keycloak#rancher local-path-provisioner]] и кластер [[Сервис PostgreSQL#CloudNativePG]] для Keycloak в [[Сервис Keycloak#Kubernetes]]
* [[Система Kubernetes#Kubernetes Dashboard]] без ServiceAccout
* Linux [[Инсталяция системы в конфигурации Desktop]] и [[Управление учетными записями в Linux#Создание тестового набора учетных записей]]
===== Шаг 2. Создание учетной записи =====
==== Вариант 2.1 Использование сертификатов ====
* [[Пакет OpenSSL#Создание пользовательского сертификата, подписанного CA]]
user1@client1:~$ cat user1.req | base64 -w0
* [[https://stackoverflow.com/questions/75735249/what-do-the-values-in-certificatesigningrequest-spec-usages-mean|What do the values in CertificateSigningRequest.spec.usages mean?]]
kube1:~/users# kubectl explain csr.spec.usages
kube1:~/users# cat user1.req.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: user1
spec:
request: LS0t...S0tCg==
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 8640000 # 100 * one day
usages:
# - digital signature
# - key encipherment
- client auth
kube1:~/users# kubectl apply -f user1.req.yaml
kube1:~/users# kubectl describe csr/user1
kube1:~/users# kubectl certificate approve user1
kube1:~/users# kubectl get csr
kube1:~/users# kubectl get csr/user1 -o yaml
kube1:~/users# kubectl get csr/user1 -o jsonpath="{.status.certificate}" | base64 -d | tee user1.crt
user1@client1:~$ scp root@kube1:users/user1.crt .
==== Вариант 2.2 Использование ServiceAccount ====
* Для примера можно использовать ServiceAccout из темы [[Система Kubernetes#Kubernetes Dashboard]] в Namespace default
* Показать временные и long-lived Bearer Token для ServiceAccount
==== Шаг 2.3 Создание файла конфигурации kubectl ====
* [[Система Kubernetes#Инструмент командной строки kubectl]]
* [[https://kubernetes.io/docs/reference/kubectl/generated/kubectl_config/kubectl_config_set-credentials/]]
user1@client1:~$ ###rm -rf .kube/
user1@client1:~$ kubectl config set-cluster cluster.local --insecure-skip-tls-verify=true --server=https://192.168.13.221:6443
ИЛИ
root@my-debian:~# kubectl config set-cluster cluster.local --certificate-authority=/run/secrets/kubernetes.io/serviceaccount/ca.crt
user1@client1:~$ cat .kube/config
user1@client1:~$ kubectl config set-credentials user1 --client-certificate=user1.crt --client-key=user1.key --embed-certs=true
ИЛИ
user1@client1:~$ kubectl config set-credentials user1 --token=...................................
ИЛИ
root@my-debian:~# kubectl config set-credentials user1 --token=$(cat /run/secrets/kubernetes.io/serviceaccount/token)
user1@client1:~$ kubectl config get-users
user1@client1:~$ kubectl config set-context default-context --cluster=cluster.local --user=user1
user1@client1:~$ kubectl config use-context default-context
user1@client1:~$ kubectl auth whoami
user1@client1:~$ kubectl get pods #-A
Error from server (Forbidden) или ...
===== Шаг 3. Использование Role и RoleBinding =====
==== Предоставление доступа к services/proxy в Namespace ====
* Cloud native distributed block storage for Kubernetes [[Система Kubernetes#longhorn]]
kube1:~# kubectl api-resources -o wide | less
APIVERSION = + "/" +
kube1:~/users# cat lh-svc-proxy-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: longhorn-system
name: lh-svc-proxy-role
rules:
- apiGroups: [""]
resources: ["services/proxy"]
verbs: ["get"]
kube1:~/users# cat user1-lh-svc-proxy-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: user1-lh-svc-proxy-rolebinding
namespace: longhorn-system
subjects:
- kind: User
name: user1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: lh-svc-proxy-role
apiGroup: rbac.authorization.k8s.io
kube1:~/users# kubectl apply -f lh-svc-proxy-role.yaml,user1-lh-svc-proxy-rolebinding.yaml
student@client1:~$ kubectl proxy
student@client1:~$ curl http://localhost:8001/api/v1/namespaces/longhorn-system/services/longhorn-frontend:80/proxy/
student@client1:~$ curl http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
kube1:~/users# kubectl delete -f lh-svc-proxy-role.yaml,user1-lh-svc-proxy-rolebinding.yaml
==== Предоставление полного доступа к Namespace ====
kube1:~/users# cat ns-full-access.yaml
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: ns-full-access
namespace: my-ns
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: ns-full-access-rolebinding
namespace: my-ns
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: cko
#kind: User
#name: user1
roleRef:
kind: Role
name: ns-full-access
apiGroup: rbac.authorization.k8s.io
#roleRef:
#apiGroup: rbac.authorization.k8s.io
#kind: ClusterRole
#name: admin
kube1:~/users# kubectl apply -f ns-full-access.yaml
* Запускаем pod my-debian ([[Система Kubernetes#Базовые объекты k8s]]) в my-ns (создать, если нет)
==== Поиск предоставленных ролей для учетной записи ====
kube1:~/users# kubectl get rolebindings --all-namespaces -o=json | jq '.items[] | select(.subjects[]?.name == "user1")'
kube1:~/users# kubectl get rolebindings --all-namespaces -o=json | jq '.items[] | select(.subjects[]?.name == "cko")'
kube1:~/users# kubectl delete -f ns-full-access.yaml
===== Шаг 4. Использование ClusterRole и ClusterRoleBinding =====
==== Предоставление доступа к services/port-forward в Cluster ====
kube1:~/users# cat svc-pfw-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
#kind: Role
metadata:
name: svc-pfw-role
# namespace: my-pgcluster-ns
rules:
- apiGroups: [""]
resources: ["services"]
verbs: ["get"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["pods/portforward"]
verbs: ["create"]
kube1:~/users# cat user1-svc-pfw-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
#kind: RoleBinding
metadata:
name: user1-svc-pfw-rolebinding
# namespace: my-pgcluster-ns
subjects:
- kind: User
name: user1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
# kind: Role
name: svc-pfw-role
apiGroup: rbac.authorization.k8s.io
kube1:~/users# kubectl apply -f svc-pfw-role.yaml,user1-svc-pfw-rolebinding.yaml
student@client1:~$ kubectl port-forward -n my-pgcluster-ns services/my-pgcluster-rw 5432:5432
student@client1:~$ psql postgres://keycloak:strongpassword@127.0.0.1:5432/keycloak
* Доступ через proxy к [[Система Kubernetes#Kubernetes Dashboard]]
kube1:~/users# kubectl delete -f svc-pfw-role.yaml,user1-svc-pfw-rolebinding.yaml
==== Предоставление полного доступа к Kubernetes Cluster ====
kube1:~/users# kubectl get clusterroles | less
kube1:~/users# kubectl get clusterrole cluster-admin -o yaml
kube1:~/users# kubectl get clusterrolebindings | less
kube1:~/users# kubectl get clusterrolebindings admin -o yaml
kube1:~/users# kubectl get clusterrolebindings cluster-admin -o yaml
kube1:~/users# cat user1-cluster-admin.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: user1-cluster-admin
subjects:
- kind: User
name: user1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
kube1:~/users# kubectl apply -f user1-cluster-admin.yaml
student@client1:~$ kubectl get nodes
==== Поиск предоставленных кластерных ролей для учетной записи ====
kube1:~/users# kubectl get clusterrolebindings -o=json | jq '.items[] | select(.subjects[]?.name == "kubeadm:cluster-admins")'
kube1:~/users# kubectl get clusterrolebindings -o=json | jq '.items[] | select(.subjects[]?.name == "user1")'
kube1:~/users# kubectl get clusterrolebindings -o=json | jq '.items[] | select(.subjects[]?.name == "default")'
kube1:~/users# kubectl delete -f user1-cluster-admin.yaml
===== Шаг 5. Использование JSON Web Token (JWT) для доступа в Kubernetes =====
* Возвращаемся на [[#Вариант 2.2 Использование ServiceAccount]]
===== Шаг 6. Использование Service Accounts в приложениях =====
* Используем ранее запущенное приложение ([[Система Kubernetes#Базовые объекты k8s]]) в my-ns
kube1:~/users# kubectl -n my-ns describe pod my-debian | grep -i account
kube1:~/users# kubectl -n my-ns exec -ti pods/my-debian -- bash
root@my-debian:/# apt update && apt install kubectl
* [[#Шаг 2.3 Создание файла конфигурации kubectl]]
kube1:~/users# kubectl auth can-i get pods --as=system:serviceaccount:my-ns:default
kube1:~/users# cat sa-default-cluster-admin.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: sa-default-cluster-admin
subjects:
- kind: ServiceAccount
name: default
namespace: my-ns
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
kube1:~/users# kubectl apply -f sa-default-cluster-admin.yaml
Проверяем доступ к API из приложения
kube1:~/users# kubectl delete -f sa-default-cluster-admin.yaml
kube1:~/dashboard# kubectl -n my-ns delete pod my-debian
===== Вопросы? =====
===== Домашнее задание =====
- Куда и через сколько исчезает "kubectl get csr" после "approve" ?