认证与授权

认证鉴权是k8s的一个非常重点的疑难点。
学习 Kubernetes 认证与鉴权是非常重要的,因为 Kubernetes 是一种强大而复杂的容器编排平台,它的安全性至关重要。以下是一些理由:
- 认证与鉴权可以帮助保护 Kubernetes 集群的安全性。Kubernetes 集群是一个分布式系统,由多个节点和多个容器组成,这些节点和容器之间需要进行身份验证和授权,以确保安全性。例如,可以使用 Kubernetes 的认证和授权机制来限制哪些用户可以访问集群,以及哪些用户可以执行哪些操作。
- Kubernetes 认证和授权机制可以帮助防止未经授权的访问和操作。如果未经授权的用户可以访问 Kubernetes 集群,他们可能会修改配置、删除容器或者窃取敏感信息。通过认证和授权机制,可以确保只有授权用户可以访问 Kubernetes 集群。
- Kubernetes 的认证和授权机制可以帮助满足合规性要求。许多企业和组织都需要遵守各种法规和标准,如 HIPAA、PCI、GDPR 等。通过使用 Kubernetes 的认证和授权机制,可以确保集群操作符合这些规定。
- Kubernetes 认证和授权机制可以帮助监控和跟踪集群的操作。通过记录谁执行了哪些操作,可以帮助管理员了解集群中发生了什么,并及时发现和解决潜在的安全问题。
总之,学习 Kubernetes 认证与鉴权是保证 Kubernetes 集群安全的重要一环,它可以帮助管理员防止未经授权的访问和操作,并提供监控和跟踪集群操作的能力,以确保集群的稳定性和安全性。

理解术语
在 Kubernetes 中,Authentication,Authorization 和 Admission Control 都是安全机制,用于保护 Kubernetes 集群中的资源不被未授权的访问和修改。
- Authentication:身份验证,即验证用户或实体是否具有访问 Kubernetes 集群的权限。Kubernetes 支持多种身份验证方法,如证书、Token、用户名和密码等。可以使用内置的身份验证机制,或者使用外部的身份验证提供者(如 LDAP 或 OAuth)。
- Authorization:授权,即控制用户或实体可以访问和操作哪些 Kubernetes 资源。Kubernetes 中的授权是基于 RBAC(基于角色的访问控制)的,通过为用户或实体分配角色和权限来实现资源的访问控制。管理员可以定义不同的角色和权限,并将其分配给不同的用户或实体。
- Admission Control:准入控制,是一种验证 Kubernetes 资源配置的机制,可以确保只有符合规则的资源配置才能被提交到 Kubernetes 集群中。可以使用内置的准入控制器,也可以编写自定义的准入控制器。准入控制器可以检查和修改资源配置,以确保其符合 Kubernetes 集群中的安全策略和最佳实践。
例如,当一个用户尝试访问 Kubernetes 集群时,首先需要进行身份验证,以验证其是否具有访问 Kubernetes 的权限。如果身份验证通过,则需要进行授权,以确定该用户可以访问和操作哪些 Kubernetes 资源。在用户提交资源配置之前,还需要进行准入控制,以确保该资源配置符合 Kubernetes 集群中的安全策略和最佳实践。
为什么要学认证与授权
Authentication:身份认证
- 这个环节它面对的输入是整个
http request,负责对来自client的请求进行身份校验,支持的方法包括:basic auth- client证书验证(https双向验证)
jwt token(用于serviceaccount)
- APIServer启动时,可以指定一种Authentication方法,也可以指定多种方法。如果指定了多种方法,那么APIServer将会逐个使用这些方法对客户端请求进行验证, 只要请求数据通过其中一种方法的验证,APIServer就会认为Authentication成功;
- 使用kubeadm引导启动的k8s集群,apiserver的初始配置中,默认支持
client证书验证和serviceaccount两种身份验证方式。 证书认证通过设置--client-ca-file根证书以及--tls-cert-file和--tls-private-key-file来开启。 - 在这个环节,apiserver会通过client证书或
http header中的字段(比如serviceaccount的jwt token)来识别出请求的用户身份,包括”user”、”group”等,这些信息将在后面的authorization环节用到。
- 这个环节它面对的输入是整个

