kubernetes 集群安全机制 - 基于RBAC授权方式

kube-apiserver 是 k8s 整个集群的入口,是一个 REST API 服务,提供的 API 实现了 Kubernetes 各类资源对象(如 Pod,RC,Service 等)的增、删、改、查,API Server 也是集群内各个功能模块之间交互和通信的枢纽,是整个集群的总线和数据中心。

 

由此可见 API Server 的重要性了,我们用 kubectl、各种语言提供的客户端库或者发送 REST 请求和集群交互,其实底层都是以 HTTP REST 请求的方式同 API Server 交互,所以k8s的安全机制基本就是围绕保护Apiserver来设计的。那么访问的安全机制是如何保证的呢,总不能随便来一个请求都能接受并响应吧。API Server 为此提供了一套特有的、灵活的安全机制,每个请求到达 API Server 后都会经过:认证(Authentication)–>授权(Authorization)–>准入控制(Admission Control) 三道安全关卡,通过这三道安全关卡的请求才给予响应:

认证(Authentication)
认证阶段的工作是识别用户身份(判断真伪),支持的认证方式有很多,比如:HTTP Base,HTTP token,TLS,Service Account,OpenID Connect 等,API Server 启动时可以同时指定多种认证方式,会逐个使用这些方法对客户请求认证,只要通过任意一种认证方式,API Server 就会认为 Authentication 成功。高版本的 Kubernetes 默认认证方式是 TLS。在 TLS 认证方案中,每个用户都拥有自己的 X.509 客户端证书,API 服务器通过配置的证书颁发机构(CA)验证客户端证书。

授权(Authorization)
授权阶段判断请求是否有相应的权限(是否有权限),授权方式有多种:AlwaysDeny,AlwaysAllow,ABAC,RBAC,Node 等。API Server 启动时如果多种授权模式同时被启用,Kubernetes 将检查所有模块,如果其中一种通过授权,则请求授权通过。 如果所有的模块全部拒绝,则请求被拒绝(HTTP状态码403)。高版本 Kubernetes 默认开启的授权方式是 RBAC 和 Node。

准入控制(Admission Control)
准入控制判断操作是否符合集群要求(能不能这么干),准入控制配备有一个“准入控制器”的列表,发送给 API Server 的每个请求都需要通过每个准入控制器的检查,检查不通过,则 API Server 拒绝调用请求,有点像 Web 编程的拦截器的意思。

总结下就是,认证是保证访问双方都是可信的;鉴权是检查请求者是否有所访问资源的权限;准入控制是API Server的功能插件集合,可以为API Server添加一些额外的处理请求的功能。

认证Authentication

Kubernetes提供的认证方式挺多:X509 Client Certs、Static Token File、Bootstrap Tokens、Static Password File、Service Account Tokens....具体看官方文档

可以归类为以下三种认证方式:

  1. HTTP Base认证:通过用户名+密码的方式认证,现在基本不用。
  2. HTTP Token认证:通过一个Token来识别合法用户,客户端发起API调用请求时,需要在HTTP Header里放入Token,如果server端含有这个token,那么认证成功,否则失败。
  3. HTTPS 证书认证:基于CA证书签名的数字证书认证,开启TLS。关于CA证书认证的具体流程请参照 HTTPS中CA证书的签发及使用过程

基于TLS证书的API Server认证

1.1 证书

TLS需要一个CA机构,用于给服务器和客户端发布证书。API Server基本只提供给集群内部访问,所以自签发一个CA根证书就好了。可以参考下kubeasz的创建CA证书和密钥

再来看看需要访问API Server的都有谁:

  • 管理员:使用kubectl或是UI界面(dashborad)访问
  • master节点:Controller Manager、Scheduler
  • Node节点:kubelet、kube-proxy、Pod容器中的进程

可以将他们大概分为两类:

  • Kubenetes组件对API Server的访问:kubectl、Controller Manager、Scheduler、kubelet、kube-proxy
  • Kubernetes管理的Pod对容器的访问:Pod(dashborad也是以Service形式运行)

先看看组件,Controller Manager、Scheduler与API Server在同一台机器,所以直接使用API Server的非安全端口访问,--insecure-bind-address=127.0.0.1其他组件比如kubectl、kubelet、kube-proxy访问API Server就都需要证书了。

1.1.1 手动签发

其中kubectl、kube-proxy需要手动地用CA根证书签发。可以查看 kubernetes 集群搭建 -- 二进制方式

