二十四、K8s集群强化2-授权
K8s管理用户授权
接着上一个K8s认证的笔记:https://blog.csdn.net/tushanpeipei/article/details/121877797?spm=1001.2014.3001.5501
上一笔记中涵盖了K8s认证的相关操作,但是我们也能看到,无论我们使用token或者kubeconfig文件认证成功后,都没有K8s操作的权限。所以,我们需要对于对应的用户进行授权操作,保证他们能够完成权限内的操作。
本章节中将对于授权行实验,准入控制将在后续的笔记中涉及到。
一、授权方式
- AlwaysAllow:允许所有请求(无论管理的用户是否被赋予对应的权限);
- AlwaysDeny:拒绝所有请求(即使用户被赋予了对应的权限,也无法进行任何操作),对本身的管理员无效;
- ABAC:Attribute-Based Access Control 不够灵活放弃(基于属性的控制,非常不灵活,基本已经被放弃,本笔记不涉及);
5.RBAC:Role Based Access Control 基于角色的访问控制(最推荐); - Node:Node授权器主要用于各个worker node上的kubelet访问apiserver时使用的,其他一般均由RBAC授权器来授权;
- Webhook。 部署webhook后端服务器,可以与K8s通过http传输数据。这样的话能够在webhook服务器中更加精确的做授权操作。(在后面的比较中会专门涉及到)
授权方式可以在/etc/kubernetes/manifests/kube-apiserver.yaml文件下进行查看和更改。默认在此文件下的command中设置了:
–authorization-mode=Node,RBAC
也就是启用了RBAC和Node的授权。下面我们来详细看看RBAC和Node授权是怎么实现的。
二、RBAC授权
1.RBAC基础
create、delete、list、watch等权限(具体可以使用命令 kubectl describe clusterrole admin查看资源类型和管理员的权限,也就是所有的权限)是绑定在一个role上,而不同的用户想要获取到这些权限,则需要与对应的role进行绑定。
注意,role和role building是基于Namespace的,当用户通过role binding绑定了这个role,则仅仅能在role所在的Namespace中获取对应的权限,如果在另外一个Namespace中,则没有权限。
如果想要在不同的命名空间中调用同一个role。这时,我们可以将role修改为cluster role。cluster role是全局的,可以通过绑定多个命名空间的role binding实现用户在多个命名空间内都有该cluster role的权限。
如果想直接赋予某个用户所有Namespace都具有相同的权限,可以使用cluster role和 cluster role building来实现。所以,RBAC的实现方式有如下三种:
- role --> role building <— K8s user
- cluster role --> 多个role building <— K8s user
- cluster role --> cluster role building <— K8s user
2.测试1,使用role和role building测试
目标:让testuser拥有default命名空间内对于pod的create、delete、list的权限。目前所在的Namespace为default,后续创建的role和role building都存在于当前的Namespace中。
首先在master上创建一个role的yaml文件(易于后续修改),然后再通过次yaml文件创建对应的role1。
root@vms71:~/authority# kubectl create role role1 --verb=get,delete,list --resource=pod --dry-run=client -o yaml > role1.yaml
root@vms71:~/authority# cat role1.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: role1
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- delete
- list
root@vms71:~/authority# kubectl apply -f role1.yaml
role.rbac.authorization.k8s.io/role1.yaml created
root@vms71:~/authentication# kubectl describe role role1
Name: role1.yaml
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get delete list]
使用rolebinding连接role1和testuser:
root@vms71:~/authority# kubectl create rolebinding rbind1 --role=role1 --user=testuser
rolebinding.rbac.authorization.k8s.io/rbind1 created
然后再使用testuser的kc1文件进行登陆验证:
root@vms71:~/authority# kubectl get pods -n default --kubeconfig=../authentication/kc1
NAME READY STATUS RESTARTS AGE
pod1 1/1 Running 3 (5h56m ago) 2d3h
pod2 1/1 Running 3 (5h56m ago) 2d3h
testpod1 1/1 Running 3 (5h56m ago) 2d1h
root@vms71:~/authority# kubectl get pods -n kube-system --kubeconfig=../authentication/kc1
Error from server (Forbidden): pods is forbidden: User "testuser" cannot list resource "pods" in API group "" in the namespace "kube-system"
可以看到,当我们查看default中的pods时,则可以查看到信息;然后,当查看-n kube-system时则权限不够。同样的,由于我们只赋予了testuser对于pods操作的相关信息,如果想要对deployments、service资源操作,一样会被拒绝:
root@vms71:~/authority# kubectl get deployments -n default --kubeconfig=../authentication/kc1
Error from server (Forbidden): deployments.apps is forbidden: User "testuser" cannot list resource "deployments" in API group "apps" in the namespace "default"
root@vms71:~/authority# kubectl get svc -n default --kubeconfig=../authentication/kc1
Error from server (Forbidden): services is forbidden: User "testuser" cannot list resource "services" in API group "" in the namespace "default"
修改并应用role1的yaml文件,增加对应于services和deployments操作的权限。
root@vms71:~/authority# cat role1.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: role1
rules:
- apiGroups:
- ""
resources:
- pods
- services
verbs:
- get
- delete
- list
- apiGroups:
- "apps"
resources:
- deployments
verbs:
- get
- delete
- list
注意,deployments与 pods和services需要分开写。这是因为pods、services的apiversion=v1,所以父级apiGroups为空。而deployments的apiversion=apps/v1,所以父级apiGroups为apps。
更改role之后,再对deployments、service资源操作时,则可以实现:
root@vms71:~/authority# kubectl get deployments -n default --kubeconfig=../authentication/kc1
No resources found in default namespace.
root@vms71:~/authority# kubectl get svc -n default --kubeconfig=../authentication/kc1
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12d
svc1 LoadBalancer 10.103.222.93 192.168.26.240 80:31604/TCP 44h
svc2 LoadBalancer 10.98.110.109 192.168.26.241 80:31459/TCP 44h
2.测试2,使用cluster role和role building测试
在删除第一步测试的role和role building后,创建一个cluster role,同样是对pods有list、get、delete权限。
root@vms71:~/authority# kubectl create clusterrole clusterrole1 --verb=get,delete,list --resource=pod --dry-run=client -o yaml > clusterrole1.yaml
root@vms71:~/authority# kubectl apply -f clusterrole1.yaml
clusterrole.rbac.authorization.k8s.io/clusterrole1 created
分别在default和kube-system这两个Namespace中创建role building,绑定k8s用户testuser:
root@vms71:~/authority# kubectl create rolebinding rbind1 --clusterrole=clusterrole1--user=testuser
root@vms71:~/authority# kubens kube-system
Context "kubernetes-admin@kubernetes" modified.
Active namespace is "kube-system".
root@vms71:~/authority# kubectl create rolebinding rbind2 --clusterrole=clusterrole1--user=testuser
然后继续在master上使用testuser查看default和kube-system下的pod信息,发现可以正常查看:
root@vms71:~/authority# kubectl get pods -n kube-system --kubeconfig=../authentication/kc1
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-78d6f96c7b-pdf9d 1/1 Running 7 (8h ago) 12d
calico-node-g52b9 1/1 Running 6 (8h ago) 12d
calico-node-j6wgm 1/1 Running 5 (8h ago) 12d
calico-node-pmn6t 1/1 Running 5 (8h ago) 12d
coredns-7f6cbbb7b8-cl4nw 1/1 Running 5 (8h ago) 12d
coredns-7f6cbbb7b8-pvnw6 1/1 Running 5 (8h ago) 12d
etcd-vms71.rhce.cc 1/1 Running 6 (8h ago) 12d
kube-apiserver-vms71.rhce.cc 1/1 Running 1 (8h ago) 9h
kube-controller-manager-vms71.rhce.cc 1/1 Running 13 (48m ago) 12d
kube-proxy-476jg 1/1 Running 5 (8h ago) 12d
kube-proxy-l8jhq 1/1 Running 6 (8h ago) 12d
kube-proxy-v6cdb 1/1 Running 5 (8h ago) 12d
kube-scheduler-vms71.rhce.cc 1/1 Running 14 (48m ago) 12d
root@vms71:~/authority# kubectl get pods -n default --kubeconfig=../authentication/kc1
NAME READY STATUS RESTARTS AGE
pod1 1/1 Running 3 (8h ago) 2d6h
pod2 1/1 Running 3 (8h ago) 2d6h
testpod1 1/1 Running 3 (8h ago) 2d3h
3.测试3,使用cluster role和clusterrolebinding测试
删除掉rbind1和rbind2,重新创建clusterrolebind:
root@vms71:~/authority# kubectl create clusterrolebinding crbind1 --clusterrole=clusterrole1 --user=testuser
clusterrolebinding.rbac.authorization.k8s.io/crbind1 created
目前,使用testuser可以在任意的Namespace中查看pod的信息:
root@vms71:~/authority# kubectl get pods --kubeconfig=../authentication/kc1 -n cert-manager
NAME READY STATUS RESTARTS AGE
cert-manager-7c6f78c46d-gdc5k 1/1 Running 5 (8h ago) 11d
cert-manager-cainjector-668d9c86df-k4jnk 1/1 Running 19 (55m ago) 11d
cert-manager-webhook-764b556954-c64tk 1/1 Running 5 (8h ago) 11d
root@vms71:~/authority# kubectl get pods --kubeconfig=../authentication/kc1 -n testns
NAME READY STATUS RESTARTS AGE
testpod2 1/1 Running 3 (8h ago) 2d3h
root@vms71:~/authority# kubectl get pods --kubeconfig=../authentication/kc1 -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-78d6f96c7b-pdf9d 1/1 Running 7 (8h ago) 12d
calico-node-g52b9 1/1 Running 6 (8h ago) 12d
calico-node-j6wgm 1/1 Running 5 (8h ago) 12d
calico-node-pmn6t 1/1 Running 5 (8h ago) 12d
coredns-7f6cbbb7b8-cl4nw 1/1 Running 5 (8h ago) 12d
coredns-7f6cbbb7b8-pvnw6 1/1 Running 5 (8h ago) 12d
etcd-vms71.rhce.cc 1/1 Running 6 (8h ago) 12d
kube-apiserver-vms71.rhce.cc 1/1 Running 1 (8h ago) 9h
kube-controller-manager-vms71.rhce.cc 1/1 Running 13 (56m ago) 12d
kube-proxy-476jg 1/1 Running 5 (8h ago) 12d
kube-proxy-l8jhq 1/1 Running 6 (8h ago) 12d
kube-proxy-v6cdb 1/1 Running 5 (8h ago) 12d
kube-scheduler-vms71.rhce.cc 1/1 Running 14 (56m ago) 12d
三、对SA授权
RBAC分为2种账户:
- user account 用户账号(UA):用于远程登陆系统,也就是我们在刚刚实验所使用的账号
- service account 服务账户(SA):Service account是为了方便Pod里面的进程(而非人工)调用Kubernetes API或其他外部服务而设计的。例如使用web来管理k8s环境时,需要调用相关的程序(pod中)有对K8s管理,当时此程序需要有相关的权限,这时候就可以创建一个SA,赋予相关的权限,并且与管理K8s的环境程序进行绑定,那么这个程序就有了SA的对应权限,可以对K8s进行管理。
首先我们需要创建一个SA:
root@vms71:~/authority# kubectl create sa sa1
serviceaccount/sa1 created
每创建一个sa,就会创建一个secret,名称为sa名-token-xxxx。而每个secret中有一个token:
root@vms71:~/authority# kubectl get secrets | grep sa1
sa1-token-pnrmf kubernetes.io/service-account-token 3 39s
root@vms71:~/authority# kubectl describe secrets sa1-token-pnrmf
Name: sa1-token-pnrmf
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: sa1
kubernetes.io/service-account.uid: bb4b5b84-5499-4c37-98b8-52bfc3ed6ca3
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1099 bytes
namespace: 7 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IkhEUXVaUEVObi1ubmZxV1NFTk5PdUMwZThubHZPZDZXUEtJWmJMOXFGN1kifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InNhMS10b2tlbi1wbnJtZiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJzYTEiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJiYjRiNWI4NC01NDk5LTRjMzctOThiOC01MmJmYzNlZDZjYTMiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpzYTEifQ.AT5MEmvjYU-I48JES63U8xG2Gs3zSFNSxdQQGAa5Ny6f_sm_rBZFdiV3ghK7E2r6ANRG43U4dJikfL3PATGugXNP7AslTw6LPDR6E001j8P3GXv1MDDfD5QglaOsbyqGglPwB_adRJbiqycrsGozyepCdspuJfcRnbNjP9zat6EkAaXsrUZ9Bk4IyoOWtTAKG2P6vG4ol36sObaOJMmW-4qlYphmrO-1ZNb0coz_y050J4bO3Y-LGqZwCDxCO4YGROwiecjbJoEPJbC0r1W7P-qHRP9_p7KYYg8lf98VBJQM28y-4ejMz2RZ2q5Zz9Y5sRBCAZ6lVf9GYVocyflIhg
当我们给SA授权时,其实也就是在跟其token授权。当我们创建pod时,绑定授权了的SA,其实也就是把token挂在了pod里面的/run/secrets/kubernetes.io/serviceaccount目录里面,也就有了对应token的权限。
给SA授权的语法如下:
kubectl create clusterrolebinding(绑定方式) sabind1(绑定名) --clusterrole=cluster-admin(角色名) --serviceaccount=security:sa1(命名空间:sa名)
例如我们在这里授权cluster-admin(K8s自带,拥有所有权限)的权限给sa1:
root@vms71:~/authority# kubectl create clusterrolebinding sabind1 --clusterrole=cluster-admin --serviceaccount=default:sa1
clusterrolebinding.rbac.authorization.k8s.io/sabind1 created
注意,如果一个pod没有手动添加SA,则默认使用的是default这个SA。当然也就是挂在了default sa的token。
root@vms71:~/authority# kubectl get sa
NAME SECRETS AGE
default 1 12d
sa1 1 13m
现在,我们来创建一个pod,并且使用sa1作为SA。yaml文件如下:
root@vms71:~/authority# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: podsa
name: podsa
spec:
terminationGracePeriodSeconds: 0
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: podsa
resources: {}
serviceAccount: sa1
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
进入podsa后,查看/run/secrets/kubernetes.io/serviceaccount目录:
root@podsa:/# root@podsa:/# ls /run/secrets/kubernetes.io/serviceaccount
ca.crt namespace token
其中,ca.crt为集群ca的证书;namespace记录了pod所在的Namespace;token则是sa1对应的token值。
root@podsa:/run/secrets/kubernetes.io/serviceaccount# cat token
eyJhbGciOiJSUzI1NiIsImtpZCI6IkhEUXVaUEVObi1ubmZxV1NFTk5PdUMwZThubHZPZDZXUEtJWmJ MOXFGN1kifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9 jYWwiXSwiZXhwIjoxNjcwODc5NzI1LCJpYXQiOjE2MzkzNDM3MjUsImlzcyI6Imh0dHBzOi8va3ViZX JuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY 2UiOiJkZWZhdWx0IiwicG9kIjp7Im5hbWUiOiJwb2RzYSIsInVpZCI6ImMzZTRkOTM5LWUyODctNDUy ZS05MTU5LWU3Y2Y3ZDUyOTNmNCJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoic2ExIiwidWlkIjo iYmI0YjViODQtNTQ5OS00YzM3LTk4YjgtNTJiZmMzZWQ2Y2EzIn0sIndhcm5hZnRlciI6MTYzOTM0Nz MzMn0sIm5iZiI6MTYzOTM0MzcyNSwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6c 2ExIn0.3n9Ke1WPqPB2X-q-90ZmgnMn4OPyoJ9Vz5-CrOeNw74V-HkAtfRTyhTqOrgPeK8iXe9frQ9J 8d2-62BYD1o9WVGbnrnooNlg5hI8ALz-1LRxhsIVDgY5h_VBR0RLcoM6vW2_0VcT9XU8QGDfogCPub9 Vly_dC8hzyr-p--s_EmBbOnmqdOIVvm-nGU9w_3KpYP_l9IkpRT6XRzeWiwmOzEW2Wx0VAd-x3D0E-c 23us1GJaQG46rLdqAHpqa4V4gMdem6DmDLPmNOMHOOjYQ-x4RkJtTxDA2CCgAX2WT33wCqRBzP9r9oF h1H-5ZPXKtbk4zyqa7UeFJ8Cc7STxI5Fg
接下来,我们在pod内对访问k8s的资源,首先先设置几个环境变量:
root@podsa:/run/secrets/kubernetes.io/serviceaccount# CA_CERT=ca.crt
root@podsa:/run/secrets/kubernetes.io/serviceaccount# TOKEN=$(cat token)
root@podsa:/run/secrets/kubernetes.io/serviceaccount# NAMESPACE=$(cat namespace)
使用如下命令访问k8s资源,查看是否能够访问成功:
curl --cacert $CA_CERT -H "Authorization: Bearer $TOKEN" "https://kubernetes.default/api/v1/namespaces/$NAMESPACE/services/"
curl --cacert $CA_CERT -H "Authorization: Bearer $TOKN" "https://192.168.26.71:6443/api/v1/namespaces/$NAMESPACE/services/"
由于本次实验中使用的是cluster-admin这个角色的权限,所以可以访问成功。也可以在master上直接使用如下命令进行测试:
root@vms71:~/authority# kubectl --as=system:serviceaccount:default:sa1 auth can-i get svc
yes
此命令使用了sa1这个账号验证师傅能够获取svc信息,返回的结果是yes。
需要注意的是,在实际环境中,我们不能给一个pod如此大的权限的SA,如果pod中存在恶意代码,又拥有对应的操作权限,会危及到我们整个K8s集群环境。同时如果没有什么特别的操作,可以不用在pod中挂载SA。有两个实现方式:
- 在创建pod时,在spec下设置automountServiceAccountToken值为false,这个值默认为ture。
- 在创建SAt时,在在外层添加automountServiceAccountToken值为false。
设置了如上两个方式的任何一个方式,就算是在pod中挂载了
四、Node认证方式
Node权限是Worker向Master的API发送各种查询请求(例如在Worker上使用kubelet)所需要的权限。
想要启用Node授权,先要在/etc/kubernetes/manifests/kube-apiserver.yaml中的command下设置如同两条语句。启用认证模式为Node,并开启准入控制器。
- --authorization-mode=Node
- --enable-admission-plugins=NodeRestriction
整理资料来源:
《老段CKS课程》
更多推荐
所有评论(0)