一、概述 :
API Server 作为 Kubernetes 集群系统的网关,是访问及管理资源对象的唯一人口,所有需要访问集群资源的组件,以及此前使用的 kubectl 命令等都要经由此网关进行集群访问和管理。
1 、 kubernetes API 访问控制
api server 是集群访问控制的统一入口
**K8s的认证过程:**认证 -> 授权 - > 准入控制 (admination controller)
用户通过kubectl、客户端库或者通过发送 REST 请求访问API。用户(自然人)和 Kubernetes 服务账户都可以被授权进行 API 访问。 请求到达 API 服务器后会经过几个阶段,具体说明如图:

首先看一下 Kubernetes API 请求的发起,请求的发起分为两个部分:
- 第一个部分是人机交互的过程。 是大家非常熟悉的用 kubectl 对 apiserver 的一个请求过程使用的是 Users Accounts普通账户;
- 第二个部分是 Pod 中的进程与 apiserver 之间的交互使用的是Service Accounts 服务帐号(ServiceAccount 为 Pod 中运行的进程提供了一个身份,Pod 内的进程可以使用其关联服务账号的身份,向集群的 APIServer 进行身份认证。)。
当我们的 apiserver 收到请求后,就会开启访问控制流程。这里面分为三个步骤:
1.Authentication 认证阶段:判断请求用户是否为能够访问集群的合法用户。如果用户是个非法用户,那 apiserver会返回一个 401 的状态码,并终止该请求;
2.如果用户合法的话,我们的 apiserver 会进入到访问控制的第二阶段 Authorization:授权阶段。在该阶段中apiserver 会判断用户是否有权限进行请求中的操作。如果无权进行操作,apiserver 会返回 403的状态码,并同样终止该请求;
3.如果用户有权进行该操作的话,访问控制会进入到第三个阶段:Admission Control。在该阶段中 apiserver 的admission controller 会判断请求是否是一个安全合规的请求。如果最终验证通过的话,访问控制流程才会结束。
为什么需要准入控制器呢?
k8s提供了多种准入控制机制,它有点类似"插件",为apiserver提供了很好的"可扩展性"。请求apiserver时,通过认证、鉴权后、持久化("api对象"保存到etcd)前,会经过"准入控制器",让它可以做"变更和验证"。
如果我们创建pod时定义了资源上下限,但不满足LimitRange规则中定义的资源上下限,此时LimitRanger就会拒绝我们创建此pod
假如我们定义了一个名称空间叫做test-aa,这个名称空间做下资源限制:限制最多可以使用10vCPU、10Gi内存,在这个名称空间test-aa下创建的所有pod,定义limit的时候,所有pod的limit值不能超过test-aa这个名称空间设置的limit上线。
此时我们的请求将会转换为一个 Kubernetes objects 相应的变更请求,最终持久化到 ETCD 中。
认证(任意一种) -->授权(一般是rbac 和 node)--> 准入控制(自己选择)