当你使用 Kubernetes 管理容器时,需要确保每个用户只能访问他们被授权的资源,并防止未经授权的用户访问或修改 Kubernetes 集群的配置。
这是通过 Kubernetes 的认证和授权机制实现的。
认证是验证用户的身份,而授权则是确定用户可以访问哪些资源以及他们可以执行哪些操作。
这种认证和授权机制帮助保护 Kubernetes 集群的安全性,确保只有授权的用户可以访问集群,从而避免潜在的安全问题。
此外,这种机制还可以帮助满足合规性要求,并提供监控和跟踪集群操作的能力,以便及时发现和解决潜在的安全问题。
kubectl认证全流程
[root@k8s-master ~]#kubectl get no -v=7
I0404 01:09:06.682651 106023 loader.go:372] Config loaded from file: /root/.kube/config
I0404 01:09:06.690915 106023 round_trippers.go:463] GET https://10.0.0.80:6443/api/v1/nodes?limit=500
I0404 01:09:06.690936 106023 round_trippers.go:469] Request Headers:
I0404 01:09:06.690952 106023 round_trippers.go:473] Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json
I0404 01:09:06.690957 106023 round_trippers.go:473] User-Agent: kubectl/v1.24.4 (linux/amd64) kubernetes/95ee5ab
I0404 01:09:06.696983 106023 round_trippers.go:574] Response Status: 200 OK in 6 milliseconds
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 25d v1.24.4
k8s-slave1 Ready <none> 25d v1.24.4
k8s-slave2 Ready <none> 25d v1.24.4
[root@k8s-master ~]#
# 挪走证书再试试
[root@k8s-master ~]#mv ~/.kube/config /tmp/
[root@k8s-master ~]#kubectl get no -v=7
I0404 01:09:56.616651 106346 round_trippers.go:463] GET http://localhost:8080/api?timeout=32s
I0404 01:09:56.616686 106346 round_trippers.go:469] Request Headers:
I0404 01:09:56.616691 106346 round_trippers.go:473] Accept: application/json, */*
I0404 01:09:56.616695 106346 round_trippers.go:473] User-Agent: kubectl/v1.24.4 (linux/amd64) kubernetes/95ee5ab
I0404 01:09:56.617398 106346 round_trippers.go:574] Response Status: in 0 milliseconds
I0404 01:09:56.617536 106346 cached_discovery.go:119] skipped caching discovery info due to Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
# 明显的kubectl是读取的~/.kube/config 配置信息,通过的认证、鉴权

k8s会校验 kubectl使用的证书,是否由根证书签发,是否合法
/etc/kubernetes/pki/ca.crt
补充证书、私钥的关系
在网络通信中,数字证书是用于证明一个实体(例如一个网站)身份的一种数字凭证。它包含了该实体的公钥和其他相关信息,可以通过互联网访问。
公钥和私钥是用于加密和解密信息的密钥。公钥是可公开的,用于加密信息。私钥是保密的,用于解密信息。这种加密方式被称为公钥加密。通过使用公钥和私钥,信息可以在不泄露私钥的情况下加密和解密。
证书中包含了一个实体的公钥和其他相关信息,证明了该实体的身份。当一个客户端与一个服务器建立连接时,服务器会将它的证书发送给客户端。客户端使用服务器的公钥来加密信息,并将其发送给服务器。服务器使用它的私钥来解密信息。
简而言之,数字证书是一种用于验证实体身份的数字凭证,其中包含了公钥和其他相关信息。公钥和私钥是用于加密和解密信息的密钥,证书中包含了公钥,用于验证实体身份。通过使用公钥和私钥,信息可以在不泄露私钥的情况下加密和解密。
k8s的证书、私钥关系
在 Kubernetes 中,证书和私钥通常用于安全地加密和认证数据传输。下面是 Kubernetes 中证书和私钥的关系:
证书是由证书颁发机构 (CA) 签署的数字凭证,用于验证与该证书相关的实体的身份。在 Kubernetes 中,CA 颁发的证书包括:
CA 证书:用于验证 kube-apiserver 证书的颁发机构。
- 客户端证书:用于验证客户端身份。
- 服务器证书:用于验证 Kubernetes API 服务器身份。
- ServiceAccount 证书:用于验证 ServiceAccount 的身份。
私钥是与证书相关联的加密密钥,用于在数据传输过程中加密和解密数据。在 Kubernetes 中,私钥通常是用于与证书一起创建和颁发的。例如,为了创建一个服务器证书,需要创建一个私钥和一个证书签名请求 (CSR),然后将 CSR 发送给 CA 进行签署。
在 Kubernetes 中,证书和私钥被用于许多不同的目的,包括:
- 对 Kubernetes API 服务器进行身份验证。
- 保护 etcd 数据库的安全。
- 在集群节点之间安全地传输敏感数据。
- 对 Kubernetes 网络流量进行加密和解密。
因此,证书和私钥在 Kubernetes 中是非常重要的安全组件,用于保护 Kubernetes 集群的安全。
理解kube/config文件
在 Kubernetes 中,kubeconfig 文件是用于配置 Kubernetes 集群连接和身份验证的文件。其中,certificate-authority-data、client-certificate-data 和 client-key-data 是 kubeconfig 文件中与安全相关的三个参数。
certificate-authority-data参数指定了用于验证 Kubernetes API 服务器证书的 CA 证书。该参数包含了一个 base64 编码的 CA 证书文件内容。(k8s集群的根证书)client-certificate-data参数指定了用于验证客户端身份的客户端证书。该参数包含了一个 base64 编码的客户端证书文件内容。client-key-data参数指定了用于与客户端证书一起使用的私钥。该参数包含了一个 base64 编码的私钥文件内容。
这些参数的作用
certificate-authority-data用于验证 Kubernetes API 服务器的身份,确保与 API 服务器进行通信的客户端是合法的。client-certificate-data和client-key-data用于验证客户端身份,以便 Kubernetes API 服务器能够确保与客户端进行通信的是合法的客户端。
在 kubeconfig 文件中,这些参数通常与 server 参数(用于指定 Kubernetes API 服务器的地址)一起使用,以便通过安全的 TLS 连接与 Kubernetes API 服务器进行通信。
同时,它们也被用于配置 Kubernetes 集群的各种客户端工具,例如 kubectl 和 Helm 等工具,以便进行与 Kubernetes 集群的安全通信。
理解k8s如何校验证书
理解大厦保安,是怎么校验你的身份的
# 解码certificate-authority-data 解码根证书
echo 证书数据 | base64 -d > test_kubelet.crt
# 得到如下证书数据
[root@k8s-master ~]#cat test_kubelet.crt
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
# 解码client-key-data,得到私钥
echo 私钥key |base64 -d >test_kubelet.key
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
# 查看k8s根证书
[root@k8s-master ~]#cat /etc/kubernetes/pki/ca.crt
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
# 验证你的客户端证书合法吗(大厦会校验,你这工牌是我们颁发的吗?)
[root@k8s-master ~]#openssl verify -CAfile /etc/kubernetes/pki/ca.crt test_kubelet.crt
test_kubelet.crt: OK
图解认证

kubectl鉴权全流程
Authorization:鉴权,你可以访问哪些资源
- 这个环节面对的输入是
http request context中的各种属性,包括:user、group、request path(比如:/api/v1、/healthz、/version等)、request verb(比如:get、list、create等)。 - APIServer会将这些属性值与事先配置好的访问策略(
access policy)相比较。APIServer支持多种authorization mode,包括Node、RBAC、Webhook等。 - APIServer启动时,可以指定一种
authorization mode,也可以指定多种authorization mode,如果是后者,只要Request通过了其中一种mode的授权, 那么该环节的最终结果就是授权成功。在较新版本kubeadm引导启动的k8s集群的apiserver初始配置中,authorization-mode的默认配置是”Node,RBAC”。
kubectl的日志调试级别
| 信息 | 描述 |
|---|---|
| v=0 | 通常,这对操作者来说总是可见的。 |
| v=1 | 当您不想要很详细的输出时,这个是一个合理的默认日志级别。 |
| v=2 | 有关服务和重要日志消息的有用稳定状态信息,这些信息可能与系统中的重大更改相关。这是大多数系统推荐的默认日志级别。 |
| v=3 | 关于更改的扩展信息。 |
| v=4 | 调试级别信息。 |
| v=6 | 显示请求资源。 |
| v=7 | 显示 HTTP 请求头。 |
| v=8 | 显示 HTTP 请求内容。可阅读最多到这,看到http信息 |
| v=9 | 显示 HTTP 请求内容,并且不截断内容。 |
回顾k8s初始化
上面已经演示过了,这里做笔记记录。
kubeadm init启动完master节点后,会默认输出类似下面的提示内容:
... ...
Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
...
这些信息是在告知我们如何配置kubeconfig文件。按照上述命令配置后,master节点上的kubectl就可以直接使用$HOME/.kube/config的信息访问k8s cluster了。 并且,通过这种配置方式,kubectl也拥有了整个集群的管理员(root)权限。
很多K8s初学者在这里都会有疑问:
- 当
kubectl使用这种kubeconfig方式访问集群时,Kubernetes的kube-apiserver是如何对来自kubectl的访问进行身份验证(authentication)和授权(authorization)的呢? - 为什么来自
kubectl的请求拥有最高的管理员权限呢?
查看/root/.kube/config文件:
前面提到过apiserver的authentication支持通过tls client certificate、basic auth、token等方式对客户端发起的请求进行身份校验, 从kubeconfig信息来看,kubectl显然在请求中使用了tls client certificate的方式,即客户端的证书。
证书base64解码:
$ echo xxxxxxxxxxxxxx |base64 -d > kubectl.crt
说明在认证阶段,apiserver会首先使用--client-ca-file配置的CA证书去验证kubectl提供的证书的有效性,基本的方式 :
$ openssl verify -CAfile /etc/kubernetes/pki/ca.crt kubectl.crt
kubectl.crt: OK
除了认证身份,还会取出必要的信息供授权阶段使用,文本形式查看证书内容:
[root@k8s-master ~]#openssl x509 -in test_kubelet.crt -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 0 (0x0)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kubernetes
Validity
Not Before: Mar 9 15:55:00 2023 GMT
Not After : Mar 6 15:55:00 2033 GMT
Subject: CN=kubernetes
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
认证通过后,提取出签发证书时指定的CN(Common Name),kubernetes-admin,作为请求的用户名 (User Name), 从证书中提取O(Organization)字段作为请求用户所属的组 (Group),group = system:masters,然后传递给后面的授权模块。
kubeadm在init初始引导集群启动过程中,创建了许多默认的RBAC规则, 在k8s有关RBAC的官方文档中,我们看到下面一些default clusterrole列表:

其中第一个cluster-admin这个cluster role binding绑定了system:masters group,这和authentication环节传递过来的身份信息不谋而合。 沿着system:masters group对应的cluster-admin clusterrolebinding“追查”下去,真相就会浮出水面。
我们查看一下这一binding:
[root@k8s-master ~]#kubectl describe clusterrolebinding cluster-admin
Name: cluster-admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
Role:
Kind: ClusterRole
Name: cluster-admin
Subjects:
Kind Name Namespace
---- ---- ---------
Group system:masters
我们看到在kube-system名字空间中,一个名为cluster-admin的clusterrolebinding将cluster-admin cluster role与system:masters Group绑定到了一起, 赋予了所有归属于system:masters Group中用户cluster-admin角色所拥有的权限。
我们再来查看一下cluster-admin这个role的具体权限信息:
[root@k8s-master ~]#kubectl describe clusterrole cluster-admin
Name: cluster-admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
*.* [] [] [*]
[*] [] [*]
k8s认证鉴权流程

什么是RBAC
张三、李四、二狗都有门禁卡,进入大厦后,他们仨是不同的角色,也就是不同的权限;
保洁、保安、总经理。
很明显,他们可在k8s集群内做的事不一样。
你需要做的就是,定义权限、定义角色、绑定权限与角色。
Role-Based Access Control,基于角色的访问控制, apiserver启动参数添加--authorization-mode=RBAC 来启用RBAC认证模式,kubeadm安装的集群默认已开启。
# 查看api-server进程,鉴权是这个组件在做
[root@k8s-master ~]#ps aux |grep apiserver
root 2040 2.8 4.0 1038884 320020 ? Ssl Apr03 8:20 kube-apiserver --advertise-address=10.0.0.80 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/etc/kubernetes/pki/ca.crt --enable-admission-plugins=NodeRestriction --enable-bootstrap-token-auth=true --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key --etcd-servers=https://127.0.0.1:2379 --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=6443 --service-account-issuer=https://kubernetes.default.svc.cluster.local --service-account-key-file=/etc/kubernetes/pki/sa.pub --service-account-signing-key-file=/etc/kubernetes/pki/sa.key --service-cluster-ip-range=10.96.0.0/12 --tls-cert-file=/etc/kubernetes/pki/apiserver.crt --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
# 看到认证模式
--authorization-mode=Node,RBAC
查看RBAC模式引入的4个资源类型
role资源
# 查看什么是role资源
[root@k8s-master ~]#kubectl explain role
KIND: Role
VERSION: rbac.authorization.k8s.io/v1
DESCRIPTION:
Role is a namespaced, logical grouping of PolicyRules that can be
referenced as a unit by a RoleBinding.
角色是 PolicyRules 的命名空间逻辑分组,可以是
被 RoleBinding 引用为一个单元。
# 查看集群内置的role
[root@k8s-master ~]#kubectl get role -A
# 随便找一个角色看看
[root@k8s-master ~]#kubectl -n ingress-nginx get role ingress-nginx
NAME CREATED AT
ingress-nginx 2023-03-28T15:17:26Z
创建一个role
可以将这个角色应用于 Kubernetes 中的角色绑定(RoleBinding)对象,以授予用户或组读取 "demo" 命名空间中 Pod 的能力。
一个Role只能授权访问单个namespace
## 示例定义一个名为pod-reader的角色,该角色具有读取demo这个命名空间下的pods的权限
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: yuchao
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
# 也支持直接写"*" 就是最大化权限,就等于是yuchao这个名称空间下的管理员admin角色了
# 允许该角色、pod-reader可以访问yuchao名称空间下的,pod,权限是get、watch、list
## apiGroups: "","apps", "autoscaling", "batch", kubectl api-versions
## resources: "services", "pods","deployments"... kubectl api-resources
## verbs: "get", "list", "watch", "create", "update", "patch", "delete", "exec"
## https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/
clusterRole
明显的集群角色、是跨namespace的;
一个ClusterRole能够授予和Role一样的权限,但是它是集群范围内的。
## 定义一个集群角色,名为secret-reader,该角色可以读取所有的namespace中的secret资源
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
# 如上是定义一个只允许读取secrets的集群角色,可以访问所有ns下的secrets
# User,Group,ServiceAccount
cluster-admin
变形下,理解什么是集群管理员角色
就是可以操作任何namespace下的任意资源,增删改查等
# 变形理解,集群管理员的角色
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*""]
# 查询系统内置的admin
[root@k8s-master ~]#kubectl get clusterrole admin -oyaml
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.authorization.k8s.io/aggregate-to-admin: "true"
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2023-03-09T15:55:07Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: admin
resourceVersion: "353"
uid: c25aa20e-509f-4074-a847-ae35a8a989f0
rules:
- apiGroups:
...
Role和ClusterRole区别
在 Kubernetes 中,Role 和 ClusterRole 都是用来定义对资源的访问控制权限的对象。但是,它们之间存在一些重要的区别。
- 范围不同:Role 只能授权对单个 Namespace 内的资源进行访问,而 ClusterRole 则可以授权对整个集群的资源进行访问。
- 绑定的对象不同:Role 可以绑定到 RoleBinding 对象上,ClusterRole 则可以绑定到 ClusterRoleBinding 对象上。
- 权限范围不同:由于 ClusterRole 可以授权对整个集群的资源进行访问,因此其权限范围通常比 Role 更大。
- ClusterRole 拥有更高的优先级:如果一个用户或者服务账号同时被赋予了一个 Role 和一个 ClusterRole,那么 ClusterRole 中定义的权限将具有更高的优先级,即将覆盖 Role 中定义的权限。
- 定义方式不同:定义 Role 和 ClusterRole 的方式基本相同,但是在 apiVersion 和 kind 字段上有所不同。Role 的 apiVersion 为 rbac.authorization.k8s.io/v1,kind 为
Role;而 ClusterRole 的 apiVersion 为 rbac.authorization.k8s.io/v1,kind 为ClusterRole。
综上所述,Role 和 ClusterRole 在范围、绑定对象、权限范围、优先级和定义方式等方面存在一些区别,需要根据实际情况进行选择和使用。
角色绑定Rolebinding
将role中定义的权限分配给用户和用户组。
RoleBinding包含主题(users,groups,或service accounts)和授予角色的引用。对
于namespace内的授权使用RoleBinding,集群范围内使用ClusterRoleBinding。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods # 角色绑定的名字
namespace: demo # 限定在demo的ns下
subjects: # subjects定义哪些实体授予权限,这用是用的User
- kind: User #这里可以是User,Group,ServiceAccount
name: chaoge # 允许chaoge用户可以在demo的ns下获取pod
apiGroup: rbac.authorization.k8s.io
roleRef: # roleRef指定给chaoge设置什么权限,匹配你预先定义好的Role对象
kind: Role #这里可以是Role或者ClusterRole,若是ClusterRole,则权限也仅限于rolebinding的内部
name: pod-reader # 这里是匹配你之前定义好的role的名字
apiGroup: rbac.authorization.k8s.io
注意:rolebinding既可以绑定role,也可以绑定clusterrole,当绑定clusterrole的时候,subject的权限也会被限定于rolebinding定义的namespace内部,若想跨namespace,需要使用clusterrolebinding
## 定义一个角色绑定,将dave这个用户和secret-reader这个集群角色绑定,虽然secret-reader是集群角色,但是因为是使用rolebinding绑定的,因此dave的权限也会被限制在development这个命名空间内
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-secrets
namespace: development
subjects:
- kind: User
name: dave # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
- kind: ServiceAccount
name: dave # Name is case sensitive
namespace: yuchao
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
考虑一个场景: 如果集群中有多个namespace分配给不同的管理员,每个namespace的权限是一样的,就可以只定义一个clusterrole,然后通过rolebinding将不同的namespace绑定到管理员身上,否则就需要每个namespace定义一个Role,然后做一次rolebinding。
简单理解
一个办公室内,有很多个房间,如果这个管理员对每个房间的权限都一样
你就直接定义个办公室整体权限,然后交给这个管理员,很省事。
你没必要重复的对每一个房间设置权限,再逐个的绑定给管理员。
集群角色绑定
区别就是跨ns的权限绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # 名字区分大小写
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
这是一个 Kubernetes 集群中的 ClusterRoleBinding 对象,用于将权限集群角色(ClusterRole)和用户、组或服务账号(subjects)绑定起来。
具体来说,这个 ClusterRoleBinding 名称为 "read-secrets-global",意味着它将授予绑定了 "manager" 组的用户、组或服务账号访问 Kubernetes 集群中的所有 secret 资源的权限。
注意,"manager" 组名是区分大小写的。
另外,这个 ClusterRoleBinding 引用了名为 "secret-reader" 的 ClusterRole,它定义了访问 secret 资源的具体权限。
最后,这些对象都属于 rbac.authorization.k8s.io API 组。
图解RBAC(重要)

kubectl的RBAC流程
kubectl的认证通过
为什么你可以查看k8s集群资源
[root@k8s-master ~]#kubectl -n yuchao get po
NAME READY STATUS RESTARTS AGE
eladmin-api-79b478cf54-m5ntl 1/1 Running 2 (26h ago) 2d20h
eladmin-web-759f77b7cb-g2z8c 1/1 Running 0 26h
mysql-7c7cf8495f-5w5bk 1/1 Running 1 (26h ago) 14d
ngx-test 1/1 Running 1 (26h ago) 4d22h
redis-7957d49f44-cxj8z 1/1 Running 1 (26h ago) 14d
kubectl肯定是通过了认证,查看kubectl怎么通过的认证
[root@k8s-master ~]#kubectl -n yuchao get po -v=7
I0404 23:58:27.925933 74516 loader.go:372] Config loaded from file: /root/.kube/config
I0404 23:58:27.934109 74516 round_trippers.go:463] GET https://10.0.0.80:6443/api/v1/namespaces/yuchao/pods?limit=500
I0404 23:58:27.934146 74516 round_trippers.go:469] Request Headers:
I0404 23:58:27.934163 74516 round_trippers.go:473] Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json
I0404 23:58:27.934168 74516 round_trippers.go:473] User-Agent: kubectl/v1.24.4 (linux/amd64) kubernetes/95ee5ab
I0404 23:58:27.940450 74516 round_trippers.go:574] Response Status: 200 OK in 6 milliseconds
NAME READY STATUS RESTARTS AGE
eladmin-api-79b478cf54-m5ntl 1/1 Running 2 (26h ago) 2d20h
eladmin-web-759f77b7cb-g2z8c 1/1 Running 0 26h
mysql-7c7cf8495f-5w5bk 1/1 Running 1 (26h ago) 14d
ngx-test 1/1 Running 1 (26h ago) 4d22h
redis-7957d49f44-cxj8z 1/1 Running 1 (26h ago) 14d
看到kubectl用的配置文件/root/.kube/config,里面有证书、私钥
我们可以通过证书,解密,和k8s集群本身的证书,做一个校验对比,是否合法
[root@k8s-master ~]#
[root@k8s-master ~]#echo "certificate-authority-data" |base64 -d > kubectl.crt
# 认证是否通过
[root@k8s-master ~]#openssl verify -CAfile /etc/kubernetes/pki/ca.crt kubectl.crt
kubectl.crt: OK
# kubectl携带的工牌,的确是这个大厦颁发的,进去吧!
kubectl的鉴权
你允许进入大楼后,你到底是什么角色,你可以查看哪些ns下的资源?可以看pod?deployment??
所以要查看RBAC规则了
除了认证身份,还会取出必要的信息供授权阶段使用,文本形式查看证书内容:
[root@k8s-master ~]#openssl x509 -in kubectl.crt -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 0 (0x0)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kubernetes
Validity
Not Before: Mar 9 15:55:00 2023 GMT
Not After : Mar 6 15:55:00 2033 GMT
Subject: CN=kubernetes
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
k8s的权限只能绑定给user、group、serviceaccount,所以看subject字段
直接看subject
该证书的 Subject 字段表示证书的主体,也就是证书所颁发给的实体。在这个证书中,Subject 字段的值为 CN=kubernetes,表示该证书所颁发给的实体的名称为 kubernetes。
CN 是 X.500 标准中常用的一个属性名,表示 Common Name,即常用名称。
在 SSL/TLS 证书中,CN 通常用于指定证书所颁发给的服务器的主机名或域名。
在这个证书中,CN=kubernetes 表示该证书所颁发给的实体名称为 kubernetes,是用于身份验证或者加密通信的 Kubernetes 集群组件。
[root@k8s-master ~]#cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data:
....
...
server: https://10.0.0.80:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
查看clusterRolebinding
# 查看权限绑定
[root@k8s-master ~]#kubectl get clusterrole cluster-admin
NAME CREATED AT
cluster-admin 2023-03-09T15:55:07Z
[root@k8s-master ~]#kubectl get clusterrolebindings.rbac.authorization.k8s.io cluster-admin
NAME ROLE AGE
cluster-admin ClusterRole/cluster-admin 26d
[root@k8s-master ~]#kubectl get clusterrolebindings.rbac.authorization.k8s.io cluster-admin -oyaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2023-03-09T15:55:07Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: cluster-admin # 集群权限绑定的名字
resourceVersion: "139"
uid: fe34eae5-b057-4a79-82d3-00d31eedd769
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole # 集群角色,跨ns的权限设置
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group # 权限绑定给了组
name: system:masters
查看cluster-admin这个权限有哪些(找出授权了)
[root@k8s-master ~]#kubectl get clusterrole cluster-admin -oyaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2023-03-09T15:55:07Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: cluster-admin
resourceVersion: "77"
uid: 48eef247-41ba-4fb4-acf7-1e42e17f789e
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
- nonResourceURLs:
- '*'
verbs:
- '*'
这是一个 Kubernetes 的 ClusterRole 资源定义,用于授权给拥有 cluster-admin 角色的用户或服务账户。这个 ClusterRole 具有最高权限,可以访问和控制集群内的所有资源,包括 API 组、资源和非资源 URL。其中 rules 字段定义了以下两个规则:
- 第一个规则授权所有 API 组和资源的所有操作,通配符 "*" 表示可以对任何资源进行任何操作。
- 第二个规则授权所有非资源 URL 的所有操作,同样使用通配符 "*" 表示可以对任何非资源 URL 进行任何操作。
这个 ClusterRole 的 metadata 字段包括创建时间、标签、名称、资源版本和唯一标识符等信息。annotations 字段中的 "rbac.authorization.kubernetes.io/autoupdate" 注解表示可以自动更新该 ClusterRole。
至此kubectl认证、鉴权结束(图解)

[root@k8s-master ~]#kubectl get clusterrolebinding cluster-admin -o jsonpath='{.subjects[?(@.kind=="Group")].name}'
system:masters
这个命令将列出被绑定到 "cluster-admin" ClusterRoleBinding 中的所有组名,其中应该包括 "system:masters" 组的名称。
其他组件的RBAC
# 一样,也是证书认证、和kubectl解析流程一样
[root@k8s-master ~]#cat /etc/kubernetes/controller-manager.conf
# 都要和api-server经过认证、授权的流程
kubelet的认证流程

kubelet需要和etcd交互,需要通过api-server进行认证、授权。
kubectl走的RBAC认证模型;
kubelet用的是Node认证模型;
https://kubernetes.io/docs/reference/access-authn-authz/node/
节点授权是一种特殊用途的授权模式,专门对 kubelet 发出的 API 请求进行授权。
查看进程
[root@k8s-master ~]#ps -ef|grep kubelet |grep 'mode'
root 2040 1838 3 Apr03 ? 00:53:21 kube-apiserver --advertise-address=10.0.0.80 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/etc/kubernetes/pki/ca.crt --enable-admission-plugins=NodeRestriction --enable-bootstrap-token-auth=true --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key --etcd-servers=https://127.0.0.1:2379 --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=6443 --service-account-issuer=https://kubernetes.default.svc.cluster.local --service-account-key-file=/etc/kubernetes/pki/sa.pub --service-account-signing-key-file=/etc/kubernetes/pki/sa.key --service-cluster-ip-range=10.96.0.0/12 --tls-cert-file=/etc/kubernetes/pki/apiserver.crt --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
[root@k8s-master ~]#
# 你会看到这么个奇怪的玩意
--authorization-mode=Node,RBAC
在Kubernetes中,Node Authorizer是一种授权插件,用于控制节点(Node)上容器的访问权限。它根据节点身份验证令牌中的信息来确定容器是否有权访问节点上的资源。
Node Authorizer通常与其他授权插件(如RBAC)一起使用,以确保容器只能访问其被授权的资源。
Node Authorizer是Kubernetes的内置授权插件之一,通常在集群创建时就启用。
要启用Node Authorizer,请在kubelet的启动参数中设置--authorization-mode=Node。
查看kubelet的授权
[root@k8s-master ~]#!cat
cat /etc/kubernetes/kubelet.conf
apiVersion: v1
clusters:
- cluster:
certificate-authority-data:
...
...
server: https://10.0.0.80:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: system:node:k8s-master
name: system:node:k8s-master@kubernetes
current-context: system:node:k8s-master@kubernetes
kind: Config
preferences: {}
users:
- name: system:node:k8s-master # 看这里,kubelet使用的用户
user:
client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pem
client-key: /var/lib/kubelet/pki/kubelet-client-current.pem
# 查询kubelet使用的,集群角色绑定规则
[root@k8s-master ~]#kubectl get clusterrolebinding -oyaml|grep -n10 system:nodes
155- name: kubeadm:node-autoapprove-certificate-rotation
156- resourceVersion: "223"
157- uid: 8cc3e49e-3e88-425a-aa5d-d6370a330d28
158- roleRef:
159- apiGroup: rbac.authorization.k8s.io
160- kind: ClusterRole
161- name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
162- subjects:
163- - apiGroup: rbac.authorization.k8s.io
164- kind: Group
165: name: system:nodes # 看这里是kubelet用的组名
166-- apiVersion: rbac.authorization.k8s.io/v1
167- kind: ClusterRoleBinding
168- metadata:
169- creationTimestamp: "2023-03-09T15:55:09Z"
170- name: kubeadm:node-proxier
171- resourceVersion: "242"
172- uid: 6a6fe0e4-d35e-4a48-901b-dcd683b6c033
173- roleRef:
174- apiGroup: rbac.authorization.k8s.io
175- kind: ClusterRole
# 查看集群角色,以及有哪些权限
[root@k8s-master ~]#kubectl describe clusterrole system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
Name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
certificatesigningrequests.certificates.k8s.io/selfnodeclient [] [] [create]
[root@k8s-master ~]#
Using Node Authorization官网资料

只要kubelet证书满足这2个要求,就可以有如上的权限。
查看一下官网对Node authorizer的介绍:
Node authorization is a special-purpose authorization mode that specifically authorizes API requests made by kubelets.
In future releases, the node authorizer may add or remove permissions to ensure kubelets have the minimal set of permissions required to operate correctly.
In order to be authorized by the Node authorizer, kubelets must use a credential that identifies them as being in the system:nodes group, with a username of system:node:<nodeName>
Core component roles
| Default ClusterRole | Default ClusterRoleBinding | Description |
|---|---|---|
| system:kube-scheduler | system:kube-scheduler user | Allows access to the resources required by the scheduler component. |
| system:volume-scheduler | system:kube-scheduler user | Allows access to the volume resources required by the kube-scheduler component. |
| system:kube-controller-manager | system:kube-controller-manager user | Allows access to the resources required by the controller manager component. The permissions required by individual controllers are detailed in the controller roles. |
| system:node | None | Allows access to resources required by the kubelet, including read access to all secrets, and write access to all pod status objects.You should use the Node authorizer and NodeRestriction admission plugin instead of the system:node role, and allow granting API access to kubelets based on the Pods scheduled to run on them.The system:node role only exists for compatibility with Kubernetes clusters upgraded from versions prior to v1.8. |
| system:node-proxier | system:kube-proxy user | Allows access to the resources required by the kube-proxy component. |

查看kubelet客户端的证书
[root@k8s-master ~]#openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 5898235558077431268 (0x51dabdfd68c87de4)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kubernetes
Validity
Not Before: Mar 9 15:55:00 2023 GMT
Not After : Mar 8 15:55:01 2024 GMT
Subject: O=system:nodes, CN=system:node:k8s-master
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
...
这个证书是 kubelet-client-current.pem,它是 kubelet 组件使用的客户端证书之一,用于向 Kubernetes API Server 进行身份验证和授权。
看这里
Subject: O=system:nodes, CN=system:node:k8s-master
O表示组,属于O=system:nodes
CN理解为用户名,符合system:node:节点名
因此符合Node授权器的规则
创建k8s多集群(重要)

上面于超老师基于k8s内置的组件,讲解RBAC、Node类型的认证、授权规则的查看;
理解了为什么kubectl、kubelet被允许访问、操作k8s集群资源;
但是如果我们要给第三方的组件、或者开发他们创建一个用户配置,限制他们只能访问某些ns下的资源,这个规则该怎么写;
其实一样的,也是要通过
- 认证
- 证书
- 授权
生成证书、私钥

# Common Name(通用名称)是SSL证书中的一个字段,用于指定要保护的网站的域名。它通常是在申请SSL证书时提供的一个必填字段,也可以在生成自签名证书时手动指定。通用名称字段可以包含一个单独的域名,也可以包含多个域名(称为通配符证书)。
# 在使用SSL证书保护网站时,浏览器会检查证书中的通用名称是否与用户访问的网站域名匹配。如果不匹配,浏览器将会提示用户证书存在问题,从而降低用户信任度和网站安全性。因此,正确设置通用名称字段非常重要,可以帮助确保网站的安全性和信誉度。
理解证书的信息
# 1.证书和私钥是成对出现的
# 生成rsa算法的密钥对,私钥写入yuchao.key 密钥长度2048
openssl genrsa -out yuchao.key 2048
# 2.基于私钥,创建证书文件
# 每个证书都有O和CN信息,属于subject的信息
# O理解是Group
# CN理解是User
[root@k8s-master ~/my_kubeconfig]#openssl req -new -key yuchao.key -out yuchao.csr -subj "/O=admin:yuchao/CN=yuchao-admin"
[root@k8s-master ~/my_kubeconfig]#ls
yuchao.csr yuchao.key
[root@k8s-master ~/my_kubeconfig]#
# 命令解释
openssl:这是调用OpenSSL的命令,OpenSSL是一个流行的开源加密库,提供各种加密功能和工具。
req:这是OpenSSL命令中的一个选项,表示要使用证书请求(Certificate Signing Request)功能。
-new:这是OpenSSL命令中的一个选项,表示要创建一个新的证书签名请求。
-key yuchao.key:这是OpenSSL命令中的另一个选项,指定要使用的私钥文件。在这个例子中,私钥文件名为"yuchao.key"。
-out yuchao.csr:这是OpenSSL命令中的另一个选项,指定要生成的证书签名请求的输出文件。在这个例子中,CSR将保存在名为"yuchao.csr"的文件中。
-subj "/O=admin:yuchao/CN=yuchao-admin":这是OpenSSL命令中的另一个选项,指定要包含在CSR中的主题(subject)信息。
在这个例子中,主题信息包含了组织名(O)和通用名称(CN)。其中,O=admin:yuchao表示组织名为"admin:yuchao",CN=yuchao-admin表示通用名称为"yuchao-admin"。通用名称用于标识证书要保护的域名或主机名。
#3.定义自签名的CA根证书(Certificate Authority)。该配置文件中的 [v3_ca] 部分定义了该证书的扩展属性。
cat > extfile.conf <<EOF
[ v3_ca ]
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
EOF
# 解释
keyUsage:指定证书的密钥用途,critical 表示密钥用途是必需的扩展属性,digitalSignature 表示证书用于数字签名,keyEncipherment 表示证书用于密钥加密。
extendedKeyUsage:指定证书的扩展密钥用途
clientAuth 表示证书用于客户端身份验证。
# 4.创建证书crt,自签个一年的证书
# 使用k8s的根证书,以它作为颁发机构,你自签的证书才能被信任
[root@k8s-master ~/my_kubeconfig]#openssl x509 -req -in yuchao.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -sha256 -out yuchao.crt -extensions v3_ca -extfile extfile.conf -days 3650
Signature ok
subject=/O=admin:yuchao/CN=yuchao-admin
Getting CA Private Key
# 5.检查证书,参考api-server的做法
[root@k8s-master ~/my_kubeconfig]#ls /etc/kubernetes/pki/apiserver.* -l
-rw-r--r-- 1 root root 1224 Mar 10 00:38 /etc/kubernetes/pki/apiserver.crt
-rw------- 1 root root 1675 Mar 9 23:55 /etc/kubernetes/pki/apiserver.key
[root@k8s-master ~/my_kubeconfig]#ll yuchao.*
-rw-r--r-- 1 root root 1074 Apr 6 22:49 yuchao.crt # 证书
-rw-r--r-- 1 root root 928 Apr 6 22:44 yuchao.csr
-rw-r--r-- 1 root root 1679 Apr 6 22:33 yuchao.key # 私钥
查看k8s默认的cluster
在Kubernetes中,"kubernetes"是默认的集群名称。当您在没有显式指定集群名称的情况下创建集群时,Kubernetes会自动为您创建一个名为"kubernetes"的集群。该集群是由控制平面组件(如API服务器、etcd存储等)和工作负载节点(如容器运行时)组成的,它们一起管理和运行Kubernetes中的容器化应用程序。
当您使用"kubectl"或其他Kubernetes工具与集群交互时,这些工具会使用kubeconfig文件中定义的当前上下文来确定要连接的Kubernetes集群。如果您没有显式指定上下文,则"kubernetes"集群通常是默认的上下文。因此,当您运行"kubectl"命令时,它将连接到默认的"kubernetes"集群,并执行相应的操作。
总之,Kubernetes创建的"kubernetes"集群是一个默认的集群实例,它提供了基本的控制平面和工作负载节点,可以让您快速开始部署和管理容器化应用程序。
[root@k8s-master ~/my_kubeconfig]#kubectl config get-clusters
NAME
kubernetes
[root@k8s-master ~/my_kubeconfig]#kubectl cluster-info
Kubernetes control plane is running at https://10.0.0.80:6443
CoreDNS is running at https://10.0.0.80:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
k8s上下文是什么
cluster、user、context(重要)
在 Kubernetes 中,一个完整的 API 请求需要三个主要部分:Cluster、User 和 Context。它们的作用分别是:
- Cluster:指定请求将发送到哪个 Kubernetes 集群。
- User:指定用于认证和授权请求的用户。
- Context:将 Cluster 和 User 绑定在一起,同时指定默认的命名空间和请求超时时间。
在创建 kubeconfig 文件时,需要为每个集群、用户和上下文分别定义一个配置项。这些配置项定义了集群、用户和上下文之间的关系:
- Cluster 配置项定义了集群的地址、证书和相关参数。
- User 配置项定义了用户的身份信息、证书和私钥等信息。
- Context 配置项将 Cluster 和 User 绑定在一起,并指定默认的命名空间和请求超时时间。
在使用 Kubernetes API 时,需要通过指定上下文名称来确定使用哪个 Cluster 和 User。如果不指定上下文名称,则使用默认上下文。因此,Cluster、User 和 Context 之间是相互关联的,它们共同构成了 Kubernetes API 认证和授权的核心机制。

# 可以查看当前context的信息
[root@k8s-master ~/my_kubeconfig]#kubectl config view --minify
在Kubernetes中,您可以创建多个不同的集群。通过创建多个集群,您可以将不同的应用程序或环境隔离开来,以便更好地管理和保护它们。例如,您可以在同一物理基础架构上创建一个用于开发和测试的集群,另一个用于生产环境。
每个Kubernetes集群都有一个唯一的名称,它是在创建集群时指定的。您可以使用"kubectl config get-clusters"命令列出当前配置文件中定义的所有集群的名称。
在Kubernetes中,上下文是一组集群、用户和命名空间的组合。当您使用"kubectl"或其他Kubernetes工具与集群交互时,您需要指定要使用的上下文。这样,您可以轻松地在多个Kubernetes集群之间切换,并且可以针对不同的用户和命名空间执行操作。因此,可以说集群是上下文的一部分,但是上下文包含了更多的信息。
[root@k8s-master ~/my_kubeconfig]#kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
[root@k8s-master ~/my_kubeconfig]#
[root@k8s-master ~/my_kubeconfig]#kubectl config current-context
kubernetes-admin@kubernetes
k8s上下文管理
https://kubernetes.io/zh-cn/docs/concepts/configuration/organize-cluster-access-kubeconfig/
官网资料
使用 kubeconfig 文件来组织有关集群、用户、命名空间和身份认证机制的信息。
kubectl 命令行工具使用 kubeconfig 文件来查找选择集群所需的信息,并与集群的 API 服务器进行通信。

创建上下文
模仿默认的kubectl使用的证书,咱也基于自签证书,创建一个配置文件
[root@k8s-master ~/my_kubeconfig]#cat ~/.kube/config
基于kubectl创建配置文件,固定用法,记住即可;
如下就是创建新的上下文,新的一套集群的玩法
# 创建kubeconfig文件,指定集群名称和地址
# 这条命令使用了 kubectl config set-cluster 命令来创建一个名为 yuchao-cluster 的 Kubernetes 集群,并将该集群的相关信息保存到 yuchao.kubeconfig 配置文件中。
#在该命令中,--certificate-authority 参数用于指定 Kubernetes 集群证书的颁发机构(CA)证书的路径和名称。--embed-certs=true 参数用于将 CA 证书嵌入到 kubeconfig 文件中,这样可以确保使用正确的 CA 证书进行验证。--server 参数用于指定 Kubernetes API Server 的地址和端口号。
#通过执行该命令,您成功地创建了一个新的 Kubernetes 集群,并将其保存到 yuchao.kubeconfig 文件中,以供后续使用。
[root@k8s-master ~/my_kubeconfig]#kubectl config set-cluster yuchao-cluster --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --server=https://10.0.0.80:6443 --kubeconfig=yuchao.kubeconfig
Cluster "yuchao-cluster" set.
------------------------------------------------------------------------------------
# 为kubeconfig文件添加认证信息
[root@k8s-master ~/my_kubeconfig]#kubectl config set-credentials yuchao-admin --client-certificate=yuchao.crt --client-key=yuchao.key --embed-certs=true --kubeconfig=yuchao.kubeconfig
User "yuchao-admin" set.
这条命令使用了 kubectl config set-credentials 命令来创建一个名为 yuchao-admin 的 Kubernetes 用户,并将该用户的相关信息保存到 yuchao.kubeconfig 配置文件中。
在该命令中,--client-certificate 参数用于指定该用户的证书文件路径和名称,--client-key 参数用于指定该用户的私钥文件路径和名称。--embed-certs=true 参数用于将证书和私钥文件嵌入到 kubeconfig 文件中,这样可以确保使用正确的证书和私钥进行认证。
通过执行该命令,您成功地创建了一个新的 Kubernetes 用户,并将其保存到 yuchao.kubeconfig 文件中,以供后续使用。
# 查询创建的集群
[root@k8s-master ~/my_kubeconfig]#kubectl config get-clusters --kubeconfig=yuchao.kubeconfig
NAME
yuchao-cluster
# 查询当前正在用的用户
[root@k8s-master ~/my_kubeconfig]#kubectl config get-users
NAME
kubernetes-admin
# 查询你刚才创建的用户
[root@k8s-master ~/my_kubeconfig]#kubectl config get-users --kubeconfig=yuchao.kubeconfig
NAME
yuchao-admin
------------------------------------------------------------------------------------
# 查看当前使用的上下文,kubeconfig的详细信息
[root@k8s-master ~/my_kubeconfig]#kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://10.0.0.80:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
# 查看你刚才创建的yuchao-admin的信息
[root@k8s-master ~/my_kubeconfig]#kubectl config view --kubeconfig=yuchao.kubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://10.0.0.80:6443
name: yuchao-cluster
contexts: null
current-context: ""
kind: Config
preferences: {}
users:
- name: yuchao-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
------------------------------------------------------------------------------------
# 为kubeconfig添加上下文配置
这条命令的作用是创建一个新的上下文 yuchao-context,并将其绑定到 yuchao-cluster 集群和 yuchao-admin 用户上。该命令的详细说明如下:
kubectl config set-context:设置一个新的上下文。
yuchao-context:新上下文的名称。
--cluster=yuchao-cluster:绑定到 yuchao-cluster 集群。
--user=yuchao-admin:绑定到 yuchao-admin 用户。
--kubeconfig=yuchao.kubeconfig:指定要修改的 kubeconfig 文件。
该命令的执行结果是在 yuchao.kubeconfig 文件中创建了一个新的上下文,该上下文与 yuchao-cluster 集群和 yuchao-admin 用户相关联。在后续的 Kubernetes API 请求中,可以使用 yuchao-context 上下文来指定请求的目标集群和用户。
[root@k8s-master ~/my_kubeconfig]#kubectl config set-context yuchao-context --cluster=yuchao-cluster --user=yuchao-admin --kubeconfig=yuchao.kubeconfig
Context "yuchao-context" created.
# 查看上下文
[root@k8s-master ~/my_kubeconfig]#kubectl config get-contexts --kubeconfig=yuchao.kubeconfig
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
yuchao-context yuchao-cluster yuchao-admin
------------------------------------------------------------------------------------
# 设置默认的上下文
[root@k8s-master ~/my_kubeconfig]#kubectl config use-context yuchao-context --kubeconfig=yuchao.kubeconfig
Switched to context "yuchao-context".
切换新的上下文
# 发现kubectl还是在用默认的kubeconfig
[root@k8s-master ~/my_kubeconfig]#kubectl get no -v=7
I0406 23:36:21.436758 62997 loader.go:372] Config loaded from file: /root/.kube/config
I0406 23:36:21.439386 62997 round_trippers.go:463] GET https://10.0.0.80:6443/api/v1/nodes?limit=500
I0406 23:36:21.439398 62997 round_trippers.go:469] Request Headers:
I0406 23:36:21.439403 62997 round_trippers.go:473] Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json
I0406 23:36:21.439408 62997 round_trippers.go:473] User-Agent: kubectl/v1.24.4 (linux/amd64) kubernetes/95ee5ab
I0406 23:36:21.444799 62997 round_trippers.go:574] Response Status: 200 OK in 5 milliseconds
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 27d v1.24.4
k8s-slave1 Ready <none> 27d v1.24.4
k8s-slave2 Ready <none> 27d v1.24.4
# 修改读取的kubeconfig
export KUBECONFIG=/root/my_kubeconfig/yuchao.kubeconfig
# 是否成功修改kubeconfig
[root@k8s-master ~/my_kubeconfig]#export KUBECONFIG=/root/my_kubeconfig/yuchao.kubeconfig
[root@k8s-master ~/my_kubeconfig]#kubectl get no -v=7
I0406 23:37:41.269742 63586 loader.go:372] Config loaded from file: /root/my_kubeconfig/yuchao.kubeconfig
I0406 23:37:41.273499 63586 round_trippers.go:463] GET https://10.0.0.80:6443/api/v1/nodes?limit=500
I0406 23:37:41.273513 63586 round_trippers.go:469] Request Headers:
I0406 23:37:41.273519 63586 round_trippers.go:473] Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json
I0406 23:37:41.273523 63586 round_trippers.go:473] User-Agent: kubectl/v1.24.4 (linux/amd64) kubernetes/95ee5ab
I0406 23:37:41.279959 63586 round_trippers.go:574] Response Status: 403 Forbidden in 6 milliseconds
I0406 23:37:41.280258 63586 helpers.go:222] server response object: [{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "nodes is forbidden: User \"yuchao-admin\" cannot list resource \"nodes\" in API group \"\" at the cluster scope",
"reason": "Forbidden",
"details": {
"kind": "nodes"
},
"code": 403
}]
Error from server (Forbidden): nodes is forbidden: User "yuchao-admin" cannot list resource "nodes" in API group "" at the cluster scope
[root@k8s-master ~/my_kubeconfig]#
[root@k8s-master ~/my_kubeconfig]#kubectl config current-context
yuchao-context
如果输出结果为 yuchao-context,则表示您已成功切换到 yuchao-context 上下文。
至此,认证已经通过了
/etc/kubernetes/pki/ca.crt
↓
/root/my_kubeconfig/yuchao.kubeconfig
但是RBAC权限这一块,还没设置。
设置新的RBAC授权规则
目前还没有针对yuchao-admin这个用户,设置任何的权限。
[root@k8s-master ~/my_kubeconfig]#kubectl get po
Error from server (Forbidden): pods is forbidden: User "yuchao-admin" cannot list resource "pods" in API group "" in the namespace "default"
创建role、rolebinding

限制yuchao-admin这个用户、只能访问yuchao这个namespace下的所有资源;
创建Role、以及Rolebinding。
# 定义权限
[root@k8s-master ~/my_kubeconfig]#cat yuchao-admin-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: yuchao
name: yuchao-admin
rules:
- apiGroups: ["*"] # "" 指定核心 API 组
resources: ["*"]
verbs: ["*"]
# 定义绑定
[root@k8s-master ~/my_kubeconfig]#cat yuchao-admin-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: yuchao-admin
namespace: yuchao
subjects:
- kind: User # 指定哪个用户,证书里写了用户名
name: yuchao-admin # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role #this must be Role or ClusterRole
name: yuchao-admin # 这里的名称必须与你想要绑定的 Role 或 ClusterRole 名称一致
apiGroup: rbac.authorization.k8s.io
你现在能创建这俩配置吗?不能,你别忘了,你当前这个yuchao-admin是没权限修改k8s资源的。
改回默认的k8s上下文
[root@k8s-master ~/my_kubeconfig]#unset KUBECONFIG
[root@k8s-master ~/my_kubeconfig]#
[root@k8s-master ~/my_kubeconfig]#kubectl get no -v=7
I0406 23:52:25.528645 70345 loader.go:372] Config loaded from file: /root/.kube/config
I0406 23:52:25.535116 70345 round_trippers.go:463] GET https://10.0.0.80:6443/api/v1/nodes?limit=500
I0406 23:52:25.535130 70345 round_trippers.go:469] Request Headers:
I0406 23:52:25.535136 70345 round_trippers.go:473] Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json
I0406 23:52:25.535141 70345 round_trippers.go:473] User-Agent: kubectl/v1.24.4 (linux/amd64) kubernetes/95ee5ab
I0406 23:52:25.540773 70345 round_trippers.go:574] Response Status: 200 OK in 5 milliseconds
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 27d v1.24.4
k8s-slave1 Ready <none> 27d v1.24.4
k8s-slave2 Ready <none> 27d v1.24.4
[root@k8s-master ~/my_kubeconfig]#kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
[root@k8s-master ~/my_kubeconfig]#kubectl config get-clusters
NAME
kubernetes
[root@k8s-master ~/my_kubeconfig]#kubectl config view --minify
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://10.0.0.80:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
创建自建的RBAC
[root@k8s-master ~/my_kubeconfig]#kubectl create -f yuchao-admin-role.yaml
role.rbac.authorization.k8s.io/yuchao-admin created
[root@k8s-master ~/my_kubeconfig]#kubectl create -f yuchao-admin-rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/yuchao-admin created
# 检查
[root@k8s-master ~/my_kubeconfig]#kubectl get role -n yuchao -oyaml
apiVersion: v1
items:
- apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: "2023-04-06T15:53:53Z"
name: yuchao-admin
namespace: yuchao
resourceVersion: "2208216"
uid: c338a9f5-df43-4643-814f-0aa33d2dea8f
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
kind: List
metadata:
resourceVersion: ""
# rolebinding
[root@k8s-master ~/my_kubeconfig]#kubectl get rolebindings.rbac.authorization.k8s.io -n yuchao -oyaml
apiVersion: v1
items:
- apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: "2023-04-06T15:53:58Z"
name: yuchao-admin
namespace: yuchao
resourceVersion: "2208226"
uid: 5c12a607-4ea6-42c4-9f81-60e396513bcc
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: yuchao-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: yuchao-admin
kind: List
metadata:
resourceVersion: ""
再次切换上下文
# 切换认证文件(换个工牌!)
export KUBECONFIG=/root/my_kubeconfig/yuchao.kubeconfig
# 查看工牌的信息
[root@k8s-master ~/my_kubeconfig]#kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://10.0.0.80:6443
name: yuchao-cluster
contexts:
- context:
cluster: yuchao-cluster
user: yuchao-admin
name: yuchao-context
current-context: yuchao-context
kind: Config
preferences: {}
users:
- name: yuchao-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
# 使用工牌身份的权限,是允许访问yuchao这个ns下所有的资源的
[root@k8s-master ~/my_kubeconfig]#kubectl get all -n yuchao
# 使用工牌身份创建个nginx
[root@k8s-master ~/my_kubeconfig]#kubectl run --image=nginx:alpine yuchao-ngx -n yuchao
pod/yuchao-ngx created
[root@k8s-master ~/my_kubeconfig]#kubectl get po -n yuchao
NAME READY STATUS RESTARTS AGE
eladmin-api-79b478cf54-m5ntl 1/1 Running 2 (3d2h ago) 4d20h
eladmin-web-759f77b7cb-g2z8c 1/1 Running 0 3d2h
mysql-7c7cf8495f-5w5bk 1/1 Running 1 (3d2h ago) 16d
ngx-test 1/1 Running 1 (3d2h ago) 6d22h
redis-7957d49f44-cxj8z 1/1 Running 1 (3d2h ago) 16d
yuchao-ngx 1/1 Running 0 5s
[root@k8s-master ~/my_kubeconfig]#kubectl get po -n yuchao -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
eladmin-api-79b478cf54-m5ntl 1/1 Running 2 (3d2h ago) 4d20h 10.244.0.48 k8s-master <none> <none>
eladmin-web-759f77b7cb-g2z8c 1/1 Running 0 3d2h 10.244.1.47 k8s-slave2 <none> <none>
mysql-7c7cf8495f-5w5bk 1/1 Running 1 (3d2h ago) 16d 10.244.0.52 k8s-master <none> <none>
ngx-test 1/1 Running 1 (3d2h ago) 6d22h 10.244.1.44 k8s-slave2 <none> <none>
redis-7957d49f44-cxj8z 1/1 Running 1 (3d2h ago) 16d 10.244.1.46 k8s-slave2 <none> <none>
yuchao-ngx 1/1 Running 0 10s 10.244.2.67 k8s-slave1 <none> <none>
[root@k8s-master ~/my_kubeconfig]#curl 10.244.2.67
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@k8s-master ~/my_kubeconfig]#
至此,这个配置文件,可以用于发给其他部门,被允许管理yuchao这个业务namespace下的资源。
[root@k8s-master ~/my_kubeconfig]#cat yuchao.kubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data:
...
...
server: https://10.0.0.80:6443
name: yuchao-cluster
contexts:
- context:
cluster: yuchao-cluster
user: yuchao-admin
name: yuchao-context
current-context: yuchao-context
kind: Config
preferences: {}
users:
- name: yuchao-admin
user:
client-certificate-data:
...
...
client-key-data:
......
[root@k8s-master ~/my_kubeconfig]#
小结
务必记住
/root/.kube/config
千万不能给别人,cluster-admin有集群最高权限。
因此给其他业务组,创建额外的 namespace,以及如 yuchao.kubeconfig 认证的文件。
图解

RBAC小计
如何理解user、group
在Kubernetes中,Role-Based Access Control(RBAC)是一种授权机制,它允许管理员定义哪些用户、组或服务帐户可以执行哪些操作(例如创建、修改、删除资源)。在Kubernetes RBAC中,用户(User)和组(Group)是两个基本的身份验证实体。
用户是一个具有一定标识信息的实体,例如用户名、客户端证书等。可以将用户授权给访问Kubernetes集群中的资源,例如Pod、Deployment等。用户可以直接分配到Role中,也可以通过绑定到组的方式授权给某个Role。
组是一组用户的集合,组的成员可以共享相同的权限。在Kubernetes中,组是由一组用户组成的,可以在Kubernetes中的ClusterRoleBindings和RoleBindings中使用组进行授权。这种授权方式可以在集群范围内或命名空间范围内进行。
因此,在Kubernetes中,用户和组通常是通过命名空间级别的RoleBinding或ClusterRoleBinding与Role或ClusterRole关联起来。通过这种方式,用户和组可以获得对Kubernetes资源的访问权限,从而完成特定的任务或操作。
我们是无法直接去查看User、group的
因为这俩是如一个证书文件里,授权的user、group
通过默认的kube-apiserver去检查认证的用户信息
[root@k8s-master ~/my_kubeconfig]#cat /etc/kubernetes/manifests/kube-apiserver.yaml |grep certfile
- --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
[root@k8s-master ~/my_kubeconfig]#
[root@k8s-master ~/my_kubeconfig]#cat /etc/kubernetes/manifests/kube-apiserver.yaml |grep ca-file
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
[root@k8s-master ~/my_kubeconfig]#
--tls-cert-file和--tls-private-key-file指定kube-apiserver使用的证书和私钥文件。--client-ca-file指定用于验证客户端证书的CA证书文件。--authentication-token-webhook-config-file和--authorization-webhook-config-file指定kube-apiserver使用的Webhook配置文件,用于对客户端的请求进行身份验证和授权。
解析出根证书的信息,查询出user、group
/etc/kubernetes/pki/ca.crt
# 解析出证书信息
[root@k8s-master ~/my_kubeconfig]#openssl x509 -in /etc/kubernetes/pki/ca.crt -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 0 (0x0)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kubernetes
Validity
Not Before: Mar 9 15:55:00 2023 GMT
Not After : Mar 6 15:55:00 2033 GMT
Subject: CN=kubernetes # 这玩意就是k8s上下文的名字
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
# 查看上下文信息
# 上下文 = cluster(kubernetes) + user(kubernetes-admin)
[root@k8s-master ~/my_kubeconfig]#kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://10.0.0.80:6443
name: kubernetes # 集群名
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin # 用户名
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
# 查看上下文信息
[root@k8s-master ~/my_kubeconfig]#kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
图解k8s的认证、授权基础(重点)

鉴权的过程就是检查User、Group、ServiceAccount 是否有访问当前请求资源的权限
- namespace
- get、delete 等
Kubernetes (k8s) 是一个容器编排平台,具有强大的安全功能,包括认证和授权。以下是 k8s 的认证和授权的概述:
- 认证(Authentication):是指验证用户或其他实体的身份的过程。k8s 支持各种认证方法,包括基于令牌(Token)、用户名和密码、证书、外部认证(External Authentication)等方式。
- 授权(Authorization):是指确定一个实体是否被允许执行某个操作的过程。k8s 使用访问控制列表(Access Control List, ACL)来授权用户对集群资源的访问。Kubernetes 中的 ACL 由角色和角色绑定(Role-Based Access Control, RBAC)来管理。通过 RBAC,管理员可以创建角色和角色绑定,将角色绑定分配给不同的用户或用户组,从而控制它们对 k8s 集群中各种资源的访问。
- 安全传输(Secure Communication):k8s 支持使用 TLS 加密的方式来保证节点之间的通信安全,从而保护数据的机密性和完整性。
总的来说,k8s 的认证和授权机制是非常强大和灵活的,可以确保只有授权的实体能够访问 k8s 集群中的资源,并保护用户数据的安全性和完整性。
Admission Control
Kubernetes Admission Control(准入控制)是一种在 Kubernetes API 服务器上运行的控制器,它用于对 Kubernetes 资源进行预先筛选和修改,以确保 Kubernetes 资源的配置和使用符合组织的策略和安全需求。
Admission Controller 可以拒绝或修改请求,也可以在请求被接受之前自动执行一些操作。它可以用于执行各种任务,如自动注入 sidecar、注入默认值、验证资源名称、强制使用特定的标签、添加默认存储类等。使用 Admission Controller 可以帮助 Kubernetes 用户确保在创建和更新资源时遵循企业的最佳实践和安全政策。
Admission Controller 也可以用于实现自定义策略。Kubernetes 中的 Dynamic Admission Control(动态准入控制)可以通过 CRD(Custom Resource Definition)和 Webhook 的方式实现,从而允许用户编写自己的 Admission Controller 并将其与 Kubernetes API 服务器集成,以自定义特定的准入控制策略。这种灵活性使得 Kubernetes 可以轻松地适应不同的安全和管理需求。
综上所述,Admission Control 是 Kubernetes 安全和策略的关键组件,它通过预先筛选和修改 Kubernetes 资源来确保 Kubernetes 集群的安全和合规性。
Admission Control和Service Account是Kubernetes中两个不同但相关的概念。
Admission Control是一种Kubernetes安全特性,它允许管理员在Pod被创建、更新或删除之前对其进行验证和修改。这可以确保只有合法的Pod才能被部署到集群中,并防止了一些安全漏洞的出现。Admission Control可以通过一系列的插件来实现,例如NamespaceLifecycle、LimitRanger、ResourceQuota等。
而Service Account则是一种身份验证机制,它为Pod提供了一种身份验证方式,使得Pod可以与Kubernetes API Server进行安全的交互。Pod中的应用程序可以使用Service Account来获取访问Kubernetes API Server所需的令牌,并且只能访问其所具备权限的资源。
这两个概念之间的关系是,Admission Control可以使用Service Account来验证和控制Pod的身份和访问权限,以确保Pod只能够访问其所具备的权限范围内的资源。因此,使用Service Account可以帮助管理员更好地实现Admission Control,以保证整个集群的安全性。
什么是service Account
在 Kubernetes 中,ServiceAccount 是一种资源对象,它为 Pod 提供了一种身份验证机制,以便它们可以相互通信并访问其他 Kubernetes 资源。
每个 ServiceAccount 都会被分配一个唯一的名称,并且它会被分配一个自己的 token,这个 token 可以用来与 Kubernetes API 服务器进行通信并访问其他 Kubernetes 资源。
Pod 可以通过挂载该 ServiceAccount 的 token 来使用它的身份验证信息。
ServiceAccount 可以用于授予 Pod 访问 Kubernetes API 或其他资源的权限,而无需使用 Kubernetes 集群中的其他身份验证机制。它还可以用于在 Pod 之间进行通信,以确保它们只与被授权的其他 Pod 进行通信。
在 Kubernetes 中,默认情况下每个 Namespace 都会有一个名为 default 的 ServiceAccount。如果没有显式指定 ServiceAccount,则 Pod 将使用该 Namespace 中的默认 ServiceAccount。
理解 ServiceAccount 的概念可以帮助开发人员更好地管理 Kubernetes 中的身份验证和授权机制,从而提高应用程序的安全性和可靠性。
前面说,认证可以通过证书,也可以通过使用ServiceAccount(服务账户)的方式来做认证。
大多数时候,我们在基于k8s做二次开发时都是选择通过ServiceAccount + RBAC 的方式。
查看k8s已有的service account
# default默认下的sa
[root@k8s-master ~]#kubectl get sa
NAME SECRETS AGE
default 0 29d
[root@k8s-master ~]#kubectl get sa -oyaml
apiVersion: v1
items:
- apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2023-03-09T15:55:23Z"
name: default
namespace: default
resourceVersion: "329"
uid: 820dbfca-23f0-4022-bf80-e21565444c31
kind: List
metadata:
resourceVersion: ""
# 换一个ns看看
[root@k8s-master ~]#kubectl -n ingress-nginx get sa
NAME SECRETS AGE
default 0 10d
ingress-nginx 0 10d
ingress-nginx-admission 0 10d
以ingress-nginx为例
咱知道,ingress-nginx是第三方的组件,需要加入到k8s集群里,并且还要访问集群资源;
它的权限怎么来的?
ingress-nginx-controller 需要监听ingress资源,权限如何获取?

[root@k8s-master ~]#kubectl -n ingress-nginx get po
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-h5l9c 0/1 Completed 0 10d
ingress-nginx-controller-5cf5b685c5-c7k65 1/1 Running 5 (44m ago) 9d
[root@k8s-master ~]#
# 该ingress-nginx-controller是通过的serviceaccount进行的认证、授权
[root@k8s-master ~]#kubectl -n ingress-nginx get po ingress-nginx-controller-5cf5b685c5-c7k65 -oyaml |grep serviceAccount
serviceAccount: ingress-nginx
serviceAccountName: ingress-nginx
- serviceAccountToken:
# 查看sa,服务账户
[root@k8s-master ~]#kubectl -n ingress-nginx get sa
NAME SECRETS AGE
default 0 10d
ingress-nginx 0 10d
ingress-nginx-admission 0 10d
[root@k8s-master ~]#
# 也可以查看你当时安装ingress-nginx-controller时,下载的deploy.yaml
# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.4.0/deploy/static/provider/cloud/deploy.yaml
# 创建资源依次是
# 也就是你安装ingress-nginx时,自动的创建了RBAC的规则
[root@k8s-master ~/k8s-all]#cat deploy.yaml |grep kind
kind: Namespace
kind: ServiceAccount
kind: ServiceAccount
kind: Role
kind: Role
kind: ClusterRole
kind: ClusterRole
kind: RoleBinding
kind: Role
- kind: ServiceAccount
kind: RoleBinding
kind: Role
- kind: ServiceAccount
kind: ClusterRoleBinding
kind: ClusterRole
- kind: ServiceAccount
kind: ClusterRoleBinding
kind: ClusterRole
- kind: ServiceAccount
kind: ConfigMap
kind: Service
kind: Service
kind: Deployment
kind: Job
kind: Job
kind: IngressClass
kind: ValidatingWebhookConfiguration
# 查看ingress-nginx的clusterRole,有哪些权限
# 也就是
[root@k8s-master ~/k8s-all]#kubectl -n ingress-nginx describe clusterrole ingress-nginx
Name: ingress-nginx
Labels: app.kubernetes.io/instance=ingress-nginx
app.kubernetes.io/name=ingress-nginx
app.kubernetes.io/part-of=ingress-nginx
app.kubernetes.io/version=1.4.0
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
events [] [] [create patch]
services [] [] [get list watch]
ingressclasses.networking.k8s.io [] [] [get list watch]
ingresses.networking.k8s.io [] [] [get list watch]
nodes [] [] [list watch get]
endpointslices.discovery.k8s.io [] [] [list watch get]
configmaps [] [] [list watch]
endpoints [] [] [list watch]
namespaces [] [] [list watch]
pods [] [] [list watch]
secrets [] [] [list watch]
leases.coordination.k8s.io [] [] [list watch]
ingresses.networking.k8s.io/status [] [] [update]
[root@k8s-master ~/k8s-all]#
# 发现是被允许访问如下资源权限的,基本是只读的
# ingresses.networking.k8s.io [] [] [get list watch]
理解ingress-nginx的SA
什么是JWT
当您在Kubernetes中创建Service Account时,它会自动为该账户生成一个与之关联的JWT(JSON Web Token),用于进行身份验证和授权。
JWT是一种在Web应用程序中广泛使用的开放标准,可以安全地将信息传递给另一个方。
使用ServiceAccount不用创建证书了,本身是通过token进行的认证。
[root@k8s-master ~/k8s-all]#kubectl -n ingress-nginx exec -it ingress-nginx-controller-5cf5b685c5-c7k65 -- bash
bash-5.1$ df -h
Filesystem Size Used Available Use% Mounted on
overlay 45.1G 7.5G 37.6G 17% /
tmpfs 64.0M 0 64.0M 0% /dev
tmpfs 3.8G 0 3.8G 0% /sys/fs/cgroup
/dev/mapper/centos-root
45.1G 7.5G 37.6G 17% /etc/hosts
/dev/mapper/centos-root
45.1G 7.5G 37.6G 17% /dev/termination-log
/dev/mapper/centos-root
45.1G 7.5G 37.6G 17% /etc/hostname
/dev/mapper/centos-root
45.1G 7.5G 37.6G 17% /etc/resolv.conf
shm 64.0M 0 64.0M 0% /dev/shm
tmpfs 7.5G 12.0K 7.5G 0% /usr/local/certificates
tmpfs 7.5G 12.0K 7.5G 0% /run/secrets/kubernetes.io/serviceaccount
tmpfs 3.8G 0 3.8G 0% /proc/acpi
tmpfs 64.0M 0 64.0M 0% /proc/kcore
tmpfs 64.0M 0 64.0M 0% /proc/keys
tmpfs 64.0M 0 64.0M 0% /proc/timer_list
tmpfs 64.0M 0 64.0M 0% /proc/timer_stats
tmpfs 64.0M 0 64.0M 0% /proc/sched_debug
tmpfs 3.8G 0 3.8G 0% /proc/scsi
tmpfs 3.8G 0 3.8G 0% /sys/firmware
bash-5.1$
/run/secrets/kubernetes.io/serviceaccount 是 Kubernetes 中的一个特殊文件夹,用于存储服务账户相关的凭据信息。当在 Kubernetes 集群中创建一个服务账户时,Kubernetes 会自动生成一个包含了账户令牌和 CA 证书的 Secrets 对象,并把该 Secrets 对象 mount 到 /run/secrets/kubernetes.io/serviceaccount 文件夹中,让容器能够方便地访问这些凭据信息。
这些凭据信息可用于在容器内部进行 Kubernetes API 的认证和授权,以及在容器内部访问 Kubernetes 集群中的其它资源,如 Pod、Service 等。容器可以通过读取 /run/secrets/kubernetes.io/serviceaccount/token 文件获取账户的令牌,通过读取 /run/secrets/kubernetes.io/serviceaccount/ca.crt 文件获取集群的 CA 证书。
使用 /run/secrets/kubernetes.io/serviceaccount 文件夹中的凭据信息,可以让容器在不暴露敏感信息的情况下,轻松地与 Kubernetes 集群进行交互和通信。
bash-5.1$ pwd
/run/secrets/kubernetes.io/serviceaccount
bash-5.1$ ls
ca.crt namespace token
# 使用token,可以允许访问k8s的API
cat /run/secrets/kubernetes.io/serviceaccount/token
Pod中若指定了serviceAccount,则k8s自动为Pod载/run/secrets/kubernetes.io/serviceaccount/token这个文件;
文件内容为token信息,业务程序可以使用该token进行k8s api的调用,同时,该token的访问权限与对应的serviceAccount的权限一致。
# 使用token,查看集群的节点情况(等于kubectl get no)
# 你肯定得有权限吧
# token就代表了ServiceAcccount
curl -k -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IllmUUhDWV9wUXEtcEZDRlhuQzlRZTMxQ0czdkhuUU9YRThNR1daVExvOVEifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzEyNDIwNjE4LCJpYXQiOjE2ODA4ODQ2MTgsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJpbmdyZXNzLW5naW54IiwicG9kIjp7Im5hbWUiOiJpbmdyZXNzLW5naW54LWNvbnRyb2xsZXItNWNmNWI2ODVjNS1jN2s2NSIsInVpZCI6IjJmZjMxODU4LTkwODAtNDI4Ny1iZDJlLTMxMzM5NzI4NGU0NSJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiaW5ncmVzcy1uZ2lueCIsInVpZCI6IjU4YTk5Y2YwLTUwOTQtNDA2OS1hOGVjLWZjMWU0MWUwZmY4ZCJ9LCJ3YXJuYWZ0ZXIiOjE2ODA4ODgyMjV9LCJuYmYiOjE2ODA4ODQ2MTgsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDppbmdyZXNzLW5naW54OmluZ3Jlc3MtbmdpbngifQ.BxH-hqFkK0USWYG2l-BSanwMmo3T178YskYPPBWeZ29QwpG6h1mUCsVWXAVjcZzEHSeENIVn5XC9q9lvVrrS5rxFg1i5A7sHaOIMGK0Phz3_nkypsQ2Pp7poaVOvScnywnTCTV9-RXxp12Hy-FUnZ3MhgN90uArde0u9TdGZshUcfs1ONEqC2TxbaHNG9QUP0afEiz1OjQC8W1an_0bRtG7XKIlo_lQS5cMKsDFj1GElMGtRYAccp6aHvlRZ2h8eXSOr2YYqHQpfhKMsc6JqhjZ0_AO6y4P--mCi_nbZcz37gJhHV1W5RYs01Uq-g14dUdIyZijDUy3W8hsfW-WIVQ" https://10.0.0.80:6443/api/v1/nodes
上面也看到了ingress-nginx的clusterrole的权限,被允许访问哪些资源。
对比kubectl理解下,例如我们查看自建的ingress资源,有哪些
[root@k8s-master ~]#kubectl -n yuchao get ingress -v=7
I0408 00:51:25.121706 39507 loader.go:372] Config loaded from file: /root/.kube/config
I0408 00:51:25.124682 39507 round_trippers.go:463] GET https://10.0.0.80:6443/apis/networking.k8s.io/v1/namespaces/yuchao/ingresses?limit=500
I0408 00:51:25.124692 39507 round_trippers.go:469] Request Headers:
I0408 00:51:25.124697 39507 round_trippers.go:473] Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json
I0408 00:51:25.124702 39507 round_trippers.go:473] User-Agent: kubectl/v1.24.4 (linux/amd64) kubernetes/95ee5ab
I0408 00:51:25.128940 39507 round_trippers.go:574] Response Status: 200 OK in 4 milliseconds
NAME CLASS HOSTS ADDRESS PORTS AGE
eladmin-api nginx eladmin.yuchao.com 80 9d
eladmin-web nginx eladmin.yuchao.com 80, 443 9d
# kubectl用的证书,通过的认证、授权
# curl命令加上token,也可以通过RBAC
# 使用token,查看集群的节点情况(等于kubectl get no)
# 你肯定得有权限吧
# token就代表了ServiceAcccount
bash-5.1$ curl -s -k -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IllmUUhDWV9wUXEtcEZDRlhuQzlRZTMxQ0czdkhuUU9YRThNR1daVExvOVEifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzEyNDIwNjE4LCJpYXQiOjE2ODA4ODQ2MTgsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJpbmdyZXNzLW5naW54IiwicG9kIjp7Im5hbWUiOiJpbmdyZXNzLW5naW54LWNvbnRyb2xsZXItNWNmNWI2ODVjNS1jN2s2NSIsInVpZCI6IjJmZjMxODU4LTkwODAtNDI4Ny1iZDJlLTMxMzM5NzI4NGU0NSJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiaW5ncmVzcy1uZ2lueCIsInVpZCI6IjU4YTk5Y2YwLTUwOTQtNDA2OS1hOGVjLWZjMWU0MWUwZmY4ZCJ9LCJ3YXJuYWZ0ZXIiOjE2ODA4ODgyMjV9LCJuYmYiOjE2ODA4ODQ2MTgsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDppbmdyZXNzLW5naW54OmluZ3Jlc3MtbmdpbngifQ.BxH-hqFkK0USWYG2l-BSanwMmo3T178YskYPPBWeZ29QwpG6h1mUCsVWXAVjcZzEHSeENIVn5XC9q9lvVrrS5rxFg1i5A7sHaOIMGK0Phz3_nkypsQ2Pp7poaVOvScnywnTCTV9-RXxp12Hy-FUnZ3MhgN90uArde0u9TdGZshUcfs1ONEqC2TxbaHNG9QUP0afEiz1OjQC8W1an_0bRtG7XKIlo_lQS5cMKsDFj1GElMGtRYAccp6aHvlRZ2h8eXSOr2YYqHQpfhKMsc6JqhjZ0_AO6y4P--mCi_nbZcz37gJhHV1W5RYs01Uq-g14dUdIyZijDUy3W8hsfW-WIVQ" https://10.0.0.80:6443/apis/networking.k8s.io/v1/namespaces/yuchao/ingresses?limit=500 |grep yuchao.com
"host": "eladmin.yuchao.com",
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"networking.k8s.io/v1\",\"kind\":\"Ingress\",\"metadata\":{\"annotations\":{},\"name\":\"eladmin-web\",\"namespace\":\"yuchao\"},\"spec\":{\"ingressClassName\":\"nginx\",\"rules\":[{\"host\":\"eladmin.yuchao.com\",\"http\":{\"paths\":[{\"backend\":{\"service\":{\"name\":\"eladmin-web\",\"port\":{\"number\":80}}},\"path\":\"/\",\"pathType\":\"Prefix\"}]}}],\"tls\":[{\"hosts\":[\"eladmin.yuchao.com\"],\"secretName\":\"tls-eladmin\"}]}}\n",
"eladmin.yuchao.com"
"host": "eladmin.yuchao.com",
# 发现没问题
# 注意,token错一个字母,都是401权限不足
图解token作用

测试创建ServiceAccount
pod默认的sa
在 Kubernetes 中,每个 Pod 都被分配了一个 ServiceAccount,用于授权 Pod 访问 API Server 中的资源。默认情况下,如果您没有为 Pod 显式指定 ServiceAccount,则会使用 default ServiceAccount。每个 Namespace 中都会有一个 default ServiceAccount,因此每个 Pod 都可以使用它来与 API Server 进行交互。
当 Pod 使用 ServiceAccount 进行 API 调用时,Kubernetes 会根据该 ServiceAccount 的角色和权限,对请求进行身份验证和授权。如果 Pod 没有使用 ServiceAccount 进行身份验证,则该 Pod 的请求将被拒绝。
因此,为了保证 Pod 的正常运行并能够与 Kubernetes API Server 进行交互,每个 Pod 都需要分配一个默认的 ServiceAccount,即 serviceAccount: default 和 serviceAccountName: default。这样可以确保 Pod 具有必要的权限和访问级别,并且可以通过 ServiceAccount 进行身份验证和授权。
修改eladmin-web的sa
得修改deployment控制器
1.创建一个serviceaccount
[root@k8s-master ~]#kubectl -n yuchao get sa
NAME SECRETS AGE
default 0 18d
[root@k8s-master ~]#
[root@k8s-master ~/k8s-all]#kubectl -n yuchao create sa eladmin-web
serviceaccount/eladmin-web created
[root@k8s-master ~/k8s-all]#kubectl -n yuchao get sa
NAME SECRETS AGE
default 0 18d
eladmin-web 0 10s
2.修改你的deployement绑定这个sa
添加 Service Account:在您的 Deployment 文件中,找到 spec.template.spec 部分,其中包含有关该 Deployment 要创建的 Pod 的详细信息。
您需要在此部分中添加 spec.template.spec.serviceAccountName 字段,并设置其值为您要使用的 Service Account 的名称。

因为是给pod副本设置的,因此在spec.template.spec给所有容器添加
[root@k8s-master ~/k8s-all]#kubectl -n yuchao get po -w
进入新的pod看看
[root@k8s-master ~]#kubectl -n yuchao exec -it eladmin-web-7458474b64-c57nc -- sh
/usr/share/nginx/html #
df |grep sec
tmpfs 2097152 12 2097140 0% /run/secrets/kubernetes.io/serviceaccount
/run/secrets/kubernetes.io/serviceaccount # ls
ca.crt namespace token
可知、创建serviceAccount
↓
pod结合sa
↓
自动在pod中挂载一个sericeaccount目录,存放token
有权限吗这会吗?
[root@k8s-master ~]#kubectl -n yuchao get sa eladmin-web -oyaml
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2023-04-07T17:33:17Z"
name: eladmin-web
namespace: yuchao
resourceVersion: "2350139"
uid: faf47263-ad8f-4eb0-b5f4-03f6d7914759
这一步,你就等于之前创建证书那一套,是有身份认证的。
但是权限呢?ClusterRole啥的都没有。
你这个token是没任何权限的(你被允许进入大楼,但是你啥也不能干,看都不行)
curl -s -k -H "Authorization: Bearer xxx-token" https://10.0.0.80:6443/apis/networking.k8s.io/v1/namespaces/yuchao/ingresses?limit=500
添加RBAC规则
给serviceaccount绑定个role,允许有yuchao这个namespace下的所有资源。
这里的操作你就理解,给某个人单独分配个权限,让他允许访问某个大厦里的一个店铺。
# role创建
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: yuchao
name: eladmin-web-reader-writer
rules:
- apiGroups: ["*"] # "" indicates the core API group
resources: ["*"]
verbs: ["*"]
# 创建clusterRolebinding
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: eladmin-web-reader-writer
namespace: yuchao
subjects:
- kind: ServiceAccount #这里可以是User,Group,ServiceAccount
name: eladmin-web # 绑定你的sa
namespace: yuchao
roleRef:
kind: Role #这里可以是Role或者ClusterRole,若是ClusterRole,则权限也仅限于rolebinding的内部
name: eladmin-web-reader-writer
apiGroup: rbac.authorization.k8s.io
创建检查
[root@k8s-master ~/k8s-all]#kubectl create -f eladmin-rbac.yaml
role.rbac.authorization.k8s.io/eladmin-web-reader-writer created
rolebinding.rbac.authorization.k8
[root@k8s-master ~/k8s-all]#kubectl -n yuchao get rolebindings.rbac.authorization.k8s.io
NAME ROLE AGE
eladmin-web-reader-writer Role/eladmin-web-reader-writer 43s
yuchao-admin Role/yuchao-admin 27h
[root@k8s-master ~/k8s-all]#kubectl -n yuchao get role
NAME CREATED AT
eladmin-web-reader-writer 2023-04-07T19:20:16Z
yuchao-admin 2023-04-06T15:53:53Z
# 查看这个role有什么权限吗?
[root@k8s-master ~/k8s-all]#kubectl -n yuchao describe role eladmin-web-reader-writer
Name: eladmin-web-reader-writer
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
*.* [] [] [*]
# 查看这个role绑定谁了
[root@k8s-master ~/k8s-all]#kubectl -n yuchao describe rolebindings.rbac.authorization.k8s.io eladmin-web-reader-writer
Name: eladmin-web-reader-writer
Labels: <none>
Annotations: <none>
Role:
Kind: Role
Name: eladmin-web-reader-writer
Subjects:
Kind Name Namespace
---- ---- ---------
ServiceAccount eladmin-web yuchao
#
试试你serviceaccount有权限吗
非yuchao这个ns下的权限是没有的
/usr/share/nginx/html # curl -k -H "Authorization: Bearer
xxxwww.yuchaoit.cn-tokenxxxxx" https://10.0.0.80:6443/api/v1/namespaces/defaul
t/pods?limit=500
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "pods is forbidden: User \"system:serviceaccount:yuchao:eladmin-web\" cannot list resource \"pods\" in API group \"\" in the namespace \"default\"",
"reason": "Forbidden",
"details": {
"kind": "pods"
},
"code": 403
}/usr/share/nginx/html #
yuchao这个ns下的权限是有的
/usr/share/nginx/html # curl -k -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IllmUUhDWV9wUXEtcEZDRlhuQzlRZTMxQ0czdkhuUU9YRThNR1daVExvOVEifQ.eyJhdWQiOls
iaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzEyNDI5ODI2LCJpYXQiOjE2ODA4OTM4MjYsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbH
VzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJ5dWNoYW8iLCJwb2QiOnsibmFtZSI6ImVsYWRtaW4td2ViLTc0NTg0NzRiNjQtYzU3bmMiLCJ1aWQiOiI3YWM1NWJkOS02ZmU5LTQyOWQtY
TcwZS0wODY5MjkzZDNhYjcifSwic2VydmljZWFjY291bnQiOnsibmFtZSI6ImVsYWRtaW4td2ViIiwidWlkIjoiZmFmNDcyNjMtYWQ4Zi00ZWIwLWI1ZjQtMDNmNmQ3OTE0NzU5In0sIndhcm5hZnRlciI6MTY4MDg5
NzQzM30sIm5iZiI6MTY4MDg5MzgyNiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Onl1Y2hhbzplbGFkbWluLXdlYiJ9.RLvS9lrKkZqn-8XkpZd6C_-XPrnVf6XYiHcLwsPHhcZaDPOt6p7cUluI2YDwXFKvgp
PkmxTBGwPAFOgiRIfgXfgb4eCUqjkaCDqK4eFkkRlZdsl9bCKPSu8MC0gXAkO8S2KQYdpN2fGz9ieYhlAQDjlkldZfxmXo012WfkN1wl-uYOLT0XSOzX7iVl7fRqKa06-O8SrF4QwihhEP_l0oj-IF2s6CQ5S1dhXcq
pwnFGOeFa6DQhnkqwLNeCTeUSw6RhHecRlhPcCIQjYgpNNKo3v-uHXpdpIt4tO9P91GmKMu5fxeMIQ-Po-T8L5iXJ_z35S_c7hsvkDDBIHxManj-Q" https://10.0.0.80:6443/api/v1/namespaces/yuchao/
pods?limit=500 |grep yuchao
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 "namespace": "yuchao",
100 65483 0 65483 0 0 5915k 0 --:--:-- --:--:-- --:--:-- 6394k
"namespace": "yuchao",
"namespace": "yuchao",
"namespace": "yuchao",
"namespace": "yuchao",
"name": "yuchao-ngx",
"namespace": "yuchao",
"run": "yuchao-ngx"
"k:{\"name\":\"yuchao-ngx\"}": {
"name": "yuchao-ngx",
"name": "yuchao-ngx",
/usr/share/nginx/html #
至此,我们就完成了
- serviceaccount创建(认证)
- role、rolebinding创建(授权)
- 以及让pod使用sa
- 进入pod、获取并且使用sa创建的token,验证了该token所持有的权限。
还有一个获取serviceAccount对应token的命令
[root@k8s-master ~/k8s-all]#kubectl -n yuchao create token eladmin-web
eyJhbGciOiJSUzI1NiIsImtpZCI6IllmUUhDWV9wUXEtcEZDRlhuQzlRZTMxQ0czdkhuUU9YRThNR1daVExvOVEifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjgwODk5NTgyLCJpYXQiOjE2ODA4OTU5ODIsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJ5dWNoYW8iLCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZWxhZG1pbi13ZWIiLCJ1aWQiOiJmYWY0NzI2My1hZDhmLTRlYjAtYjVmNC0wM2Y2ZDc5MTQ3NTkifX0sIm5iZiI6MTY4MDg5NTk4Miwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Onl1Y2hhbzplbGFkbWluLXdlYiJ9.bJJy5De53yy4kfvYIS6QNupaIzF2IlHp6Pp4GVDl-wZylEmWWqMyTBVc-dCpcq4VAcqeAkw9mlAzOxeJMEmHDLDL4pekZT1zcGbPHTEFba9Kx0YFrnqXGb476G63D8Ou0SHMyzKdpemQOgQtekhFqqb0pFTXzc-Nf5hbLbA3iFgNzOYf8fNf8PPQaJd28HiuUN4SVJ9o6ierBBnGENRn6yscGVCsnE9ly1rWw57-jlW1g0gVbgO3xf87NcOS0EH8fAxzeClvk6Sn2unhvL3pevgf_YEgs-PDFRTIVOZoxSKMiNCSA9SVoBokHaJ7GzoA4yQTDJzAwou75T0DudWj7A
# 每次执行都可以到该serviceaccount对应的token,都是随机的字符串,但是权限是一样的
小结
- 无论证书、还是SA、都是经过api-server走的RBAC进行认证、授权。
- kubectl等集群内操作,以证书去操作
- 通过代码、以API形式操作k8s都以token形式。