确认Kubernetes用户管理和RBAC情况

首先

当我们确认了RBAC的运行方式时,话题转向了用户管理。

如果您想了解更详细的信息,建议查看下面的樱花互联网的文章,比起这篇文章,它更详细地解释了。请阅读这篇文章会更好。

让我们理解Kubernetes用户管理和身份验证授权机制。

设置用户认证

在Kubernetes中,提供了几种标准的身份验证模块,但这次我们将使用”X509 Client Certs”。

生成私钥

秘密鍵「user01.key」を作成し、署名リクエストファイル「user01.csr」を作成します。

$ openssl genrsa -out user01.key 2048
Generating RSA private key, 2048 bit long modulus
.....................................+++
.......................................................................+++
e is 65537 (0x10001)
$ openssl req -new -key user01.key -out user01.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:user01
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:user01
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

创建签名文件

创建名为“user01.crt”的签名文件。

$ sudo openssl x509 -req -in user01.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out user01.crt -days 10000

Signature ok
subject=/C=XX/L=Default City/O=user01/CN=user01
Getting CA Private Key

$ ls
user01.crt  user01.csr  user01.key

添加到证书的API服务器

将已创建的证书添加到API服务器中。

$ kubectl config set-credentials user01 --client-certificate=user01.crt --client-key=user01.key --embed-certs=true
User "user01" set.

上下文的设定

确认集群名称和现有上下文

$ kubectl config get-clusters
NAME
kubernetes
$ kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin

创建语境

我会创建一个用于用户01的上下文。

$ kubectl config set-context user01-context --user=user01 --cluster=kubernetes
Context "user01-context" created.
$ kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin
          user01-context                kubernetes   user01

转换语境

$ kubectl config use-context user01-context
Switched to context "user01-context".
$ kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
          kubernetes-admin@kubernetes   kubernetes   kubernetes-admin
*         user01-context                kubernetes   user01

确认

由于当前时间点上未设置user01的权限,我们将使用kubectl命令来确认是否会出现错误。

$ kubectl get pod
Error from server (Forbidden): pods is forbidden: User "user01" cannot list resource "pods" in API group "" in the namespace "default"

確認できたら、元のContextに戻します。

$ kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".

RBAC的设置

为了对之前创建的user01进行权限设置,将使用RBAC。
RBAC有两种方式:角色(Role)/角色绑定(RoleBinding)和集群角色(ClusterRole)/集群角色绑定(ClusterRoleBinding)。角色/角色绑定是在命名空间级别进行设置,而集群角色/集群角色绑定是在集群级别进行设置,范围不同。

使用基于角色的访问控制进行授权

设置ClusterRole/ClusterRoleBinding

以下のマニフェストですべてのAPI Groupのすべてのリソースでget/list/watchができる設定にします。

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: readonly-for-all
rules:
- apiGroups: ["*"]
  resources: ["*"]
  verbs: ["get", "list", "watch"]
- nonResourceURLs: ["*"]
  verbs: ["get", "list", "watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: readonly-for-test
subjects:
- kind: User
  name: user01
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: readonly-for-all
  apiGroup: rbac.authorization.k8s.io
$ kubectl apply -f clusterRole.yaml
clusterrole.rbac.authorization.k8s.io/readonly-for-all created
clusterrolebinding.rbac.authorization.k8s.io/readonly-for-test created

确认设置内容。

$ kubectl describe clusterrole readonly-for-all
Name:         readonly-for-all
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"ClusterRole","metadata":{"annotations":{},"name":"readonly-for-all"},"rules":[{"apiGr...
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  *.*        []                 []              [get list watch]
             [*]                []              [get]
             [*]                []              [list]
             [*]                []              [watch]
$ kubectl describe clusterrolebinding readonly-for-test
Name:         readonly-for-test
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"name":"readonly-for-test"},"roleRef...
Role:
  Kind:  ClusterRole
  Name:  readonly-for-all
Subjects:
  Kind  Name    Namespace
  ----  ----    ---------
  User  user01

确认行动

切换上下文,验证RBAC的操作。

$ kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin
          user01-context                kubernetes   user01
$ kubectl config use-context user01-context
Switched to context "user01-context".
$ kubectl config current-context
user01-context
$ kubectl get pod
No resources found in default namespace.
$ kubectl apply -f nginx.yaml
Error from server (Forbidden): error when creating "nginx.yaml": pods is forbidden: User "user01" cannot create resource "pods" in API group "" in the namespace "example"

没有Pod存在,但在设置了RBAC之前,运行kubectl get pod命令会出现错误,现在却正常返回结果。
此外,由于没有创建Pod的权限,因此创建Pod失败了。

总结

用户认证流程如下。由于本次验证环境为On-premise环境,因此API服务器和客户端将在同一节点上。因此,用户切换仅为上下文切换,并未更改操作系统用户。我认为这个设置可能在从集群外部访问云上集群时发挥作用。

image.png

RBAC本身只需要关联资源,而且角色和群集角色也有一些默认提供的选项,所以我认为相对容易理解。

顺便说一下,樱互联网的文章给了我很大的学习帮助。非常感谢。

bannerAds