2、 认证 Authentication
认证(Authentication)是指用户是否可以登录/访问Kubernetes,即是否可以向 API Server 发送请求。
认证有多种,可以启动一种或多种认证方式,只要有一种认证方式通过,就不再对其它方式认证,通常启动X509 Client Certs和Service Accout Tokens两种认证方式
其他常见的认证:
- 引导令牌(Token) : 如:节点加入时认证:kubelet
- 静态令牌: 存储于API Server进程可直接加载到的文件中保存的令牌,该文件内容会由API Server缓存于内存中;
- 静态密码:存储于API Server进程可直接加载到的文件中保存的账户和密码令牌,该文件内容会由API Server缓存于内存中;
- ServiceAccount令牌:
- OpenID Connect令牌:OIDC令牌,
- OAuth 2 webhook令牌
- 代理认证等
访问k8s的API Server的客户端(用户)主要分为两类:
- kubectl :用户家目录中的 .kube/config 里面保存了客户端访问API Server的密钥相关信息,这样当用kubectl访问k8s时,它就会自动读取该配置文件,向API Server发起认证,然后完成操作请求,使用Users Accounts普通账户。
- pod:Pod中的进程需要访问API Server,而Pod自身去连接API Server时,使用的账号是:Service Account,生产中后者使用居多。
所以在 Kubernetes 中,有两类用户:
- Normal Users:外部用户,即普通用户,通常是给人使用的,标记的是个人,平时常用的kubectl命令都是普通用户执行的。
- Service Accounts:内部用户,即服务账户,通常都是用于pod 中的应用授权,例如pod 中的程序要访问集群做一些操作就可以使用sa ,默认pod都有一个default sa。
如何理解k 8s 的N ormal User?
Normal User(用户账号):一般是指由独立于Kubernetes之外的其他服务管理的用户账号,例如由管理员分发的密钥、Keystone一类的用户存储(账号库)、甚至是包含有用户名和密码列表的文件等。Kubernetes中不存在表示此类用户账号的对象, 因此不能被直接添加进 Kubernetes 系统中 。
如果用户都不在 Kubernetes 中,都不归它管,那它是如何进行认证的呢?
对于一般的应用系统来说,用户提供用户名和密码,服务端收到过后会在数据库中进行检查是否存在并有效,如果有就表示认证成功,反之失败。
那对于 Kubernetes 来说,是如何实现的呢?
尽管无法通过 API 调用来添加普通用户,Kubernetes 巧妙的通过证书来进行用户认证。也就是说,不管任何用户,只要能提供有效的证书就能通过 Kubernetes 用户认证。
通过用户认证过后,Kubernetes 会把证书中的 CN 作为用户名(比如证书中"/CN=joker",则用户名就是 Joker),把 Organization 作为用户组,然后由用户名和用户组绑定的 Role 来决定用户的权限。
如何理解Ser vice Accounts ?
Service Accounts 由 Kubernetes 管理,用于为Pod 之中的服务进程在访问Kubernetes API时提供身份标识( identity )。它们被绑定到特定的 namespace,其可以通过 API Server 自己创建,也可以通过调用 API 来创建,比如使用 kubectl 客户端工具。
与 Normal Users 不同,Service Accounts 存在对应的 Kubernetes 对象,当创建 Service Accounts,会创建相应的 Secret,里面保存对应的密码信息(在 1.24.x 版本中,不会创建对应的 secret)。当创建的 Pod 指定了一个 Service Account,其 Secret 会被 Mount 到 Pod 中,Pod 中的进程就可以访问 Kubernetes API 了。
ServiceAccount令牌认证
K8S自动为每个Pod注入一个ServiceAccount令牌,在每个名称空间中,会自动存在(由ServiceAccount准入控制器负责)一个ServiceAccount,将被该空间下的每个Pod共享使用。
认证令牌保存于该空间下的一个Secret对象中,该对象中共有三个信息:
1.namespace
2.ca.crt
3.token
ServiceAccount资源定义格式:
bash
[root@master01 ~]# kubectl explain sa
apiVersion: v1 #ServiceAccount所属的API群组及版本
kind: serviceAccount #资源类型标识
metadata:
name <string> #资源名称
namespace <string> # ServiceAccount是名称空间级别的资源
automountServiceAccountToken <boolean> # 是否让Pod自动挂载API令牌
secrets <[]object> #以该SA运行的Pod所要使用的Secret对象组成的列表
apiVersion <string> #引用的Secret对象所属的API群组及版本,可省略
kind <string> #引用的资源的类型,这里是指Secret,可省略
name <string> #引用的Secret对象的名称,通常仅给出该字段即可
namespace <string> #引用的Secret对象所属的名称空间
uid <string># 引用的Secret对象的标识符;
imagePullSecrets <[]object> # 引用的用于下载Pod中容器镜像的Secret对象列表,之前讲到secret时提到过Pod挂载私有仓库secret,实际使用不方便需要每个Pod单独挂载,放到serviceaccount就不用每个Pod单独挂载
name <string> #docker-registry类型的Secret资源的名称
示例: 查看Pod 默认ServiceAccount及Secret
bash
[root@master01 ~]# kubectl get sa
NAME SECRETS AGE
default 0 121d
[root@master01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
centos-deployment-66d8cd5f8b-9x47c 1/1 Running 1 41h
demodb-0 1/1 Running 0 17h
demodb-1 1/1 Running 0 16h
默认情况下没有指定ServiceAccount,都会把默认的ServiceAccount挂载到Pod
bash
[root@master01 ~]# kubectl describe pod demodb-0
...
Service Account: default
...
Annotations: <none>
...
Mounts:
/demodb/data from data (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-fsshk (ro) #默认的ServiceAccount令牌
...
Volumes:
data:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: data-demodb-0
ReadOnly: false
default-token-fsshk: #默认的ServiceAccount令牌存储卷
Type: Secret (a volume populated by a Secret)
SecretName: default-token-fsshk
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events: <none>
每个名称空间下都自动生成一个默认的secret
bash
[root@master01 ~]# kubectl get secret
NAME TYPE DATA AGE
default-token-fsshk kubernetes.io/service-account-token 3 51d
[root@master01 ~]# kubectl get secret -n kube-system
NAME TYPE DATA AGE
.........
default-token-xjfpp kubernetes.io/service-account-token 3 51d
............
主要包含的3类信息,都是以加密方式显示
namespace、
ca.crt、
token
bash
[root@master01 ~]# kubectl describe secret default-token-xjfpp -n kube-system #查看secret 详细信息
Name: default-token-xjfpp
Namespace: kube-system
Labels: <none>
Annotations: kubernetes.io/service-account.name: default
kubernetes.io/service-account.uid: a7cfad17-e87a-42dd-8f34-46181dd43b05
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1066 bytes
namespace: 11 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ijh4bkpFMkMxV0FtZmxPTmxsV3ZhY3lIRnZiRjlaUnhFSXdHSnRGc21adUUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLXhqZnBwIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJhN2NmYWQxNy1lODdhLTQyZGQtOGYzNC00NjE4MWRkNDNiMDUiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06ZGVmYXVsdCJ9.ifUAhcEjhmSszILrjPkbmKAKuo6nDBPrmQTjz6HjBXw85eTsu-D5CCjGwSaVj7X6xqK3GTwcv-r8518pSv92rfbN5cc9FdpknJGjtuigCrksap1gHcqZvco3BM7KFEaTFpCaxiVvzp6YBh4pVmm4zAJGieE8964m3SwZqXUmf3VP3LyVDrYnlISQXoXy5oEXODe8694H1vwU3wuRmkwLOCV5QthTxFpx5siM7_KFkcBuG-pt0lTbf6d15OXk-WY6J3qkdbmLrJFaofAo-1tas6Fp7ziQnIAkG_lTrbXPHD-rHJf9v1PobVIVvlEe5hKc_V1tE36SEwpIYHb61DfWRw
说明:
https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/
我们可以简单总结下不同版本的 K8s 集群下面的 ServiceAccount Token 是如何工作的。
1.20(含 1.20)之前的版本,在创建 sa 时会自动创建一个 secret,然后会把这个 secret 通过投射卷挂载到 pod 里,该 secret 里面包含的 token 是永久有效的。
1.21~1.23 版本,在创建 sa 时也会自动创建 secret,但是在 pod 里并不会使用 secret 里的 token,而是由 kubelet 到 TokenRequest API 去申请一个 token,该 token 默认有效期为一年,但是 pod 每一个小时会更新一次 token。
1.24 版本及以上,在创建 sa 时不再自动创建 secret 了,只保留由 kubelet 到 TokenRequest API 去申请 token。
当然我们仍然可以手动创建 Secret 来保存 ServiceAccount 令牌,例如在你需要一个永不过期的令牌的时候。一旦手动创建一个 Secret 并将其关联到 ServiceAccount,Kubernetes 控制平面就会自动将令牌填充到该 Secret 中。
尽管存在手动创建长久 ServiceAccount 令牌的机制,但还是推荐使用 TokenRequest 获得短期的 API 访问令牌。
Pod 默认的挂载路径 /var/run/secrets/kubernetes.io/serviceaccount
bash
[root@master01 ~]# kubectl exec -it demodb-0 -- /bin/sh
/demodb/data # cd /var/run/secrets/kubernetes.io/serviceaccount
/run/secrets/kubernetes.io/serviceaccount # ls
ca.crt namespace token
/run/secrets/kubernetes.io/serviceaccount # cat namespace
/run/secrets/kubernetes.io/serviceaccount # cat ca.crt
-----BEGIN CERTIFICATE-----
MIIC5zCCAc+gAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl
cm5ldGVzMB4XDTIxMDYyODE3NDIxMFoXDTMxMDYyNjE3NDIxMFowFTETMBEGA1UE
AxMKa3ViZXJuZXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwQ
mCJJ0GuIDdzZa8XAJIy7BRUGBT0oI0lVuWc3PD25whr1MBRyUru0u0n7mKVQTzbY
0G8USHzwSnX51OoMpU5YwHK6WGLgJ6gdCfjAY6v12e7y+rvjOKYns6ljUf2MnaIL
nrCy1/u56Lnh1wCH1XkLECP539MFamYkRGxeS9FZlFcgLvJp43VX9V4IWQeumHd9
1abKVei/41qbbvyDU7l4l7klUmLUTGDlYpf1GPU/Jaom4QLRaEt2csYcNZ8J3yaY
GvOloGM150Rsx4vL8DWOqZcUUg/uXujKg1MfWRrD9KvqK1QdP92IE+l6nXUKY34r
voDCmOcL8J0nPyjbyf0CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB
/wQFMAMBAf8wHQYDVR0OBBYEFOwi2wrUbuvVmbiV2rnnLtz0hsgcMA0GCSqGSIb3
DQEBCwUAA4IBAQBCFkEU4gyouDs4hG0pjdlrJRkDw1kKg1JV8m3CqcKUKmJBUT9H
9R8LaU2s/6yS5zX3VSdUNgF1V/hpjUJ6bSud9Xfnmbw8lHKUucUSIWU9a+TGTvkn
DqI8FcC8gKstUAwagxdRwj3KEy7HSAcbMXjKFSdAlQ2Qq7CG8vLXilurHhEEbrzq
unbuVjJ80gIWeeo23HkAbjOiTiSokN2AoGyGW9eS3bMLSJgMHzLtX80uWwS75jc3
2mMrYe59nzGIR2yY2zxkmmj6DOLoMQKyJlqPC2fGKyAv0N79QKAGl7JjbXzYvaV2
egWtCk0FHnfah9Fu+/P8pNtY8agSluneeHkL
-----END CERTIFICATE-----
/run/secrets/kubernetes.io/serviceaccount #
二、认证U sers Account
尽管无法通过 API 调用来给kubernetes增加普通用户,Kubernetes 仍然认为能够提供由集群的证书机构签名的合法证书的用户是通过身份认证的用户。基于这样的配置,Kubernetes 使用证书中的 'subject' 的通用名称(Common Name)字段(例如,"/CN=devuser")来确定用户名,Kubernetes使用证书中的 'subject' 的单位名称 (Organization Name) 字段(例如,"/O=system:masters")来确定用户组。
1 、 Users Accounts认证
kubeconfig配置文件
之前有提到过,K8S间的通信是通过https实现,https通信每次都需要认证,比如我们在命令行输入命令
bash
[root@master01 ~]# kubectl get pod
都需要https认证,而且https是无状态链接 意味着每次访问 都需要附带证书,如果这一切都手动指定完成,实际操作肯定非常不方便,为了简化连接和方便使用,K8s使用kubeconfig配置文件来简化使用时文件附带认证信息
kubeconfig配置文件:3种搜索路径
1.指定kubeconfig配置文件位置,优先级最高
2.通过环境变量KUBECONFIG加载config文件
3.读取用户家目录 HOME/.kube/config
kubeconfig配置文件:
将用户名、认证信息等组织一起,便于认证API Server上的认证信息文件;支持一个文件中保存m个集群的n个认证信息;

kubectl选项中可以看到可以指定证书与秘钥
bash
[root@master01 ~]# kubectl options
The following options can be passed to any command:
--add-dir-header=false: If true, adds the file directory to the header of the log messages
--alsologtostderr=false: log to standard error as well as files
--as='': Username to impersonate for the operation
--as-group=[]: Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--cache-dir='/root/.kube/cache': Default cache directory
--certificate-authority='': Path to a cert file for the certificate authority
--client-certificate='': Path to a client certificate file for TLS #客户端证书
--client-key='': Path to a client key file for TLS #指客户端秘钥
--cluster='': The name of the kubeconfig cluster to use
--context='': The name of the kubeconfig context to use
--insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will
make your HTTPS connections insecure
...
kubeconfig配置文件
大致会包含4种信息;支持一个文件中保存m个集群的n个认证信息;
- clusters:配置要访问的kubernetes集群
- contexts:配置访问kubernetes集群的具体上下文环境
- current-context:配置当前使用的上下文环境
- users:配置访问的用户信息,用户名以及证书信息
系统默认的几个config配置文件
bash
[root@k8s-master core]# cd /etc/kubernetes/
[root@k8s-master kubernetes]# ll #kubernetes 安装完成 几个config配置文件
total 32
-rw------- 1 root root 5565 Jun 29 01:42 admin.conf #管理员配置文件
-rw------- 1 root root 5601 Jun 29 01:42 controller-manager.conf #管理控制器配置文件
-rw------- 1 root root 1933 Jun 29 01:43 kubelet.conf #kubelet的配置文件
drwx------ 2 root root 113 Jun 29 01:42 manifests
drwxr-xr-x 3 root root 4096 Jun 29 01:42 pki
-rw------- 1 root root 5541 Jun 29 01:42 scheduler.conf #调度器的配置文件
[root@k8s-master kubernetes]# cat admin.conf
apiVersion: v1
clusters: # 集群相关的信息
- cluster: #API service ca证书
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeE1EWXlPREUzTkRJeE1Gb1hEVE14TURZeU5qRTNOREl4TUZvd0ZdFVBd2FneGRSd2ozS0V5N0hTQWNiTVhqS0ZTZEFsUTJRcTdDRzh2TFhpbHVySGhFRWJyenEKdW5idVZqSjgwZ0lXZWVvMjNIa0Fiak9pVGlTb2tOMkFvR3lHVzllUzNiTUxTSmdNSHpMdFg4MHVXd1M3NWpjMwoybU1yWWU1OW56R0lSMnlZMnp4a21tajZET0xvTVFLeUpscVBDMmZHS3lBdjBONzlRS0FHbDdKamJYell2YVYyCmVnV3RDazBGSG5mYWg5RnUrL1A4cE50WThhZ1NsdW5lZUhrTAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
server: https://192.168.30.10: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: #用户token 秘钥
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURFekNDQWZ1Z0F3SUJBZ0lJTzB3MXV1SWhEbDR3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TVRBMk1qZ3hOelF5TVRCYUZ3MHlNakEyTWpneE56UXnp2V3RsRStRdUc2Ulk0bjB3UEc0OFR1N0JobGgxVTQKYTNVb3p4SHV4MmRBdi9JNHdBMmRrem8xc0FIL1pFUUFFTjNBN0JZL28rWWE1MXErNmNYMjYvN3hkVlhvMjVKTwpzRkdqUjVJbTIvcDYwR2R4N1MraGlDSE9MZzc1ZFBlZVQvOTZRMk15cVFiaHAyYmlERnNtMnRCSjBhWXdhQThyCm9rMHJYcTd4NmZ1M2l1R2NmaWt0azhRWjA5b29WM29Kd21ORVlSY3A5RTd4TjIxM042dFlOcHVtK0dxVWNiVTIKSHB5MmF4YjZhRWNOVk90YTVJdWluZUtmR1NaZ1hmND0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBeVVSd3hnVmwvNmczRkpiYnh3Y2EwUi9kejdua0lpbGVFcWl1Tm1yTVE3UlhaSnR3Ckh1bEhnTlQvREtENUMxOTg0cGtQZXV5RzZJc3V6VHFtL0REVERMdndBNXArMWNFNksvWDI5LzV3U29TMUtJN2c3dXc2NEZnSHRBazB3aVloYkhQUGVOMVAKa0Y5RDVFUTdySkZ0S3ZDU2ZPKzdueDhYUEVFM01CTWdBNlR0cXdJREFRQUJBb0lCQUdldHVlcElIYUwxSkdxVwp5K0JhNkpXUnROR3RFTGdJVjAyRlZ6anhDd2hWZmk5MVl1eUpmeXYrak9RVWlEWXpta0dnVnprYlh1T3J6eEFwCmhwpdQpOMFFEaE9iZlE3c1BQV08wSWpzeVo0anVKbDlxYTVsS2N6TTNJTWU3aFdYcXpTUXMwblNKRW9QS04zQUh2UllhCkJNdFZBb0dBRnNkUyswcHBIVnllWlVoblRJZXhiOEhSa0ViT2I2Z3lXenM3bThzcllXK2dwU3RJTVBpR3NTNFoKL0xYZ0RvZ2xUQ01VTnJ1Zjd3RjVtRWcrVTFEZGEyTmtSeWZPRmlnZGQybDVyZkRTN1BxMDhIOGdrZmtNWXFYdQppYUg5cnR3QmRCOEF3bktzTjlKaWFTRkV4RXlxOCtRM3ZIaXpGenhkV1IxU0VQZzQ2V0E9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
kubeconfig文件3种不同的指定方式
方式1 指定配置文件
bash
[root@master01 ~]# kubectl --kubeconfig=/etc/kubernetes/admin.conf get pod
方式2通过环境变量指定
bash
[root@master01 ~]# export KUBECONFIG=/etc/kubernetes/admin.conf
[root@master01 ~]# echo $KUBECONFIG
[root@master01 ~]# kubectl get pod
如果KUBECONFIG环境变量存在,kubectl 使用 KUBECONFIG 环境变量中列举的文件合并后的有效配置。如果KUBECONFIG环境变量不存在,kubectl 使用默认的 kubeconfig 文件,$HOME/.kube/config。
方式3拷贝到家目录
集群初始化提示我们拷贝到家目录主文件
kubeconfig文件查看常用命令
root@master01 \~\]# kubectl config -h
bash
[root@master01 ~]# kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.30.10: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
- 查看指定config文件上下文信息
bash
[root@master01 ~]# kubectl config get-contexts --kubeconfig=/etc/kubernetes/scheduler.conf
2、示例1:使用 openssl创建 k 8s 的 认证 用户并生成 kubeconfig配置文件
下面我们来创建一个User Account,测试访问某些我们授权的资源
尽管无法通过 API 调用来添加给kubernetes增加普通用户,Kubernetes 仍然认为能够提供由集群的证书机构签名的合法证书的用户是通过身份认证的用户。基于这样的配置,Kubernetes 使用证书中的 'subject' 的通用名称(Common Name)字段(例如,"/CN=devuser")来确定用户名,Kubernetes使用证书中的 'subject' 的单位名称 (Organization Name) 字段(例如,"/O=system:masters")来确定用户组。接下来,基于角色访问控制(RBAC)子系统会确定用户是否有权针对 某资源执行特定的操作。
1.创建私钥
使用openssl工具做 X509认证 支持双向认证 ,通过k8s自己的CA去签证
2.在K8S组件目录中可以看到ca.crt只有一个,这是因为所有组件都是通过api-server的ca签发的,如果想让我们自己的key通过api-server认证,那么就需要通过这个ca来签发证书

具体操作步骤如下:
1.创建用户私钥
bash
[root@master01 ~]# cd /etc/kubernetes/
[root@master01 kubernetes]# mkdir usercerts
[root@master01 kubernetes]# cd usercerts/
[root@master01 usercerts]# umask 077; openssl genrsa -out tom.key 2048
Generating RSA private key, 2048 bit long modulus
.....................................................................+++
........+++
e is 65537 (0x10001)
[root@master01 usercerts]# ls
tom.key
2.创建证书签署请求
bash
O=组织信息,CN=用户名
[root@master01 usercerts]# openssl req -new -key tom.key -out tom.csr -subj "/O=jbt/CN=tom"
[root@master01 usercerts]# ls
tom.csr tom.key
- 基于证书请求和集群的ca公私钥创建证书
接下来创建用户的证书,基于这个私钥创造一个自签证书是不行的,需要根据上一步创建的证书签署请求,通过k8s的ca来签署用户证书
openssl 常用选项
-days 时间
-CA 指定使用的CA
-CAkey 指定私钥
-CAcreateserial CA自己创造序列号
-in 待签文件
-out 输出
bash
[root@master01 usercerts]# openssl x509 -req -days 3650 -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -in tom.csr -out tom.crt
Signature ok
subject=/O=jbt/CN=tom
Getting CA Private Key
[root@master01 usercerts]# ls
tom.crt tom.csr tom.key
查看证书详情
bash
[root@master01 usercerts]# openssl x509 -in tom.crt -text -noout
Certificate:
Data:
Version: 1 (0x0)
Serial Number:
cb:a5:36:cb:f7:8e:3d:86
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kubernetes
Validity
Not Before: Feb 15 07:37:45 2023 GMT
Not After : Feb 12 07:37:45 2033 GMT
Subject: O=jbt, CN=tom
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:c1:cd:1b:97:fd:2d:6c:a1:f2:c8:f8:8a:2b:56:
a8:60:67:b3:f3:4a:36:59:82:f8:11:db:2d:c0:4b:
15:3c:7b:a9:58:23:20:dc:d8:46:67:85:21:0b:eb:
86:a5:9e:67:09:eb:18:d5:a7:5f:20:43:04:44:1e:
1f:7d:84:e7:aa:86:39:4a:03:2b:02:48:9d:76:17:
eb:09:9e:0f:29:79:64:9d:cd:39:4f:a8:11:bf:f0:
66:df:90:43:70:71:3d:00:73:f0:9f:4e:96:54:bf:
77:23:73:17:cd:95:97:7e:fd:f5:33:a6:18:43:6e:
80:21:33:75:0b:27:eb:e8:29:d1:17:f0:f8:fc:59:
59:01:c3:69:17:70:b9:54:ec:d7:43:30:ed:bd:06:
5f:6f:ce:da:31:19:b6:c0:61:05:2f:cd:c4:45:94:
94:4e:44:88:1a:64:89:18:1a:52:4f:f1:1d:81:22:
1d:38:67:b8:5d:56:16:5c:2c:1e:c8:2a:e5:da:2d:
cc:4b:69:7e:0a:50:02:0c:25:5a:8e:19:8e:8a:80:
fc:b9:b3:74:4f:bc:a3:58:ec:1a:f3:86:55:78:ad:
e1:14:f2:87:1a:04:27:23:92:d6:17:f7:d6:6c:21:
34:ef:17:41:fe:fa:f2:20:ac:e4:15:f2:96:23:df:
69:51
Exponent: 65537 (0x10001)
Signature Algorithm: sha256WithRSAEncryption
26:11:a3:12:ed:29:83:06:14:95:f8:db:50:e8:83:8b:a5:ec:
0c:26:32:c3:fc:b7:b6:a2:f3:ea:ee:4a:91:8e:4a:20:58:c5:
44:87:54:6c:5a:bd:f9:b0:a0:3b:33:00:cb:86:35:ff:8a:fc:
05:94:24:ae:bc:64:53:5c:ff:a8:25:2a:be:f1:35:4d:fd:dd:
b8:64:dd:47:c6:84:af:db:ea:d3:4b:c1:ee:f5:99:95:2f:d6:
7e:ac:a1:f2:69:7f:74:9f:fe:03:57:42:59:41:ab:21:46:99:
72:ad:4d:39:01:d4:e4:4a:3f:98:c9:59:2f:52:bd:5f:38:0e:
15:d2:0e:e7:57:a5:f8:5c:fd:7d:37:67:d5:99:40:6c:99:09:
39:ea:60:a4:df:8c:61:b6:2d:c9:9c:e8:b6:3f:0a:5d:96:e5:
1f:77:f9:f4:00:61:1b:1f:a1:76:ca:5d:07:3d:a0:b9:70:16:
29:1f:7e:be:23:8a:ef:d5:70:e6:c0:d6:55:d8:78:35:bc:b3:
4b:d8:d3:9c:11:9d:ad:05:76:a3:53:12:85:b1:97:80:93:a3:
ea:01:9a:33:9c:20:71:7a:d1:0b:de:b1:97:82:4d:76:da:c5:
25:eb:86:fc:20:85:35:dd:2d:51:3f:83:48:f9:10:0c:9d:8e:
b2:f8:cd:97
4.创建kubeconfig配置文件
创建配置文件主要有以下几个步骤:
1)kubectl config set-cluster --kubeconfig=/PATH/TO/SOMEFILE #集群配置
2)kubectl config set-credentials NAME --kubeconfig=/PATH/TO/SOMEFILE #用户配置
3)kubectl config set-context #context配置
4)kubectl config use-context #切换context
bash
--embed-certs=true的作用是不在配置文件中显示证书信息。
--kubeconfig=/root/tom.conf用于创建新的配置文件,如果不加此选项,则内容会添加到家目录下.kube/config文件中,可以使用use-context来切换不同的用户管理k8s集群。
集群就是k8s 集群,里面配置了集群证书,地址等信息;
用户就是授权对象,配置认证信息,后面是通过rbac 对用户授权才能访问集群;
context简单的理解就是用什么用户来管理哪个集群,即用户和集群的结合。上下文就是把集群+用户+命名空间联系在一起,例如用户tom+集群k8s-new+命名空间dev的意思是在此上下文中通过kubectl 命令执行的操作都是在集群k8s-new的空间dev 的操作,以tom 身份执行的
config 配置文件示例:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlDeURDQ0FiQ2dBd0lCQWdJQkFEQU5CZ2txaGtpRzl3MEJBUXNGQURBVk1STXdFUVlEVlFRREV3cHJkV0psDQpjbTVsZEdWek1CNFhEVEl3TURreE5UQTVNekl3TUZvWERUTXdNRGt4TXpBNU16SXdNRm93RlRFVE1CRUdBMVVFDQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTHE1DQpmVVpWT3RTRzhocTV2Tk8xUzJmTkQrVnd5TjFYb25lT1JrbXV5ZHRPMHJSQ0VwSWdjZFg1d3pvek40L0s3Rld1DQp6MzZmWm9yV3JTWjFyMzNWcUNzdzZlUFVQcmJQaU5ZSStQdEszU29icHh4ZVQ5KzlUSVpxVmc2UTJhcEExckM5DQpObTBuMCswdmh0SUxjeGs3amRXM3QrSkhiWWhlNE4zZ2tCUUVoaS9OVDNyZDJUNzQ3SFk5L1ZmUFdHZStNTEZwDQo1V056T2ZyL0ZqWUhVMmR5dnRZMnl6VlVaeFBPRitaTjlENGpHWmpDbzR5MFdhTVBOeUxGV056dnQ4NkM1dmYrDQppUUZTN2E4bVo1emwybWFabldtZ204bjVLNUd0QWdNM3VVZXh1QlZpOXZ5OCt3K3kralcyYnR6QmkwRUgxYUQ2DQppbW1UUVZsaHdscEhpWU1STEIwQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCDQovd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBRjRhTElSRm10R210NDd6UVFZKy9yb2FEK3pIDQoxUnZnMStDYjk4NnZkbENtc08ybVNadldyb2tYUTFtL2pyMzUxeW1xUzNwU3FId05kOUdFaWg5cWJpYmpTQXhCDQo4RU1vUmxhclBRUDBRemlNcytIR1N1RHRYYW95RzZvN3RnQVErV1R1NUdBazBPWnRlcVdhdzVKK2FQZGIydEluDQpqSWVyUW1BMmhnYlRoVFdDbjIwL2lrUUVWSm44OFQvYU1YUG01TGdPbXQ2RGdpbHZEKzdySFBONk5WY1NvcmFXDQoydE9qd3VJa0tMSFhUcFZwb213UDU3UGl1VWNxSTV0NjVuaTQ1WEhoVDBnS0F2ZUZCa2wxZzJ0M00veTdvTU9yDQp6R2Q4MW1ORTMrQzV6WWdHL2ZsTWREeVVLTzcvNXhDbVYvNVRkWkIxWTVEWm1DYkNaUDJhazBnMnVaZz0NCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
server: https://192.168.1.200:6443
name: k8s-new
- cluster:
server: https://192.168.1.210:6443
name: k8s-old
contexts:
- context:
cluster: k8s-new
user: langkai
name: k8s-new-all
- context:
cluster: k8s-new
namespace: langkai
user: langkai
name: k8s-new-langkai
- context:
cluster: k8s-old
namespace: default
user: kzf
name: k8s-old-default
current-context: k8s-new-langkai
kind: Config
preferences: {}
users:
- name: kzf
user:
password: 1qaz2wsx
username: kouzhenfang
- name: langkai
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNvekNDQVlzQ0NRQ0Jwa2dGSUhoTGx6QU5CZ2txaGtpRzl3MEJBUXNGQURBVk1STXdFUVlEVlFRREV3cHIKZFdKbGNtNWxkR1Z6TUI0WERUSXdNVEF4TWpBek5EUXlNbG9YRFRJeE1UQXhNakF6TkRReU1sb3dFakVRTUE0RwpBMVVFQXd3SGJHRnVaMnRoYVRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTTROClN6ZUZkVjNIT2FWR1FVbmpSUFFrS2h4Z2ZkT2xJdVFlb243UGtEeHhwb0d5SkE4UkNqbUpXcVhDT2lhbWtma2QKMWhPT3k0Z2M5K2F0M2JDZkRjMjI2VENyUUg5RVUyL1R3ejhvd3FRdWoyTG1EdnB1ZVBGWUNsRlNLeU1GMTYzMApaL3FpamU1YnlWK1p3TklKaC92bzVNbStPZlV3QjRzWmJIeFJxb1pOb3I3dytjbEk1M3VYMm5uNEVobEFxL3hLCmwxcXhmeFRXNEJ4RVZ3cWx2Z2Q2aFBlVS90SUJDbjJ5YVhCVW52WkF0aEhjRjV3aDdpcW9OYUF1Yi9zR1c4elEKdURMYUxNOHFnd3pVZDd6ZVhuNTc1K1hLcGU3UEVuKzFOVjZSTkg1bUNtdkI0VDUrcXl1VFBCWW9lTXV6eS84UQpya2pQREZNZ1A5TmUyK25sK1hzQ0F3RUFBVEFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBYjdGL1BUZnlTK3ovClp6eGZ2Y2g2YmxGVGZXaTFiZGRXemdWd1pOVWlrMUxiUEFmMGxsM2hDMjJoRUlvNm5CUXRnMG1XNzVNY3VlZWwKMXZ1VldMaVN2ZGd6aWRZcmtseFgwY2d3d3p6MjNwSWhJM0dVUjU3QU55N212ZTBIMjM2eWNsZi9SNkFTdE9BcAo5eUlkYWkwWjk2ejRzK1FDaldNOWw2Y2JDNnhDbUlEMEhGTHRMNHhmTXlnSHd2YmRtQTNxbGl2alRwVUEzMEZTCjl2M2tiRXpvRDAvbE1HQ1hZZlJpb1FlV0w0TjJVOExMeldFT2NmSTg2Tm4xVFdtRGZXcmVhSExFSHU2NTZlWkQKUy9ucjMrRVVHL09YUndaVnc0V0QrL3VoZlFIbkNvdjZWUEN3bXR3TXNOM1NlVE5MWk1vU3BKVWlyN1VtTlJNVQpLYjZla3VQNU1RPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBemcxTE40VjFYY2M1cFVaQlNlTkU5Q1FxSEdCOTA2VWk1QjZpZnMrUVBIR21nYklrCkR4RUtPWWxhcGNJNkpxYVIrUjNXRTQ3TGlCejM1cTNkc0o4TnpiYnBNS3RBZjBSVGI5UERQeWpDcEM2UFl1WU8KK201NDhWZ0tVVklySXdYWHJmUm4rcUtON2x2Slg1bkEwZ21IKytqa3liNDU5VEFIaXhsc2ZGR3FoazJpdnZENQp5VWpuZTVmYWVmZ1NHVUNyL0VxWFdyRi9GTmJnSEVSWENxVytCM3FFOTVUKzBnRUtmYkpwY0ZTZTlrQzJFZHdYCm5DSHVLcWcxb0M1dit3WmJ6TkM0TXRvc3p5cURETlIzdk41ZWZudm41Y3FsN3M4U2Y3VTFYcEUwZm1ZS2E4SGgKUG42cks1TThGaWg0eTdQTC94Q3VTTThNVXlBLzAxN2I2ZVg1ZXdJREFRQUJBb0lCQVFES3NhOGRWZTdIcXBTZApiY2dKL0VTM2VkL20vRkNxNDFhNFd4NTBhcEN6dFFVYnJuYmtUMW5ra2FhWFNzSlRoU1l4amxVcDloMW5yejk2CkwrelZzeEVzSFZPMWFiRlB3SkhuZnNRaG5HSWtpaHpKS0JEeDc3eVBoWkRZd0dEbzJmVjZET1JBWEtvTUlVU3UKQTV6M3dTS0EvM0FZdVVWZ1diZ0I4S2VVZisya29IS0ZjQUM1N1VJUklDcy9qSDV3SGJBSFdFR0NNRWRQdUdrUgpBZXBSQkxXdERURjduSFBLSk02VEJrMnc2c2lwMFpyWkpKbFZycDd1UzFYcHNkbmtLOEVRY3BLK3ZoT1NUUlVaCjB0d2lwNEVZand1Rks1bTIySVlHQlBVaEFWY2VOMExsekFKUk5vUFNsWkREWGYyMVZtS3RaM3VWTEs5T3BkNGcKNXYrazRuUlpBb0dCQVAwd3NGYitseUV4a1ZWbnF2ZVBzZ3o5S3ZvUmVLQ09oOHEvNUZKR2VhYWN1ZFpJeGVOUgpPN3FHa1VYNFB1K21kZVhKRXFoOVBhRzQ0Uy9HcGUvTjFFR3dIUVJiWU1kSXNoT2RqUUJ6TWF6TWo3N0ZCcVRqCm8zUzVTNVlrOFgrN2d0NElmeTNtWDVQNDdnZkN4aDZuc1RkbTY1dVpDMlluQ1lpZ3k2bi9aaEgvQW9HQkFOQlcKcjRMQU9DRkk2S0VkZCtmekdXUStOVU9yUWEvR2RiMnlsRlY5c2xNMExseElrUWRjT0YvU1l4N0RQM3ozV2UwYgpLdGluZUpuejZpb2NwSElRV2owcW13UEFONlFsRnVhQ3JWc0FReEs0UVdwamprTXFVVEtLN2JhaE5mditPUnB0ClY5RStoWTgvNnlOMktZMVRBMlQ0M2d5dERoYjAxa0MrRm8zZTRXQ0ZBb0dBUjQ5cVY3d3ZSTjk0bnpYa3VZR3cKcGtFcjAyLzZzdzUxek5VOW1BOTVOS0VaV1RwS1MveGFzRloyV3R0V0ZtL3E1SjVYR3E0RExHRlByQ3d1SEVBRgpuT2RFM0VWamJnL2EzUFpyc3RQY0YyWGR2dUo3QlVHZG9sRDR6eC96N2RFMnBNQ3NDWElTVTRWSTZZS2djbXVkCkIvYWI0dWQzdEZDV1BqcU1OYWtNMVVzQ2dZQitmWU1HRVlxQ3V1OXlrcCt3VmlwK2NENktuVG0rYlBJamdIOEwKQU12Nk5GNUpiVTJRZUc5SnprU2I4dE5qSGhLZElMZDgzd0VjQjdtT1krRjcxMjNTWVVISW56V3BGVk80RkhNSQpJenFWN1FUYWdTTm9xQkt3YXlVMGt1Qmg1TkhxdDZSdnlGUHl5MDRLTTcyNnJrSUxWZ1lMRUM3VHhVY24rOEZaCjFZNWt1UUtCZ0ZUMXFjakF4ME9NaGF3dVI4ODJycmNnMTFWR2hBQU5uZGtMa3ZIUVN0bEc0Zyt3Tkg3ZHB6MTkKbzJhdjUrcHdONlhWQVBBR2k2SzM0MFVlNkt6NGVTUzNWR3Flb0RNSXJrcVdtby9qV1lxM1hoWXowU29VRkFORgpyNkZSZy9YREo5SXhkUWZyMXpBaEM1UytmbjJ1Q3F4V1NPV0FlMEFJRGZ4Ym9uTVlIeUxTCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
- 生成kubeconfig配置文件,配置集群信息,存放在/tmp/mykubeconfig目录
bash
[root@master01 ~]# kubectl config set-cluster kubernetes --server=https://192.168.30.10:6443 --embed-certs --certificate-authority=/etc/kubernetes/pki/ca.crt --kubeconfig=/tmp/tomkubeconfig
Cluster "kuberetes" set.
[root@master01 usercerts]# cat /tmp/tomkubeconfig
apiVersion: v1
clusters:
- cluster: #集群的认证信息
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1USXdOVEF3TXpjMU4xb1hEVE15TVRJd01qQXdNemMxTjFvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUJKCmZhUVZJQzFHVmQwTU83Y2dTK0V0dElud3dXVjhSK3BJRnlUYTVhL2xWR1JTTVJ6b1RxMC9MSWZDUU82ZWdkK3kKQkZhV2VpM2IyREpEaHZheE1hRWNvM1JNZWVMQXh1alpOelpiTDJ0Tkl3VkJVZW0rZml2YTZvdDhqbzdmZ3VsUAo0WjVTNWtUTDJ2cjFkbzBJNDBaQmVINnl5NklQUFdxb1VDS2l1bWpBRWVGdStVSGZUM2RwVzJMcHdZWktvQ012Cm82YXUyVkNWMWQ1cHZ0V0VrY2tpSm15anZvdFJvNEdtZTAxMVpXL0pJTlpKQUNsaTR2dDYrajNQcUFXZXR0TmUKR2ljUmhDUGsrYXd1ZVhlM2dhMUhpSUI5SDRRVkM0V1hGdUNDUUpRbitGeDBxUngzYUZpalQ1Z09USTczS3U3aAozWDRNQnppL3NydW5LRXRtQU9zQ0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZGMkFWWmtSdXVkd0pNK0RJckllRVFkYUhIY1NNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQyttd0o0bk9Kb3hoYnBoT0FWSgordFVFOUtGQTlOUmJ4WTZ4eGNlUTFySDhsS2FvbjhHOHJyL0N0Tm1TRTVzamdWVWZIdEFQRXhqVkk3eXdRWU5iCk9oM2Y3T3R4em1MR1ZzVU1SWnN5enV6UWhPaENVSjFKMVpvdVlJOWZjV0YvMnB2bEhyekZWL2lnUldua3kwVG8KL3Z0UDVKVnppcUlUMElld3JKOTNaRi9sT3ZlMFZMbG5XWWdGdnM4MjRyaUlrL09tMytINWlBbjIyaUlkbDNzTApQZStMb3ZReTRzeDNiKzdYNlRoaHA3enRHaWl0R04rd2pORkREd0JHOWgxVGY1R1pYL3ZSRU1GeWxHK3RUcmxwCkxhMDl6d1JmOHNwaTFzUC9aMUxuWlhWMElHaUNyNzNnbFoxdEpFT3ViMEFwNGdSWGlhYklvaW5uNHZtVEdHRnoKMlpJPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
server: https://192.168.30.10:6443
name: kubernetes
contexts: null #上下文信息为空
current-context: ""
kind: Config
preferences: {}
users: null #用户信息为空
2)配置集群用户tom
bash
[root@master01 usercerts]# kubectl config set-credentials --help #用户可以使用多种方式认证
[root@master01 usercerts]# kubectl config set-credentials tom --client-certificate=./tom.crt --client-key=./tom.key --embed-certs=true --kubeconfig=/tmp/tomkubeconfig
User "tom" set.
[root@master01 usercerts]# kubectl config view --kubeconfig=/tmp/tomkubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.30.10:6443
name: kubernetes
contexts: null
current-context: ""
kind: Config
preferences: {}
users:
- name: tom #添加用户tom
user:
client-certificate-data: REDACTED #信息隐藏--embed-certs=true的作用
client-key-data: REDACTED #信息隐藏--embed-certs=true的作用
3)添加上下文,对集群与用户进行绑定
bash
[root@master01 usercerts]# kubectl config set-context "tom@kubernetes" --user=tom --cluster=kubernetes --kubeconfig=/tmp/tomkubeconfig
Context "tom@kubernetes" created.
[root@master01 usercerts]# kubectl config view --kubeconfig=/tmp/tomkubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.30.10:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: tom
name: tom@kubernetes
current-context: ""
kind: Config
preferences: {}
users:
- name: tom
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
4)切换上下文
bash
[root@master01 usercerts]# kubectl config use-context tom@kubernetes --kubeconfig=/tmp/tomkubeconfig
Switched to context "tom@kubernetes".
[root@master01 usercerts]# kubectl config view --kubeconfig=/tmp/tomkubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.30.10:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: tom
name: tom@kubernetes
current-context: tom@kubernetes #将tom@kubernetes切换为当前上下文
kind: Config
preferences: {}
users:
- name: tom
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
[root@master01 usercerts]# kubectl get nodes --kubeconfig=/tmp/tomkubeconfig
Error from server (Forbidden): nodes is forbidden: User "tom" cannot list resource "nodes" in API group "" at the cluster scope
上面的错误是指授权有问题,认证已经通过,已经完成示例的要求,授权会在下一节讲到
普通用户并不是通过k8s来创建和维护,是通过创建证书和切换上下文环境的方式来创建和切换用户。
3、示例2: kubeconfig 配置文件 合并
注tom.crt证书在示例1已经完成
1)集群不用再创建,默认配置文件里已经有了(/root/.kube/config)
添加集群用户tom
bash
[root@master01 usercerts]# kubectl config set-credentials tom --client-certificate=./tom.crt --client-key=./tom.key --embed-certs=true
User "tom" set.
[root@master01 usercerts]# kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.30.10: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
- name: tom
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
2)在默认kubeconfig中创建contexts
bash
[root@master01 usercerts]# kubectl config set-context "tom@kubernetes" --user=tom --cluster=kubernetes
Context "tom@kubernetes" created.
[root@master01 usercerts]# kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.30.10:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
- context:
cluster: kubernetes
user: tom
name: tom@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- name: tom
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
3)切换当前context 为tom@kubernetes
bash
[root@master01 usercerts]# kubectl config use-context tom@kubernetes
Switched to context "tom@kubernetes".
[root@master01 usercerts]# kubectl get pod
Error from server (Forbidden): pods is forbidden: User "tom" cannot list resource "pods" in API group "" in the namespace "default"
4)指定使用前context
bash
[root@master01 usercerts]# kubectl get nodes --context=kubernetes-admin@kubernetes
NAME STATUS ROLES AGE VERSION
master01 Ready control-plane 73d v1.25.4
node01 Ready <none> 73d v1.25.4
node02 Ready <none> 73d v1.25.4
修改默认context
[root@master01 usercerts]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".
[root@master01 usercerts]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master01 Ready control-plane 73d v1.25.4
node01 Ready <none> 73d v1.25.4
node02 Ready <none> 73d v1.25.4
5)删除context
bash
[root@master01 usercerts]# kubectl config delete-context tom@kubernetes
deleted context tom@kubernetes from /root/.kube/config
[root@master01 usercerts]# kubectl config delete-user tom
deleted user tom from /root/.kube/config
[root@master01 usercerts]# kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.30.10: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
6)通过环境变量合并配置文件
bash
[root@master01 usercerts]# export KUBECONFIG=$HOME/.kube/config:/tmp/tomkubeconfig
[root@master01 usercerts]# kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.30.10:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
- context:
cluster: kubernetes
user: tom
name: tom@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- name: tom
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
7)在通过环境变量合并配置文件基础上,通过--merge --flatten选项,可以展平合并重复项,生成新的配置文件
bash
[root@master01 usercerts]# kubectl config view --merge --flatten > /tmp/newkubeconfig
[root@master01 usercerts]# kubectl config view --kubeconfig=/tmp/newkubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.30.10:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
- context:
cluster: kubernetes
user: tom
name: tom@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- name: tom
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
三、 RBAC 访问控制 Users Accounts
前面已经对ServiceAccount、Users Account认证进行了介绍与创建,但最后的测试发现是Users Account并没有访问权限,本节介绍RBAC授权对ServiceAccount、Users Account认证进行授权。
1、k 8s 授权模式
在K8S中授权ABAC(基于属性的访问控制)、RBAC(基于访问的访问控制)、Webhook、Node、AlwaysDeny(一直拒绝)和AlwaysAllow(一直访问)等6中模式,从1.6版本起,K8S默认启用RBAC访问控制策略,目前RBAC已作为稳定的功能,启用RBAC,需要在 apiserver 中添加参数--authorization-mode=RBAC,如果使用的kubeadm安装的集群,1.6+版本都默认开启了RBAC。

