用户通过kubectl、客户端库或者通过发送REST请求访问API。用户和Kubernetes服务账户都可以被授权进行API访问。k8s API服务器在接收到请求后,整体的处理流程如下:
各阶段包含的资源如下:
Authentication(认证)
认证方式现在共有8种,可以启用一种或多种认证方式,只要有一种认证方式通过,就不再进行其他方式的认证。通常启用X509 Client Certs和Service Account Tokens两种认证方式。
Authorization(授权)
通过认证后,才会进行授权,根据所有授权策略匹配请求资源属性,决定允许或拒绝请求。授权的方式一共有6中。默认集群强制开启RBAC授权:
- AlwaysAllow:一直允许AlwaysDeny:一直拒绝ABAC:基于属性的访问控制,定义了一种访问控制泛型,通过使用将属性组组合在一起的策略,将访问权限授予用户。策略可以使用任何类型的属性(用户属性、资源属性、对象、环境属性等)RBAC:基于角色的访问控制,是一种基于企业内个人用户的角色来管理对计算机或网络资源访问的方法。在RABC中,权限是翻个用户执行特定任务的能力,例如查看、创建或修改文件等Webhook:是一个HTTP回调。发生某些事情时调用的HTTP POST;通过HTTP POST进行简单的时间通知。实现Webhook的Web应用程序会在发生某些事情时,将消息发布到URLNode:一个专用鉴权组件,根据调度到kubelet上运行的Pod为kubelet授予权限
Admission Control(准入控制)
2、请求Kubernetes API Server的客户端
kubectl:本文配置下,用户的根目录(/home/sa-test-user/.kube)下的config文件中,保存了客户端访问API Server的密钥相关信息,当使用kubectl访问k8s时,kubectl会自动读取读取该配置,并向API Server发起认证请求,通过后完成操作请求
pod:Pod中的进程需要访问API Server,如果是用户去访问或编写的脚本去访问,这类访问使用UserAccount;而当Pod自身去连接API Server时,这类访问将使用ServiceAccount
kubectl向apiserver发起的命令,采用的是http的方式,本质就是通过URL发起对资源的增删改查等操作:
# 映射到本地端口
kubectl proxy --port=8080
# 重新开启一个会话
curl http://localhost:8080/api/v1/namespaces/default
{
"kind": "Namespace",
"apiVersion": "v1",
"metadata": {
"name": "default",
"uid": "ba8fffd9-8752-4ee9-bbb0-403c532d21d8",
"resourceVersion": "199",
"creationTimestamp": "2022-02-28T09:23:48Z",
"managedFields": [
{
"manager": "kube-apiserver",
"operation": "Update",
"apiVersion": "v1",
"time": "2022-02-28T09:23:48Z",
"fieldsType": "FieldsV1",
"fieldsV1": {"f:status":{"f:phase":{}}}
}
]
},
"spec": {
"finalizers": [
"kubernetes"
]
},
"status": {
"phase": "Active"
}
}
curl http://localhost:8080/apis/apps/v1/namespaces/default/deployments
{
"kind": "DeploymentList",
"apiVersion": "apps/v1",
"metadata": {
"resourceVersion": "354693"
},
"items": []
}
以上两种API的区别是:
api:是一种特殊连接,只有在核心v1群组中的对象才能使用apis:是一般API访问的入口 3、RBAC(Role-based Access Control)鉴权
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zUvdUqVr-1646455475200)(D:学习总结sourcesRBAC关系.png)]
相对于基于属性的访问控制ABAC,RABC主要是引用了角色(Role)和角色绑定(Role Binding)的抽象概念。在ABAC中,k8s集群中的访问策略只能跟用户之间关联,而在RABC中,访问策略可以跟某个角色关联,具体的用户再跟某一个或多个角色关联。
3.1 RABC优势权限管理和控制覆盖了集群中所有的资源和非资源RABC使用rabc.authorization.k8s.ioAPI组来驱动鉴权决策,同其余的API对象一样,管理员可以通过kubectl或API进行操作可以在集群运行过程中,动态地对角色进行配置,不需要重新启动API Server如果集群使用RABC的鉴权模式,则只需要在启动kube-apiserver时,在启动参数中的authorization-mode添加RABC选项即可,如果开启多个鉴权模式,则用逗号间隔即可,eg:--authorization-mode=RABC,Node 3.2 UserAccount和ServiceAccount
User Account(用户账号):指独立于Kubernetes之外的其他服务管理的用户账号。Kubernetes不存在表示这类账户的对象,所以用户账号不能像服务账号那样,可以直接添加到Kubernetes系统中。Service Account(服务账号):指通过Kubernetes API管理的账号,主要用于为Pod之间的服务进程在访问Kubernetes API时提供身份标识。Service Account通常是需要绑定在一个命名空间上,通过Kubernetes API调用手动创建,并附带一组存储Secret的用于访问API Server的凭据。
区别:
用户账户是针对人而言的。 服务账户是针对运行在 pod 中的进程而言的用户账户是全局性的。 其名称在集群各 namespace 中都是全局唯一的,未来的用户资源不会做 namespace 隔离, 服务账户是 namespace 隔离的通常情况下,集群的用户账户可能会从企业数据库进行同步,其创建需要特殊权限,并且涉及到复杂的业务流程。 服务账户创建的目的是为了更轻量,允许集群用户为了具体的任务创建服务账户 ( 即权限最小化原则 ) 3.3 创建服务账号(Service Account)
# 1、创建命名空间 kubectl create ns sa-test kubectl get ns NAME STATUS AGE default Active 3d22h kube-node-lease Active 3d22h kube-public Active 3d22h kube-system Active 3d22h sa-test Active 47s # 新创建的namespace # 2、查看sa kubectl get sa -n sa-test NAME SECRETS AGE default 1 36s # k8s默认创建了一个default的sa # 3、查看秘钥 kubectl describe sa default -n sa-test Name: default Namespace: sa-test Labels:Annotations: Image pull secrets: Mountable secrets: default-token-z8dvz Tokens: default-token-z8dvz Events: kubectl get secret -n sa-test NAME TYPE DATA AGE default-token-z8dvz kubernetes.io/service-account-token 3 4m13s ## 可以看到,创建了ns后,k8s默认创建了一个default的sa,同时为这个sa创建了一个类型为kubernetes.io/service-account-token的秘钥 # 4、创建一个在sa-test namespace下的pod cat > sa-test-pod.yaml << EOF apiVersion: v1 kind: Pod metadata: name: sa-test-pod namespace: sa-test spec: containers: - name: sa-test-pod image: nginx imagePullPolicy: IfNotPresent ports: - containerPort: 80 EOF # 5、 创建 kubectl apply -f sa-test-pods.yaml pod/sa-test-pod created # 6、查看 kubectl describe pod sa-test -n sa-test ... Volumes: default-token-mb5pj: Type: Secret (a volume populated by a Secret) SecretName: default-token-mb5pj # 新增的pod,如果未指定sa,则默认挂载在default下面,对应的秘钥会自动挂载在Pod的/var/run/secrets/kubernetes.io/serviceaccount/目录中 Optional: false ...
# 1、创建sa kubectl create sa sa-test-account -n sa-test # 2、查看sa基本信息 kubectl describe sa sa-test-account -n sa-test Name: sa-test-account Namespace: sa-test Labels:3.4 创建用户账号(UserAccount) 3.4.1 创建系统用户Annotations: Image pull secrets: Mountable secrets: sa-test-account-token-9p5qx Tokens: sa-test-account-token-9p5qx Events: # 3、查看sa的秘钥 kubectl get secret -n sa-test NAME TYPE DATA AGE default-token-mb5pj kubernetes.io/service-account-token 3 9h sa-test-account-token-9p5qx kubernetes.io/service-account-token 3 8h ## 可以看到,新生成了一个sa-test-account的token # 4、获取秘钥 (可以通过该token在dashboard上免密登陆) kubectl describe secrets -n sa-test $(kubectl -n sa-test get secret | awk '/sa-test/{print $1}') Name: sa-test-account-token-wk785 Namespace: sa-test Labels: Annotations: kubernetes.io/service-account.name: sa-test-account kubernetes.io/service-account.uid: 24f4d8e3-07a5-4200-9930-c94ac6f2e385 Type: kubernetes.io/service-account-token Data ==== ca.crt: 1359 bytes namespace: 7 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ink0U2dyR1B5M3NZaHR6ZHBnNm5jRzN4YUx5aTNkcDR2S2ZCTUcxVmVtODAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJzYS10ZXN0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InNhLXRlc3QtYWNjb3VudC10b2tlbi13azc4NSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJzYS10ZXN0LWFjY291bnQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIyNGY0ZDhlMy0wN2E1LTQyMDAtOTkzMC1jOTRhYzZmMmUzODUiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6c2EtdGVzdDpzYS10ZXN0LWFjY291bnQifQ.ixgTxU_CMQwfZKDue9kPHa50KubsXxC72zSdH8gO0OGqRkmXjYMZBwPxOyXrI1gcLEWWpA_j-m35823rH5vHBC943qa3ExUDJsZmReAGB2qc7c8_iNjsjf23be9hzhoIxInv5s4-XHVh4sXct3ouMbj5JIeDXduc0kfDj3BXX9cxBwYXIKVSaxFqYkc_Gk1UaGa5ajxRBduZSmn3vuX_E33iOHxhMXKRw53vFWqu4ktVyvTlLRJpO6KtTlzvVyzmmvECpevLODc_L4Ql9V3x_KJJ7fwduPDy8X_AOD3YLdeqf1WolBLT5iHrccLubY8clIEraYqg1T6FosQD-gLUUw ## 获取秘钥的另外一种方式是登陆到对应的namespace下的pod kubectl exec -it sa-test-pod -n sa-test -- /bin/bash ## 进入目录 cd /var/run/secrets/kubernetes.io/serviceaccount ls -al total 0 drwxrwxrwt. 3 root root 140 Mar 3 03:52 . drwxr-xr-x. 3 root root 28 Mar 3 03:52 .. drwxr-xr-x. 2 root root 100 Mar 3 03:52 ..2022_03_03_03_52_36.651932225 lrwxrwxrwx. 1 root root 31 Mar 3 03:52 ..data -> ..2022_03_03_03_52_36.651932225 lrwxrwxrwx. 1 root root 13 Mar 3 03:52 ca.crt -> ..data/ca.crt lrwxrwxrwx. 1 root root 16 Mar 3 03:52 namespace -> ..data/namespace lrwxrwxrwx. 1 root root 12 Mar 3 03:52 token -> ..data/token ## 此处的token就是之前shell命令拿到的那个token
# 1、创建,root用户下进行 useradd sa-test-user # 2、转换用户,root用户下进行 su - sa-test-user # 访问k8s集群,sa-test-user用户下进行 kubectl get pod The connection to the server localhost:8080 was refused - did you specify the right host or port? ## 默认肯定是访问不到的,原因有两个: ## 1、如果需要访问,需要给当前用户账号创建访问证书 ## 2、在访问证书创建完成后,还需要给当前用户分配访问权限(通过role、RoleBinding)3.4.2 创建访问证书
# 退出当前用户,返回root用户,以下操作都在root用户下进行
exit
# 这里还是采用cfssl工具进行证书签订,根证书及工具cfssl都需要沿用k8s集群的根证书和工具
# 1、创建并进入证书工作路径
mkdir -p /usr/local/sa-test-user-cert/ & cd /usr/local/sa-test-user-cert/
# 2、创建CA证书签名请求JSON文件
cat > sa-test-user-csr.json << EOF
{
"CN": "sa-test-user",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"O": "Ctyun",
"ST": "BeiJing",
"OU": "System"
}
]
}
EOF
# 3、创建访问证书工作路径
mkdir -p /etc/kubernetes/pki & cd /etc/kubernetes/pki
# 4、复制k8s集群创建时的根证书ca.pem、ca-key.pem到当前路径
cp ~/TLS/k8s/k8s/ca.pem ~/TLS/k8s/k8s/ca-key.pem ./
## 此处用的是cfssl默认的配置文件生成的根证书,如丢失,需要重新生成,但是必须保证和k8s集群创建时的根证书一致
# 5、生成sa-test-user的访问证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -profile=kubernetes /usr/local/sa-test-user/sa-test-user-csr.json | cfssljson -bare sa-test-user
## 创建成功,当前目录下多出sa-test-user-key.pem、sa-test-user.pem和sa-test-user.csr文件
3.4.3 创建部署配置文件
# 1、更换路径
cd /usr/local/sa-test-user-cert
# 2、设置api-server的环境变量
export KUBE_APISERVER="https://172.16.160.102:6443"
# 3、创建kubeconfig文件
kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.pem --embed-certs=true --server=${KUBE_APISERVER} --kubeconfig=sa-test-user.kubeconfig
## 创建成功后,会生成sa-test-user-csr.json、sa-test-user.kubeconfig两个文件
# 4、设置客户端参数,绑定用户信息到kubeconfig中
kubectl config set-credentials sa-test-user --client-certificate=/etc/kubernetes/pki/sa-test-user.pem --client-key=/etc/kubernetes/pki/sa-test-user-key.pem --embed-certs=true --kubeconfig=sa-test-user.kubeconfig
# 5、设置上下文参数
kubectl config set-context kubernetes --cluster=kubernetes --user=sa-test-user --namespace=sa-test --kubeconfig=sa-test-user.kubeconfig
# 6、将kubeconfig文件复制到sa-test-user用户的家目录的.kube目录下
mkdir -p /home/sa-test-user/.kube
cp sa-test-user.kubeconfig /home/sa-test-user/.kube/config
# 7、修改文件所有者
chown -R sa-test-user.sa-test-user .kube/
# 8、切换用户
su - sa-test-user
# 9、指定当前用户的kubeconfig切换副本
cd .kube
kubectl config use-context kubernetes --kubeconfig=config
3.5 用户组
3.6 角色(Role)
Role其实是包含了一组相关权限的规则。其中,这些规则是纯粹累加的,不存在拒绝某操作的规则。(即只有正向权限)创建Role时,必须指定该 Role 所属的namespace
可以配置一个角色,授予对给定命名空间的只读访问权限(使用动词“get”、“list”和“watch”)。管理员还可以将仍在掌握事情窍门的新开发人员或需要只读访问权限的任何其他人映射到此角色:
cat > sa-test-role.yaml << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: Role # 类型 metadata: name: sa-test-role # 名称 namespace: sa-test # 命名空间 rules: # 规则可以配置多条 - apiGroups: [""] # 为""表示为默认的core api group resources: ["pods","pods/log"] # 数据源类型 verbs: ["get","watch","list"] # 赋予的权限 EOF ## 以上Role策略表示在名字为sa-test的namespace中,对Pods资源有get,watch,list的权限(查看权限)
rules中参数说明如下:
apiGroups:支持的API组列表,例如:“apiVersion:batch/v1”、“apiVersion:extensions:v1beat1”、"apiVersion:apps/v1beta1"等resources: 支持的资源对象列表,例如 pods、 deployments、 jobs等resourceName:支持资源的名称(指定为该名称的资源)verbs: 对资源对象 的操作方法列表 ,例如 get、 watch、 list、 delete、 replace、 patch 等 3.7 角色绑定(RoleBinding)
cat sa-test-rolebinding.yaml << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: sa-test-rolebinding # rolebinding的名称 namespace: sa-test # 命名空间 subjects: - kind: User # 资源权限类型 name: sa-test-user # 账号名称 namespace: sa-test # 命名空间 apiGroup:"" roleRef: kind: Role # 要绑定的Role的类型 name: sa-test-role # role名称 apiGroup: "" EOF ## 以上角色绑定表示为将名称为sa-test-role的角色绑定到名称为sa-test-user的用户3.8 集群角色(ClusterRole)
因为集群角色具备集群级别的生效范围,所以集群角色除了具备与角色一致的命名空间内的资源管理能力,还能用于一些特殊元素的权限管理上:
集群范围的资源,例如Node非资源的特殊路径,例如"/healthz"包含全部命名空间的资源,例如pods(用于kubectl get pods --all-namespaces这样的操作授权)
对于需要管理员访问整个集群的超级用户,将“kind”值更改为“ClusterRole”,这使用户可以访问集群内的所有资源,而不仅仅是一个命名空间,如下所示:
cat > sa-test-clusterrole.yaml << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: sa-test-clusterrole # 集群角色名称 # namespace:xxx ## 如果在clusterrole中指定了namespace,则这个clusterrole的功能即可以认定为一个role(角色降级) rules: - apiGroups: [""] resources: ["services"] verbs: ["get","create","list"] EOF ## 以上集群角色策略表示,有获取,创建,列出整个可用服务的权限3.9 集群角色绑定(ClusterRoleBinding)
cat > sa-test-clusterrolebinding.yaml << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: sa-test-clusterrolebinding subjects: - kind: User # 账户类型 name: sa-test-user # 账户名称 namespace: sa-test apiGroup: "" roleRef: kind: ClusterRole # 角色类型 name: sa-test-clusterrole # 集群角色名称 apiGroup: "" EOF ## 以上集群角色绑定表示为将名称为sa-test-clusterrole的角色绑定到名称为sa-test-user的用户3.10 绑定账户进行权限试验
ServiceAccount
# 1、查看sa-test-role信息 kubectl describe role sa-test-role -n sa-tes Name: sa-test-role Labels:Annotations: PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get watch list] ## 这里可以看出,之前创建的role详情 # 2、为sa-test-account绑定角色 cat > sa-test-rolebinding.yaml << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: sa-test-rolebinding namespace: sa-test subjects: - kind: ServiceAccount # 注意这里,之前是User,现在是ServiceAccount name: sa-test-account namespace: sa-test apiGroup: "" roleRef: kind: Role name: sa-test-role apiGroup: "" EOF # 绑定 kubectl create -f sa-test-rolebinding.yaml # 3、查看绑定信息 kubectl describe rolebinding sa-test-rolebinding -n sa-test Name: sa-test-rolebinding # 角色绑定信息 Labels: Annotations: Role: # 角色信息 Kind: Role Name: sa-test-role Subjects: # 对象信息 Kind Name Namespace ---- ---- --------- ServiceAccount sa-test-account sa-test
ServiceAccount的权限验证是通过PostMan实现的
# 获取ServiceAccount的sa-test-account的token # 在Postman中直接导入下面的curl进行访问,注意替换curl中信息,包括ip及token curl --location --request GET 'https://172.16.160.102:6443/api/v1/namespaces/sa-test/pods' --header 'authority: 172.16.160.102:6443' --header 'cache-control: max-age=0' --header 'sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="98", "Google Chrome";v="98"' --header 'sec-ch-ua-mobile: ?0' --header 'sec-ch-ua-platform: "Windows"' --header 'upgrade-insecure-requests: 1' --header 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36' --header 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9' --header 'sec-fetch-site: none' --header 'sec-fetch-mode: navigate' --header 'sec-fetch-user: ?1' --header 'sec-fetch-dest: document' --header 'accept-language: zh-CN,zh;q=0.9' --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Ink0U2dyR1B5M3NZaHR6ZHBnNm5jRzN4YUx5aTNkcDR2S2ZCTUcxVmVtODAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJzYS10ZXN0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InNhLXRlc3QtYWNjb3VudC10b2tlbi13azc4NSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJzYS10ZXN0LWFjY291bnQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIyNGY0ZDhlMy0wN2E1LTQyMDAtOTkzMC1jOTRhYzZmMmUzODUiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6c2EtdGVzdDpzYS10ZXN0LWFjY291bnQifQ.ixgTxU_CMQwfZKDue9kPHa50KubsXxC72zSdH8gO0OGqRkmXjYMZBwPxOyXrI1gcLEWWpA_j-m35823rH5vHBC943qa3ExUDJsZmReAGB2qc7c8_iNjsjf23be9hzhoIxInv5s4-XHVh4sXct3ouMbj5JIeDXduc0kfDj3BXX9cxBwYXIKVSaxFqYkc_Gk1UaGa5ajxRBduZSmn3vuX_E33iOHxhMXKRw53vFWqu4ktVyvTlLRJpO6KtTlzvVyzmmvECpevLODc_L4Ql9V3x_KJJ7fwduPDy8X_AOD3YLdeqf1WolBLT5iHrccLubY8clIEraYqg1T6FosQD-gLUUw'
执行结果如下:
可以看出,当前sa有权限访问pod且正确获取到了pod的相关信息,证明之前的权限已经生效,下面通过修改curl来进一步确认之前设置的权限是否有效:
获取svc
通过截图可以确定,当前sa不能访问svc,而我们之前设置的权限只有对pod的读取权限,没有对svc的读取权限,权限设置正确
创建pod
通过截图可以确定,当前sa不能创建pod,而我们之前设置的权限只有对pod的读取权限,没有对pod的创建权限,权限设置正确
UserAccount
# 1、创建角色 kubectl create -f sa-test-role.yaml ## 执行成功 rolebinding.rbac.authorization.k8s.io/sa-test-rolebinding created ## 查看 kubectl get rolebinding -n sa-test | grep sa-test ## 结果 sa-test-rolebinding Role/sa-test-role 53s ## 查看描述 kubectl describe role sa-test-role -n sa-test Name: sa-test-role Labels:Annotations: PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get watch list] # 2、角色绑定 kubectl create -f sa-test-rolebinding.yaml ## 执行成功 rolebinding.rbac.authorization.k8s.io/sa-test-rolebinding created ## 查看描述 kubectl describe rolebinding sa-test-rolebinding -n sa-test Name: sa-test-rolebinding Labels: Annotations: Role: Kind: Role Name: sa-test-role Subjects: Kind Name Namespace ---- ---- --------- User sa-test-user # 3、查看pod ## 切换用户 su - sa-test-user ## 查看pod kubectl get pod NAME READY STATUS RESTARTS AGE sa-test-pod 1/1 Running 0 4h50m ## 创建pod kubectl apply -f sa-test-pod.yaml Warning: resource pods/sa-test-pod is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically. Error from server (Forbidden): error when applying patch: {"metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"sa-test-pod","namespace":"sa-test"},"spec":{"containers":[{"image":"nginx","imagePullPolicy":"IfNotPresent","name":"sa-test-pod","ports":[{"containerPort":80}]}]}}n"}}} to: Resource: "/v1, Resource=pods", GroupVersionKind: "/v1, Kind=Pod" Name: "sa-test-pod", Namespace: "sa-test" for: "sa-test-pod.yaml": pods "sa-test-pod" is forbidden: User "sa-test-user" cannot patch resource "pods" in API group "" in the namespace "sa-test" ### 从响应结果可以看出,该用户不能进行pod创建,证明权限设置正确且已经生效 ## 查看svc kubectl get svc Error from server (Forbidden): services is forbidden: User "sa-test-user" cannot list resource "services" in API group "" in the namespace "sa-test" ### 从响应结果可以看出,该用户不能访问svc,证明权限设置正确且已经生效



