基于RBAC的k8s用户授权示例

文章详细介绍了如何在Kubernetes(k8s)环境中使用Role和RoleBinding进行基于RBAC的用户授权。首先展示了Role的创建,用于定义一组权限,如Pod的读权限。接着,通过RoleBinding将这些权限赋予特定用户,如用户mckinsey。然后,演示了如何使用k8sCA签发客户端证书和生成kubeconfig文件,以供用户进行身份验证。最后,逐步添加了对Service和Deployment的读权限,以及Pod的写权限,展示了RBAC权限策略的动态调整过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Role与RoleBinding创建示例

Role示例

Role是一组权限的集合。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]   # 空值表示核心API组,包括namespace、pod、service、pv、pvc等
  resources: ["pods"]  # 资源名称(复数),例如pods、deployments、services
  verbs: ["get", "watch", "list"]   # 对资源的操作动词

查看API resource是否属于核心API组:

[root@k8s-master rbac]# kubectl api-resources
NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND
configmaps                        cm           v1                                     true         ConfigMap
endpoints                         ep           v1                                     true         Endpoints
namespaces                        ns           v1                                     false        Namespace
nodes                             no           v1                                     false        Node
persistentvolumeclaims            pvc          v1                                     true         PersistentVolumeClaim
persistentvolumes                 pv           v1                                     false        PersistentVolume
pods                              po           v1                                     true         Pod
secrets                                        v1                                     true         Secret
serviceaccounts                   sa           v1                                     true         ServiceAccount
services                          svc          v1                                     true         Service
daemonsets                        ds           apps/v1                                true         DaemonSet
deployments                       deploy       apps/v1                                true         Deployment
replicasets                       rs           apps/v1                                true         ReplicaSet
statefulsets                      sts          apps/v1                                true         StatefulSet

其中,APIVERSION列的值为v1的资源属于核心API组。例如上面的configmap、namespaces、pods、services就属于核心API组;反之,deployments、replicasets、statefulsets就不属于核心API组。

RoleBinding示例

RoleBinding可以将Role中定义的权限赋予一个用户或者一组用户。

apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定允许 "jane" 读取 "default" 名字空间中的Pod
# 需要在该命名空间中有一个名为 “pod-reader” 的Role
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:   # 可以指定不止一个subject(主体)
- kind: User   # 主体的类型
  name: jane   # 主体的名称,区分大小写
  apiGroup: rbac.authorization.k8s.io
roleRef:   # roleRef指定与某Role或ClusterRole的绑定关系
  kind: Role         # 此字段必须是Role或ClusterRole
  name: pod-reader   # 此字段必须与要绑定的Role或ClusterRole的名称匹配
  apiGroup: rbac.authorization.k8s.io

基于RBAC的用户授权示例

用k8s CA签发客户端证书

创建Kubernetes集群时自动生成的根证书位于/etc/kubernetes/pki/ca.crt

准备生成CA证书JSON配置文件和证书签名请求(CSR)的脚本。其中,ca-config.json用于生成证书颁发机构(Certificate Authority, CA)文件,可以指定证书过期时间;mckinsey.csr.json则用于生成用户mckinsey的CA证书签名请求,其中CN字段对应用户名(CommonName)。

[root@k8s-master rbac]# cat cert.sh
cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}
EOF

