Skip to content

Kubernets基于RBAC的认证与授权

集群认证和授权(RBAC)

主体(subject)---->认证----->授权(action)----->准入控制(object)

subject:表示三类主体,user,group,serviceAccount。 action:能对Object做什么,例如:get、list、watch、patch、delete、update、create等。 object:主要表现为以下三类对象。 Resource:代表一类资源,也被称为Resource Group,例如Secret。 Resource Names:代表ResourceGroup中具体的单个资源。 Non-Resource URLs:它被称为非资源URL或称为虚拟URL对象,是k8s中所需要的特殊动作(不需要多关注)。

授权管理

授权模式

授权模式定义认证成功的用户对集群的操作权限,有kube-apiserver配置文件定义:

bash
vim /etc/kubernetes/manifests/kube-apiserver.yaml
......
#在spec.containers下的command中添加参数--authorization-mode指定
spec:
 containers:
  - command:
    - --authorization-mode=Node,RBAC
......

支持的模式:

AlwaysAllow,允许用户所有请求。 AlwaysDeny,拒绝用户所有请求,不管用户是否具有权限,但不限制admin用户。 ABAC,Attribute Based Access Control,详情参考ABAC。 Webhook,详情参考Webhook。 RBAC,Role Based Access Control,基于角色的访问控制,只有明确了赋予用户权限,用户才能执行相关操作。 Node,用于各个node上的kubelet访问apiserver时使用。

Role管理

kubernetes为了方便管理权限,将一组特定权限赋予角色,然后将角色赋予用户,那么用户将继承该角色具有的权限。

Role: 定义一组规则,用于访问某一命名空间中的Kubernetes资源。

角色分类

role,namespace角色,限定用户访问特定namespace。role绑定给用户,称之为rolebinding clusterrole,集群角色,可以管理集群,包括所有namespace中资源。clusterrole绑定给用户,称之为clusterrolebinding

权限由kubernetes系统预定义的,clusterroles/admin中包涵系统中全部权限列表。

Cluster Role管理

ClusterRole: 定义了一组访问集群中Kubernetes资源(包括所有命名空间)的规则。

kubernetes系统中已经预定义了很多cluster role,常见的clusterrole如下:

view,对系统中几乎所有的对象都有get、list和watch权限。 edit,对系统中几乎所有的对象都有get、list和watch权限。其中部分对象额外具有create、delete、deletecollection、patch、update权限。 admin,对系统中大部分的对象具有所有权限。基本上用于绑定用户到特定namespace中 cluster-admin,对系统中所有的对象具有所有权限。

Service Account

Service Account,即服务账户,pod使用Service Account身份运行容器。

赋予Service Account相应角色,则使用该Service Account身份运行的pod中进程将具有对应Service Account的权限。

在每个namespace中都有一个名称为default的Service Account。每个Service Account都有一个Secret。

sa会创建一个secret,pod或deployment使用sa账户时,会将sa的secret进行挂载到pods中使用。

用户授权案例

账户创建与绑定

  1. 创建指定namespace
bash
kubectl create namespace

kubectl config set-context --current --namespace rbac
  1. 创建sa账户
bash
kubectl create serviceaccount user1

kubectl get sa
NAME      SECRETS   AGE
default   0         5m
lxh       0         57s
  1. 创建role角色,normal-user

针对rbac名称空间下的pod拥有查看、修改和删除权限。

针对rbac名称空间下的deployment查看的权限,不具有修改和删除权限。

创建role.yaml文件

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: rbac
  name: normal-user
rules:
- apiGroups: ["*"]
  resources: ["pods/exec"]
  #verbs: ["*"]
  ##RO-Role
  verbs: ["get", "list", "watch", "create"]


- apiGroups: ["*"]
  resources: ["pods"]
  #verbs: ["*"]
  ##RO-Role
  verbs: ["get", "list", "watch", "delete"]

- apiGroups: ["apps/v1"]
  resources: ["deployments"]
  #verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
  ##RO-Role
  verbs: ["get", "watch", "list"]
bash
kubectl apply -f role.yaml

kubectl get role
NAME          CREATED AT
normal-user   2022-12-19T21:19:11Z
  1. 将sa账户绑定到role normal-user角色

创建rolebinding.yaml文件

yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: role-bind
  namespace: rbac
subjects:
- kind: ServiceAccount
  name: lxh
  namespace: rbac
roleRef:
  kind: Role
  name: normal-user
  apiGroup: rbac.authorization.k8s.io
bash
kubectl apply -f role-bind.yaml
  1. 查看sa账户绑定role角色
bash
kubectl get rolebindings.rbac.authorization.k8s.io -o yaml