首先创建证书请求文件:

{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "HangZhou",
      "L": "XS",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}

然后就可以向CA申请证书:

cfssl gencert \
        -ca=ca.pem \
        -ca-key=ca-key.pem \
        -config=ca-config.json \
        -profile=kubernetes admin-csr.json | cfssljson -bare admin"

之后就可以在本地生成了三个文件:

  • admin.csr:证书请求
  • admin-key.pem:公钥
  • admin.pem:私钥

1.1.2 自动签发

kubelet可以使用Bootstrap Tokens,动态地让master分配证书。所谓Bootstrap Tokens就是创建集群时,API Server与kubelet约定好一个token,kubelet首次访问API Server时,使用token做认证,通过后,Controller Manager会为kubelet生成一个证书,以后的访问都是用证书做认证了。使用Bootstrap Tokens,可以不用一个一个地为Node生成kubelet的证书,而只需要一个统一的token,可以方便集群的创建。关于Bootstrap Tokens,可以看看文档这篇博客。写到这里我有个疑问,如果Bootstrap Tokens是为了不用在创建集群时,一个个地为Node生成kubelet证书。那么同为运行在Node上的组件的kube-proxy为什么又需要先生成证书才能访问API Server呢.....

1.1.3 kubeconfig

有了证书之后,还需要生成kubeconfig文件。kubeconfig文件包含集群参数(CA证书、API Server地址),客户端参数(上面生成的证书和私钥),集群context信息(集群名称、用户名)。Kubenetes组件通过启动时指定不同的kubeconfig文件可以切换到不同的集群。kubelet的kubeconfig文件是通过Bootstrap Tokens获取到证书后生成的。关于kubeconfig的文档

安装完 k8s 集群后会生成 $HOME/.kube/config 文件,这个文件就是 kubectl 命令行工具访问集群时使用的认证文件,也叫 Kubeconfig 文件。

这个 Kubeconfig 文件中有很多重要的信息,文件大概结构是这样,这里说明下每个字段的含义:

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: ...
    server: https://192.168.26.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: ...
    client-key-data: ...

可以看出文件分为三大部分:clusters、contexts、users
clusters 部分
定义集群信息,包括 api-server 地址、certificate-authority-data: 用于服务端证书认证的自签名 CA 根证书(master 节点 /etc/kubernetes/pki/ca.crt 文件内容 )。

contexts 部分
集群信息和用户的绑定,kubectl 通过上下文提供的信息连接集群。

users 部分
多种用户类型,默认是客户端证书(x.509 标准的证书)和证书私钥,也可以是 ServiceAccount Token。这里重点说下前者:

  • client-certificate-data: base64 加密后的客户端证书;
  • client-key-data: base64 加密后的证书私钥;

一个请求在通过 api-server 的认证关卡后,api-server 会从收到的客户端证书中读取用户信息,然后用于后面的授权关卡,这里所说的用户并不是服务账号,而是客户端证书里面的 Subject 信息:O 代表用户组,CN 代表用户名。为了证明,可以使用 openssl 手动获取证书中的这个信息:

首先,将 Kubeconfig 证书的 user 部分 client-certificate-data 字段内容进行 base64 解密(echo 'xxxxxxxxx' | base64 --decode),保存文件为 client.crt。

然后使用 openssl 解析证书信息即可看到 Subject 信息:openssl x509 -in client.crt -text

解析集群默认的 Kubeconfig 客户端证书得到的 Subject 信息是:

Subject: O=system:masters, CN=kubernetes-admin

可以看出该证书绑定的用户组是 system:masters,用户名是 kubernetes-admin,而集群中默认有个 ClusterRoleBinding 叫 cluster-admin,它将名为 cluster-admin 的 ClusterRole 和用户组 system:masters 进行了绑定,而名为 cluster-admin 的 ClusterRole 有集群范围的 Superadmin 权限,这也就理解了为什么默认的 Kubeconfig 能拥有极高的权限来操作 k8s 集群了。

1.1.4 ServiceAccount

Kubernetes 中两种账号类型

K8S中有两种用户(User):服务账号(ServiceAccount)和普通的用户(User)。 ServiceAccount 是由 k8s 管理的,而 User 账号是在外部管理,k8s 不存储用户列表,也就是说针对用户的增、删、该、查都是在集群外部进行,k8s 本身不提供普通用户的管理。

