RBAC (контроль доступа с привязкой ролей) на K3s
после просмотра видеороликов о RBAC (управление доступом на основе ролей) на кубернетах (из которых этот был для меня наиболее прозрачным), я выполнил шаги, однако на k3s, а не на k8s, как предполагают все источники. Из того, что я смог собрать (не работает), проблема не в фактическом процессе привязки ролей, а в сертификате пользователя x509, который не подтверждается службой API.
$ kubectl получить модули --kubeconfig userkubeconfig
ошибка: вы должны войти на сервер (неавторизованный)
Также не задокументировано по безопасности для K3s (хотя задокументировано для их реализации k8s)?, хотя описано для самого в вики RancherRancher2.x , не уверен, проблема ли это в моей реализации или в k3s <-> k8s.
$ kubectl version --short
Client Version: v1.20.5+k3s1
Server Version: v1.20.5+k3s1
С дублированием процесса мои шаги следующие:
- Получите сертификаты k3s ca
Было описано, что это находится в / etc / kubernetes / pki (k8s), однако, исходя из этого, похоже, в / var / lib / rancher / k3s / server / tls / (server-ca.crt & server-ca.key).
- Сертификаты пользователей Gen из сертификатов CA
#generate user key
$ openssl genrsa -out user.key 2048
#generate signing request from ca
openssl req -new -key user.key -out user.csr -subj "/CN=user/O=rbac"
# generate user.crt from this
openssl x509 -req -in user.csr -CA server-ca.crt -CAkey server-ca.key -CAcreateserial -out user.crt -days 365
- Создание файла kubeConfig для пользователя на основе сертификатов:
# Take user.crt and base64 encode to get encoded crt
cat user.crt | base64 -w0
# Take user.key and base64 encode to get encoded key
cat user.key | base64 -w0
- Создан файл конфигурации:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: <server-ca.crt base64-encoded>
server: https://<k3s masterIP>:6443
name: home-pi4
contexts:
- context:
cluster: home-pi4
user: user
namespace: rbac
name: user-homepi4
current-context: user-homepi4
kind: Config
preferences: {}
users:
- name: user
user:
client-certificate-data: <user.crt base64-encoded>
client-key-data: <user.key base64-encoded>
- Установить роль и привязку ролей (в указанном пространстве имен 'rbac')
- роль
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: user-rbac
namespace: rbac
rules:
- apiGroups:
- "*"
resources:
- pods
verbs:
- get
- list
- roleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: user-rb
namespace: rbac
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: user-rbac
subjects:
apiGroup: rbac.authorization.k8s.io
kind: User
name: user
После всего этого я получаю удовольствие от ...
$ kubectl get pods --kubeconfig userkubeconfig
error: You must be logged in to the server (Unauthorized)
Любые предложения, пожалуйста?
По-видимому, этот вопрос stackOverflow представил решение проблемы, но после подачи github он более или менее пришел к тому же подходу, который использовался здесь (если я что-то не упускаю)?
2 ответа
Как мы можем найти в документации по на запросамподпись сертификатов Kubernetes :
Требуется несколько шагов, чтобы обычный пользователь смог пройти аутентификацию и вызвать API.
Я создам пример, чтобы проиллюстрировать, как вы можете получить обычного пользователя, который может аутентифицировать и вызывать API (я буду использовать пользователя в качестве примера).
Сначала создайте закрытый ключ PKI и CSR:
# openssl genrsa -out john.key 2048
ПРИМЕЧАНИЕ:
CN
имя пользователя и
O
это группа, к которой будет принадлежать этот пользователь
# openssl req -new -key john.key -out john.csr -subj "/CN=john/O=group1"
# ls
john.csr john.key
Затем создайте и отправьте его в кластер Kubernetes через
kubectl
.
# cat <<EOF | kubectl apply -f -
> apiVersion: certificates.k8s.io/v1
> kind: CertificateSigningRequest
> metadata:
> name: john
> spec:
> groups:
> - system:authenticated
> request: $(cat john.csr | base64 | tr -d '\n')
> signerName: kubernetes.io/kube-apiserver-client
> usages:
> - client auth
> EOF
certificatesigningrequest.certificates.k8s.io/john created
# kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
john 39s kubernetes.io/kube-apiserver-client system:admin Pending
# kubectl certificate approve john
certificatesigningrequest.certificates.k8s.io/john approved
# kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
john 52s kubernetes.io/kube-apiserver-client system:admin Approved,Issued
Экспорт выданного сертификата из
CertificateSigningRequest
:
# kubectl get csr john -o jsonpath='{.status.certificate}' | base64 -d > john.crt
# ls
john.crt john.csr john.key
Создав сертификат, мы можем определить и для этого пользователя, чтобы получить доступ к ресурсам кластера Kubernetes. Я буду использовать
Role
а также
RoleBinding
похож на ваш.
# cat role.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: john-role
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
# kubectl apply -f role.yml
role.rbac.authorization.k8s.io/john-role created
# cat rolebinding.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: john-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: john-role
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: john
# kubectl apply -f rolebinding.yml
rolebinding.rbac.authorization.k8s.io/john-binding created
Последний шаг - добавить этого пользователя в файл kubeconfig (см .: Добавить в kubeconfig)
# kubectl config set-credentials john --client-key=john.key --client-certificate=john.crt --embed-certs=true
User "john" set.
# kubectl config set-context john --cluster=default --user=john
Context "john" created.
Наконец, мы можем изменить контекст на и проверить, работает ли он должным образом.
# kubectl config use-context john
Switched to context "john".
# kubectl config current-context
john
# kubectl get pods
NAME READY STATUS RESTARTS AGE
web 1/1 Running 0 30m
# kubectl run web-2 --image=nginx
Error from server (Forbidden): pods is forbidden: User "john" cannot create resource "pods" in API group "" in the namespace "default"
Как видите, все работает как положено (пользователь
john
только есть
get
а также
list
разрешения).
Кроме того, вы можете легко автоматизировать описанный выше процесс с скрипта помощьюcreate-kube-user.sh .
Спасибо matt_j за пример | предоставлен ответ на мой вопрос. Отметил это как ответ, так как это был прямой ответ на мой вопрос о RBAC через сертификаты. В дополнение к этому, я также хотел бы привести пример RBAC через учетные записи служб в качестве варианта (для тех, кто предпочитает конкретный вариант использования).
- Создание учетной записи службы
//kubectl создает имя учетной записи службы -n пространство имен
$ kubectl create serviceaccount udef -n rbac
Это создает учетную запись службы + автоматически соответствующий секрет (udef-token-lhvm8). Смотрите с выводом yaml:
- Получить токен из созданного секрета:
//kubectl описать секрет secretName -o yaml
$ kubectl описать секретный udef-token-lhvm8 -o yaml
secret будет содержать 3 объекта, (1) ca.crt (2) namespace (3) токен
# ... other secret context
Data
====
ca.crt: x bytes
namespace: x bytes
token: xxxx token xxxx
- Поместите токен в файл конфигурации
Можно начать с получения файла конфигурации admin и вывода в файл
// location of **k3s** kubeconfig
$ sudo cat /etc/rancher/k3s/k3s.yaml > /home/{userHomeFolder}/userKubeConfig
В разделе пользователей можно заменить данные сертификата токеном:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: xxx root ca cert content xxx
server: https://<host IP>:6443
name: home-pi4
contexts:
- context:
cluster: home-pi4
user: nametype
namespace: rbac
name: user-homepi4
current-context: user-homepi4
kind: Config
preferences: {}
users:
- name: nametype
user:
token: xxxx token xxxx
- Роли и манифесты привязки ролей могут быть созданы по мере необходимости, как указано ранее ( nb в том же пространстве имен), в этом случае связываясь с учетной записью службы:
# role manifest
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: user-rbac
namespace: rbac
rules:
- apiGroups:
- "*"
resources:
- pods
verbs:
- get
- list
---
# rolebinding manifest
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: user-rb
namespace: rbac
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: user-rbac
subjects:
- kind: ServiceAccount
name: udef
namespace: rbac
После этого вы сможете удаленно тестировать:
// показать поды -> будет разрешено
$ kubectl получить поды --kubeconfig
..... предоставлен действительный ответ
// получить пространства имен (или другие типы команд) -> не должно быть разрешено
$ kubectl получить пространства имен --kubeconfig
Ошибка сервера (запрещено): пространства имен запрещены: пользователь bla-bla