实战:RBAC(基于角色的权限控制)-2021.11.28

image-20211128095633164

目录

实验环境

实验环境:
1、win10,vmwrokstation虚机;
2、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
   k8s version:v1.22.2
   containerd://1.5.5

实验软件(无)

1、RBAC(基于角色的权限控制)

前面我们已经学习一些常用的资源对象的使用,我们知道对于资源对象的操作都是通过 APIServer 进行的,那么集群是怎样知道我们的请求就是合法的请求呢?这个就需要了解 Kubernetes 中另外一个非常重要的知识点了:RBAC(基于角色的权限控制)。

管理员可以通过 Kubernetes API 动态配置策略来启用RBAC,需要在 kube-apiserver 中添加参数--authorization-mode=RBAC,如果使用的 kubeadm 安装的集群那么是默认开启了 RBAC 的,可以通过查看 Master 节点上 apiserver 的静态 Pod 定义文件:

[root@master1 ~]#cat /etc/kubernetes/manifests/kube-apiserver.yaml |grep mode
    - --authorization-mode=Node,RBAC
[root@master1 ~]#

⚠️如果是二进制的方式搭建的集群,添加这个参数过后,记得要重启 kube-apiserver 服务。(如何重启?是删除pod吗??

2、API 对象

在学习 RBAC 之前,我们还需要再去理解下 Kubernetes 集群中的对象,我们知道,**在 Kubernetes 集群中,Kubernetes 对象是我们持久化的实体,就是最终存入 etcd 中的数据,集群中通过这些实体来表示整个集群的状态。**前面我们都直接编写的 YAML 文件,通过 kubectl 来提交的资源清单文件,然后创建的对应的资源对象,那么它究竟是如何将我们的 YAML 文件转换成集群中的一个 API 对象的呢?

这个就需要去了解下声明式 API的设计,Kubernetes API 是一个以 JSON 为主要序列化方式的 HTTP 服务(可以理解为一个web server)除此之外也支持 Protocol Buffers 序列化方式,主要用于集群内部组件间的通信为了可扩展性,Kubernetes 在不同的 API 路径(比如/api/v1 或者 /apis/batch)下面支持了多个 API 版本,不同的 API 版本意味着不同级别的稳定性和支持:

  • Alpha 级别,例如 v1alpha1 默认情况下是被禁用的,可以随时删除对功能的支持,所以要慎用
  • Beta 级别,例如 v2beta1 默认情况下是启用的,表示代码已经经过了很好的测试,但是对象的语义可能会在随后的版本中以不兼容的方式更改
  • 稳定级别,比如 v1 表示已经是稳定版本了,也会出现在后续的很多版本中。

在 Kubernetes 集群中,一个 API 对象在 Etcd 里的完整资源路径,是由:Group(API 组)Version(API 版本)Resource(API 资源类型)三个部分组成的。通过这样的结构,整个 Kubernetes 里的所有 API 对象,实际上就可以用如下的树形结构表示出来:

apiserver tree

从上图中我们也可以看出 Kubernetes 的 API 对象的组织方式,在顶层,我们可以看到有一个核心组(由于历史原因,是 /api/v1 下的所有内容而不是在 /apis/core/v1 下面)和命名组(路径 /apis/$NAME/$VERSION)和系统范围内的实体,比如 /metrics

⚠️我们也可以用下面的命令来查看集群中的 API 组织形式:

[root@master1 ~]#kubectl get --raw /
{
  "paths": [
    "/.well-known/openid-configuration",
    "/api",
    "/api/v1",
    "/apis",
    "/apis/",
    "/apis/admissionregistration.k8s.io",
    "/apis/admissionregistration.k8s.io/v1",
    "/apis/apiextensions.k8s.io",
    "/apis/apiextensions.k8s.io/v1",
    "/apis/apiregistration.k8s.io",
    "/apis/apiregistration.k8s.io/v1",
    "/apis/apps",
    "/apis/apps/v1",
    "/apis/authentication.k8s.io",
    "/apis/authentication.k8s.io/v1",
    "/apis/authorization.k8s.io",
    "/apis/authorization.k8s.io/v1",
    "/apis/autoscaling",
    "/apis/autoscaling/v1",
    "/apis/autoscaling/v2beta1",
    "/apis/autoscaling/v2beta2",
    "/apis/batch",
    "/apis/batch/v1",
    "/apis/batch/v1beta1",
    "/apis/certificates.k8s.io",
    "/apis/certificates.k8s.io/v1",
    "/apis/coordination.k8s.io",
    "/apis/coordination.k8s.io/v1",
    "/apis/discovery.k8s.io",
    "/apis/discovery.k8s.io/v1",
    "/apis/discovery.k8s.io/v1beta1",
    "/apis/events.k8s.io",
    "/apis/events.k8s.io/v1",
    "/apis/events.k8s.io/v1beta1",
    "/apis/flowcontrol.apiserver.k8s.io",
    "/apis/flowcontrol.apiserver.k8s.io/v1beta1",
    "/apis/metrics.k8s.io",
    "/apis/metrics.k8s.io/v1beta1",
    "/apis/networking.k8s.io",
    "/apis/networking.k8s.io/v1",
    "/apis/node.k8s.io",
    "/apis/node.k8s.io/v1",
    "/apis/node.k8s.io/v1beta1",
    "/apis/policy",
    "/apis/policy/v1",
    "/apis/policy/v1beta1",
    "/apis/rbac.authorization.k8s.io",
    "/apis/rbac.authorization.k8s.io/v1",
    "/apis/scheduling.k8s.io",
    "/apis/scheduling.k8s.io/v1",
    "/apis/storage.k8s.io",
    "/apis/storage.k8s.io/v1",
    "/apis/storage.k8s.io/v1beta1",
    "/healthz",
    "/healthz/autoregister-completion",
    "/healthz/etcd",
    "/healthz/log",
    "/healthz/ping",
    "/healthz/poststarthook/aggregator-reload-proxy-client-cert",
    "/healthz/poststarthook/apiservice-openapi-controller",
    "/healthz/poststarthook/apiservice-registration-controller",
    "/healthz/poststarthook/apiservice-status-available-controller",
    "/healthz/poststarthook/bootstrap-controller",
    "/healthz/poststarthook/crd-informer-synced",
    "/healthz/poststarthook/generic-apiserver-start-informers",
    "/healthz/poststarthook/kube-apiserver-autoregistration",
    "/healthz/poststarthook/priority-and-fairness-config-consumer",
    "/healthz/poststarthook/priority-and-fairness-config-producer",
    "/healthz/poststarthook/priority-and-fairness-filter",
    "/healthz/poststarthook/rbac/bootstrap-roles",
    "/healthz/poststarthook/scheduling/bootstrap-system-priority-classes",
    "/healthz/poststarthook/start-apiextensions-controllers",
    "/healthz/poststarthook/start-apiextensions-informers",
    "/healthz/poststarthook/start-cluster-authentication-info-controller",
    "/healthz/poststarthook/start-kube-aggregator-informers",
    "/healthz/poststarthook/start-kube-apiserver-admission-initializer",
    "/livez",
    "/livez/autoregister-completion",
    "/livez/etcd",
    "/livez/log",
    "/livez/ping",
    "/livez/poststarthook/aggregator-reload-proxy-client-cert",
    "/livez/poststarthook/apiservice-openapi-controller",
    "/livez/poststarthook/apiservice-registration-controller",
    "/livez/poststarthook/apiservice-status-available-controller",
    "/livez/poststarthook/bootstrap-controller",
    "/livez/poststarthook/crd-informer-synced",
    "/livez/poststarthook/generic-apiserver-start-informers",
    "/livez/poststarthook/kube-apiserver-autoregistration",
    "/livez/poststarthook/priority-and-fairness-config-consumer",
    "/livez/poststarthook/priority-and-fairness-config-producer",
    "/livez/poststarthook/priority-and-fairness-filter",
    "/livez/poststarthook/rbac/bootstrap-roles",
    "/livez/poststarthook/scheduling/bootstrap-system-priority-classes",
    "/livez/poststarthook/start-apiextensions-controllers",
    "/livez/poststarthook/start-apiextensions-informers",
    "/livez/poststarthook/start-cluster-authentication-info-controller",
    "/livez/poststarthook/start-kube-aggregator-informers",
    "/livez/poststarthook/start-kube-apiserver-admission-initializer",
    "/logs",
    "/metrics",
    "/openapi/v2",
    "/openid/v1/jwks",
    "/readyz",
    "/readyz/autoregister-completion",
    "/readyz/etcd",
    "/readyz/informer-sync",
    "/readyz/log",
    "/readyz/ping",
    "/readyz/poststarthook/aggregator-reload-proxy-client-cert",
    "/readyz/poststarthook/apiservice-openapi-controller",
    "/readyz/poststarthook/apiservice-registration-controller",
    "/readyz/poststarthook/apiservice-status-available-controller",
    "/readyz/poststarthook/bootstrap-controller",
    "/readyz/poststarthook/crd-informer-synced",
    "/readyz/poststarthook/generic-apiserver-start-informers",
    "/readyz/poststarthook/kube-apiserver-autoregistration",
    "/readyz/poststarthook/priority-and-fairness-config-consumer",
    "/readyz/poststarthook/priority-and-fairness-config-producer",
    "/readyz/poststarthook/priority-and-fairness-filter",
    "/readyz/poststarthook/rbac/bootstrap-roles",
    "/readyz/poststarthook/scheduling/bootstrap-system-priority-classes",
    "/readyz/poststarthook/start-apiextensions-controllers",
    "/readyz/poststarthook/start-apiextensions-informers",
    "/readyz/poststarthook/start-cluster-authentication-info-controller",
    "/readyz/poststarthook/start-kube-aggregator-informers",
    "/readyz/poststarthook/start-kube-apiserver-admission-initializer",
    "/readyz/shutdown",
    "/version"
  ]
}
[root@master1 ~]#

比如我们来查看批处理这个操作,在我们当前这个版本中存在两个版本的操作:/apis/batch/v1/apis/batch/v1beta1,分别暴露了可以查询和操作的不同实体集合.

🍀同样我们还是可以通过 kubectl 来查询对应对象下面的数据

[root@master1 ~]#kubectl get --raw /apis/batch/v1 | python -m json.tool
{
    "apiVersion": "v1",
    "groupVersion": "batch/v1",
    "kind": "APIResourceList",
    "resources": [
        {
            "categories": [
                "all"
            ],
            "kind": "CronJob",
            "name": "cronjobs",
            "namespaced": true,
            "shortNames": [
                "cj"
            ],
            "singularName": "",
            "storageVersionHash": "sd5LIXh4Fjs=",
            "verbs": [
                "create",
                "delete",
                "deletecollection",
                "get",
                "list",
                "patch",
                "update",
                "watch"
            ]
        },
        {
            "kind": "CronJob",
            "name": "cronjobs/status",
            "namespaced": true,
            "singularName": "",
            "verbs": [
                "get",
                "patch",
                "update"
            ]
        },
        {
            "categories": [
                "all"
            ],
            "kind": "Job",
            "name": "jobs",
            "namespaced": true,
            "singularName": "",
            "storageVersionHash": "mudhfqk/qZY=",
            "verbs": [
                "create",
                "delete",
                "deletecollection",
                "get",
                "list",
                "patch",
                "update",
                "watch"
            ]
        },
        {
            "kind": "Job",
            "name": "jobs/status",
            "namespaced": true,
            "singularName": "",
            "verbs": [
                "get",
                "patch",
                "update"
            ]
        }
    ]
}
[root@master1 ~]#

[root@master1 ~]#kubectl get --raw /apis/batch/v1beta1 | python -m json.tool
 [root@master1 ~]#kubectl get --raw /apis/batch/v1beta1 | python -m json.tool
{
    "apiVersion": "v1",
    "groupVersion": "batch/v1beta1",
    "kind": "APIResourceList",
    "resources": [
        {
            "categories": [
                "all"
            ],
            "kind": "CronJob",
            "name": "cronjobs",
            "namespaced": true,
            "shortNames": [
                "cj"
            ],
            "singularName": "",
            "storageVersionHash": "sd5LIXh4Fjs=",
            "verbs": [
                "create",
                "delete",
                "deletecollection",
                "get",
                "list",
                "patch",
                "update",
                "watch"
            ]
        },
        {
            "kind": "CronJob",
            "name": "cronjobs/status",
            "namespaced": true,
            "singularName": "",
            "verbs": [
                "get",
                "patch",
                "update"
            ]
        }
    ]
}
[root@master1 ~]#

🍀但是这个操作和我们平时操作 HTTP 服务的方式不太一样,这里我们可以通过 kubectl proxy 命令来开启对 apiserver 的访问:

[root@master1 ~]#kubectl proxy
Starting to serve on 127.0.0.1:8001

然后重新开启一个新的终端,我们可以通过如下方式来访问批处理的 API 服务:

[root@master1 ~]#curl http://127.0.0.1:8001/apis/batch/v1
{
  "kind": "APIResourceList",
  "apiVersion": "v1",
  "groupVersion": "batch/v1",
  "resources": [
    {
      "name": "cronjobs",
      "singularName": "",
      "namespaced": true,
      "kind": "CronJob",
      "verbs": [
        "create",
        "delete",
        "deletecollection",
        "get",
        "list",
        "patch",
        "update",
        "watch"
      ],
      "shortNames": [
        "cj"
      ],
      "categories": [
        "all"
      ],
      "storageVersionHash": "sd5LIXh4Fjs="
    },
    {
      "name": "cronjobs/status",
      "singularName": "",
      "namespaced": true,
      "kind": "CronJob",
      "verbs": [
        "get",
        "patch",
        "update"
      ]
    },
    {
      "name": "jobs",
      "singularName": "",
      "namespaced": true,
      "kind": "Job",
      "verbs": [
        "create",
        "delete",
        "deletecollection",
        "get",
        "list",
        "patch",
        "update",
        "watch"
      ],
      "categories": [
        "all"
      ],
      "storageVersionHash": "mudhfqk/qZY="
    },
    {
      "name": "jobs/status",
      "singularName": "",
      "namespaced": true,
      "kind": "Job",
      "verbs": [
        "get",
        "patch",
        "update"
      ]
    }
  ]
}[root@master1 ~]#

同样也可以去访问另外一个版本的对象数据:

[root@master1 ~]#curl http://127.0.0.1:8001/apis/batch/v1beta1
{
  "kind": "APIResourceList",
  "apiVersion": "v1",
  "groupVersion": "batch/v1beta1",
  "resources": [
    {
      "name": "cronjobs",
      "singularName": "",
      "namespaced": true,
      "kind": "CronJob",
      "verbs": [
        "create",
        "delete",
        "deletecollection",
        "get",
        "list",
        "patch",
        "update",
        "watch"
      ],
      "shortNames": [
        "cj"
      ],
      "categories": [
        "all"
      ],
      "storageVersionHash": "sd5LIXh4Fjs="
    },
    {
      "name": "cronjobs/status",
      "singularName": "",
      "namespaced": true,
      "kind": "CronJob",
      "verbs": [
        "get",
        "patch",
        "update"
      ]
    }
  ]
}[root@master1 ~]#

通常,Kubernetes API 支持通过标准 HTTP POSTPUTDELETEGET 在指定 PATH 路径上创建、更新、删除和检索操作,并使用 JSON 作为默认的数据交互格式。

比如现在我们要创建一个 Deployment 对象,那么我们的 YAML 文件的声明就需要怎么写:

apiVersion: apps/v1
kind: Deployment

其中 Deployment 就是这个 API 对象的资源类型(Resource),apps 就是它的组(Group),v1 就是它的版本(Version)。API Group、Version 和 资源就唯一定义了一个 HTTP 路径,然后在 kube-apiserver 端对这个 url 进行了监听,然后把对应的请求传递给了对应的控制器进行处理而已,当然在 Kuberentes 中的实现过程是非常复杂的。

3、RBAC

上面我们介绍了 Kubernetes 所有资源对象都是模型化的 API 对象,允许执行 CRUD(Create、Read、Update、Delete) 操作(也就是我们常说的增、删、改、查操作),比如下面的这些资源:

  • Pods
  • ConfigMaps
  • Deployments
  • Nodes
  • Secrets
  • Namespaces

对于上面这些资源对象的可能存在的操作有:

  • create
  • get
  • delete
  • list
  • update
  • edit
  • watch
  • exec #exec只是对pod有的,其他的没
  • patch

在更上层,这些资源和 API Group 进行关联,比如 Pods 属于 Core API Group,而 Deployements 属于 apps API Group,现在我们要在 Kubernetes 中通过 RBAC 来对资源进行权限管理,除了上面的这些资源和操作以外,我们还需要了解另外几个概念:

  • Rule:规则,规则是一组属于不同 API Group 资源上的一组操作的集合

  • RoleClusterRole:角色和集群角色,这两个对象都包含上面的 Rules 元素,二者的区别在于,**在 Role 中,定义的规则只适用于单个命名空间,也就是和 namespace 关联的,而 ClusterRole 是集群范围内的,因此定义的规则不受命名空间的约束。**另外 Role 和 ClusterRole 在Kubernetes 中都被定义为集群内部的 API 资源,和我们前面学习过的 Pod、Deployment 这些对象类似,都是我们集群的资源对象,所以同样的可以使用 YAML 文件来描述,用 kubectl 工具来管理。

  • Subject:主题,对应集群中尝试操作的对象,集群中定义了3种类型的主题资源:

    • User Account:用户,这是由外部独立服务进行管理的,管理员进行私钥的分配,用户可以使用 KeyStone 或者 Goolge 帐号,甚至一个用户名和密码的文件列表也可以。对于用户的管理集群内部没有一个关联的资源对象,所以用户不能通过集群内部的 API 来进行管理。

      [root@master1 ~]#kubectl get user
      error: the server doesn't have a resource type "user"
      
    • Group:组,这是用来关联多个账户的,集群中有一些默认创建的组,比如 cluster-admin

      [root@master1 ~]#kubectl get group
      error: the server doesn't have a resource type "group"
      
    • ⚠️Service Account:服务帐号,通过 Kubernetes API 来管理的一些用户帐号,和 namespace 进行关联的,适用于集群内部运行的应用程序,需要通过 API 来完成权限认证,所以在集群内部进行权限操作,我们都需要使用到 ServiceAccount,这也是我们这节课的重点。

  • RoleBindingClusterRoleBinding:角色绑定和集群角色绑定,简单来说就是把声明的 Subject 和我们的 Role 进行绑定的过程(给某个用户绑定上操作的权限),二者的区别也是作用范围的区别:RoleBinding 只会影响到当前 namespace 下面的资源操作权限,而 ClusterRoleBinding 会影响到所有的 namespace。

接下来我们来通过几个简单的示例,来学习下在 Kubernetes 集群中如何使用 RBAC

💘1.演示:只能访问某个 namespace 的普通用户

我们想要创建一个 User Account,只能访问 kube-system 这个命名空间,对应的用户信息如下所示:

username: cnych
group: youdianzhishi
(1)创建用户凭证

我们前面已经提到过,Kubernetes 没有 User Account 的 API 对象,不过要创建一个用户帐号的话也是挺简单的,利用管理员分配给你的一个私钥就可以创建了,这个我们可以参考官方文档中的方法,这里我们来使用 OpenSSL 证书来创建一个 User,当然我们也可以使用更简单的 cfssl工具来创建:

🍀给用户 cnych 创建一个私钥,命名成 cnych.key

[root@master1 ~]#mkdir rbac
[root@master1 ~]#cd rbac/
[root@master1 rbac]#openssl genrsa -out cnych.key 2048
Generating RSA private key, 2048 bit long modulus
..+++
..........................................................................+++
e is 65537 (0x10001)
[root@master1 rbac]#ls
cnych.key

🍀使用我们刚刚创建的私钥创建一个证书签名请求文件cnych.csr,要注意需要确保在-subj参数中指定用户名和组(CN表示用户名,O表示组):

[root@master1 rbac]#openssl req -new -key cnych.key -out cnych.csr -subj "/CN=cnych/O=youdianzhishi"
[root@master1 rbac]#ls
cnych.csr  cnych.key

🍀然后找到我们的 Kubernetes 集群的 CA 证书,我们使用的是 kubeadm 安装的集群,CA 相关证书位于 /etc/kubernetes/pki/ 目录下面,如果你是二进制方式搭建的,你应该在最开始搭建集群的时候就已经指定好了 CA 的目录,我们会利用该目录下面的 ca.crtca.key两个文件来批准上面的证书请求。生成最终的证书文件,我们这里设置证书的有效期为 500 天:

[root@master1 rbac]#openssl x509 -req -in cnych.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out cnych.crt -days 500
Signature ok
subject=/CN=cnych/O=youdianzhishi
Getting CA Private Key

#现在查看我们当前文件夹下面是否生成了一个证书文件:
[root@master1 rbac]#ls
cnych.crt  cnych.csr  cnych.key

🍀现在我们可以使用刚刚创建的证书文件和私钥文件在集群中创建新的凭证和上下文(Context),我们先来创建新的凭证:

[root@master1 rbac]#kubectl config --help #这里我们可以先看下config的帮助信息
……
Available Commands:
  current-context Display the current-context #care
  delete-cluster  Delete the specified cluster from the kubeconfig
  delete-context  Delete the specified context from the kubeconfig
  delete-user     Delete the specified user from the kubeconfig
  get-clusters    Display clusters defined in the kubeconfig  #care
  get-contexts    Describe one or many contexts
  get-users       Display users defined in the kubeconfig
  rename-context  Rename a context from the kubeconfig file
  set             Set an individual value in a kubeconfig file
  set-cluster     Set a cluster entry in kubeconfig
  set-context     Set a context entry in kubeconfig
  set-credentials Set a user entry in kubeconfig  #care
  unset           Unset an individual value in a kubeconfig file
  use-context     Set the current-context in a kubeconfig file
  view            Display merged kubeconfig settings or a specified kubeconfig file
……

我们先来创建新的凭证:

[root@master1 rbac]#kubectl config set-credentials cnych --client-certificate=cnych.crt --client-key=cnych.key
User "cnych" set.

我们可以看到一个用户 cnych 创建了,然后为这个用户设置新的 Context,我们这里指定特定的一个 namespace:

#因为我们当前只有一个k8s集群,我么可以用命令先看一下
[root@master1 rbac]#kubectl config get-clusters
NAME
kubernetes

#为这个用户设置新的 Context
[root@master1 rbac]#kubectl config set-context cnych-context --cluster=kubernetes --namespace=kube-system --user=cnych
Context "cnych-context" created.

🍀到这里,我们的用户 cnych 就已经创建成功了,现在我们使用当前的这个配置文件来操作 kubectl 命令的时候,应该会出现错误,因为我们还没有为该用户定义任何操作的权限呢:

[root@master1 rbac]#kubectl get pod --context=cnych-context
Error from server (Forbidden): pods is forbidden: User "cnych" cannot list resource "pods" in API group "" in the namespace "kube-system"

因此,需要按如下思路去操作:

image-20211128105731669

(2)创建角色

用户创建完成后,接下来就需要给该用户添加操作权限,我们来定义一个 YAML 文件,创建一个允许用户操作 Deployment、Pod、ReplicaSets 的角色,如下定义:

[root@master1 rbac]#vim cnych-role.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: cnych-role
  namespace: kube-system
rules:
- apiGroups: ["", "apps"]
  resources: ["deployments", "replicasets", "pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # 也可以使用['*']

其中 Pod 属于 core 这个 API Group,在 YAML 中用空字符就可以,而 Deployment 和 ReplicaSet 现在都属于 apps 这个 API Group(如果不知道则可以用 kubectl explain 命令查看),所以 rules 下面的 apiGroups 就综合了这几个资源的 API Group:["", “apps”],其中 verbs 就是我们上面提到的可以对这些资源对象执行的操作,我们这里需要所有的操作方法,所以我们也可以使用['*']来代替,然后直接创建这个 Role:

[root@master1 rbac]#kubectl apply -f cnych-role.yaml
role.rbac.authorization.k8s.io/cnych-role created

注意这里我们没有使用上面的 cnych-context 这个上下文,因为暂时还木有权限。

(3)创建角色权限绑定

Role 创建完成了,但是很明显现在我们这个 Role 和我们的用户 cnych 还没有任何关系,对吧?这里就需要创建一个 RoleBinding 对象,在 kube-system 这个命名空间下面将上面的 cnych-role 角色和用户 cnych 进行绑定:

[root@master1 rbac]#vim cnych-rolebinding.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: cnych-rolebinding
  namespace: kube-system
subjects:
- kind: User
  name: cnych
  apiGroup: "" #没有就填个空字符串!!!
roleRef:
  kind: Role
  name: cnych-role
  apiGroup: rbac.authorization.k8s.io  # 留空字符串也可以,则使用当前的apiGroup
  
#把cnych用户和cnych-role角色绑定在一起,而Role角色具有相应权限,就相当于cnych用户有了这个权限。

⚠️注意RoleBingdingsubjectsroleRef字段下的apiGroup的值:

[root@master1 rbac]#kubectl explain rolebinding.subjects
   apiGroup     <string>
     APIGroup holds the API group of the referenced subject. Defaults to "" for
     ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User
     and Group subjects.
……

[root@master1 rbac]#kubectl explain rolebinding.roleRef
   apiGroup     <string> -required->
     APIGroup is the group for the resource being referenced
……

上面的 YAML 文件中我们看到了 subjects 字段,这里就是我们上面提到的用来尝试操作集群的对象,这里对应上面的 User 帐号 cnych,使用kubectl 创建上面的资源对象:

[root@master1 rbac]#kubectl apply -f cnych-rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/cnych-rolebinding created
(4)测试

现在我们应该可以上面的 cnych-context 上下文来操作集群了:

[root@master1 rbac]#kubectl get pod --context=cnych-context
NAME                              READY   STATUS    RESTARTS      AGE
coredns-7568f67dbd-9dls5          1/1     Running   0             16d
coredns-7568f67dbd-kqhjq          1/1     Running   0             27d
etcd-master1                      1/1     Running   1             28d
kube-apiserver-master1            1/1     Running   2 (28d ago)   28d
kube-controller-manager-master1   1/1     Running   2             28d
kube-flannel-ds-5lm5t             1/1     Running   0             25d
kube-flannel-ds-rmtfk             1/1     Running   0             25d
kube-flannel-ds-xbp6g             1/1     Running   0             25d
kube-proxy-4sw76                  1/1     Running   0             28d
kube-proxy-mkghd                  1/1     Running   0             28d
kube-proxy-s2748                  1/1     Running   0             28d
kube-scheduler-master1            1/1     Running   2             28d
metrics-server-76b8bfbb47-8v2lr   1/1     Running   0             6d15h
[root@master1 rbac]#kubectl get pod,deploy,rs --context=cnych-context
NAME                                  READY   STATUS    RESTARTS      AGE
pod/coredns-7568f67dbd-9dls5          1/1     Running   0             16d
pod/coredns-7568f67dbd-kqhjq          1/1     Running   0             27d
pod/etcd-master1                      1/1     Running   1             28d
pod/kube-apiserver-master1            1/1     Running   2 (28d ago)   28d
pod/kube-controller-manager-master1   1/1     Running   2             28d
pod/kube-flannel-ds-5lm5t             1/1     Running   0             25d
pod/kube-flannel-ds-rmtfk             1/1     Running   0             25d
pod/kube-flannel-ds-xbp6g             1/1     Running   0             25d
pod/kube-proxy-4sw76                  1/1     Running   0             28d
pod/kube-proxy-mkghd                  1/1     Running   0             28d
pod/kube-proxy-s2748                  1/1     Running   0             28d
pod/kube-scheduler-master1            1/1     Running   2             28d
pod/metrics-server-76b8bfbb47-8v2lr   1/1     Running   0             6d15h

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/coredns          2/2     2            2           28d
deployment.apps/metrics-server   1/1     1            1           6d15h

NAME                                        DESIRED   CURRENT   READY   AGE
replicaset.apps/coredns-7568f67dbd          2         2         2       28d
replicaset.apps/metrics-server-76b8bfbb47   1         1         1       6d15h
replicaset.apps/metrics-server-859bf7c488   0         0         0       6d15h
[root@master1 rbac]#

我们可以看到我们使用 kubectl 的使用并没有指定 namespace,这是因为我们我们上面创建这个 Context 的时候就绑定在了 kube-system 这个命名空间下面,如果我们在后面加上一个-n default试看看呢?

[root@master1 rbac]#kubectl get po --context=cnych-context --namespace=deafult
Error from server (Forbidden): pods is forbidden: User "cnych" cannot list resource "pods" in API group "" in the namespace "deafult"
[root@master1 rbac]#kubectl get po --context=cnych-context -n default
Error from server (Forbidden): pods is forbidden: User "cnych" cannot list resource "pods" in API group "" in the namespace "default"
[root@master1 rbac]#

🍀如果去获取其他的资源对象呢:

[root@master1 rbac]#kubectl get svc --context=cnych-context
Error from server (Forbidden): services is forbidden: User "cnych" cannot list resource "services" in API group "" in the namespace "kube-system"
[root@master1 rbac]#

我们可以看到没有权限获取,因为我们并没有为当前操作用户指定其他对象资源的访问权限,是符合我们的预期的。

这样我们就创建了一个只有单个命名空间访问权限的普通 User 。

💘2.演示:只能访问某个 namespace 的 ServiceAccount

上面我们创建了一个只能访问某个命名空间下面的普通用户,我们前面也提到过 subjects 下面还有一种类型的主题资源:ServiceAccount,现在我们来创建一个集群内部的用户只能操作 kube-system 这个命名空间下面的 pods 和 deployments。

🍀首先来创建一个 ServiceAccount 对象:

[root@master1 rbac]#kubectl create sa cnych-sa -nkube-system
serviceaccount/cnych-sa created

当然我们也可以定义成 YAML 文件的形式来创建:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: cnych-sa
  namespace: kube-system

🍀然后新建一个 Role 对象:

[root@master1 rbac]#vim cnych-sa-role.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: cnych-sa-role
  namespace: kube-system
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

可以看到我们这里定义的角色没有创建、删除、更新 Pod 的权限,待会我们可以重点测试一下,创建该 Role 对象:

[root@master1 rbac]#kubectl apply -f cnych-sa-role.yaml
role.rbac.authorization.k8s.io/cnych-sa-role created

🍀然后创建一个 RoleBinding 对象,将上面的 cnych-sa 和角色cnych-sa-rolebinding进行绑定:

[root@master1 rbac]#vim cnych-sa-rolebinding.yaml

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: cnych-sa-rolebinding
  namespace: kube-system
subjects:
- kind: ServiceAccount
  name: cnych-sa
  namespace: kube-system #注意这里
roleRef:
  kind: Role
  name: cnych-sa-role
  apiGroup: rbac.authorization.k8s.io

添加这个资源对象:

[root@master1 rbac]#kubectl apply -f cnych-sa-rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/cnych-sa-rolebinding created

🍀

image-20211128152016479

然后我们怎么去验证这个 ServiceAccount 呢?我们前面的课程中是不是提到过一个 ServiceAccount 会生成一个 Secret 对象和它进行映射,这个 Secret 里面包含一个 token,我们可以利用这个 token 去登录 Dashboard,然后我们就可以在 Dashboard 中来验证我们的功能是否符合预期了:

[root@master1 rbac]#kubectl get secret -nkube-system|grep cnych-sa
cnych-sa-token-gbqm7                             kubernetes.io/service-account-token   3      10m
[root@master1 rbac]#kubectl get secret cnych-sa-token-gbqm7 -nkube-system -oyaml #可以先查看下这个secret

#因为这个secret里面的token是经过base64加密的,因此dashboard想要使用的话,需要先解密
[root@master1 rbac]#kubectl get secret cnych-sa-token-gbqm7 -o jsonpath={.data.token} -nkube-system |base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6Im9hOERROHhuWTRSeVFweG1kdnpXSTRNNXg3bDZ0ZkRDVWNzN0l5Z0haT1UifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjbnljaC1zYS10b2tlbi1nYnFtNyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJjbnljaC1zYSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjQ0NzRlMDkyLWEwNjAtNDZhMi04MDY5LTg4YjRhYWQyNTlkNyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTpjbnljaC1zYSJ9.D_iKDmhTAyvbOPW7FfT_r23r0QXW7vXnr8WTFp7sSHWiwzD6eiMpGyv_Xp-TRrvPdmNDwEhm-FcW8JuaPkesjNbkdaTDg0dW2EbYz3UiCSMd-YBxlbP2au6rqu2PA8EZ8i2EypDZYH6g7n_9IV7x2DVU7wyXdFsDNq1MUZytgtGBYui9xjyb5wE-dMHFZB5nwr-qCqWn1naCLsEVhOJFC4i1Ws_nHktYzY_TealCjnfqXcfwyqHKJ_XZN_-dshiE743eEHQIZvhUsoL5rl68qvWsx6g5YDgekZfJBCRCbFMVbmCTX0YV0Nonzhz876xl0UrT0JnCq5xyUz62fIWJKQ[root@master1 rbac]#
# 会生成一串很长的base64后的字符串

我们先来确认下自己的k8s的dashboard是否可以正常使用:

[root@master1 ~]#kubectl get po -A|grep dashboard
kubernetes-dashboard   dashboard-metrics-scraper-856586f554-kcs78   1/1     Running   0                 27d
kubernetes-dashboard   kubernetes-dashboard-67484c44f6-fngdw        1/1     Running   0                 16d
[root@master1 ~]#kubectl get svc -A|grep dashboard
kubernetes-dashboard   dashboard-metrics-scraper   ClusterIP   10.99.185.146    <none>        8000/TCP                 27d
kubernetes-dashboard   kubernetes-dashboard        NodePort    10.105.110.130   <none>        443:30498/TCP            27d

image-20211128163647331

可以看到我们的dashboard是没问题的。

使用这里的 token 去 Dashboard 页面进行登录:

image-20211128163906154

我们可以看到上面的提示信息说我们现在使用的这个 ServiceAccount 没有权限获取当前命名空间下面的资源对象,这是因为我们登录进来后默认跳转到 default 命名空间,我们切换到 kube-system 命名空间下面就可以了:

image-20211128164254282

我们可以看到可以访问 pod 列表了,但是也会有一些其他额外的提示:events is forbidden: User “system:serviceaccount:kube-system:cnych-sa” cannot list events in the namespace “kube-system”,这是因为当前登录用只被授权了访问 pod 和 deployment 的权限,同样的,访问下deployment看看可以了吗?

同样的,你可以根据自己的需求来对访问用户的权限进行限制,可以自己通过 Role 定义更加细粒度的权限,也可以使用系统内置的一些权限……

💘3.演示:可以全局访问的 ServiceAccount

刚刚我们创建的 cnych-sa 这个 ServiceAccount 和一个 Role 角色进行绑定的,如果我们现在创建一个新的 ServiceAccount,需要他操作的权限作用于所有的 namespace,这个时候我们就需要使用到 ClusterRoleClusterRoleBinding 这两种资源对象了。

🍀同样,首先新建一个 ServiceAcount 对象:

[root@master1 rbac]#vim cnych-sa2.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: cnych-sa2
  namespace: kube-system

创建:

[root@master1 rbac]#kubectl apply -f cnych-sa2.yaml
serviceaccount/cnych-sa2 created

🍀然后创建一个 ClusterRoleBinding 对象:

[root@master1 rbac]#vim cnych-clusterrolebinding.yaml

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: cnych-sa2-clusterrolebinding
subjects:
- kind: ServiceAccount
  name: cnych-sa2
  namespace: kube-system
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

从上面我们可以看到我们没有为这个资源对象声明 namespace,因为这是一个 ClusterRoleBinding 资源对象,是作用于整个集群的,我们也没有单独新建一个 ClusterRole 对象,而是使用的 cluster-admin 这个对象,这是 Kubernetes 集群内置的 ClusterRole 对象,我们可以使用 kubectl get clusterrolekubectl get clusterrolebinding 查看系统内置的一些集群角色和集群角色绑定,这里我们使用的 cluster-admin 这个集群角色是拥有最高权限的集群角色,所以一般需要谨慎使用该集群角色。

🍀创建上面集群角色绑定资源对象,创建完成后同样使用 ServiceAccount 对应的 token 去登录 Dashboard 验证下:

[root@master1 rbac]#kubectl apply  -f cnych-clusterrolebinding.yaml
clusterrolebinding.rbac.authorization.k8s.io/cnych-clusterrolebinding created
[root@master1 rbac]#kubectl get secret -nkube-system |grep cnych-sa2
cnych-sa2-token-ctfn7                            kubernetes.io/service-account-token   3      25m

[root@master1 rbac]#kubectl get secrets cnych-sa2-token-ctfn7 -o jsonpath={.data.token} -nkube-system |base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6Im9hOERROHhuWTRSeVFweG1kdnpXSTRNNXg3bDZ0ZkRDVWNzN0l5Z0haT1UifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjbnljaC1zYTItdG9rZW4tY3RmbjciLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiY255Y2gtc2EyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiMDNmNTgxNjUtYTg5ZS00ZjgxLWE2NzQtZDk1NTU1YzRhOTJhIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmNueWNoLXNhMiJ9.sq1Isdckl7CK5pFm_BIKBlWslbjTx6XfE6a96ocbcPHit7SD6Y0-eiCJY7ZN8ZFnNJYyB9e2Z9P6ezrsJrPoZZnxCr4DJ4-SBITwS74lK2CcpV2Vz-FWdENj9fDfzq0qoP9wsaBxYrXRawBzOr9WC-4LvM1Lkliu9f7a9OdxhX4rfFrcawBHRiZOsgrMJlprqqmkCLZiP1g7uaJe7cMtk1fbOQzXHujck606nQuBhz2e6uWX-BR8OWsle0OVeZsDmbMOG-MfxlVD9v3s6NxR5U6K2DSXcCvyVPPFC2NIvdBYYvFngYF7x3K-XXlxsMmjoDWalO4vMy-thr-9SQsO0g[root@master1 rbac]#
# 会生成一串很长的base64后的字符串

image-20211128171913123

实验结束。

4、注意事项

1.noResources概念

image-20211128124429822

image-20211128124352644

[root@master1 rbac]#kubectl get --raw /
[root@master1 rbac]#kubectl get --raw /
{
  "paths": [
    "/.well-known/openid-configuration",
    "/api",
    "/api/v1",
    "/apis",
    "/apis/",
    "/apis/admissionregistration.k8s.io",
    "/apis/admissionregistration.k8s.io/v1",
    "/apis/apiextensions.k8s.io",
    "/apis/apiextensions.k8s.io/v1",
    "/apis/apiregistration.k8s.io",
    "/apis/apiregistration.k8s.io/v1",
    "/apis/apps",
    "/apis/apps/v1",
    "/apis/authentication.k8s.io",
    "/apis/authentication.k8s.io/v1",
    "/apis/authorization.k8s.io",
    "/apis/authorization.k8s.io/v1",
    "/apis/autoscaling",
    "/apis/autoscaling/v1",
    "/apis/autoscaling/v2beta1",
    "/apis/autoscaling/v2beta2",
    "/apis/batch",
    "/apis/batch/v1",
    "/apis/batch/v1beta1",
    "/apis/certificates.k8s.io",
    "/apis/certificates.k8s.io/v1",
    "/apis/coordination.k8s.io",
    "/apis/coordination.k8s.io/v1",
    "/apis/discovery.k8s.io",
    "/apis/discovery.k8s.io/v1",
    "/apis/discovery.k8s.io/v1beta1",
    "/apis/events.k8s.io",
    "/apis/events.k8s.io/v1",
    "/apis/events.k8s.io/v1beta1",
    "/apis/flowcontrol.apiserver.k8s.io",
    "/apis/flowcontrol.apiserver.k8s.io/v1beta1",
    "/apis/metrics.k8s.io",
    "/apis/metrics.k8s.io/v1beta1",
    "/apis/networking.k8s.io",
    "/apis/networking.k8s.io/v1",
    "/apis/node.k8s.io",
    "/apis/node.k8s.io/v1",
    "/apis/node.k8s.io/v1beta1",
    "/apis/policy",
    "/apis/policy/v1",
    "/apis/policy/v1beta1",
    "/apis/rbac.authorization.k8s.io",
    "/apis/rbac.authorization.k8s.io/v1",
    "/apis/scheduling.k8s.io",
    "/apis/scheduling.k8s.io/v1",
    "/apis/storage.k8s.io",
    "/apis/storage.k8s.io/v1",
    "/apis/storage.k8s.io/v1beta1",
    "/healthz",
    "/healthz/autoregister-completion",
    "/healthz/etcd",
    "/healthz/log",
    "/healthz/ping",
    "/healthz/poststarthook/aggregator-reload-proxy-client-cert",
    "/healthz/poststarthook/apiservice-openapi-controller",
    "/healthz/poststarthook/apiservice-registration-controller",
    "/healthz/poststarthook/apiservice-status-available-controller",
    "/healthz/poststarthook/bootstrap-controller",
    "/healthz/poststarthook/crd-informer-synced",
    "/healthz/poststarthook/generic-apiserver-start-informers",
    "/healthz/poststarthook/kube-apiserver-autoregistration",
    "/healthz/poststarthook/priority-and-fairness-config-consumer",
    "/healthz/poststarthook/priority-and-fairness-config-producer",
    "/healthz/poststarthook/priority-and-fairness-filter",
    "/healthz/poststarthook/rbac/bootstrap-roles",
    "/healthz/poststarthook/scheduling/bootstrap-system-priority-classes",
    "/healthz/poststarthook/start-apiextensions-controllers",
    "/healthz/poststarthook/start-apiextensions-informers",
    "/healthz/poststarthook/start-cluster-authentication-info-controller",
    "/healthz/poststarthook/start-kube-aggregator-informers",
    "/healthz/poststarthook/start-kube-apiserver-admission-initializer",
    "/livez",
    "/livez/autoregister-completion",
    "/livez/etcd",
    "/livez/log",
    "/livez/ping",
    "/livez/poststarthook/aggregator-reload-proxy-client-cert",
    "/livez/poststarthook/apiservice-openapi-controller",
    "/livez/poststarthook/apiservice-registration-controller",
    "/livez/poststarthook/apiservice-status-available-controller",
    "/livez/poststarthook/bootstrap-controller",
    "/livez/poststarthook/crd-informer-synced",
    "/livez/poststarthook/generic-apiserver-start-informers",
    "/livez/poststarthook/kube-apiserver-autoregistration",
    "/livez/poststarthook/priority-and-fairness-config-consumer",
    "/livez/poststarthook/priority-and-fairness-config-producer",
    "/livez/poststarthook/priority-and-fairness-filter",
    "/livez/poststarthook/rbac/bootstrap-roles",
    "/livez/poststarthook/scheduling/bootstrap-system-priority-classes",
    "/livez/poststarthook/start-apiextensions-controllers",
    "/livez/poststarthook/start-apiextensions-informers",
    "/livez/poststarthook/start-cluster-authentication-info-controller",
    "/livez/poststarthook/start-kube-aggregator-informers",
    "/livez/poststarthook/start-kube-apiserver-admission-initializer",
    "/logs",
    "/metrics",
    "/openapi/v2",
    "/openid/v1/jwks",
    "/readyz",
    "/readyz/autoregister-completion",
    "/readyz/etcd",
    "/readyz/informer-sync",
    "/readyz/log",
    "/readyz/ping",
    "/readyz/poststarthook/aggregator-reload-proxy-client-cert",
    "/readyz/poststarthook/apiservice-openapi-controller",
    "/readyz/poststarthook/apiservice-registration-controller",
    "/readyz/poststarthook/apiservice-status-available-controller",
    "/readyz/poststarthook/bootstrap-controller",
    "/readyz/poststarthook/crd-informer-synced",
    "/readyz/poststarthook/generic-apiserver-start-informers",
    "/readyz/poststarthook/kube-apiserver-autoregistration",
    "/readyz/poststarthook/priority-and-fairness-config-consumer",
    "/readyz/poststarthook/priority-and-fairness-config-producer",
    "/readyz/poststarthook/priority-and-fairness-filter",
    "/readyz/poststarthook/rbac/bootstrap-roles",
    "/readyz/poststarthook/scheduling/bootstrap-system-priority-classes",
    "/readyz/poststarthook/start-apiextensions-controllers",
    "/readyz/poststarthook/start-apiextensions-informers",
    "/readyz/poststarthook/start-cluster-authentication-info-controller",
    "/readyz/poststarthook/start-kube-aggregator-informers",
    "/readyz/poststarthook/start-kube-apiserver-admission-initializer",
    "/readyz/shutdown",
    "/version"
  ]
}
[root@master1 rbac]#

2.这个cluster-adminclusterrole的权限是无敌的哈哈

这里我们使用的 cluster-admin 这个集群角色是拥有最高权限的集群角色,所以一般需要谨慎使用该集群角色。

[root@master1 ~]# kubectl  get clusterrole
NAME                                                                   CREATED AT
……
cluster-admin                                                          2021-10-31T00:00:22Z
……

image-20211128100422549

3.2种方式访问k8s集群

1.集群外访问:kubectl

2.集群内访问:sa

image-20211128100609530

image-20211128154706274

4.RBAC流程

image-20211128095845724

5.Role资源清单文件里rules字段可以按如下方式编写

1.可以把不同apiGroup放在一起
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: cnych-role
  namespace: kube-system
rules:
- apiGroups: ["", "apps"]
  resources: ["deployments", "replicasets", "pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # 也可以使用['*']
  
2.或者把不同apiGroup分开写
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: cnych-role
  namespace: kube-system
rules:
- apiGroups: [""] #核心组
  resources: ["pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # 也可以使用['*'] 
- apiGroup: ["apps"] #apps组
  resources: ["deployments", "replicasets", "pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # 也可以使用['*']   
  
3.参考cluster-admin 这个cluster-role
[root@master1 ~]#kubectl get clusterrole cluster-admin -nkube-system -oyaml
rules:
- apiGroups: #资源对象
  - '*'
  resources:
  - '*'
  verbs:
  - '*'
- nonResourceURLs: #非资源对象
  - '*'
  verbs:
  - '*'

6.Forbidden字段报错更大可能性要想到的可能是权限问题

我们可以先给业务一个小的权限,可根据报错来进一步看他们需要什么权限
[root@master1 rbac]#kubectl get svc --context=cnych-context
Error from server (Forbidden): services is forbidden: User "cnych" cannot list resource "services" in API group "" in the namespace "kube-system"
[root@master1 rbac]#

7.我们可以去分析系统自带的 clusterroleclusterrolebinding 这些资源对象的编写方法

我们在最开始接触到 RBAC 认证的时候,可能不太熟悉,特别是不知道应该怎么去编写 rules 规则,大家可以去分析系统自带的 clusterroleclusterrolebinding 这些资源对象的编写方法,怎么分析?还是利用 kubectl 的 get、describe、 -o yaml 这些操作,所以 kubectl 最基本的操作用户一定要掌握好。

8.如何确定某个资源对象属于哪个apiGroup呢?

方法1:kubectl explains命令

[root@master1 rbac]#kubectl explain pod
KIND:     Pod
VERSION:  v1

……

方法2:kubectl api-resource命令

[root@master1 rbac]#kubectl api-resources |head -1;kubectl api-resources |grep pods
NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND
pods                              po           v1                                     true         Pod
pods                                           metrics.k8s.io/v1beta1                 true         PodMetrics
podsecuritypolicies               psp          policy/v1beta1                         false        PodSecurityPolicy
[root@master1 rbac]#

image-20211128210439481

关于我

我的博客主旨:我希望每一个人拿着我的博客都可以做出实验现象,先把实验做出来,然后再结合理论知识更深层次去理解技术点,这样学习起来才有乐趣和动力。并且,我的博客内容步骤是很完整的,也分享源码和实验用到的软件,希望能和大家一起共同进步!

各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人免费帮您解决问题:

  1. 个人微信二维码:x2675263825 (舍得), qq:2675263825。

    image-20211002091450217

  2. 个人博客地址:www.onlyonexl.cn

    image-20211002092057988

  3. 个人微信公众号:云原生架构师实战

    image-20211002141739664

  4. 个人csdn

    https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

    image-20211002092344616

最后

​ 好了,关于RBAC实验就到这里了,感谢大家阅读,最后贴上我女神的photo,祝大家生活快乐,每天都过的有意义哦,我们下期见!

image-20211128185446179

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值