两种账号的区别:

  • ServiceAccount 是 k8s 内部资源,而普通用户是存在于 k8s 之外的;
  • ServiceAccount 是属于某个命名空间的,不是全局的,而普通用户是全局的,不归某个 namespace 特有;
  • ServiceAccount 一般用于集群内部 Pod 进程使用,和 api-server 交互,而普通用户一般用于 kubectl 或者 REST 请求使用;

上面提到的是Kubenetes组件访问API Server的情况,另一种情况是Pod中的容器访问API Server。因为Pod的创建、销毁是动态的,所以要为它手动生成证书就不可行的。Kubenetes使用了Service Account解决Pod 访问API Server的认证问题。使用Service Account要在API Server启动时,带上--admission-controller=ServiceAccount参数。

1.1.4.1 Secret

Kubernetes设计了一种资源对象叫做Secret,分为两类,一种是用于ServiceAccount的service-account-token, 另一种是用于保存用户自定义保密信息的Opaque。我们在ServiceAccount中用到包含三个部分:Token、ca.crt、namespace。

  • token是使用API Server私钥签名的JWT。用于访问API Server时,Server端认证。
  • ca.crt,根证书。用于Client端验证API Server发送的证书。
  • namespace, 标识这个service-account-token的作用域名空间。
root@kube-1:~# kubectl get secret --all-namespaces
NAMESPACE     NAME                               TYPE                                  DATA      AGE
default       default-token-gnlqz                kubernetes.io/service-account-token   3         11d
kube-public   default-token-pcql2                kubernetes.io/service-account-token   3         11d
kube-system   default-token-5gm9r                kubernetes.io/service-account-token   3         11d
kube-system   kubernetes-dashboard-key-holder    Opaque                                2         11d

以上三个service-account-token都是系统默认添加的,会在每个namespace默认的ServiceAccount中使用。

一个具体的service-account-token:

root@kube-1:~# kubectl describe secret default-token-5gm9r --namespace=kube-system
Name:         default-token-5gm9r
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name=default
              kubernetes.io/service-account.uid=99473738-64d1-11e8-80e9-fa163e39e787

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1346 bytes
namespace:  11 bytes
token:      eyjh......7FcRPVz0g

再回过头来看看ServiceAccount,默认情况下每个namespace都会有一个ServiceAccount,如果Pod在创建时没有指定ServiceAccount,就会使用Pod所属的namespace的ServiceAccount。

一个具体的ServiceAccount:

root@kube-1:~# kubectl describe sa default --namespace=kube-system
Name:                default
Namespace:           kube-system
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   default-token-5gm9r
Tokens:              default-token-5gm9r
Events:              <none>
  • Image pull secrets 用于指定pull镜像时的Secret。
  • Tokens 指定用于访问API Server认证的Secret。
  • Mountable secrets 指定需要挂载到Pod中的Secret。可以随便建一个pod,exec到容器中,就可以在目录中看到Secret的三个文件了。

上图清晰阐明了Pod中的容器访问API Server的过程:

  • 每个namespace默认都会有一个ServiceAccount
  • Pod在创建时需指定ServiceAccount,如未指定,则使用所属的namespace的默认ServiceAccount
  • ServiceAccount中会关联具体使用哪个Secret,以此实现了Pod与Secret的绑定
  • Pod中将挂载Secret中用于访问API Server的三个认证文件,默认路径为:/run/secrets/kubernetes.io/serviceaccount/

1.2 总结

简单总结下,基于TLS证书的API Server认证如下图所示:

鉴权Authorization

上面认证过程,只是确认通信的双方都确认了对方是可信的,可以相互通信。而鉴权是确定请求方有哪些资源的权限。apiserver目前支持以下几种授权策略(通过apiserver的启动参数--authorization-mode设置)
alwaysDeny:表示拒绝所有的请求,一般用于测试
alwaysAllow:允许接收所有的请求,如果集群不需要授权流程,则可以采用该策略
ABAC(Attrilbute-Based Access Control):基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制
webbook:通过调用外部REST服务对用户进行授权
RBAC(Role-Based Access Control):基于角色的访问控制,现在默认的规则

RBAC授权模式

相对其他访问控制方式,RBAC拥有以下优势:

  • 对集群中的资源和非资源均拥有完整的覆盖
  • 整个RBAC完全由几个api对象完成,同其他api对象一样,可以用kubectl或api进行操作
  • 可以在运行时进行调整,无需重启apiserver