- AlwaysDeny:表示拒绝所有请求,一般用于测试。
- AlwaysAllow:允许接收所有请求。如果集群不需要授权流程,则可以采用该策略,这也是Kubernetes的默认配置。
- ABAC(Attribute-Based Access Control):基于属性的访问控制。表示使用用户配置的授权规则对用户请求进行匹配和控制。
- Webhook:通过调用外部REST服务对用户进行授权。
- RBAC:Role-Based Access Control,基于角色的访问控制(本章讲解)。
- Node:是一种专用模式,用于对kubelet发出的请求进行访问控制。
2、R BAC
1)RBAC是什么
RBAC是基于角色的访问控制(Role-Based Access Control ),在 RBAC 中,权限与角色相关联,用户通过成为角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。
2)RBAC有四种资源
RBAC API 声明了四种 Kubernetes 对象:Role、ClusterRole、RoleBinding 和 ClusterRoleBinding。
角色:
在 RBAC API 中,一个角色包含了一套表示一组权限的规则(一组权限的集合)。这里的权限都是许可形式的,不存在拒绝的规则。角色可以由命名空间(namespace)内的 Role 对象定义,而整个 Kubernetes 集群范围内有效的角色则通过 ClusterRole 对象实现。
- Role:角色,名称空间级别;授权特定命名空间的访问权限
- ClusterRole:集群角色,全局级别;授权所有命名空间的访问权限
角色绑定:
角色绑定将一个角色中定义的各种权限授予一个或者一组用户。角色绑定包含了一组相关主体(即 subject, 包括用户 ------User、用户组 ------Group、或者服务账户 ------Service Account)以及对被授予角色的引用。在命名空间中可以通过 RoleBinding 对象授予权限,而集群范围的权限授予则通过 ClusterRoleBinding 对象完成。
- RoleBinding:将角色绑定到主体(即subject),意味着,用户仅得到了特定名称空间下的Role的权限,作用范围也限于该名称空间;
- ClusterRoleBinding:将集群角色绑定到主体,让用户扮演指定的集群角色;意味着,用户得到了是集群级别的权限,作用范围也是集群级别;
主体(subject)
- User:用户
- Group:用户组
- ServiceAccount:服务账号
绑定对应关系
- 主体(Subject) --> RoleBinding --> Role #主体获得名称空间下的Role的权限
- 主体(Subject) --> ClusterRoleBinding --> clusterRoles #主体获得集群级别clusterRoles的权限
- 主体(Subject) --> Rolebindig -->ClusterRole #权限降级 主体获得名称空间下的clusterRoles的权限
RoleBinding用于将Role上的许可权限绑定到一个或一组用户之上,它隶属于且仅能作用于一个命名空间。绑定时,可以引用同一命名空间中的Role,也可以引用集群级别的 ClusterRole。
ClusterRoleBinding则把ClusterRole中定义的许可权限绑定在一个或一组用户之上,它仅可以引用集群级别的ClusterRole。
Role、RoleBinding、ClusterRole和ClusterRoleBinding 的关系如图 所示 。

