1. RBAC 鉴权
基于角色(Role)的访问控制(RBAC)是一种基于组织中用户的角色来调节控制对计算机或网络资源的访问的方法。
RBAC 鉴权机制使用 rbac.authorization.k8s.io
API 组来驱动鉴权决定, 允许你通过 Kubernetes API 动态配置策略。
要启用 RBAC,在启动 API 服务器时将 --authorization-mode
参数设置为一个逗号分隔的列表并确保其中包含 RBAC
。
2. Role 和 ClusterRole
RBAC 的 Role 或 ClusterRole 中包含一组代表相关权限的规则。 这些权限是纯粹累加的(不存在拒绝某操作的规则)。
Role 总是用来在某个名字空间内设置访问权限; 在你创建 Role 时,你必须指定该 Role 所属的名字空间。
与之相对,ClusterRole 则是一个集群作用域的资源。这两种资源的名字不同(Role 和 ClusterRole) 是因为 Kubernetes 对象要么是名字空间作用域的,要么是集群作用域的,不可两者兼具。
ClusterRole 有若干用法。你可以用它来:
- 定义对某名字空间域对象的访问权限,并将在个别名字空间内被授予访问权限;
- 为名字空间作用域的对象设置访问权限,并被授予跨所有名字空间的访问权限;
- 为集群作用域的资源定义访问权限。
如果你希望在名字空间内定义角色,应该使用 Role; 如果你希望定义集群范围的角色,应该使用 ClusterRole
3. 鉴权
Kubernetes 使用 API 服务器对 API 请求进行鉴权。 它根据所有策略评估所有请求属性来决定允许或拒绝请求。 一个 API 请求的所有部分都必须被某些策略允许才能继续。 这意味着默认情况下拒绝权限。
当系统配置了多个鉴权模块时,Kubernetes 将按顺序使用每个模块。 如果任何鉴权模块批准或拒绝请求,则立即返回该决定,并且不会与其他鉴权模块协商。 如果所有模块对请求没有意见,则拒绝该请求。 被拒绝响应返回 HTTP 状态代码 403。
3.1 审查你的请求属性
Kubernetes 仅审查以下 API 请求属性:
- 用户 —— 身份验证期间提供的
user
字符串。 - 组 —— 经过身份验证的用户所属的组名列表。
- 额外信息 —— 由身份验证层提供的任意字符串键到字符串值的映射。
- API —— 指示请求是否针对 API 资源。
- 请求路径 —— 各种非资源端点的路径,如
/api
或/healthz
。 - API 请求动词 —— API 动词
get
、list
、create
、update
、patch
、watch
、proxy
、redirect
、delete
和deletecollection
用于资源请求。 要确定资源 API 端点的请求动词,请参阅确定请求动词。 - HTTP 请求动词 —— HTTP 动词
get
、post
、put
和delete
用于非资源请求。 - 资源 —— 正在访问的资源的 ID 或名称(仅限资源请求)- 对于使用
get
、update
、patch
和delete
动词的资源请求,你必须提供资源名称。 - 子资源 —— 正在访问的子资源(仅限资源请求)。
- 名字空间 —— 正在访问的对象的名称空间(仅适用于名字空间资源请求)。
- API 组 —— 正在访问的 API 组 (仅限资源请求)。空字符串表示核心 API 组。
3.2 确定请求动词
HTTP 动词 | 请求动词 |
---|---|
POST | create |
GET, HEAD | get (针对单个资源)、list(针对集合) |
PUT | update |
PATCH | patch |
DELETE | delete(针对单个资源)、deletecollection(针对集合) |
4. 实验
4.1 允许用户访问指定Namespace下资源
要求:
1. 创建用户qiuqin
2. 允许用户qiuqin操作Namespace linux下所有pod和deployment
4.1.1 创建用户
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl create serviceaccount qiuqin -n linux
serviceaccount/qiuqin created
4.1.2 创建角色
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: linux
name: qiuqin-role
rules:
- apiGroups: ["*"]
resources: ["pods","pods/exec"]
verbs: ["*"]
- apiGroups: ["apps/v1"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
执行生效
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl apply -f qiuqin-role.yaml
role.rbac.authorization.k8s.io/linux-role created
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl get role -n linux
NAME CREATED AT
qiuqin-role 2022-08-20T09:21:15Z
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl describe role qiuqin-role -n linux
Name: qiuqin-role
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods.*/exec [] [] [*]
pods.* [] [] [*]
deployments.apps/v1 [] [] [get list watch create update patch delete
4.1.3 将用户与角色关联
新建一个名为role-bind-qiuqin的Rolebinding
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: role-bind-qiuqin
namespace: linux
subjects:
- kind: ServiceAccount
name: qiuqin
namespace: linux
roleRef:
kind: Role
name: qiuqin-role
apiGroup: rbac.authorization.k8s.io
执行生效
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl apply -f qiuqin-role-bind.yaml
rolebinding.rbac.authorization.k8s.io/role-bind-qiuqin created
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl get rolebindings -n linux
NAME ROLE AGE
role-bind-qiuqin Role/qiuqin-role 4m13s
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl describe rolebindings -n linux role-bind-qiuqin
Name: role-bind-qiuqin
Labels: <none>
Annotations: <none>
Role:
Kind: Role
Name: qiuqin-role
Subjects:
Kind Name Namespace
---- ---- ---------
ServiceAccount qiuqin linux
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl get serviceaccounts -n linux
NAME SECRETS AGE
default 1 3d5h
qiuqin 1 21m
4.1.4 获取token
我们已经获得了token的名字qiuqin-token-kp498
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl get secrets -n linux
NAME TYPE DATA AGE
default-token-mgxx7 kubernetes.io/service-account-token 3 3d7h
qiuqin-token-kp498 kubernetes.io/service-account-token 3 119m
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl describe secrets -n linux qiuqin-token-kp498
Name: qiuqin-token-kp498
Namespace: linux
Labels: <none>
Annotations: kubernetes.io/service-account.name: qiuqin
kubernetes.io/service-account.uid: 478b045b-831c-48e8-97d7-6e372f0b1747
Type: kubernetes.io/service-account-token
Data
====
namespace: 5 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjUxUzlHTUdYcUN2YnA2UU9ndEFSbEZJaUtySVFxdWJvVGc0TEFIR2NhbGcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJsaW51eCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJxaXVxaW4tdG9rZW4ta3A0OTgiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicWl1cWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNDc4YjA0NWItODMxYy00OGU4LTk3ZDctNmUzNzJmMGIxNzQ3Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmxpbnV4OnFpdXFpbiJ9.IgwpQroRFz7FjQFJW50A2GtKRkBPoaFKn9d3Hrh1aDX5UCD7AKfqAOY-EtKzUmpYgmzGJzDqBIZ5ryxLeiCXsB5LB8PAQ6FiEgB47F4XHc6_hVw5SlSGn4aL0EhWm7wZ0JzXE4kb7OmfYefA_MOp7BsreSewIHhCghzNXO3aIm-G0kxVZDAiyJdvwZAAsowDOGZi4ZkUSG29W8KnaBGoBR8Wg_dScd2_NndwBinCFZCaJV3yWioObRRlgVrYUB9mGR3Uy4y1_HN5X9vpaWFxkeLMVDJuCJfa8CgWTVQCU2tAMwsJP7fnbkoZWZDSJD-E--8XcQEnPL0DUr4dKwS5zA
ca.crt: 1350 bytes
这样我们就能拿着这个token登录dashboard了.
此时登录pod也是可以的
但是其他没授权的比如service等还是无法查看的
4.1.5 修改权限
删除deployment的创建,删除,更新等功能.
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: linux
name: qiuqin-role
rules:
- apiGroups: ["*"]
resources: ["pods","pods/exec"]
verbs: ["list", "get", "watch"]
- apiGroups: ["apps/v1"]
resources: ["deployments"]
verbs: ["get", "list", "watch"]
生效后,再去删除pod就不再被允许
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl apply -f qiuqin-role.yaml
role.rbac.authorization.k8s.io/qiuqin-role configured
4.2 生成config文件
4.2.1 证书配置文件
qiuqin-csr.json
{
"CN": "China",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Shanghai",
"L": "Shanghai",
"O": "Pana",
"OU": "System"
}
]
}
4.2.2 签发证书
root@k8s-master-01:/opt/k8s-data/yaml/rbac# ln -sf /etc/kubeasz/bin/cfssl* /usr/bin/
root@k8s-master-01:/opt/k8s-data/yaml/rbac# cfssl gencert -ca=/etc/kubernetes/ssl/ca.pem -ca-key=/etc/kubernetes/ssl/ca-key.pem -config=/etc/kubeasz/clusters/intra-k8s-01/ssl/ca-config.json -profile=kubernetes qiuqin-csr.json | cfssljson -bare qiuqin
2022/08/20 19:40:36 [INFO] generate received request
2022/08/20 19:40:36 [INFO] received CSR
2022/08/20 19:40:36 [INFO] generating key: rsa-2048
2022/08/20 19:40:36 [INFO] encoded CSR
2022/08/20 19:40:36 [INFO] signed certificate with serial number 610630013445757508226794504391648952770806866718
2022/08/20 19:40:36 [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").
签发后会生成qiuqin.csr,qiuqin.pem,qiuqin-key.pem三个文件
root@k8s-master-01:/opt/k8s-data/yaml/rbac# ll
total 32
drwxr-xr-x 2 root root 4096 Aug 20 19:44 ./
drwxr-xr-x 10 root root 4096 Aug 20 16:51 ../
-rw-r--r-- 1 root root 997 Aug 20 19:44 qiuqin.csr
-rw-r--r-- 1 root root 221 Aug 20 19:44 qiuqin-csr.json
-rw------- 1 root root 1675 Aug 20 19:44 qiuqin-key.pem
-rw-r--r-- 1 root root 1387 Aug 20 19:44 qiuqin.pem
-rw-r--r-- 1 root root 260 Aug 20 19:43 qiuqin-role-bind.yaml
-rw-r--r-- 1 root root 304 Aug 20 19:42 qiuqin-role.yaml
4.2.3 生成kubeconfig文件
4.2.3.1 生成普通用户kubeconfig文件
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl config set-cluster cluster --certificate-authority=/etc/kubernetes/ssl/ca.pem --embed-certs --server=https://192.168.31.188:6443 --kubeconfig=qiuqin.kubeconfig
4.2.3.2 将证书信息嵌入kubeconfig文件
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl config set-credentials qiuqin --client-certificate=/opt/k8s-data/yaml/rbac/qiuqin.pem --client-key=/opt/k8s-data/yaml/rbac/qiuqin-key.pem --embed-certs=true --kubeconfig=qiuqin.kubeconfig
User "qiuqin" set.
4.2.3.3 设置上下文参数
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl config set-context cluster1 --cluster=cluster1 --user=qiuqin --namespace=linux --kubeconfig=qiuqin.kubeconfig
Context "cluster1" created.
4.2.3.4 设置默认上下文
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl config use-context cluster1 --kubeconfig=qiuqin.kubeconfig
Switched to context "cluster1".
4.2.3.5 将token写入kubeconfig
root@k8s-master-01:/opt/k8s-data/yaml/rbac# kubectl describe secrets qiuqin-token-kp498 -n linux
Name: qiuqin-token-kp498
Namespace: linux
Labels: <none>
Annotations: kubernetes.io/service-account.name: qiuqin
kubernetes.io/service-account.uid: 478b045b-831c-48e8-97d7-6e372f0b1747
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1350 bytes
namespace: 5 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjUxUzlHTUdYcUN2YnA2UU9ndEFSbEZJaUtySVFxdWJvVGc0TEFIR2NhbGcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJsaW51eCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJxaXVxaW4tdG9rZW4ta3A0OTgiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicWl1cWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNDc4YjA0NWItODMxYy00OGU4LTk3ZDctNmUzNzJmMGIxNzQ3Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmxpbnV4OnFpdXFpbiJ9.IgwpQroRFz7FjQFJW50A2GtKRkBPoaFKn9d3Hrh1aDX5UCD7AKfqAOY-EtKzUmpYgmzGJzDqBIZ5ryxLeiCXsB5LB8PAQ6FiEgB47F4XHc6_hVw5SlSGn4aL0EhWm7wZ0JzXE4kb7OmfYefA_MOp7BsreSewIHhCghzNXO3aIm-G0kxVZDAiyJdvwZAAsowDOGZi4ZkUSG29W8KnaBGoBR8Wg_dScd2_NndwBinCFZCaJV3yWioObRRlgVrYUB9mGR3Uy4y1_HN5X9vpaWFxkeLMVDJuCJfa8CgWTVQCU2tAMwsJP7fnbkoZWZDSJD-E--8XcQEnPL0DUr4dKwS5zA
将token复制到qiuqin.kubeconfig文件最后
略
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjUxUzlHTUdYcUN2YnA2UU9ndEFSbEZJaUtySVFxdWJvVGc0TEFIR2NhbGcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJsaW51eCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJxaXVxaW4tdG9rZW4ta3A0OTgiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicWl1cWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNDc4YjA0NWItODMxYy00OGU4LTk3ZDctNmUzNzJmMGIxNzQ3Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmxpbnV4OnFpdXFpbiJ9.IgwpQroRFz7FjQFJW50A2GtKRkBPoaFKn9d3Hrh1aDX5UCD7AKfqAOY-EtKzUmpYgmzGJzDqBIZ5ryxLeiCXsB5LB8PAQ6FiEgB47F4XHc6_hVw5SlSGn4aL0EhWm7wZ0JzXE4kb7OmfYefA_MOp7BsreSewIHhCghzNXO3aIm-G0kxVZDAiyJdvwZAAsowDOGZi4ZkUSG29W8KnaBGoBR8Wg_dScd2_NndwBinCFZCaJV3yWioObRRlgVrYUB9mGR3Uy4y1_HN5X9vpaWFxkeLMVDJuCJfa8CgWTVQCU2tAMwsJP7fnbkoZWZDSJD-E--8XcQEnPL0DUr4dKwS5zA
将kubeconfig复制出来,之后就能用这个文件直接登录dashboard了