K3s 上的 RBAC(基于角色的访问控制)

Pau*_*aul 4 kubernetes rancher k3s kubernetes-rbac

在观看了 kubernetes 上的 RBAC(基于角色的访问控制)视频(其中这个对我来说是最透明的)后,我遵循了这些步骤,但是在 k3s 上,而不是所有来源暗示的 k8s 上。据我收集的信息(不起作用),问题不在于实际的角色绑定过程,而在于 API 服务未确认的 x509 用户证书

$ kubectl get pods --kubeconfig userkubeconfig

错误:您必须登录到服务器(未经授权)

Rancher 的 wiki上也没有记录K3s 的安全性(虽然记录了他们的 k8s 实现)?虽然对rancher 2.x本身进行了描述,但不确定这是否是我的实现的问题,或者是 k3s <-> k8s 的问题。

$ kubectl version --short
Client Version: v1.20.5+k3s1
Server Version: v1.20.5+k3s1

Run Code Online (Sandbox Code Playgroud)

通过重复该过程,我的步骤如下:

  1. 获取 k3s ca 证书

这被描述为位于/etc/kubernetes/pki (k8s) 下,但是基于似乎位于/var/lib/rancher/k3s/server/tls/ (server-ca.crt 和 server-ca.key)

  1. 从 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
Run Code Online (Sandbox Code Playgroud)

... 都好: 在此输入图像描述

  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
Run Code Online (Sandbox Code Playgroud)
  • 创建的配置文件:
$ kubectl version --short
Client Version: v1.20.5+k3s1
Server Version: v1.20.5+k3s1

Run Code Online (Sandbox Code Playgroud)
  1. 设置角色和角色绑定(在指定的命名空间“rbac”内)
  • 角色
#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
Run Code Online (Sandbox Code Playgroud)
  • 角色绑定
# 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
Run Code Online (Sandbox Code Playgroud)

经历了这一切之后,我度过了愉快的时光……

$ kubectl get pods --kubeconfig userkubeconfig
error: You must be logged in to the server (Unauthorized)
Run Code Online (Sandbox Code Playgroud)

请问有什么建议吗?

显然这个stackOverflow 问题提出了问题的解决方案,但是在 github feed 之后,它或多或少归结为这里遵循的相同方法(除非我遗漏了一些东西)?

mat*_*t_j 5

正如我们在Kubernetes 证书签名请求文档中可以找到的:

为了让普通用户能够验证并调用 API,需要执行几个步骤。


我将创建一个示例来说明如何获得能够验证并调用 API 的普通用户(我将使用用户john作为示例)。


首先,创建 PKI 私钥和 CSR:

# openssl genrsa -out john.key 2048
Run Code Online (Sandbox Code Playgroud)

注意: CN是用户的名称,并且O是该用户所属的组

# openssl req -new -key john.key -out john.csr -subj "/CN=john/O=group1"

# ls
john.csr  john.key
Run Code Online (Sandbox Code Playgroud)

然后创建一个CertificateSigningRequest并通过 提交到 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
Run Code Online (Sandbox Code Playgroud)

从以下位置导出颁发的证书CertificateSigningRequest

# kubectl get csr john -o jsonpath='{.status.certificate}'  | base64 -d > john.crt

# ls
john.crt  john.csr  john.key
Run Code Online (Sandbox Code Playgroud)

创建证书后,我们可以定义该用户访问 Kubernetes 集群资源的Role权限。RoleBinding我将使用RoleRoleBinding与你类似的。

# 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
Run Code Online (Sandbox Code Playgroud)

最后一步是将此用户添加到 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.
Run Code Online (Sandbox Code Playgroud)

最后,我们可以将上下文更改为john并检查它是否按预期工作。

# 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"
Run Code Online (Sandbox Code Playgroud)

如您所见,它按预期工作(用户john仅具有getlist权限)。