在RBAC api中,通过如下步骤进行授权:
- 定义角色:在定义角色时会指定此角色对于资源访问控制的规则;
- 绑定角色:将主体与角色进行绑定,对用户进行访问授权;

rules中的参数说明:
- apiGroups:apiGroups 就是api资源组,执行kubectl get apiservice 就可以看到集群所有的api组,例如:"apiVersion: apps/v1"等
- resources:支持的资源对象列表,就是k8s资源的名称。例如pods、deplayments、jobs等。kubectl api-resources 这个命令可以查看到,第一列是资源名称,就是可以写在这里的。第二列是简写,kubectl get 后面的可以简写。第三列是APIGROUP组。第四列是是否属于NAMESPACED资源,就是你可以在ns下面看到的资源。第五列是kind的时候写的名称。有些资源下面还分子资源,就需要使用"/"分割资源和下级资源。
例如:GET /api/v1/namespaces/{namespace}/pods/{name}/log
bash
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
resources: ["pods","pods/log"]
verbs: ["get","list"]
resourceNames: 指定resource的名称
bash
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["my-config"]
- verbs:对资源对象的操作方法列表, Create、get、delete、list、update、edit、watch、exec。
API Server是RESTful风格的API,各类客户端基于HTTP协议的请求报文(首部)发送身份认证信息并由认证插件完成身份验证,而后通过http协议的请求方法指定对目标对象的操作请求并由授权插件进行授权检查,而操作的对象则是借助URL路径指定的REST资源。下表对比给出了http方法和kubernetes API Server资源操作的对应关系。
|-----------|-------------------------|
| HTTP verb | Request verb |
| POST | Create |
| GET,HEAD | Get、list |
| PUT | update |
| PATCH | patch |
| DELETE | Delete、deletecollection |
3)role和clusterrole
Role
Role 就是用来在某一个namespace内设置访问权限。创建Role的时候,必须指定namespaces。
下面是一个位于 "default" 命名空间的 Role 的示例,可用来授予对 pods 的读访问权限:
bash
apiVersion: rbac.authorization.k8s.io/v1 # api
kind: Role # 资源kind的名称
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # apiGroups 就是api资源组,通过kubectl get apiservice 就可以看到集群所有的api组
resources: ["pods"] # 就是k8s资源的名称。kubectl api-resources 这个命令可以查看到,第一列是资源名称,就是可以写在这里的。
# 第二列是简写,kubectl get 后面的可以简写。
# 第三列是APIGROUP组
# 第四列是是否属于NAMESPACED资源,就是你可以在ns下面看到的资源
# 第五列是kind的时候写的名称
# 资源还分子资源
verbs: ["get", "watch", "list"] # 定义动作,get是查看权限,update是更新权限
ClusterRole
ClusterRole 就是用来在集群内设置访问权限。ClusterRole不用固定在一个namespaces。
这两种资源的名字不同(Role 和 ClusterRole)是因为 Kubernetes 对象要么是namespaces作用域的,要么是集群作用域的,不可两者兼具。
下面是一个 ClusterRole 的示例,可用来为任一特定名字空间中的 Secret 授予读访问权限, 或者跨名字空间的访问权限(取决于该角色是如何绑定的):
bash
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制
name: secret-reader
rules:
- apiGroups: [""]
# 在 HTTP 层面,用来访问 Secret 对象的资源的名称为 "secrets"
resources: ["secrets"]
verbs: ["get", "watch", "list"]
4)RoleBinding 和 ClusterRoleBinding
RoleBinding 和 ClusterRoleBinding 是用来把用户和角色关联起来的。
角色绑定(Role Binding)是将角色中定义的权限赋予一个或者一组用户。
它包含若干主体(用户、组或服务账户)的列表和对这些主体所获得的角色的引用。
RoleBinding 在指定的命名空间中执行授权,而 ClusterRoleBinding 在集群范围执行授权。
RoleBinding
一个 RoleBinding 可以绑定同一的namespaces中的任何一个Role。
或者,一个 RoleBinding 可以引用某 ClusterRole ,并将该 ClusterRole 绑定到 RoleBinding 所在的namespaces。
下面的例子中的 RoleBinding 将 "pod-reader" Role 授予在 "default" 命名空间中的用户 "tom"。
这样,用户 "jerry" 就具有了读取 "default" 名字空间中 pods 的权限。
bash
apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定允许 "jerry" 读取 "default" 名字空间中的 Pods
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
# 你可以指定不止一个"subject(主体)"
- kind: User
name: jerry # "name" 是不区分大小写的
apiGroup: rbac.authorization.k8s.io
roleRef:
# "roleRef" 指定与某 Role 或 ClusterRole 的绑定关系
kind: Role # 此字段必须是 Role 或 ClusterRole
name: pod-reader # 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配
apiGroup: rbac.authorization.k8s.io
RoleBinding 也可以引用 ClusterRole,以将对应 ClusterRole 中定义的访问权限授予 RoleBinding 所在命名空间的资源。
这种引用使得你可以跨整个集群定义一组通用的角色, 之后在多个名字空间中复用。
例如,尽管下面的 RoleBinding 引用的是一个 ClusterRole,
"jerry"(这里的主体, 不区分大小写)只能访问 "development" 命名空间中的 Secrets 对象,
因为 RoleBinding 所在的命名空间(由其 metadata 决定)是 "development"。
apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定使得用户 "dave" 能够读取 "development" 名字空间中的 Secrets
# 你需要一个名为 "secret-reader" 的 ClusterRole
bash
kind: RoleBinding
metadata:
name: read-secrets
# RoleBinding 的命名空间决定了访问权限的授予范围。
# 这里隐含授权仅在 "development" 名字空间内的访问权限。
namespace: development
subjects:
- kind: User
name: jerry # 'name' 是不区分大小写的
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
ClusterRoleBinding
如果你希望将某 ClusterRole 绑定到集群中所有命名空间,你要使用 ClusterRoleBinding。
要跨整个集群完成访问权限的授予,你可以使用一个 ClusterRoleBinding。
下面的 ClusterRoleBinding 允许 "manager" 组内的所有用户访问任何命名空间中的 Secrets。
bash
apiVersion: rbac.authorization.k8s.io/v1
# 此集群角色绑定允许 "manager" 组中的任何人访问任何命名空间中的 secrets
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # 'name' 是不区分大小写的
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
3、创建 role角色绑定 , 作用域为名称空间
示例1:
bash
[root@master01 ~]# mkdir authfiles
[root@master01 ~]# cd authfiles
1)创建role
bash
[root@master01 authfiles]# cat pods-reader-rbac.yaml
kind : Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pods-reader
rules:
- apiGroups: [""] #空表示默认群组
resources: ["pods","services","pods/log"] #对象资源
verbs: ["get","list","watch"] #权限
创建rolebinding
bash
[root@master01 authfiles]# cat tom-pods-reader.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tom-pods-reader
namespace: default
subjects:
- kind: User
name: tom #绑定的用户名
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pods-reader #绑定之前的角色
apiGroup: rbac.authorization.k8s.io
[root@master01 authfiles]# kubectl apply -f pods-reader-rbac.yaml
role.rbac.authorization.k8s.io/pods-reader created
[root@master01 authfiles]# kubectl apply -f tom-pods-reader.yaml
rolebinding.rbac.authorization.k8s.io/tom-pods-reader created
[root@master01 authfiles]# kubectl get role
NAME CREATED AT
pods-reader 2023-02-17T04:04:13Z
[root@master01 authfiles]# kubectl get rolebinding
NAME ROLE AGE
tom-pods-reader Role/pods-reader 78s
2)使用tom用户验证权限 pod、svc
bash
[root@master01 authfiles]# kubectl config get-contexts --kubeconfig=/tmp/tomkubeconfig
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* tom@kubernetes kubernetes tom
[root@master01 authfiles]# kubectl get pod --kubeconfig=/tmp/tomkubeconfig NAME READY STATUS RESTARTS AGE
nginx-5df7494dc-s8bk9 1/1 Running 0 4d1h
[root@master01 authfiles]# kubectl get svc --kubeconfig=/tmp/tomkubeconfig
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 74d
3)验证deployment、nodes权限 没有授权访问失败
bash
[root@master01 authfiles]# kubectl get deployment --kubeconfig=/tmp/tomkubeconfig
Error from server (Forbidden): deployments.apps is forbidden: User "tom" cannot list resource "deployments" in API group "apps" in the namespace "default"
[root@master01 authfiles]# kubectl get nodes --kubeconfig=/tmp/tomkubeconfig
Error from server (Forbidden): nodes is forbidden: User "tom" cannot list resource "nodes" in API group "" at the cluster scope
4 、内建管理员
- 名称空间管理员admin
clusterrole admin是名称空间级别资源,拥有所有名称空间下的资源的所有操作权限。
- 集群管理员 cluster-admin
clusterrole cluster-admin是集群级别资源,拥有集群所有空的资源的所有操作权限。
之前绑定的rolebinding只对默认名称空间有一定的权限
bash
[root@master01 ~]# kubectl get pod -n kube-system --kubeconfig=/tmp/tomkubeconfig
Error from server (Forbidden): pods is forbidden: User "tom" cannot list resource "pods" in API group "" in the namespace "kube-system"
clusterrole admin对所有名称空间下的资源权限
bash
[root@master01 ~]# kubectl get clusterrole admin
NAME CREATED AT
admin 2022-12-05T00:38:05Z
[root@master01 ~]# kubectl get clusterrole admin -o yaml
删除之前的绑定,重新绑定到clusterrole admin
bash
[root@master01 ~]# kubectl get rolebinding
NAME ROLE AGE
tom-pods-reader Role/pods-reader 119m
[root@master01 ~]# kubectl delete role/pods-reader
role.rbac.authorization.k8s.io "pods-reader" deleted
[root@master01 ~]# kubectl delete rolebinding/tom-pods-reader
rolebinding.rbac.authorization.k8s.io "tom-pods-reader" deleted
[root@master01 ~]# kubectl get pod --kubeconfig=/tmp/tomkubeconfig
Error from server (Forbidden): pods is forbidden: User "tom" cannot list resource "pods" in API group "" in the namespace "default"
示例2: 绑定admin 并验证权限,作用域为名称空间
bash
[root@master01 ~]# kubectl create --help
[root@master01 ~]# kubectl create clusterrolebinding --help
绑定并进行权限验证
bash
[root@master01 ~]# kubectl create clusterrolebinding tom-admin --user=tom --clusterrole=admin
clusterrolebinding.rbac.authorization.k8s.io/tom-admin created
[root@master01 ~]# kubectl get pod -n kube-system --kubeconfig=/tmp/tomkubeconfig
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-798cc86c47-w4fv4 1/1 Running 0 4d5h
calico-node-556xv 1/1 Running 3 (4d5h ago) 74d
calico-node-j7sxr 1/1 Running 2 (4d5h ago) 74d
calico-node-ktp2z 1/1 Running 2 (4d5h ago) 74d
..............................
[root@master01 ~]# kubectl get pod --kubeconfig=/tmp/tomkubeconfig
NAME READY STATUS RESTARTS AGE
nginx-5df7494dc-s8bk9 1/1 Running 0 4d4h
node是集群级别资源,无权限
bash
[root@master01 ~]# kubectl get node --kubeconfig=/tmp/tomkubeconfig
Error from server (Forbidden): nodes is forbidden: User "tom" cannot list resource "nodes" in API group "" at the cluster scope
[root@master01 ~]# kubectl get pv --kubeconfig=/tmp/tomkubeconfig
Error from server (Forbidden): persistentvolumes is forbidden: User "tom" cannot list resource "persistentvolumes" in API group "" at the cluster scope
示例3: 绑定cluster-admin 并验证权限,作用域为集群级别资源
bash
[root@master01 ~]# kubectl delete clusterrolebinding tom-admin
clusterrolebinding.rbac.authorization.k8s.io "tom-admin" deleted
[root@master01 ~]# kubectl create clusterrolebinding tom-cluster-admin --user=tom --clusterrole=cluster-admin
clusterrolebinding.rbac.authorization.k8s.io/tom-cluster-admin created
[root@master01 ~]# kubectl get node --kubeconfig=/tmp/tomkubeconfig NAME STATUS ROLES AGE VERSION
master01 Ready control-plane 74d v1.25.4
node01 Ready <none> 74d v1.25.4
node02 Ready <none> 74d v1.25.4
[root@master01 ~]# kubectl get pv --kubeconfig=/tmp/tomkubeconfig No resources found
需要注意的是 cluster-admin 是通过system:masters组方式进行授权,如果我们在创建用户证书时,/CN=XX/O=system:masters;那么这个用户就拥有超级管理员的权限
bash
[root@master01 ~]# 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 #通过组授权所有system:masters都拥有超级管理员权限
示例4: rolebinding 绑定admin权限降级
前面有提到User --> Rolebindig -->ClusterRole:权限降级,
ClusterRole,用户得到的权限仅是ClusterRole的权限在Rolebinding所属的名称空间上的一个子集.
删除之前绑定
bash
[root@master01 ~]# kubectl delete clusterrolebinding tom-cluster-admin
clusterrolebinding.rbac.authorization.k8s.io "tom-cluster-admin" deleted
创建角色绑定集群角色,权限降级,只对指定名称空间有权限
bash
[root@master01 ~]# kubectl create rolebinding tom-admin --user=tom -n default --clusterrole=admin
rolebinding.rbac.authorization.k8s.io/tom-admin created
测试权限,作用域尽为default名称空间
bash
[root@master01 ~]# kubectl get pod -n default --kubeconfig=/tmp/tomkubeconfig
NAME READY STATUS RESTARTS AGE
nginx-5df7494dc-s8bk9 1/1 Running 0 4d6h
[root@master01 ~]# kubectl get pod -n kube-system --kubeconfig=/tmp/tomkubeconfig
Error from server (Forbidden): pods is forbidden: User "tom" cannot list resource "pods" in API group "" in the namespace "kube-system"
四、 RBAC 访问控制 ServiceAccount
在上一节已经介绍过RBAC 通过绑定授权Users Accounts 得到不同作用域权限
这节对Serviceaccount进行绑定授权
首先在help中可以看到 有对serviceaccount的绑定