apiVersion: v1
items:
- apiVersion: rbac.authorization.k8s.io/v1
  kind: RoleBinding
  metadata:
    annotations:
      kubectl.kubernetes.io/last-applied-configuration: |
        {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"name":"role-bind","namespace":"rbac"},"roleRef":{"apiGroup":"rbac.authorization.k8s.io","kind":"Role","name":"normal-user"},"subjects":[{"kind":"ServiceAccount","name":"user1","namespace":"rbac"}]}
    creationTimestamp: "2022-12-19T21:19:11Z"
    name: role-bind
    namespace: rbac
    resourceVersion: "712005"
    uid: d3e3daf6-0eea-425b-9e5a-335ad0406722
  roleRef:
    apiGroup: rbac.authorization.k8s.io
    kind: Role
    name: normal-user
  subjects:
  - kind: ServiceAccount
    name: lxh
    namespace: rbac
kind: List
metadata:
  resourceVersion: ""
  1. 创建sa账户secret类型token(1.23版本前不需要手动创建)

创建sa-token.yaml文件

yaml
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
  name: lxh-token
  namespace: rbac
  annotations:
    kubernetes.io/service-account.name: "user1"
bash
kubectl apply -f sa-token.yaml
  1. 查看sa账户secret类型token
bash
kubectl describe secrets user1-token | grep token
Name:         user1-token
Type:  kubernetes.io/service-account-token
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IlpLSTRfNW4wYy1ncDdHaS1zQjVvWXRjVHUzam8zazNwd3NmQzJtVVctb2MifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJyYmFjIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Imx4aC10b2tlbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJseGgiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI0MjdhMDdmNi1hYzNhLTRjZDItYWViNC0xOGJlMTNhYjZiZTIiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6cmJhYzpseGgifQ.UnCLtXk96Ycj30jR_4NAaIxwfoSoeg36Clvgnc6UOJAdhf2f5jMSvw174AshDZfcDb4S-gWZbRNeN0-RsT8MocXqa37LQg_ZgoMQAhAvc7fxH32dhoPENrIvX63z9KISCpFqdeU5AX4vL_XIH9LXXjOdcbALYMsiDw_DwupLqajzIyzuu9aCMqrrAVA-RUtnKRaRfCWw4hL0Y39hKpf0QxEnY7jzrg906-6Kcl7zC9izkEb4WMG2Fsw0USGNEnjWPcI1DaZtXIpUnHOecpZlgpWFCSZwaldz3TI0QMzhCTi3nVKUkz3iVjiYUoOpKS5buTFfBJNyolRkgsw-H3bqlQ

生成kubeconfig文件

创建证书目录

bash
mkdir /root/rbac/certs
  1. 生成csr证书
bash
cat /root/rbac/certs/user1-csr.json
{
  "CN": "China",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
  1. 签发证书

cfssl安装,在master节点执行

bash
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 

mv cfssl-certinfo_1.6.1_linux_amd64 cfssl-certinfo
mv cfssl_1.6.1_linux_amd64 cfssl
mv cfssljson_1.6.1_linux_amd64 cfssljson

chmod a+x cfssl-certinfo cfssl cfssljson
cp cfssl-certinfo cfssl cfssljson /usr/local/bin/

# 测试
cfssl version

# 从部署节点deploy拷贝集群证书文件到master节点

scp /etc/kubeasz/clusters/k8s-cluster1/ssl/ca-config.json master1:/root/rbac/certs

签发证书

bash
cfssl gencert -ca=/etc/kubernetes/ssl/ca.pem -ca-key=/etc/kubernetes/ssl/ca-key.pem -config=./ca-config.json -profile=kubernetes ./user1.json | cfssljson -bare user1

生成集群配置文件kubenetes config

bash
kubectl config set-cluster cluster1 \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=https://192.168.100.2:6443 \
--kubeconfig=./user.kubeconfig
  1. 设置客户端认证

复制用户证书到k8s集群证书目录下

bash
cp user1*.pem /etc/kubernetes/ssl/

创建用户认证到集群配置文件

bash
kubectl config set-credentials user1 \
--client-certificate=/etc/kubernetes/ssl/user1.pem \
--client-key=/etc/kubernetes/ssl/user1-key.pem \
--embed-certs=true \
--kubeconfig=./user.kubeconfig
  1. 设置上下文
bash
ubectl config set-context cluster1 \
--cluster=cluster1 \
--user=user1 \
--namespace=rbac \
--kubeconfig=./user.kubeconfig
  1. 设置默认上下文
bash
kubectl config use-context cluster1 --kubeconfig=user.kubeconfig
  1. 追加用户token到集群配置文件 将刚才获取道到的token追加至user.kubeconfig最后,保存即可

本文作者:许怀安
创作时间:2022.12.19
版权声明:本博客所有文章除特别声明外,均采用BY-NC-SA许可协议。转载请禀明出处!

许怀安 | MIT License