RBAC(Role-Based Access Control,基于角色的访问控制),允许通过 Kubernetes API 动态配置策略。

概念理解

角色(权限的集合)

  • Role:授权特定命名空间的访问权限
  • ClusterRole:授权所有命名空间的访问权限(集群角色)

角色绑定

  • RoleBinding:将角色(Role)绑定到主体(即subject)
  • ClusterRoleBinding:将集群角色(ClusterRole)绑定到主体

主体(subject)

  • User:用户
  • Group:用户组
  • ServiceAccount:服务账号

以上三个概念按照以下可以通俗的理解

Role ---> RoleBinding ---> User/Group/ServiceAccount
ClusterRole ---> ClusterRoleBinding ---> User/Group/ServiceAccount

将准备要设置赋予的权限,放到角色(Role/ClusterRole)里,通过角色绑定(RoleBinding/ClusterRoleBinding)将权限放在绑定到主体(User/Group/ServiceAccount)上

理解示例:比如上班使用的工卡,工卡上具有进入大厦以及公司的权限,然后给员工发卡时,就要知道是普通员工还是领导身份,普通员工则有进入工作场所的权限,而领导的还具有进入 “闲人免进” 字样的场所。工卡的权限就是角色,通过人事部将工卡发送给员工,此时人事部就是角色绑定,员工就是主体。

RBAC 案例

背景:新人上岗,让新人快速熟悉 k8s 环境,为了减少风险,担心误操作,决定给他一个很小的权限让他先熟悉项目。

为 FeiYi 用户授权 nginx 命名空间的 Pod 读取权限

签发证书

用 k8s 的 CA 签发一个客户端证书,k8s 使用 cfssl 工具用来生成证书,需要注意的是必须用 K8S 的 CA 来签发

安装cfssl工具

# cfssl:证书签发的主要工具
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/bin/cfssl
# cfssl-json:将cfssl生成的整数(json格式)变为文件承载式证书
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/bin/cfssljson
# cfssl-certinfo:验证证书的信息
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -O /usr/bin/cfssl-certinfo
# 授权cfssl工具可执行
chmod +x /usr/bin/cfssl*

创建CA:用来签发证书

cat > ca-config.json << EOF
{
  "signing": {
    "default": {
      "expiry": "438000h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth", 
            "client auth"
        ],
        "expiry": "438000h"
      }
    }
  }
}
EOF
# signing:表示该证书可用于签名其它证书;生成的 .pem 证书文件中 CA=TRUE
# expiry:默认的证书到期时间为50年,87600h为10年
# profiles:包含了server auth和client auth,所以可以签发三种不同类型证书;expiry 证书有效期,默认50年,可以定义多个profile
# kubernetes:kubernetes这个名字可以自定义,后续指定profiles时要一致,这就是一个单个的profile
# server auth:表示client可以用该 CA 对server提供的证书进行验证
# client auth:表示server可以用该CA对client提供的证书进行验证

创建CA证书签名请求文件