RBAC定义了4个资源对象:Role、ClusterRole、RoleBinding、 ClusterRoleBinding。

Role(ClusterRole)定义了一个角色(集群角色)在namespace(clutser)范围内对某些资源的操作权限。

RoleBinding(ClusterRoleBinding)将用户、组、ServiceAccount同角色进行绑定,绑定的账户就拥有了角色(集群角色)所指定的权限。

之前说过,ServiceAccount 是 k8s 内部资源,而普通用户是存在于 k8s 之外的,Kubenetes并不会存储普通用户的数据,那么User、Group、ServiceAccount指定的用户又是从哪里来的呢?

同样,根据谁需要访问API Server来说,就有三种情况:

  • 手动签发

  Kubenetes组件(kubectl、kube-proxy)或是其他自定义的用户在向CA申请证书时,需要提供一个证书请求文件:

root@kube-1:~# cat /etc/kubernetes/ssl/admin-csr.json 
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "HangZhou",
      "L": "XS",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}

  API Server会把客户端证书的CN字段作为User,把names.O字段作为Group。

  • 自动签发

  kubelet使用TLS Bootstaping认证时,API Server可以使用Bootstrap Tokens或者Token authentication file验证token,无论哪一种,Kubenetes都会为token绑定一个默认的User和Group。相关文档

  • ServiceAccount

  Pod使用ServiceAccount认证时,service-account-token中的JWT会保存User信息。

Role and ClusterRole
在RBAC API中,Role表示一组规则权限,权限只会增加(累加权限),不存在一个资源一开始就有很多权限而通过RBAC对其进行减少的操作,Role可以定义在一个namespace中,如果想要跨namespace则可以创建ClusterRole。

ClusterRole具有与Role相同的权限角色控制能力,不同的是ClusterRole是集群级别的,ClusterRole可以用于:

  • 集群级别的资源控制(例如node访问权限)
  • 非资源型endpoints(例如/healthz访问)
  • 所有命名空间资源控制(例如pods)

RoleBinding and ClusterRoleBinding 
RoleBinding可以将角色中定义的权限授予用户或用户组,RoleBinding包含一组权限列表(subjects)、权限列表中包含有不同形式的待授予权限资源类型(users、groups、service accounts),RoleBinding同样包含对Bind的Role引用。RoleBinding适用于某个命名空间内授权,而ClusterRoleBinding适用于集群范围内的授权。RoleBinding 同样可以引用ClusterRole来对当前namespace内用户、用户组或ServiceAccount进行授权,这种操作允许集群管理员在整个集群内定义一些通用的CLusterRole,然后在不同的namespace中使用RoleBinding来引用,使用ClusterRoleBinding可以对整个集群中的所有命名空间资源权限进行授权。

RBAC例子:给一个只读用户授权

我们已经解释了为什么默认的 Kubeconfig 文件具有 Superadmin 权限,这个权限比较高,有点类似 Linux 系统的 Root 权限。有时我们会将集群访问权限开放给其他人员,比如供研发人员查看 Pod 状态、日志等信息,这个时候直接用系统默认的 Kubeconfig 就不太合理了,权限太大,集群的安全性没有了保障。更合理的做法是给研发人员一个只读权限的账号,避免对集群进行一些误操作导致故障。

我们以客户端证书认证方式创建 Kubeconfig 文件,所以需要向集群自签名 CA 机构(master 节点)申请证书,然后通过 RBAC 授权方式给证书用户授予集群只读权限。具体操作如下:

1.创建用户

首先根据上文可以得知,Kubernetes 不存储用户具体细节信息,也就是说只要通过它的那几种方式能进来的用户,Kubernetes 就认为它是合法的;那么为了让 kubectl 只读,所以我们需要先给它创建一个用来承载只读权限的用户;这里用户创建我们选择使用证书方式

# 首先先创建一个用于签发证书的 json(证书创建使用 cfssl)
{
  "CN": "readonly",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "develop:readonly",
      "OU": "develop"
    }
  ]
}

然后基于以 Kubernetes apiserver 的 CA 证书创建这个只读用户的证书