1、示例1:给s a 授予对资源的权限
多数资源可以用其名称的字符串表示,也就是Endpoint中的URL相对路径,例如pod中的日志是GET /api/v1/namaspaces/{namespace}/pods/{podname}/log
如果需要在一个RBAC对象中体现上下级资源,就需要使用"/"分割资源和下级资源。
例如:若想授权让某个主体同时能够读取Pod和Pod log,则可以配置 resources为一个数组
root@master01 \~\]# kubectl create ns test \[root@master01 \~\]# vi role-test.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: logs-reader namespace: test rules: - apiGroups: \[""
resources: ["pods","pods/log"]
verbs: ["get","list","watch"]
root@master01 \~\]# kubectl apply -f role-test.yaml \[root@master01 \~\]# kubectl create sa sa-test -n test \[root@master01 \~\]#kubectl create rolebinding sa-test-1 -n test --role=logs-reader --serviceaccount=test:sa-test \[root@master01 \~\]# vim pod-test.yaml apiVersion: v1 kind: Pod metadata: name: sa-test-pod namespace: test labels: app: sa spec: serviceAccountName: sa-test containers: - name: sa-tomcat ports: - containerPort: 80 image: nginx imagePullPolicy: IfNotPresent
注:Service Account也是一种账号,是给运行在Pod里的进程提供了必要的身份证明。需要在Pod定义中指明引用的Service Account,这样就可以对Pod的进行赋权操作。
bash
[root@master01 ~]# kubectl apply -f pod-test.yaml
[root@master01 ~]# kubectl exec -it sa-test-pod -n test -- /bin/bash
root@sa-test-pod:~# cd /var/run/secrets/kubernetes.io/serviceaccount/
root@sa-test-pod:/var/run/secrets/kubernetes.io/serviceaccount# ls
ca.crt namespace token
root@sa-test-pod:/var/run/secrets/kubernetes.io/serviceaccount# curl --cacert ./ca.crt -H "Authorization: Bearer $(cat ./token)" https://kubernetes.default/api/v1/namespaces/test/pods/sa-test-pod/log
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/03/31 06:16:06 [notice] 1#1: using the "epoll" event method
2023/03/31 06:16:06 [notice] 1#1: nginx/1.23.4
2023/03/31 06:16:06 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2023/03/31 06:16:06 [notice] 1#1: OS: Linux 6.0.10-1.el7.elrepo.x86_64
2023/03/31 06:16:06 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 65536:65536
2023/03/31 06:16:06 [notice] 1#1: start worker processes
2023/03/31 06:16:06 [notice] 1#1: start worker process 28
2023/03/31 06:16:06 [notice] 1#1: start worker process 29
2023/03/31 06:16:06 [notice] 1#1: start worker process 30
2023/03/31 06:16:06 [notice] 1#1: start worker process 31
2 、示例 2:部署DashBoard , 验证ServiceAccount权限
因为sa权限是针对Pod的权限,命令行直接验证不直观,所以借助dashbaortd来验证
DashBoard官网URL:https://kubernetes.io/zh/docs
查看dashboard版本是否支持k8s版本:https://github.com/kubernetes/dashboard/releases
root@master01 \~\]#kubectl apply -f [https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml](https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml "https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml")
注:需要翻墙,但可以使用我提供的dashboard yaml文件和镜像,yaml文件内容需要修改一下。
1)本地上传镜像到 node01 和 node02 上并导入镜像
以node01为例导入镜像,node02也执行同样的操作:
bash
[root@node01 ~]# ctr -n k8s.io images import dashboard_v2.7.0.tar
[root@node01 ~]# ctr -n k8s.io images import metrics-scraper_v1.0.8.tar
[root@node01 ~]# systemctl restart containerd
查看镜像
root@node01 \~\]# crictl img 注1:所以在导入镜像时需要指定命令空间为 k8s.io,否则使用 crictl images 无法查询到。 注2:更换 Containerd 后,以往我们常用的 docker 命令也不再使用,取而代之的分别是 crictl 和 ctr 两个命令客户端。 crictl 是遵循 CRI 接口规范的一个命令行工具,通常用它来检查和管理kubelet节点上的容器运行时和镜像。 ctr 是 containerd 的一个客户端工具。
2)下载配置文件recmomended.yaml并修改
注:需要翻墙才可以下载
https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml
修改配置文件,下面标红的行
.................... //省略部分内容
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
type: NodePort #新增,修改配置使用NodePort方式映射端口
ports:
- port: 443
targetPort: 8443
nodePort: 30008 #新增,指定要映射的node端口
selector:
k8s-app: kubernetes-dashboard
.................... //省略部分内容
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
containers:
- name: kubernetes-dashboard
image: kubernetesui/dashboard:v2.2.0
imagePullPolicy: IfNotPresent #将Always修改为IfNotPresent
ports:
- containerPort: 8443
protocol: TCP
.................... //省略部分内容
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: dashboard-metrics-scraper
name: dashboard-metrics-scraper
namespace: kubernetes-dashboard
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: dashboard-metrics-scraper
template:
metadata:
labels:
k8s-app: dashboard-metrics-scraper
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: dashboard-metrics-scraper
image: kubernetesui/metrics-scraper:v1.0.6
imagePullPolicy: IfNotPresent #将Always修改为IfNotPresent
ports:
- containerPort: 8000
protocol: TCP
..................... //省略部分内容
3)部署dashbord
bash
[root@master01 ~]# kubectl apply -f recommended.yaml
namespace/kubernetes-dashboard created
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created
查看deployment、pod、svc

