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


С дублированием процесса мои шаги следующие:

  1. Получите сертификаты k3s ca

Было описано, что это находится в / etc / kubernetes / pki (k8s), однако, исходя из этого, похоже, в / var / lib / rancher / k3s / server / tls / (server-ca.crt & server-ca.key).

  1. Сертификаты пользователей 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

... все хорошо:

  1. Создание файла 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>
  1. Установить роль и привязку ролей (в указанном пространстве имен '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 через учетные записи служб в качестве варианта (для тех, кто предпочитает конкретный вариант использования).

  1. Создание учетной записи службы

//kubectl создает имя учетной записи службы -n пространство имен

$ kubectl create serviceaccount udef -n rbac

Это создает учетную запись службы + автоматически соответствующий секрет (udef-token-lhvm8). Смотрите с выводом yaml:

  1. Получить токен из созданного секрета:

//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 
  1. Поместите токен в файл конфигурации

Можно начать с получения файла конфигурации 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
  1. Роли и манифесты привязки ролей могут быть созданы по мере необходимости, как указано ранее ( 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

Другие вопросы по тегам