k8s的认证和鉴权
k8s的认证和鉴权
认证和授权
环境准备
[root@master30 ~]# kubectl create ns auth
[root@master30 ~]# kubectl config set-context --current --namespace auth
鉴权概述
Kubernetes API 服务器对 API 请求进行鉴权。 它根据所有策略评估所有请求属性来决定允许或拒绝请求。 一个 API 请求的所有部分都必须被某些策略允许才能继续。 这意味着默认情况下拒绝权限。
当系统配置了多个鉴权模块时,Kubernetes 将按顺序使用每个模块。
如果任何鉴权模块批准或拒绝请求,则立即返回该决定,并且不会与其他鉴权模块协商。
如果所有模块对请求没有意见,则拒绝该请求。 被拒绝响应返回 HTTP 状态代码 403。
鉴权模式
鉴权模式定义认证成功的用户对集群的操作权限,由kube-apiserver配置文件指定:
[root@master30 ~]# cat /etc/kubernetes/manifests/kube-apiserver.yaml |grep mode
- --authorization-mode=Node,RBAC
我们这里使用RBAC和Node模式。
支持的模式:
- Node,是节点专用的鉴权模式,根据调度到 kubelet 上运行的 Pod 为 kubelet 授予权限。 要了解有关使用节点鉴权模式的更多信息,请参阅节点鉴权。
- ABAC,基于属性的访问控制(ABAC)定义了一种访问控制范型,通过使用将属性组合在一起的策略, 将访问权限授予用户。策略可以使用任何类型的属性(用户属性、资源属性、对象,环境属性等)。 要了解有关使用 ABAC 模式的更多信息,请参阅 ABAC 模式。
- RBAC,基于角色的访问控制(RBAC) 是一种基于企业内个人用户的角色来管理对计算机或网络资源的访问的方法。要了解有关使用 RBAC 模式的更多信息,请参阅 RBAC 模式。
- 被启用之后,RBAC(基于角色的访问控制)使用
rbac.authorization.k8s.ioAPI 组来驱动鉴权决策,从而允许管理员通过 Kubernetes API 动态配置权限策略。 - 要启用 RBAC,请使用
--authorization-mode = RBAC启动 API 服务器。
- 被启用之后,RBAC(基于角色的访问控制)使用
- Webhook —— WebHook 是一个 HTTP 回调:发生某些事情时调用的 HTTP POST; 通过 HTTP POST 进行简单的事件通知。 实现 WebHook 的 Web 应用程序会在发生某些事情时将消息发布到 URL。 要了解有关使用 Webhook 模式的更多信息,请参阅 Webhook 模式。
- AlwaysAllow,允许用户所有请求。
# 前面我们删除了用户laoma权限,更改为AlwaysAllow模式,测试laoma用户权限。
[root@master30 ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
......
# 在spec.containers下的command中添加参数- --basic-auth-file=/etc/kubernets/pki/aa.csv
spec:
containers:
- command:
- --authorization-mode=AlwaysAllow
......
# 更改完成后,kubernetes会自动重启pod/kube-apiserver,等该pod状态为running再次验证。
[root@client ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master30.laoma.cloud Ready control-plane 12d v1.30.2
worker31.laoma.cloud Ready <none> 12d v1.30.2
worker32.laoma.cloud Ready <none> 12d v1.30.2
- AlwaysDeny,拒绝用户所有请求,不管用户是否具有权限,但不限制admin用户。
role 管理
kubernetes 方便管理权限,将一组特定权限赋予角色,然后将角色赋予用户,那么用户将继承该角色具有的权限。
角色分类
-
role,namespace 角色,限定用户访问特定namespace。role绑定给用户,称之为rolebinding。
-
clusterrole,cluster 角色,可以管理集群,包括所有namespace中资源。clusterrole绑定给用户,称之为clusterrolebinding。
权限由kubernetes系统预定义的,clusterroles/admin中包涵系统中全部权限列表。
[root@master30 ~]# kubectl describe clusterroles admin
Name: admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
rolebindings.rbac.authorization.k8s.io [] [] [create delete deletecollection get list patch update watch]
roles.rbac.authorization.k8s.io [] [] [create delete deletecollection get list patch update watch]
configmaps [] [] [create delete deletecollection patch update get list watch]
endpoints [] [] [create delete deletecollection patch update get list watch]
......
输出说明:
-
Resources:代表系统中资源类型,例如Secret,Configmap等。
-
Resource Names:代表特定资源。如果Resources是Secret,那么这里就指特定Secret。
-
Non-Resource URLs: 被称为非资源URL或虚拟URL对象,是k8s中所需要的特殊动作(不需要关注)。
-
Verbs:代表针对资源执行的动作,包括操作get、list、create、delete、update、edit、watch、exec。
- get,用于获得特定资源信息,例如,针对pod,可以执行
GET /api/v1/namespaces/{namespace}/pods/{podname}。
- get,用于获得特定资源信息,例如,针对pod,可以执行
[root@client ~]# kubectl get pod -n kube-system
Error from server (Forbidden): pods is forbidden: User "laoma" cannot list resource "pods" in API group "" in the namespace "kube-system"
[root@client ~]# kubectl get pod kube-proxy-8kp8w -n kube-system
NAME READY STATUS RESTARTS AGE
kube-proxy-8kp8w 1/1 Running 4 52d
list,用户查看某一类型资源清单,例如针对pod,可以执行GET /api/v1/namespaces/{namespace}/pods。
[root@client ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-6dfcd885bf-lq4n5 1/1 Running 4 52d
calico-node-44cf4 1/1 Running 4 52d
calico-node-48sm4 1/1 Running 4 52d
.....
[root@client ~]# kubectl get pod kube-proxy-8kp8w -n kube-system
Error from server (Forbidden): pods "kube-proxy-8kp8w" is forbidden: User "laoma" cannot get resource "pods" in API group "" in the namespace "kube-system"
创建 role
[root@master30 ~]# kubectl create role -h
Create a role with single rule.
Usage:
kubectl create role NAME --verb=verb --resource=resource.group/subresource
[--resource-name=resourcename] [--dry-run=server|client|none] [options]
示例1:可以对项目中所有pods执行get、list、watch操作
[root@master30 ~]# kubectl create role pod-role --verb=get,list,watch --resource=pods -n default --dry-run=client -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: pod-role
namespace: default
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
[root@master30 ~]# kubectl create role pod-role --verb=get,list,watch --resource=pods -n default
[root@master30 ~]# kubectl get roles pod-role -n default
NAME CREATED AT
pod-role 2021-08-24T10:24:36Z
[root@master30 ~]# kubectl describe roles pod-role -n default
Name: pod-role
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get list watch]
示例2:访问特定资源pods/readablepod
[root@master30 ~]# kubectl create role pod-role --verb=get --resource=pods \
--resource-name=readablepod --resource-name=anotherpod
示例3:可以对项目中所有replicasets执行get list watch操作
[root@master30 ~]# kubectl create role foo --verb=get,list,watch --resource=replicasets
修改 role
# 增加create权限
[root@master30 ~]# kubectl edit roles -n default pod-role
......
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
# 在verbs下添加相应权限
- list
- get
- watch
- creat
apiGroups
-
角色的 rules 属性中
apiGroups默认为空。 -
pod、service 资源的 apiVersion 是v1,apiGroups为""。
-
Deployment、DaemonSet 资源的 apiVersion 是apps/v1,apiGroups为"apps"。如下:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: creationTimestamp: null name: deployments-role namespace: default rules: - apiGroups: - "apps" resources: - deployments verbs: - get - list - watch
**示例1:**定义角色,无法操作deployments,因为apiGroups未指定apps
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: deployments-role
namespace: default
rules:
- apiGroups:
- ""
resources:
- deployments
verbs:
- get
- list
- watch
**示例2:**定义一个可以 scale deployments 的角色
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: deployments-role
namespace: default
rules:
- apiGroups:
- "apps"
resources:
- deployments
# 额外添加以下资源
- deployments/scale
verbs:
- get
- list
- watch
# 额外添加以下权限
- patch
**示例3:**定义一个对不同类型资源赋予不同权限的角色。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: all-role
namespace: default
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
- apiGroups:
- "apps"
resources:
- deployments
- deployments/scale
verbs:
- get
- list
- watch
- patch
常见apiGroups
| Type | apiVersion | apiGroups |
|---|---|---|
| Pod、Service、PersistentVolume、PersistentVolumeClaim | v1 | “” |
| Deployment、DaemonSet、StatefulSets | apps/v1 | apps |
| Job | batch/v1 | batch |
| CronJob | batch/v1beta1 | batch |
| Role RoleBinding ClusterRole ClusterRoleBinding | rbac.authorization.k8s.io/v1 | rbac.authorization.k8s.io |
| NetworkPolicy | networking.k8s.io/v1 | networking.k8s.io |
每种类型资源的 apiVersion 都可以通过以下命令查询:
[root@master30 ~]# kubectl explain deployment|grep VERSION
VERSION: apps/v1
[root@master30 ~]# kubectl explain networkpolicy|grep VERSION
VERSION: networking.k8s.io/v1
# 或者
root@master30:~/auth# kubectl api-resources |grep -i deploy
deployments deploy apps/v1 true Deployment
role 绑定
将 role 绑定给用户。
[root@master30 ~]# kubectl create rolebinding default-pod-laoma -n default --role=pod-role --user=laoma --dry-run=client -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: null
name: default-pod-laoma
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-role
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: laoma
# 绑定 ns/default 中角色 pod-role 给 laoma
[root@master30 ~]# kubectl create rolebinding default-pod-laoma -n default --role=pod-role --user=laoma
# 角色绑定完成后,角色的权限发生变化,用户获得的权限也会跟着动态变化。
[root@master30 ~]# kubectl get rolebindings -n default default-pod-laoma
NAME ROLE AGE
default-pod-laoma Role/pod-role 2m15s
[root@master30 ~]# kubectl describe rolebindings -n default default-pod-laoma
Name: default-pod-laoma
Labels: <none>
Annotations: <none>
Role:
Kind: Role
Name: pod-role
Subjects:
Kind Name Namespace
---- ---- ---------
User laoma
验证
[root@client ~]# kubectl run web --image=docker.io/library/httpd --image-pull-policy=IfNotPresent -n default
[root@client ~]# kubectl get pod -n default
NAME READY STATUS RESTARTS AGE
web 1/1 Running 0 2m30s
[root@client ~]# kubectl get pod -n default -w
NAME READY STATUS RESTARTS AGE
web 1/1 Running 0 2m42s
role 回收
[root@master30 ~]# kubectl delete rolebindings default-pod-laoma -n kube-system
rolebinding.rbac.authorization.k8s.io "default-pod-laoma" deleted
# 再次验证
[root@client ~]# kubectl get pod -n default
Error from server (Forbidden): pods is forbidden: User "laoma" cannot list resource "pods" in API group "" in the namespace "default"
role 删除
[root@master30 ~]# kubectl delete roles pod-role -n default
clusterrole 管理
常见 clusterrole
kubernetes系统中已经预定义了很多clusterrole,常见的clusterrole如下:
- view,对系统中几乎所有的对象都有get、list和watch权限。
- edit,对系统中几乎所有的对象都有get、list和watch权限。其中部分对象额外具有 create、delete、deletecollection、patch、update 权限。
- admin,对系统中大部分的对象具有所有权限。
- cluster-admin,对系统中所有的对象具有所有权限。
创建 clusterrole
[root@master30 ~]# kubectl create clusterrole -h
Usage:
kubectl create clusterrole NAME --verb=verb --resource=resource.group
[--resource-name=resourcename] [--dry-run=server|client|none] [options]
示例1:创建一个可以get、list、watch所有项目中pods的clusterrole
[root@master30 ~]# kubectl create clusterrole pod-role --verb=get,list,watch --resource=pods --dry-run=client -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: null
name: pod-role
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
[root@master30 ~]# kubectl create clusterrole pod-role --verb=get,list,watch --resource=pods
[root@master30 ~]# kubectl get clusterrole pod-role
NAME CREATED AT
pod-role 2021-08-25T14:31:21Z
[root@master30 ~]# kubectl describe clusterrole pod-role
Name: pod-role
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get list watch]
[root@master30 ~]# kubectl create clusterrole pod-role --verb=get,list,watch --resource=pods
[root@master30 ~]# kubectl get clusterrole pod-role
NAME CREATED AT
pod-role 2021-08-25T14:31:21Z
[root@master30 ~]# kubectl describe clusterrole pod-role
Name: pod-role
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get list watch]
示例2:创建一个可以get、list、watch所有项目中pods/readablepod和pods/anotherpod的clusterrole
[root@master30 ~]# kubectl create clusterrole pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod
示例3:创建一个可以get、list、watch所有项目中pods和pods/status的clusterrole
[root@master30 ~]# kubectl create clusterrole foo --verb=get,list,watch --resource=pods,pods/status
修改 clusterrole
[root@master30 ~]# kubectl edit clusterrole pod-role
......
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
# 添加create权限
- create
clusterrole 绑定
将clusterrole绑定给用户。
[root@master30 ~]# kubectl create clusterrolebinding laoma-pod-role --clusterrole=pod-role --user=laoma --dry-run=client -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
creationTimestamp: null
name: laoma-pod-role
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: pod-role
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: laoma
[root@master30 ~]# kubectl create clusterrolebinding laoma-pod-role --clusterrole=pod-role --user=laoma
[root@master30 ~]# kubectl get clusterrolebinding laoma-pod-role
NAME ROLE AGE
laoma-pod-role ClusterRole/pod-role 35s
[root@master30 ~]# kubectl describe clusterrolebinding laoma-pod-role
Name: laoma-pod-role
Labels: <none>
Annotations: <none>
Role:
Kind: ClusterRole
Name: pod-role
Subjects:
Kind Name Namespace
---- ---- ---------
User laoma
# client节点使用laoma用户测试权限
[root@client ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-6dfcd885bf-lq4n5 1/1 Running 6 53d
calico-node-44cf4 1/1 Running 6 53d
......
[root@client ~]# kubectl get pod -n default
NAME READY STATUS RESTARTS AGE
web 1/1 Running 1 15h
clusterrole 回收
[root@master30 ~]# kubectl delete clusterrolebinding laoma-pod-role
删除 clusterrole
[root@master30 ~]# kubectl delete clusterrole pod-reader
实践 1:角色管理
- 在 auth 命名空间,创建角色 pod-reader,针对pod,具备权限get、list、watch
- 赋予 laoma 用户 auth 命名空间 角色 pod-reader
- 管理员身份在 auth 命名空间创建 deployment
- 回收laoma 用户 集群管理员角色 cluster-admin(如果存在)
- laoma 用户验证:查看deployment和pod
- 清理资源:回收用户角色,删除 deployment
实践 2:使用现有集群角色
- 赋予 laoma 用户集群角色 admin,指定在auth命名空间
- laoma 用户在 auth 命名空间:创建、查看和删除 deployment
- laoma 用户在 default 命名空间:创建、查看和删除 deployment
- 回收 laoma 用户权限
结果:绑定集群角色的时候,限定特定命名空间是没有意义的,仍然针对集群级别所有命名空间生效。
实践 3:自定义集群角色
- 创建 clusterrole 名称 cluster-pod-deploy-reader,能够查看pod和deployment
- 赋予给 laoma 用户
- laoma 用户在 auth 命名空间中:查看pod、deployment
- laoma 用户在 kube-system 命名空间中:查看pod、deployment
- 删除集群角色绑定和集群角色
更多推荐
所有评论(0)