4)打开浏览器,访问dashboard的web页面

这里登录用到的token,就是Serviceaccount的token,对Serviceaccount的授权不同决定了dashboard的操作权限
3 、示例 3 :创建 serviceaccount 绑定admin,并验证权限,作用域为名称空间
User --> Rolebindig -->ClusterRole:权限降级,serviceaccount dev-admin对名称空间dev拥有完全权限
bash
[root@master01 ~]# kubectl create ns dev
namespace/dev created
1)创建 serviceaccount
bash
[root@master01 ~]# kubectl create serviceaccount dev-admin -n dev
serviceaccount/dev-admin created
2)对serviceaccount通过 rolebinding 绑定admin
bash
[root@master01 ~]# kubectl create rolebinding dev-admin -n dev --clusterrole=admin --serviceaccount=dev:dev-admin
rolebinding.rbac.authorization.k8s.io/dev-admin created
[root@master01 ~]# kubectl get sa -n dev
NAME SECRETS AGE
default 0 2m10s
dev-admin 0 66s
[root@master01 ~]# kubectl get rolebinding -n dev
NAME ROLE AGE
dev-admin ClusterRole/admin 4s
3)创建token
在以前版本的 kubernetes 中,进行了创建 serviceaccount 会自动生成一个 Secret 里面存放 token 值,但是新版本不会这样做了。
bash
[root@master01 ~]# cat dashboard-admin-token.yaml
apiVersion: v1
kind: Secret
metadata:
name: dashboard-admin-secret
namespace: dev
annotations:
kubernetes.io/service-account.name: dev-admin
type: kubernetes.io/service-account-token
[root@master01 ~]# kubectl apply -f dashboard-admin-token.yaml
secret/dashboard-admin-secret created
[root@master01 ~]# kubectl get secrets -n dev
NAME TYPE DATA AGE
dashboard-admin-secret kubernetes.io/service-account-token 3 2s
4)查看serviceaccount中secrets的token
bash
[root@master01 ~]# kubectl describe secret dashboard-admin-secret -n dev
Name: dashboard-admin-secret
Namespace: dev
Labels: <none>
Annotations: kubernetes.io/service-account.name: dev-admin
kubernetes.io/service-account.uid: c50d10e1-5051-46b5-9b52-a43b93f33774
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1099 bytes
namespace: 3 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6ImNCYi1qTmVLUjM3WVpVVTVuQUFfVGpRT2UxNzV4cENDUHRuZkVCWUFwcVkifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZXYiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluLXNlY3JldCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJkZXYtYWRtaW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJjNTBkMTBlMS01MDUxLTQ2YjUtOWI1Mi1hNDNiOTNmMzM3NzQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGV2OmRldi1hZG1pbiJ9.6cmDj8k04mzApqLf4-5iuRaoFxNdarlsAYD0fo45RBtO6NUJOKdsnaNfd67IGPVtwAhdNrZ1JJ6GhaA1uqKU1OCzVDcivt3x0QsEEReWghrYDHVQ7oy_R2beStApRu_1wGAFTHALtwEhXM6GAEfAv44AoHHWq9vcClBCtuWKKiMFib3ZW1Xd-TyJdFqFN5pVg5TYJKINrAEYHA6yBEIzgLBDFkdGQr78d1qTewinzmLTIV-nZ6aBmrS95FiJsfeDHEfkq-KqFXbnz1GbTkFFSvjFiYh6ZMcUP5QFQxW8c6ABjJFWMjlLgZcOBF02whxAJtMC0P76OctXTWVMRxOkTQ
5)复制上面的token到kubernetes dashboard界面