cfssl gencert --ca /root/TLS/k8s/ca.pem \
                   --ca-key /root/TLS/k8s/ca-key.pem \
                   --config /root/TLS/k8s/ca-config.json \
                   --profile kubernetes readonly.json | \
                   cfssljson --bare readonly
  • -ca:指明ca的证书

  • -ca-key:指明ca的私钥文件

  • -config:指明请求证书的json文件,注意不是readonly申请的json文件,而是配置CA证书生成策略的ca-config.json

  • -profile:与-config中的profile对应,是指根据config中的profile段来生成证书的相关信息

  • readonly.json才是用户申请的json文件,最后的readonly将指定最终生成的证书名
[root@binary-master readonly]# cfssl gencert --ca /root/TLS/k8s/ca.pem \
>                    --ca-key /root/TLS/k8s/ca-key.pem \
>                    --config /root/TLS/k8s/ca-config.json \
>                    --profile kubernetes readonly.json | \
>                    cfssljson --bare readonly
2021/07/06 16:37:53 [INFO] generate received request
2021/07/06 16:37:53 [INFO] received CSR
2021/07/06 16:37:53 [INFO] generating key: rsa-2048
2021/07/06 16:37:53 [INFO] encoded CSR
2021/07/06 16:37:53 [INFO] signed certificate with serial number 378883748233996180219945451996884016282033113658
2021/07/06 16:37:53 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
[root@binary-master readonly]# ll
total 16
-rw-r--r-- 1 root root 1017 Jul  6 16:37 readonly.csr
-rw-r--r-- 1 root root  235 Jul  5 15:21 readonly.json
-rw------- 1 root root 1675 Jul  6 16:37 readonly-key.pem
-rw-r--r-- 1 root root 1407 Jul  6 16:37 readonly.pem

最终会生成 readonly-key.pemreadonly.pem 两个证书文件以及一个 csr 请求文件

2.创建 kubeconfig

有了用于证明身份的证书以后,接下来创建一个 kubeconfig 文件方便 kubectl 使用

[root@binary-master readonly]# vi readonly-kubeconfig.sh

#!/bin/bash

KUBE_API_SERVER="https://172.31.93.210:6443"
CERT_DIR=${2:-"/root/TLS/k8s"}

kubectl config set-cluster default-cluster --server=${KUBE_API_SERVER} \
    --certificate-authority=${CERT_DIR}/ca.pem \
    --embed-certs=true \
    --kubeconfig=readonly.kubeconfig

kubectl config set-credentials develop-readonly \
    --certificate-authority=${CERT_DIR}/ca.pem \
    --embed-certs=true \
    --client-key=readonly-key.pem \
    --client-certificate=readonly.pem \
    --kubeconfig=readonly.kubeconfig

kubectl config set-context default-system --cluster=default-cluster \
    --user=develop-readonly \
    --kubeconfig=readonly.kubeconfig

kubectl config use-context default-system --kubeconfig=readonly.kubeconfig

需要根据实际情况修改脚本中两个参数,这个脚本会将证书也写入到 readonly.kubeconfig 配置文件中:

3.创建 ClusterRole

本示例创建的只读用户权限范围为 Cluster 集群范围,所以先创建一个只读权限的 ClusterRole;

创建 ClusterRole 不知道都有哪些权限的话,最简单的办法是将集群的 admin ClusterRole 保存出来,然后做修改

# 导出 admin ClusterRole
kubectl get clusterrole admin -o yaml > readonly.yaml

这个 admin ClusterRole 是默认存在的,导出后我们根据自己需求修改就行;最基本的原则就是像 update、delete 这种权限必须删掉(我们要创建只读用户),修改后如下

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: cluster-readonly
rules:
- apiGroups:
  - ""
  resources:
  - pods
  - pods/attach
  - pods/exec
  - pods/portforward
  - pods/proxy
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - configmaps
  - endpoints
  - persistentvolumeclaims
  - replicationcontrollers
  - replicationcontrollers/scale
  - secrets
  - serviceaccounts
  - services
  - services/proxy
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - bindings
  - events
  - limitranges
  - namespaces/status
  - pods/log
  - pods/status
  - replicationcontrollers/status
  - resourcequotas
  - resourcequotas/status
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - namespaces
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - apps
  resources:
  - deployments
  - deployments/rollback
  - deployments/scale
  - statefulsets
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - autoscaling
  resources:
  - horizontalpodautoscalers
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - batch
  resources:
  - cronjobs
  - jobs
  - scheduledjobs
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - extensions
  resources:
  - daemonsets
  - deployments
  - ingresses
  - replicasets
  verbs:
  - get
  - list
  - watch

