k8s:认证、授权、准入控制

一、概述 :

API Server 作为 Kubernetes 集群系统的网关,是访问及管理资源对象的唯一人口,所有需要访问集群资源的组件,以及此前使用的 kubectl 命令等都要经由此网关进行集群访问和管理。

1 kubernetes API 访问控制

官方文档:https://kubernetes.io/zh/docs

api server 是集群访问控制的统一入口

**K8s的认证过程:**认证 -> 授权 - > 准入控制 (admination controller)

用户通过kubectl、客户端库或者通过发送 REST 请求访问API。用户(自然人)和 Kubernetes 服务账户都可以被授权进行 API 访问。 请求到达 API 服务器后会经过几个阶段,具体说明如图:

首先看一下 Kubernetes API 请求的发起,请求的发起分为两个部分:

  1. 第一个部分是人机交互的过程。 是大家非常熟悉的用 kubectl 对 apiserver 的一个请求过程使用的是 Users Accounts普通账户;
  2. 第二个部分是 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两种认证方式

其他常见的认证:

  1. 引导令牌(Token) : 如:节点加入时认证:kubelet
  2. 静态令牌: 存储于API Server进程可直接加载到的文件中保存的令牌,该文件内容会由API Server缓存于内存中;
  3. 静态密码:存储于API Server进程可直接加载到的文件中保存的账户和密码令牌,该文件内容会由API Server缓存于内存中;
  4. ServiceAccount令牌:
  5. OpenID Connect令牌:OIDC令牌,
  6. OAuth 2 webhook令牌
  7. 代理认证等

访问k8s的API Server的客户端(用户)主要分为两类:

  1. kubectl :用户家目录中的 .kube/config 里面保存了客户端访问API Server的密钥相关信息,这样当用kubectl访问k8s时,它就会自动读取该配置文件,向API Server发起认证,然后完成操作请求,使用Users Accounts普通账户。
  2. pod:Pod中的进程需要访问API Server,而Pod自身去连接API Server时,使用的账号是:Service Account,生产中后者使用居多。

所以在 Kubernetes 中,有两类用户:

  1. Normal Users:外部用户,即普通用户,通常是给人使用的,标记的是个人,平时常用的kubectl命令都是普通用户执行的。
  2. 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类信息,都是以加密方式显示

  1. namespace、

  2. ca.crt、

  3. 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个认证信息;

  1. clusters:配置要访问的kubernetes集群
  2. contexts:配置访问kubernetes集群的具体上下文环境
  3. current-context:配置当前使用的上下文环境
  4. 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文件查看常用命令

  1. 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
  1. 查看指定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
  1. 基于证书请求和集群的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==
  1. 生成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。

  1. AlwaysDeny:表示拒绝所有请求,一般用于测试。
  2. AlwaysAllow:允许接收所有请求。如果集群不需要授权流程,则可以采用该策略,这也是Kubernetes的默认配置。
  3. ABAC(Attribute-Based Access Control):基于属性的访问控制。表示使用用户配置的授权规则对用户请求进行匹配和控制。
  4. Webhook:通过调用外部REST服务对用户进行授权。
  5. RBAC:Role-Based Access Control,基于角色的访问控制(本章讲解)。
  6. 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 对象实现。

  1. Role:角色,名称空间级别;授权特定命名空间的访问权限
  2. ClusterRole:集群角色,全局级别;授权所有命名空间的访问权限

角色绑定:

角色绑定将一个角色中定义的各种权限授予一个或者一组用户。角色绑定包含了一组相关主体(即 subject, 包括用户 ------User、用户组 ------Group、或者服务账户 ------Service Account)以及对被授予角色的引用。在命名空间中可以通过 RoleBinding 对象授予权限,而集群范围的权限授予则通过 ClusterRoleBinding 对象完成。

  1. RoleBinding:将角色绑定到主体(即subject),意味着,用户仅得到了特定名称空间下的Role的权限,作用范围也限于该名称空间;
  2. ClusterRoleBinding:将集群角色绑定到主体,让用户扮演指定的集群角色;意味着,用户得到了是集群级别的权限,作用范围也是集群级别;

主体(subject)

  1. User:用户
  2. Group:用户组
  3. ServiceAccount:服务账号

绑定对应关系

  1. 主体(Subject) --> RoleBinding --> Role #主体获得名称空间下的Role的权限
  2. 主体(Subject) --> ClusterRoleBinding --> clusterRoles #主体获得集群级别clusterRoles的权限
  3. 主体(Subject) --> Rolebindig -->ClusterRole #权限降级 主体获得名称空间下的clusterRoles的权限

RoleBinding用于将Role上的许可权限绑定到一个或一组用户之上,它隶属于且仅能作用于一个命名空间。绑定时,可以引用同一命名空间中的Role,也可以引用集群级别的 ClusterRole。

ClusterRoleBinding则把ClusterRole中定义的许可权限绑定在一个或一组用户之上,它仅可以引用集群级别的ClusterRole。

Role、RoleBinding、ClusterRole和ClusterRoleBinding 的关系如图 所示 。

在RBAC api中,通过如下步骤进行授权:

  1. 定义角色:在定义角色时会指定此角色对于资源访问控制的规则;
  2. 绑定角色:将主体与角色进行绑定,对用户进行访问授权;

rules中的参数说明:

  1. apiGroups:apiGroups 就是api资源组,执行kubectl get apiservice 就可以看到集群所有的api组,例如:"apiVersion: apps/v1"等
  2. 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"]
  1. 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 、内建管理员

  1. 名称空间管理员admin

clusterrole admin是名称空间级别资源,拥有所有名称空间下的资源的所有操作权限。

  1. 集群管理员 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页面

https://192.168.30.20:30008

这里登录用到的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(限制范围)对象提供的限制能够做到:

  1. 在一个命名空间中实施对每个 Pod 或 Container 最小和最大的资源使用量的限制。
  2. 在一个命名空间中实施对每个 PersistentVolumeClaim 能申请的最小和最大的存储空间大小的限制。
  3. 在一个命名空间中实施对一种资源的申请值(requests)和限制值(limit)的比值的控制。
  4. 设置一个命名空间中对计算资源的默认申请/限制值,并且自动的在运行时注入到多个 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总量的硬限制

相关推荐
主机哥哥10 小时前
还不会部署OpenClaw?阿里云推出五种OpenClaw快速部署方案
阿里云·云计算
小锋学长生活大爆炸12 小时前
【教程】免Root在Termux上安装Docker
运维·docker·容器
进击切图仔12 小时前
常用 Docker 命令备份
运维·docker·容器
Re.不晚14 小时前
可视化大数据——淘宝母婴购物数据【含详细代码】
大数据·阿里云·云计算
阿里云云原生15 小时前
巨人网络《超自然行动组》携手阿里云打造云原生游戏新范式
云原生
zhougl99617 小时前
云计算超详细介绍
云计算
我在人间贩卖青春18 小时前
C++之STL容器
c++·容器·stl
71ber19 小时前
深入理解 HAProxy:四层/七层透传与高级 ACL 调度详解
linux·云原生·haproxy
A-刘晨阳19 小时前
K8S 之 DaemonSet
运维·云原生·容器·kubernetes·daemonset