6)权限验证,只对dev名称空间有权限

4 、示例 4:创建serviceaccount绑定cluster-admin
拥有超级管理员权限,作用域为集群级别资源
1)创建serviceaccoun
bash
[root@master01 ~]# kubectl create serviceaccount cluster-admin -n kubernetes-dashboard
serviceaccount/cluster-admin created
2)创建clusterrolebinding 绑定cluster-admin,集群级别资源,不需要指定名称空间
bash
[root@master01 ~]# kubectl create clusterrolebinding sa-cluster-admin --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:cluster-admin
clusterrolebinding.rbac.authorization.k8s.io/sa-cluster-admin created
3)创建 token
root@master01 \~\]# cat dashboard-cluster-admin-secret.yaml apiVersion: v1 kind: Secret metadata: name: dashboard-admin-secret namespace: kubernetes-dashboard annotations: kubernetes.io/service-account.name: cluster-admin type: kubernetes.io/service-account-token \[root@master01 \~\]# kubectl apply -f dashboard-cluster-admin-secret.yaml secret/dashboard-admin-secret created
4)查看serviceaccount中secrets的token
root@master01 \~\]# kubectl describe secret dashboard-admin-secret -n kubernetes-dashboard Name: dashboard-admin-secret Namespace: kubernetes-dashboard Labels: \
Annotations: kubernetes.io/service-account.name: cluster-admin kubernetes.io/service-account.uid: 99aa419b-4f89-4678-8d35-1fd868758088 Type: kubernetes.io/service-account-token Data ==== ca.crt: 1099 bytes namespace: 20 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6ImNCYi1qTmVLUjM3WVpVVTVuQUFfVGpRT2UxNzV4cENDUHRuZkVCWUFwcVkifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tc2VjcmV0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImNsdXN0ZXItYWRtaW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI5OWFhNDE5Yi00Zjg5LTQ2NzgtOGQzNS0xZmQ4Njg3NTgwODgiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6Y2x1c3Rlci1hZG1pbiJ9.vnlpUMNSwaYRfv9CVNzifqyol7ZQrGcV98fF0xj3yfGO6OmY1FJEjRadZ222-nf5e5keWYGTw5lF1mHVWSUSkaLicenH_ftJhEQQPIxYCTDLSj6X3WoIAqXyBnHBxYG5t8QleQjKGH9mLOXD-GYN6HhvDcXwI9jWqScDJ3r4SilFPTp6GTYUcccMxUZIiadpopoV0ZWBfKTuPNIyAbSCj_GBK1e-hL4FmislJYbMVNHCESlfAKEtlLPBOEic3ca9eWScnVaahaRHKGE2o3f_QIc6QmQgUEQCiBTk16M4bBXSaRIL-dVzw_94jL6bsjqCSyd_0ydBya6CQAMAoqAdVw
5)复制上面的token到kubernetes dashboard界面