最后执行 kubectl create -f readonly.yaml 创建即可

[root@binary-master readonly]# kubectl get clusterrole cluster-readonly
NAME               CREATED AT
cluster-readonly   2021-07-06T09:44:41Z

4、创建 ClusterRoleBinding

用户已经创建完成,集群权限也有了,接下来使用 ClusterRoleBinding 绑定到一起即可

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: cluster-readonly
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-readonly
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: develop:readonly

将以上保存为 readonly-bind.yaml 执行 kubectl create -f readonly-bind.yaml 即可

[root@binary-master readonly]# kubectl get clusterrolebinding cluster-readonly
NAME               ROLE                           AGE
cluster-readonly   ClusterRole/cluster-readonly   59s

5、测试权限

将最初创建的 kubeconfig 放到 ~/.kube/config 或者直接使用 --kubeconfig 选项测试读取、删除 pod 等权限即可,测试后如下所示:

[root@binary-master readonly]# kubectl --kubeconfig readonly.kubeconfig  get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-6799fc88d8-6g9q2   1/1     Running   1          93d
[root@binary-master readonly]# kubectl --kubeconfig readonly.kubeconfig  delete pod nginx-6799fc88d8-6g9q2
Error from server (Forbidden): pods "nginx-6799fc88d8-6g9q2" is forbidden: User "readonly" cannot delete resource "pods" in API group "" in the namespace "default"

可见,新建的 Kubeconfig 文件可以使用,指定使用该 Kubeconfig 文件访问k8s集群的话,只能查看,无法删除。

 

准入控制 Admission Control

准入控制是API Server的插件集合,通过添加不同的插件,实现额外的准入控制规则。甚至于API Server的一些主要的功能都需要通过Admission Controllers实现,比如ServiceAccount。

可以通过查看进程信息,来得知已经开启的插件:

[root@binary-master readonly]#  ps aux |grep apiserver
root        690  2.7 21.3 1164804 397092 ?      Ssl  Jul05  43:54 /opt/kubernetes/bin/kube-apiserver --logtostderr=false --v=2 --log-dir=/opt/kubernetes/logs --etcd-servers=https://172.31.93.210:2379,https://172.31.93.211:2379 --bind-address=172.31.93.210 --secure-port=6443 --advertise-address=172.31.93.210 --allow-privileged=true --service-cluster-ip-range=10.0.0.0/24 --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction --authorization-mode=RBAC,Node --enable-bootstrap-token-auth=true --token-auth-file=/opt/kubernetes/cfg/token.csv --service-node-port-range=30000-32767 --kubelet-client-certificate=/opt/kubernetes/ssl/server.pem --kubelet-client-key=/opt/kubernetes/ssl/server-key.pem --tls-cert-file=/opt/kubernetes/ssl/server.pem --tls-private-key-file=/opt/kubernetes/ssl/server-key.pem --client-ca-file=/opt/kubernetes/ssl/ca.pem --service-account-key-file=/opt/kubernetes/ssl/ca-key.pem --etcd-cafile=/opt/etcd/ssl/ca.pem --etcd-certfile=/opt/etcd/ssl/server.pem --etcd-keyfile=/opt/etcd/ssl/server-key.pem --audit-log-maxage=30 --audit-log-maxbackup=3 --audit-log-maxsize=100 --audit-log-path=/opt/kubernetes/logs/k8s-audit.log

官网推荐1.11版本以上使用的插件:

–enable-admission-plugins= \ NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds, ResourceQuota

列举几个插件的功能:

  • NamespaceLifecycle: 防止在不存在的namespace上创建对象,防止删除系统预置namespace,删除namespace时,连带删除它的所有资源对象。
  • LimitRanger:确保请求的资源不会超过资源所在Namespace的LimitRange的限制。
  • ServiceAccount: 实现了自动化添加ServiceAccount。
  • ResourceQuota:确保请求的资源不会超过资源的ResourceQuota限制。

 

 

参考:https://blog.csdn.net/qianghaohao/article/details/100012855

https://mritd.com/2018/03/20/use-rbac-to-control-kubectl-permissions/

https://jiayi.space/post/kubernetescong-ru-men-dao-fang-qi-4-an-quan-ji-zhi

 

posted @ 2021-07-06 18:14  酒红色  阅读(220)  评论(0编辑  收藏  举报