访问控制介绍
k8s作为一个集群管理系统,保证集群的安全性是非常重要的,所谓的安全性其实就是对k8s的各种客户端的访问进行认证和鉴权。k8s对于访问 API 提供了三个步骤的安全措施:身份认证、权限鉴别、准入控制。
k8s用户分类
认证解决的问题是识别用户的身份,那k8s中都有几种用户?
集群用户:可以理解为人通过kubectl访问API的用户,此类用户嵌入在客户端的证书中。
ServiceAccount(服务账户): 指在k8s集群中的Pod要访问API时所使用的身份。
创建集群用户方式
案例:在集群中创建一个名称为devuser的集群用户,需要先准备用户所需的证书
#生成证书签名请求文件
tee devuser.csr <<EOF
{
"CN": "devuser",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "devuser",
"OU": "user"
}
]
}
EOF使用现有的CA证书及其私钥 ,对devuser.csr 证书签名请求文件进行签署,生成一个新的https证书和对应的私钥
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes devuser.csr | cfssljson -bare devuser生成devuser账号
kubectl config set-credentials devuser --client-certificate=./devuser.pem --client-key=./devuser-key.pem --embed-certs=true
#说明:
--embed-certs=true //将证书数据嵌入到$HOME/.kube/config文件中,这样即使证书文件移动或删除,kube.config文件仍然有效配置devuser账号安全上下文,将集群、用户关联起来
kubectl config set-context devuser@kubernetes --cluster=kubernetes --user=devuser查看集群上下文信息 * 表示当前所处的用户上下文环境
# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
devuser@kubernetes kubernetes devuser
* kubernetes kubernetes admin通过上下文名称切换到devuser用户
kubectl config use-context devuser@kubernetes查看上下文信息
kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* devuser@kubernetes kubernetes devuser
kubernetes kubernetes admin使用devuser用户查看test空间下的Pod
kubectl get po -n test
Error from server (Forbidden): pods is forbidden: User "devuser" cannot list resource "pods" in API group "" in the namespace "test"
#提示:禁止devuser用户列出test下API组中的pods资源切换身份到管理员
kubectl config use-context kubernetes-admin@kubernetes
kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
devuser@kubernetes kubernetes devuser
* kubernetes kubernetes admin Service Account
认证:在 k8s中,Service Account 是一种用于身份验证和授权的机制。它提供了一种方式,使容器内的应用程序可以与集群进行交互,并使用 API 进行操作。
授权:Service Account 可以与k8s的访问控制机制(RBAC)结合使用,以控制应用程序对集群资源的访问权限。通过为 Service Account 分配适当的角色和权限,可以限制程序的操作范围。
创建Service Account
Service Account是面向名称空间的资源,每创建一个名称空间,k8s会自动在这个空间下创建一个名为default的Service Account,使容器内的应用程序可以与集群进行交互
#查看Service Account
kubectl get sa -n test#创建Service Account方式
tee cicd-token.yml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: cicd-token
namespace: test
EOF权限控制RBAC
RBAC(Role-Based Access Control)基于角色访问控制:是一种权限控制机制,用于管理用户、组、服务账户对集群资源的访问和操作权限。确保只有经过授权的实体可以执行特定的操作,并限制其对资源的访问范围。
参考地址:https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/rbac/
本环境已经开启RBAC、Node访问控制功能,可通过kube-apiserver.conf文件查看
grep 'authorization-mode' /etc/kubernetes/kube-apiserver.conf
...
--authorization-mode=Node,RBAC \Node是节点鉴权器,作用是允许 kubelet 对API 执行读取和写入操作。
在RBAC中,有三个核心概念:对象、角色和权限绑定。它们用于定义用户、组和服务账户的访问和操作权限。
对象:可以是集群用户或组(User、Groups)或 Service Account 服务账号。
角色(Role、ClustserRole):角色定义了一组权限, 用于管理集群中特定资源。
权限绑定(RoleBinding、ClusterRoleBinding):权限绑定将角色与用户、组或服务账户关联起来,以授予它们相应的权限。
创建Role方式
Role(角色)一个角色就是一组权限,Role只能在单个名称空间内使用,创建Role需要指定空间
案例:创建一个名为devuser-role的角色,并具备查看test空间的Pod、deploy资源权限
命令帮助:kubectl create role -h
#命令方式创建(查看需要get,list,watch三个权限才可以)
kubectl create role devuser-role --verb=get,list,watch --resource=pod,deploy -n test
#查看Role信息
kubectl get role -n test
#查看Role详细信息
kubectl describe role devuser-role -n test#yaml文件方式创建
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: devuser-role #Role名称
namespace: test #名称空间
rules:
- apiGroups: #支持核心API组
- ""
resources: #支持的资源列表
- pods
verbs: #允许对资源执行的操作
- get
- list
- watch
- apiGroups:
- apps
resources:
- deployments
verbs:
- get
- list
- watch resources:支持的资源对象列表(命令行创建时可以使用资源名称的缩写,yaml文件不支持缩写)
"services","endpoints","pods","secrets","configmaps","crontabs","deployments","jobs","nodes","rolebindings","clusterroles","daemonsets","replicasets","statefulsets","horizontalpodautoscalers","replicationcontrollers","cronjobs"verbs:对资源对象的操作方法列表
"get","list","watch","create","update","patch","delete","exec"创建RoleBinding方式
RoleBinding(角色绑定) 将 Role 授予用户、组或服务账户,并将其绑定到特定的命名空间内。
案例:创建一个名为devuser-rolebinding的RoleBinding,将devuser-role角色绑定给devuser用户
命令帮助:kubectl create rolebinding -h
kubectl create rolebinding devuser-rolebinding --role=devuser-role --user=devuser -n test#查看RoleBinding信息
kubectl get rolebinding -n test
#查看RoleBinding详细信息
kubectl describe rolebinding devuser-rolebinding -n test#yaml文件方式创建
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: devuser-rolebinding #名称自定义
namespace: test #须指定名称空间
subjects: #定义目标对象
- kind: User #对象类型(User、Groups)
name: devuser #对象名称(提前创建好)
apiGroup: rbac.authorization.k8s.io
roleRef: #指向的角色
kind: Role #角色类型(Role、ClustserRole)
name: devuser-role #角色名称(提前创建好)
apiGroup: rbac.authorization.k8s.io切换devuser用户验证权限
#查看上下文信息
kubectl config get-contexts
#通过上下文名称切换到devuser用户
kubectl config use-context devuser@kubernetes
#验证权限
kubectl get pod,deploy -n test
#查看其他空间下资源
kubectl get pod,deploy -n kube-system#切换回管理员账号
kubectl config use-context kubernetes创建ClusterRole方式
ClusterRole(集群角色)一个集群角色就是一组权限,对比于Role,ClusteRole可以跨命名空间使用,创建ClusteRole不需要指定名称空间(指定也无效)。
案例:创建一个名为devuser-clusterrole的集群角色,并具备查看所有空间的Pod、deploy资源权限
命令帮助:kubectl create clusterrole -h
kubectl create clusterrole devuser-clusterrole \
--verb=get,list,watch \
--resource=pod,deploy#查看所有集群角色,k8s中内置了很多的ClusterRole为集群系统使用,其中集群管理员角色cluster-admin
kubectl get clusterrole
#查看devuser-clusterrole
kubectl get clusterrole | grep devuser-clusterrole
#查看devuser-clusterrole详细信息
kubectl describe clusterrole devuser-clusterrole#yaml文件方式创建
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: devuser-clusterrole
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
- apiGroups:
- apps
resources:
- deployments
verbs:
- get
- list
- watch创建ClusterRoleBinding方式
ClusterRoleBinding 将 ClusterRole 授予用户、组或服务账户,并在整个集群范围内绑定。
案例:创建一个名为devuser-clusterrolebinding的ClusterRoleBinding,将devuser-clusterrole绑定给devuser用户
命令帮助:kubectl create clusterrolebinding -h
kubectl create clusterrolebinding devuser-clusterrolebinding \
--clusterrole=devuser-clusterrole \
--user=devuser#查看所有集群角色绑定
kubectl get clusterrolebinding
#查看devuser-clusterrolebinding
kubectl get clusterrolebinding | grep devuser-clusterrolebinding
#查看devuser-clusterrolebinding详细信息
kubectl describe clusterrolebinding devuser-clusterrolebinding#yaml文件创建方式
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: clusterrole-rolebinding
roleRef: #指向的角色
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole #角色类型
name: devuser-clusterrole #角色名称(提前创建好)
subjects: #定义对象
- kind: User #对象类型
name: devuser #用户名称切换devuser用户验证权限
#查看上下文信息
kubectl config get-contexts
#通过上下文名称切换到devuser用户
kubectl config use-context devuser@kubernetes
#验证权限
kubectl get pod,deploy -n test
#查看其他空间下资源
kubectl get pod,deploy -n kube-system#切换回管理员账号
kubectl config use-context kubernetes一种很常用的做法是,集群管理员为集群范围预定义好一个ClusterRole,然后通过RoleBinding在多个命名空间中重复使用这个ClusterRole,同一个ClusterRole只能读取某一个空间内的资源
案例:通过RoleBinding将devuser-clusterrole集群角色与devuser用户绑定,并限制devuser用户只能访问test和kube-system空间Pod、deploy资源。
#删除前边为devuser用户设置的Rolebinding与ClusterRoleBinding
kubectl delete rolebinding devuser-rolebinding -n test
kubectl delete clusterrolebinding devuser-clusterrolebinding#在test空间创建一个名为devuser-test的RoleBinding,将devuser-clusterrole集群角色与devuser用户绑定
kubectl create rolebinding devuser-test \
--clusterrole=devuser-clusterrole \
--user=devuser -n test
#查看RoleBinding
kubectl get rolebinding -n test
#查看RoleBinding详细信息
kubectl describe rolebinding devuser-test -n test#在kube-system空间创建一个名为devuser-kubesystem的RoleBinding,将devuser-clusterrole集群角色与devuser用户绑定
kubectl create rolebinding devuser-kubesystem \
--clusterrole=devuser-clusterrole \
--user=devuser -n kube-system
#查看RoleBinding
kubectl get rolebinding -n kube-system
#查看RoleBinding详细信息
kubectl describe rolebinding devuser-kubesystem -n kube-system切换devuser用户验证权限
#查看上下文信息
kubectl config get-contexts
#通过上下文名称切换到devuser用户
kubectl config use-context devuser@kubernetes
#验证权限
kubectl get pod,deploy -n test
#查看kube-system空间下资源
kubectl get pod,deploy -n kube-system
#查看default空间下资源
kubectl get pod,deploy#切换回管理员账号
kubectl config use-context kubernetesService Account绑定
案例:创建一个名为deployment-clusterrole的ClusterRole,并设置对Deployment、StatefulSet、DaemonSet资源具备创建权限,在test空间创建一个名为cicd-token-rolebinding的RoleBinding,并将deployment-clusterrole角色绑定到test空间的cicd-token(Service Account)上。
#创建名为deployment-clusterrole的ClusterRole,并设置对Deployment、StatefulSet、DaemonSet资源具备创建权限
kubectl create clusterrole deployment-clusterrole --verb=create --resource=deploy,sts,ds#在test空间创建一个名为cicd-token-rolebinding的RoleBinding,并将deployment-clusterrole角色绑定到test空间的cicd-token(Service Account)上
kubectl create rolebinding cicd-token-rolebinding --clusterrole=deployment-clusterrole --serviceaccount=test:cicd-token -n test创建Pod并使用Service Account
# cat nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-nginx
namespace: test
spec:
replicas: 1
selector:
matchLabels:
app: web-nginx
template:
metadata:
labels:
app: web-nginx
spec:
containers:
- name: nginx
image: nginx:1.20.1
ports:
- containerPort: 80
serviceAccountName: cicd-token #指定Pod使用的Service Account总结:认证解决的是识别用户的身份,鉴权解决用户有哪些权限。
评论区