6)权限验证,对所有名称空间有权限


7)简单使用 dashboard
登录面板以后,可以很方便的集群的各种资源如 pod、deployment、configmap 等进行查看。同时,提供了多种创建资源的方式。
接下来用表单创建一个apache的 deploy。

可以看见已经创建完成。

五、准入控制
1、什么是 K8S之准入控制
就是在创建资源经过身份验证之后,kube-apiserver在数据写入etcd之前做一次拦截,然后对资源进行更改、判断正确性等操作。
官网参考资料url:
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/admission-controllers/
LimitRange,ResourceQuota
目的:能控制特定命名空间中的资源使用量,最终实现集群的公平使用和成本的控制
LimitRange: 此准入控制器会监测传入的请求,并确保请求不会违反 Namespace 中 LimitRange 对象所设置的任何约束。 如果你在 Kubernetes 部署中使用了 LimitRange 对象,则必须使用此准入控制器来执行这些约束。 LimitRanger 还可以用于将默认资源请求应用到没有设定资源约束的 Pod。当前,默认的 LimitRanger 对 default 名字空间中的所有 Pod 都设置 0.1 CPU 的需求。
**ResourceQuota:**此准入控制器会监测传入的请求,并确保它不违反任何一个Namespace 中的ResourceQuota 对象中列举的约束。如果你在Kubernetes 部署中使用了ResourceQuota, 则必须使用这个准入控制器来强制执行配额限制。
**1)LimitRange:**为Pod添加默认的计算资源需求(requests)和计算资源限制(limit);以及存储资源需求和存储资源限制;
支持分别在容器和Pod级别进行限制;
比如:指定名称空间下每个Pod CPU、内存的最低最高额度
一个 LimitRange(限制范围)对象提供的限制能够做到:
- 在一个命名空间中实施对每个 Pod 或 Container 最小和最大的资源使用量的限制。
- 在一个命名空间中实施对每个 PersistentVolumeClaim 能申请的最小和最大的存储空间大小的限制。
- 在一个命名空间中实施对一种资源的申请值(requests)和限制值(limit)的比值的控制。
- 设置一个命名空间中对计算资源的默认申请/限制值,并且自动的在运行时注入到多个 Container 中。
2)ResourceQuota:限制资源数量,限制计算资源总量,存储资源总量;
比如:指定名称空间下,只允许创建Pod、svc的数量, 所有Pod CPU、内存的最低最高额度
3)如何启用一个准入控制器?
Kubernetes API 服务器的 enable-admission-plugins 标志接受一个(以逗号分隔的)准入控制插件列表, 这些插件会在集群修改对象之前被调用。
bash
[root@master01 ~]# cat /etc/kubernetes/manifests/kube-apiserver.yaml
........................
--enable-admission-plugins=NodeRestriction
........................
提示:
apiserver启用准入控制插件需要使用--enable-admission-plugins选项来指定,该选项可以使用多个值,用逗号隔开表示启用指定的准入控制插件;这里配置文件中显式启用了NodeRestrication这个插件;默认没有写在这上面的内置准入控制器,它也是启用了的,比如LimitRanger、ResourceQuota、ServiceAccount等等;对于不同的k8s版本,内置的准入控制器和启用与否请查看相关版本的官方文档;对于那些没有启动的准入控制器,我们可以在上面选项中直接启用,分别用逗号隔开即可。
对应的官网地址:
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/admission-controllers/
4)怎么关闭准入控制器?
Kubernetes API 服务器的 disable-admission-plugins 标志,会将传入的(以逗号分隔的) 准入控制插件列表禁用,即使是默认启用的插件也会被禁用。
--disable-admission-plugins=PodNodeSelector,AlwaysDeny ...
2、示例 1: 创建LimitRange准入控制策略
1)对Pod、容器、PVC等资源进行限制
bash
[root@master01 ~]# cat limitrange-demo.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: core-resource-limits
namespace: dev #命名空间级别资源,对整个命名空间生效
spec:
limits:
- type: Pod #对Pod限制
max:
cpu: "4" #CPU最大不能超过4核
memory: "4Gi" #内存不能超过4G
min:
cpu: "500m" #CPU最小不能小于500m
memory: "16Mi" #内存不能小于16M
- type: Container #对容器作限制
max:
cpu: "4"
memory: "1Gi"
min:
cpu: "100m"
memory: "4Mi"
default: #上限阈值 #如果容器中没有做requests或limits作限制,则附加的默认值
cpu: "2"
memory: "512Mi"
defaultRequest: #下限阈值
cpu: "500m"
memory: "64Mi"
maxLimitRequestRatio: #最大限制请求比率 上限阈值/下限阈值,也可以用倍数做限制
cpu: "4"
- type: PersistentVolumeClaim #对PV做限制
max:
storage: "10Gi"
min:
storage: "1Gi"
default:
storage: "5Gi"
defaultRequest:
storage: "1Gi"
maxLimitRequestRatio: #没有下阈值,也可以用倍数做限制
storage: "5"
创建LimitRange策略
bash
[root@master01 ~]# kubectl apply -f limitrange-demo.yaml
limitrange/core-resource-limits created
[root@master01 ~]# kubectl get limitrange -n dev
NAME CREATED AT
core-resource-limits 2023-02-21T07:05:49Z
[root@master01 ~]# kubectl describe limitrange core-resource-limits -n dev

2)验证测试策略是否生效
bash
[root@master01 ~]# kubectl run testpod-$RANDOM --image=nginx -n dev
pod/testpod-13568 created
[root@master01 ~]# kubectl get pods testpod-13568 -n dev -o yaml

注:
CPU 以核心为单位。
memory 以字节为单位。
requests 为kubernetes scheduler执行pod调度时node节点至少需要拥有的资源。
limits 为pod运行成功后最多可以使用的资源上限
创建小于内存限制的Pod 创建失败
bash
[root@master01 ~]# cat testpod_limitrange.yaml
apiVersion: v1
kind: Pod
metadata:
name: testpod
namespace: dev
spec:
containers:
- name: testpod
image: nginx
imagePullPolicy: IfNotPresent
resources:
requests:
memory: "8Mi"
cpu: "1"
limits:
memory: "1Gi"
cpu: "2"
[root@master01 ~]# kubectl apply -f testpod_limitrange.yaml
Error from server (Forbidden): error when creating "testpod_limitrange.yaml": pods "testpod" is forbidden: minimum memory usage per Pod is 16Mi, but request is 8388608
3、 ResourceQuota
ResourceQuota资源可限制名称空间中处于非终止状态的所有Pod对象的计算资源需求及计算资源限制总量。
示例2:创建ResourceQuota准入控制策略
bash
[root@master01 ~]# cat resourcequota-demo.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: resourcequota-demo
namespace: dev
spec:
hard :
pods: "5" #Pod总量
count/services: "5" #svc总量
count/configmaps: "5"
count/secrets: "5"
count/cronjobs.batch: "2"
requests.cpu: "2" #cpu下限阈值总量
requests.memory: "4Gi"
limits.cpu: "4" #cpu上限阈值总量
limits.memory: "8Gi"
count/deployments.apps: "2"
count/statefulsets.apps: "2"
persistentvolumeclaims: "6"
requests.storage: "20Gi"
longhorn.storageclass.storage.k8s.io/requests.storage: "20Gi"
longhorn.storageclass.storage.k8s.io/persistentvolumeclaims: "6"
[root@master01 ~]# kubectl get resourcequota -n dev

创建不符合标准的Pod 验证测试策略是否生效
bash
[root@master01 ~]# kubectl describe resourcequota resourcequota-demo -n dev

bash
[root@master01 ~]# kubectl run testpod-$RANDOM --image="nginx" -n dev
pod/testpod-3542 created
[root@master01 ~]# kubectl describe resourcequota resourcequota-demo -n dev

root@master01 \~\]# kubectl run testpod-$RANDOM --image="nginx" -n dev Error from server (Forbidden): pods "testpod-3047" is forbidden: exceeded quota: resourcequota-demo, requested: limits.cpu=2, used: limits.cpu=4, limited: limits.cpu=4 \[root@master01 \~\]# kubectl describe resourcequota resourcequota-demo -n dev

创建pod失败的原因是因为超出了cpu总量的硬限制