cat > ca-csr.json << EOF
{
  "CN": "feiyi",
  "hosts": [],
  "key": { 
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",    
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF
# "CN: feiyi": Common Name,feiyi作为之后要授权的用户
# C: 国家 ST: 州/省 L: 地区/城市 
# O: Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group),也就是feiyi用户所属的组,之后也可给该组授权
# OU: 组织单位名称,公司部门

使用 k8s 的 CA 签发证书

cfssl gencert \
-ca=/etc/kubernetes/pki/ca.crt \
-ca-key=/etc/kubernetes/pki/ca.key \
-config=ca-config.json \
-profile=kubernetes ca-csr.json | cfssljson -bare feiyi
# -ca: 指定k8s的ca文件所在位置
# -ca-key: 指定k8s的ca密钥文件所在位置
# -config: 指定刚刚创建好的CA-config.json文件
# -profile: 指定ca-config.json中的profile---kubernetes
# cfssljson -bare feiyi:将以上信息解析,生成以feiyi为前缀的证书文件

当前目录会新增三个文件

feiyi-key.pem  # ca的私钥
feiyi.pem      # ca证书
feiyi.csr      # 签署请求

生成 kubeconfig 授权文件

在创建完集群后,会让你执行如下命令

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

其中的 admin.conf ,就和要准备生成的 kubeconfig文件结构是一样的,只不过使用的 admin.conf 类似 Linux 系统的 root 用户,可以随意查看 K8S 集群里面的任何内容,具有最高权限

集群信息写入 kubeconfig

# 因为创建的kubeconfig也将作用于K8S集群,所以需要指定K8S的API信息
kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/pki/ca.crt \
  --embed-certs=true \
  --server=https://192.168.1.11:6443 \
  --kubeconfig=feiyi.kubeconfig
# --certificate-authority:ca证书
# --server:apiserver地址
# --kubeconfig:根据给定的信息生成的kubeconfig名字
# --embed-certs:为true时,将证书信息写入kubeconfig文件;为false时,在kubeconfig文件中引用证书所在路径  

################################################################
# 这一步主要生成了以下信息
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0t
...
ejhKYld1OHY3WmI4TVR2MG9GVQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    server: https://172.16.182.193:6443
  name: kubernetes

客户端信息写入 kubeconfig

kubectl config set-credentials feiyi \
  --client-key=feiyi-key.pem \
  --client-certificate=feiyi.pem \
  --embed-certs=true \
  --kubeconfig=feiyi.kubeconfig
# set-credentials: 在 kubeconfig 中设置用户条目
# --client-key: 指定刚才生成私钥
# --client-certificate=feiyi.pem: 指定生成的数字证书
# --kubeconfig: 将客户端信息加入刚才生成的kubeconfig文件中

################################################################
# 这一步主要生成了以下信息
users:
- name: feiyi
  user:
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0
...
Si8rbHRhdXM4UWFRVmhCOHlndz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
    client-key-data: LS0tLS1CRUdJTi BSU0EgUFJJVkFURSBLRVktLS0tLQp
... 
ck9xK0pFdDJDNGpidmh0Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==

上下文信息写入 kubeconfig

设置默认上下文加入 kubeconfig:如果存在多套集群,通过设置上下文可以在多套集群间切换

kubectl config set-context kubernetes \
  --cluster=kubernetes \
  --user=feiyi \
  --kubeconfig=feiyi.kubeconfig 
# set-context: 设置上下文,默认在名为kubernetes的集群
# --user=feiyi: 使用客户端用户为feiyi
# --cluster=kubernetes: 用户作用到名为kubernetes的集群
# --kubeconfig:将上下文信息加入刚才生成的kubeconfig文件中

################################################################
# 这一步主要生成了以下信息,表示使用feiyi用户访问集群kubernetes
contexts:
- context:
    cluster: kubernetes
    user: feiyi
  name: kubernetes

感兴趣的话,可以将 admin.conf 和刚生成的 kubeconfig 对比一下,结构是一样的。

初始验证

使用刚生成的 kubeconfig 来查看集群信息

$ kubectl get node -n nginx --kubeconfig=feiyi.kubeconfig 
Error from server (Forbidden): pods is forbidden: User "feiyi" cannot list resource "pods" in API group "" in the namespace "nginx"

这是因为现在生成的 kubeconfig 还没有任何权限,所以任何资源还无法访问

创建 RBAC 权限策略

仅给予查看 nginx 命名空间的 pod 资源

$ vim rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: nginx  # 将权限给到nginx命名空间
  name: rbac-test
rules:
- apiGroups: [""] # 如果为空,则代表核心组(一般不指定),可以指定多个
  resources: ["pods"] # 仅允许该role对pod操作,可以指定多个
  verbs: ["get", "watch", "list"] # 对pod 所作的操作
---
# 将role绑定到user
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: nginx
  name: rbac-test-binding
subjects:
- kind: User
  name: feiyi  # 该名为生成证书时的CN名字
  apiGroup: rbac.authorization.k8s.io
roleRef:  # 指定上面创建的Role与feiyi绑定
  kind: Role
  name: rbac-test
  apiGroup: rbac.authorization.k8s.io

创建 RBAC 权限策略

kubectl apply -f rbac.yaml

再次使用 kubeconfig 查看

kubectl get pods -n nginx --kubeconfig=./cfssl/kubeconfig/feiyi.kubeconfig 
NAME                               READY   STATUS    RESTARTS   AGE
nginx-deployment-c94f957b8-4t4f8   1/1     Running   0          17d
nginx-deployment-c94f957b8-gj4j7   1/1     Running   0          17d

可以尝试查看其它资源是都看不了的,和没授权的报错是一样的。

总结

最后创建完成后的访问流程

kubectl(客户端)通过使用创建好的 kubeconfig 中的User访问到 api,api 通过提取证书中的 CN 字段作为 Uesr ,然后去查看是否在创建好的 RABC 中有对应用户的策略权限,来判断该不该执行这个操作。这个过程就经历了,鉴权和授权

评论




正在载入...
PoweredHexo
HostedAliyun
DNSAliyun
ThemeVolantis
UV
PV
BY-NC-SA 4.0