cat > mckinsey-csr.json <<EOF
{
  "CN": "mckinsey",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "USA",
      "ST": "California",
      "L": "Sacramento",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF

# 指定根证书、JSON配置文件,生成以用户名mckinsey为前缀的密钥和证书文件
cfssl gencert -ca=/etc/kubernetes/pki/ca.crt -ca-key=/etc/kubernetes/pki/ca.key -config=ca-config.json -profile=kubernetes mckinsey-csr.json | cfssljson -bare mckinsey

运行脚本签发客户端证书:

[root@k8s-master rbac]# ./cert.sh
2022/12/31 05:00:06 [INFO] generate received request
2022/12/31 05:00:06 [INFO] received CSR
2022/12/31 05:00:06 [INFO] generating key: rsa-2048
2022/12/31 05:00:06 [INFO] encoded CSR
2022/12/31 05:00:06 [INFO] signed certificate with serial number 695268160968997598742877842743429519856567946785
2022/12/31 05:00:06 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
[root@k8s-master rbac]#
[root@k8s-master rbac]# ls
ca-config.json  cert.sh  mckinsey.csr  mckinsey-csr.json  mckinsey-key.pem  mckinsey.pem 

其中,mckinsey-key.pem为私钥,mckinsey.pem为数字证书。

生成kubeconfig授权证书

查看k8s管理员的kubeconfig文件:

[root@k8s-master rbac]# cat /root/.kube/config | grep server
    server: https://192.168.124.139:6443

准备为用户mckinsey生成kubeconfig授权证书的脚本:

[root@k8s-master rbac]# cat kubeconfig.sh

kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/pki/ca.crt \
  --embed-certs=true \
  --server=https://192.168.124.139:6443 \
  --kubeconfig=mckinsey.kubeconfig

# 设置客户端认证
kubectl config set-credentials mckinsey \
  --client-key=mckinsey-key.pem \
  --client-certificate=mckinsey.pem \
  --embed-certs=true \
  --kubeconfig=mckinsey.kubeconfig

# 设置默认上下文
kubectl config set-context kubernetes \
  --cluster=kubernetes \
  --user=mckinsey \
  --kubeconfig=mckinsey.kubeconfig

# 设置当前使用配置
kubectl config use-context kubernetes --kubeconfig=mckinsey.kubeconfig

运行脚本生成授权证书mckinsey.kubeconfig

[root@k8s-master rbac]# ./kubeconfig.sh
Cluster "kubernetes" set.
User "mckinsey" set.
Context "kubernetes" created.
Switched to context "kubernetes".
[root@k8s-master rbac]# ls
ca-config.json  cert.sh  kubeconfig.sh  mckinsey.csr  mckinsey-csr.json  mckinsey-key.pem  mckinsey.kubeconfig  mckinsey.pem  

创建RBAC权限策略:Pod读权限

在创建RBAC权限之前,前面的用户mckinsey是没有权限访问集群资源的:

[root@k8s-master rbac]# kubectl get pods --kubeconfig=./mckinsey.kubeconfig
Error from server (Forbidden): pods is forbidden: User "mckinsey" cannot list resource "pods" in API group "" in the namespace "default"

为mckinsey用户创建并绑定RBAC权限策略,这里仅授予对Pod的读权限。

[root@k8s-master rbac]# cat rbac.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

---

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: mckinsey
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

运行脚本授予RBAC权限:

[root@k8s-master rbac]# kubectl apply -f rbac.yaml
role.rbac.authorization.k8s.io/pod-reader created
rolebinding.rbac.authorization.k8s.io/read-pods created

指定kubeconfig文件测试权限

[root@k8s-master rbac]# kubectl get pods --kubeconfig=./mckinsey.kubeconfig
NAME                                      READY   STATUS             RESTARTS       AGE
bs2                                       1/1     Running            11 (12d ago)   147d
nfs-client-provisioner-5d5775b9bb-5657c   1/1     Running            9 (12d ago)    140d
web-0                                     0/1     ImagePullBackOff   4 (56d ago)    59d
web-1                                     0/1     ImagePullBackOff   4 (56d ago)    59d
web-2                                     0/1     ImagePullBackOff   4 (56d ago)    59d
[root@k8s-master rbac]#
[root@k8s-master rbac]# kubectl get deploy --kubeconfig=./mckinsey.kubeconfig
Error from server (Forbidden): deployments.apps is forbidden: User "mckinsey" cannot list resource "deployments" in API group "apps" in the namespace "default"

可以看出,mckinsey用户对Pod资源有读权限,对其他资源(例如Deployment)没有读权限。

添加RBAC权限策略:Service读权限

Service与Pod同属于核心API组。修改rbac.yaml为mckinsey用户添加对Service资源的读权限:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods", "services"]   # 添加"services"资源
  verbs: ["get", "watch", "list"]

---

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: mckinsey
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

更新RBAC策略并验证mckinsey用户权限:

[root@k8s-master rbac]# kubectl apply -f rbac.yaml
role.rbac.authorization.k8s.io/pod-reader configured
rolebinding.rbac.authorization.k8s.io/read-pods unchanged
[root@k8s-master rbac]#
[root@k8s-master rbac]# kubectl get svc --kubeconfig=./mckinsey.kubeconfig
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   161d
nginx        ClusterIP   None         <none>        80/TCP    59d

添加RBAC权限策略:Deployment读权限

查看Deploments资源所属的API组:

[root@k8s-master rbac]# kubectl api-resources | grep deploy
deployments                       deploy       apps/v1                                true         Deployment

可以看到,deployments资源属于apps API组。

修改rbac.yaml为mckinsey用户添加对Service资源的读权限:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: ["", "apps"]   # 添加"apps" API组
  resources: ["pods", "services", "deployments"]   # 添加"deployments"资源
  verbs: ["get", "watch", "list"]

---

kind: RoleBinding
# 此处内容不变,已省略

更新RBAC策略并验证mckinsey用户权限:

[root@k8s-master rbac]# kubectl apply -f rbac.yaml
role.rbac.authorization.k8s.io/pod-reader configured
rolebinding.rbac.authorization.k8s.io/read-pods unchanged
[root@k8s-master rbac]#
[root@k8s-master rbac]# kubectl get deploy --kubeconfig=./mckinsey.kubeconfig
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
nfs-client-provisioner   1/1     1            1           140d

添加RBAC权限策略:Pod写权限

目前mckinsey用户对Pod只有读权限。如果尝试用该用户删除Pod,会收到报错:

[root@k8s-master rbac]# kubectl delete pod web-1 --kubeconfig=./mckinsey.kubeconfig
Error from server (Forbidden): pods "web-1" is forbidden: User "mckinsey" cannot delete resource "pods" in API group "" in the namespace "default"

为mckinsey用户添加删除Pod的权限:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: ["", "apps"]
  resources: ["pods", "services", "deployments"]
  verbs: ["get", "watch", "list"]
- apiGroups: [""]   # 应当在rules下另起一个子项
  resources: ["pods"]
  verbs: ["delete"]   # 删除单个资源对应的动词为"delete"

---

kind: RoleBinding
# 此处内容不变,已省略

更新RBAC策略并验证mckinsey用户权限:

[root@k8s-master rbac]# kubectl apply -f rbac.yaml
role.rbac.authorization.k8s.io/pod-reader configured
rolebinding.rbac.authorization.k8s.io/read-pods unchanged
[root@k8s-master rbac]#
[root@k8s-master rbac]# kubectl delete pod web-1 --kubeconfig=./mckinsey.kubeconfig
pod "web-1" deleted

我们可以把mckinsey.kubeconfig拷贝到任意一台服务器上,只要该服务器能够连接到mckinsey.kubeconfig中的server,就可以通过mckinsey用户的权限来访问Kubernetes集群资源。

如果想在执行kubectl命令时省略--kubeconfig=./mckinsey.kubeconfig,可以将mckinsey.kubeconfig文件重命名为系统用户家目录下的.kube/config

References
【1】https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/authentication/
【2】https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/certificates/
【3】https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/certificate-signing-requests/#add-to-kubeconfig
【4】https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/rbac/
【5】https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/authorization/#determine-the-request-verb

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GottdesKrieges

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值