zoukankan      html  css  js  c++  java
  • kubernetes 集群安全机制

    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

  • 相关阅读:
    Console
    在IOS10系统中无法定位问题
    c# js 时间
    ConcurrentDictionary,ConcurrentStack,ConcurrentQueue
    转 控件拖动 未验证
    消息处理模拟点击
    C ProcessAsUser
    SessionChange
    installer
    mysql主从同步配置
  • 原文地址:https://www.cnblogs.com/xulan0922/p/14769989.html
Copyright © 2011-2022 走看看