VMware Cloud 应用现代化

vSphere with Kubernetes实战之:用户访问控制

VMware 在2020年4月2日发布了vSphere 7.0的正式版。这个版本的vSphere最显著的特性之一是它在hypervisor层内部创建了Kubernetes控制平面。该功能使vSphere大大扩展了它所能运行的工作负载范围,涵盖了更多当前流行的应用程序。我们将此功能之前称为“ Project Pacific”或WCP(工作负载控制平面),现在的正式名称是“vSphere with Kubernetes”。要了解有关vSphere 7的新功能的更多信息,请访问我们的网站:https://www.vmware.com/products/vsphere.html.

 

0.背景介绍

vSphere with Kubernetes中的用户角色

从上图可以发现,vSphere 7中的用户角色比其他旧版本更多。我们仍然有“数据中心管理员”(VI Admin),他们管理着整个数据中心的计算,网络和存储资源。在vShpere 7中,数据中心管理员可以启用和管理一种被称为“ Supervisor Kubernetes”的全新群集,该群集在vSphere的hypervisor层面武装了一个Kubernetes的控制中心。在“ Supervisor Kubernetes”群集中,数据中心管理员可以创建一个或多个命名空间(Namespace)。命名空间(Namespace)是“vSphere with Kubernetes”中的多租户解决方案。每个命名空间都有隔离的网络资源和访问控制范围。数据中心管理员还可以给命名空间分配的CPU,内存和存储的资源配额。

数据中心管理员可以将命名空间的各种权限委派给其他的用户(User)或组(Group)。那些获得“view”权限的用户称为“Namespace审计员”,他们可以监控和观察命名空间里的资源使用状况;那些获得“edit”权限的用户称为“Namespace管理员”,他们可以管理和控制命名空间里的资源,并且可以在命名空间内创建一个或多个Tanzu Kubernetes群集(之前称为Guest Cluster)。这些Namespace管理员还可以在命名空间中直接部署和运行应用程序(在虚拟机和Pod VM上),在这种情况下,它们也称为“Supervisor 集群开发者”。

默认情况下,“Namespace管理员”将成为新创建的Tanzu Kubernetes群集的Tanzu群集管理员”。通过使用kubernetes的RBAC,“Namespace管理员”可以将集群管理员角色或更加细粒度的权限分配给其他用户和组,这些用户称为Tanzu集群开发者”,他们负责在Tanzu Kubernetes集群上开发和部署应用程序。

本文将通过实战的方式,来一步步展示这些不同的角色是如何通过Kubernetes的客户端命令“kubectl”,来访问vSphere With Kubernetes不同层次的集群,以及每个角色有哪些不同的权限和限制。本文共包括4部分的内容:

  • “数据中心管理员”对Supervisor Kubernetes集群的访问
  • “Namespace管理员”对Supervisor Kubernetes集群的访问
  • “Tanzu集群管理员”对Tanzu Kubernetes集群的访问
  • “Tanzu集群开发者”对Tanzu Kubernetes集群的访问

 

1. “数据中心管理员”对Supervisor Kubernetes集群的访问

数据中心管理员一般通过vSphere单点登录(SSO)服务认证的用户,缺省的用户名一般是[email protected]。这个用户通常是通过登录vCenter Server的浏览器客户端来进行数据中心的管理。在这一节中我们看看,这个数据中心管理员是如何通过新的Kubernetes客户端命令“kubectl”来管理vSpherew with Kubernetes。下面的实战练习需要几个前提条件:

 

1.1 登录Supervisor Kubernetes集群

  1. 要想通过kubectl命令连接Supervisor集群,首先需要使用“数据中心管理员”的SSO的账号登录,可以使用以下的命令。其中“SUPERVISOR-CLUSTER-CONTROL-PLANE-IP-ADDRESS”是Supervisor集群控制节点的IP地址,通过vCenter Server管理控制台浏览器客户端可以查看。“VCENTER-SSO-USER”是管理员用户名,一般为[email protected]
    kubectl vsphere login –server=SUPERVISOR-CLUSTER-CONTROL-PLANE-IP-ADDRESS–vsphere-username VCENTER-SSO-USER
    例如:

    $ kubectl vsphere login --server=10.117.233.1 --vsphere-username [email protected]

    要注意的是:成功登录后vSphere的kubectl插件会保存一个登录凭证(token),这个凭证可以保证你在10小时内不需要重新登录系统就能直接访问集群。超过10小时则需要重新执行这条登录命令。

  2. 显示当前可以访问的集群配置信息

    $ kubectl config get-contexts
     
    CURRENT   NAME            CLUSTER        AUTHINFO                                       NAMESPACE
    *         10.117.233.1    10.117.233.1   wcp:10.117.233.1:[email protected]
             microservices   10.117.233.1   wcp:10.117.233.1:[email protected]   microservices
              wangyu          10.117.233.1   wcp:10.117.233.1:[email protected]   wangyu
    从上面的输出中,您可以看到我们已经在Supervisor集群中创建了两个命名空间,分别为“microservices”和“ wangyu”。 数据中心管理员可以访问Supervisor集群中所有的命名空间。第一行记录显示绑定的命名空间为空,其实是绑定到一个叫做“default”的命名空间上。您可以使用以下命令来更改当前上下文(context)

    $ kubectl config use-context wangyu
    Switched to context "wangyu"

    更改上下文对于数据中心管理员是可选的,在当前的命名空间里您可以使用“ -n”选项,来操作其他命名空间的资源。例如:


    $ kubectl get pods -n microcervices

 

1.2 数据中心管理员通过kubectl能够做的事情

  1. 数据中心管理员可以查看和操作一些特殊的kubernetes资源(例如namespaces和storageclass)。稍后您会发现,这些资源的访问权限是别的用户(例如Namespace管理员)所没有的。

    $ kubectl get namespaces
    NAME                               STATUS   AGE
    default                            Active   4d20h
    kube-node-lease                    Active   4d20h
    kube-public                        Active   4d20h
    kube-system                        Active   4d20h
    microservices                      Active   2d2h
    vmware-system-capw                 Active   4d20h
    vmware-system-csi                  Active   4d20h
    vmware-system-kubeimage            Active   4d20h
    vmware-system-nsx                  Active   4d20h
    vmware-system-registry             Active   4d20h
    vmware-system-registry-754088061   Active   4d17h
    vmware-system-tkg                  Active   4d20h
    vmware-system-ucs                  Active   4d20h
    vmware-system-vmop                 Active   4d20h
    wangyu                             Active   4d20h
    $ kubectl get storageclass
    NAME                     PROVISIONER              AGE
    pacific-storage-policy   csi.vsphere.vmware.com   4d20h
  2. 您甚至可以列出部署在系统命名空间中的Pod资源,例如,以“kube-”开头和“vmware-”开头的命名空间就是属于系统的命名空间。

    $ kubectl get pods -n kube-system
    NAME                                                       READY   STATUS    RESTARTS   AGE
    coredns-7fb7656c66-65nc6                                   1/1     Running   0          5d
    coredns-7fb7656c66-9zp8z                                   1/1     Running   0          5d
    coredns-7fb7656c66-fgfml                                   1/1     Running   0          5d
    csr-signer-42164f156d72f36753e2cdfb7de0c558                1/1     Running   0          5d
    csr-signer-4216c813a129bb53c21f21e63990fd6b                1/1     Running   0          5d
    csr-signer-4216d818db629c2b035276f82acfdba3                1/1     Running   0          5d
    docker-registry-42164f156d72f36753e2cdfb7de0c558           1/1     Running   0          5d
    docker-registry-4216c813a129bb53c21f21e63990fd6b           1/1     Running   0          5d
    docker-registry-4216d818db629c2b035276f82acfdba3           1/1     Running   0          5d
    ......

 

1.3数据中心管理员通过kubectl不能够做的事情

实际上,数据中心管理员也不是万能的,有不少资源的操作和访问是通过kubectl命令无法完成的。

  1. 在上一小节中,您可能发现数据中心管理员可以列出系统命名空间中的资源。但是他不能将应用程序部署到这些系统命名空间中。例如:

    $ kubectl create -f hello.yaml -n kube-system
    Error from server (Forbidden): error when creating "hello.yaml": deployments.apps is forbidden:
    User "sso:[email protected]" cannot create resource "deployments" in API group "apps"
    in the namespace "kube-system"

    实际上,只有那些在vCenter Server客户端里显示的命名空间(Menu → Workload Management),才能部署客户自己开发的应用。如下图所示:

  2. 数据中心管理员无法使用kubectl命令来创建新的命名空间

    $ kubectl create namespace test01
    Error from server (Forbidden): namespaces is forbidden: User "sso:[email protected]" cannot create resource "namespaces" in API group "" at the cluster scope

    在此vSphere版本里,Supervisor集群中创建命名空间唯一有效的方法是通过vCenter Client Console。在今后的版本里可能会添加新的方法。

  3. 另外还有一些其他的Kubernetes的资源是数据中心管理员通过kubectl命令也无法访问的,例如(role,rolebinding,psp,crd等等):

    $ kubectl get roles
    Error from server (Forbidden): roles.rbac.authorization.k8s.io is forbidden:
    User "sso:[email protected]" cannot list resource "roles" in API
    group "rbac.authorization.k8s.io" in the namespace "default"

    $ kubectl get rolebindings
    Error from server (Forbidden): rolebindings.rbac.authorization.k8s.io is forbidden:
    User "sso:[email protected]" cannot list resource "rolebindings" in API
    group "rbac.authorization.k8s.io" in the namespace "default"

    $ kubectl get customresourcedefinitions
    Error from server (Forbidden): customresourcedefinitions.apiextensions.k8s.io
    is forbidden: User "sso:[email protected]" cannot list resource
    "customresourcedefinitions" in API group "apiextensions.k8s.io" at the cluster scope

    $ kubectl get certificatesigningrequests
    Error from server (Forbidden): certificatesigningrequests.certificates.k8s.io
    is forbidden: User "sso:[email protected]" cannot list resource
    "certificatesigningrequests" in API group "certificates.k8s.io" at the cluster scope

    $ kubectl get psp
    Error from server (Forbidden): podsecuritypolicies.policy is forbidden:
    User "sso:[email protected]" cannot list resource "podsecuritypolicies"
    in API group "policy" at the cluster scope

 

1.4小结

在本节中,您已经知道如何以数据中心管理员(VI Admin)的身份通过“ kubectl”命令连接Supervisor集群,并进行相应的操作。实际上,数据中心管理员很少使用“ kubectl”命令,vCenter Server Client Console才是数据中心管理员的常用武器。通常,数据中心管理员会将命名空间的管理员权限委派给其他用户,让我们在下一节中看到应该怎么做。

 

2. “Namespace管理员”对Supervisor Kubernetes集群的访问

在Supervisor集群上创建命名空间后,正确使用这些命名空间的方式是将命名空间的管理员角色委派给其他现有vSphere SSO用户(例如本地帐户),而不是使用数据中心管理员“ [email protected]”的身份。vSphere SSO可以通过Identity Federation技术,来接入第三方的identity provider管理用户和用户组(请参考技术博客:https://blogs.vmware.com/vsphere/2020/03/vsphere-7-identity-federation.html)。当然,最简单的方式就是通过vCenter Server 客户端控制台创建一个新的本地用户,并为其分配命名空间的管理员角色。下面我们看看,这个Namespace管理员是如何被分配的,他是如何通过Kubernetes客户端命令“kubectl”来管理vSpherew with Kubernetes。下面的实战练习需要几个前提条件:

 

2.1 Namespace的管理员权限代理给其他vSphere用户

  1. 在vCenter Server的客户端以数据中心管理员的身份登录。
    在vCenter Server的客户端创建一个本地用户(Administration → Single Sign On→ Users and Groups → Add User),如下图所示:
  2. 将supervisor集群命名空间的“edit”角色赋予刚才创建的用户 (Menu → Workload Management → Namespaces → Your Namespace → Permissions → Add),如下图所示:

 

2.2 登录Supervisor Kubernetes集群

  1. 用刚才创建的用户来登录到Supervisor集群上:

    $ kubectl vsphere login --server=10.117.233.1 --vsphere-username [email protected]

    要注意的是:成功登录后,vSphere的kubectl插件会保存一个登录凭证(token),这个凭证可以保证你在10小时内不需要重新登录系统就能直接访问集群。超过10小时则需要重新执行这条登录命令。

  2. 成功登录后,vSphere的kubectl插件会根据登录返回的信息自动更新kubeconfig配置文件。如果当前这个用户被赋予多个命名空间的权限, 所有这些命名空间都会被列到上下文里(contexts):

    $ kubectl config get-contexts
    CURRENT   NAME      CLUSTER      AUTHINFO                                NAMESPACE
    *         wangyu    10.117.233.1 wcp:10.117.233.1:[email protected]   wangyu

 

2.3 Namespace管理员通过kubectl能够做的事情

  1. Namespace管理员可以在当前的命名空间里查看和操作一些kubernetes资源:

    $ kubectl get serviceaccount
    NAME                     SECRETS   AGE
    default                  1         6d1h
    my-tanzu-cluster-ccm     1         5d6h
    my-tanzu-cluster-pvcsi   1         5d6h
    $ kubectl get secret
    NAME                          TYPE                                  DATA   AGE
    default-token-lqfwr           kubernetes.io/service-account-token   3      6d1h
    wangyu-default-image-pull-secret     kubernetes.io/dockerconfigjson        1      5d22h
    wangyu-default-image-push-secret     kubernetes.io/dockerconfigjson        1      5d22h
  2. Namespace管理员还可以在当前的命名空间部署和运行自己开发的应用。在这种情况下, Namespace管理员摇身一变,称为“Supervisor 集群开发者”。


    $ kubectl create -f hello.yaml
    deployment.apps/helloweb created
    $ kubectl get pods
    NAME                        READY   STATUS         RESTARTS   AGE
    helloweb-7cd97b9cb8-cdw22   0/1     Running        0          74s
    helloweb-7cd97b9cb8-vzcc5   0/1     Running        0          4s

     

  3. Namespace管理员还可以在当前的命名空间部署一个Tanzu Kubernetes集群。在这种情况下, Namespace管理员缺省的称为 “Tanzu集群管理员“。创建Tanzu集群的具体步骤,请参见官方文档(https://docs.vmware.com/en/VMware-vSphere/7.0/vmware-vsphere-with-kubernetes/GUID-DBF5D8F2-2A28-4730-8AA3-32E9CE1C3BB8.html)

    $ kubectl create -f tanzucluster.yaml
    .....
    $ kubectl get tanzukubernetescluster
    NAME             CONTROLPLANE  WORKER  DISTRIBUTION          AGE    PHASE
    my-tanzu-cluster 1             3       v1.16.8+vmware.1    5d6h   running

 

2.4 Namespace管理员通过kubectl不能够做的事情

  1. 数据中心管理员没有权限做的事情,Namespace管理员都没有权限做。请参考上一节的内容。
  2. Namespace管理员不能在他没有赋权的命名空间里访问和操作相关Kubernetes资源
  3. 有些Kubernetes资源属于全局资源,只有数据中心管理员才有权限操作,其他任何Namespace管理员都没有权限,例如namespace,node和storageclass等等.

    $ kubectl get nodes
    Error from server (Forbidden): nodes is forbidden: User "sso:[email protected]"
    cannot list resource "nodes" in API group "" at the cluster scope

    $ kubectl get namespaces
    Error from server (Forbidden): namespaces is forbidden: User "sso:[email protected]"
    cannot list resource "namespaces" in API group "" at the cluster scope

    $ kubectl get storageclass
    Error from server (Forbidden): storageclasses.storage.k8s.io is forbidden: User
    "sso:[email protected]" cannot list resource "storageclasses" in API group
    "storage.k8s.io" at the cluster scope

 

2.5 小结

在本节中,您已经知道如何以Namespace管理员的身份通过“ kubectl”命令连接Supervisor集群,并对赋权的命名空间进行相应的操作。实际上,更多的Kubernetes应用通常都部署在Tanzu Kubernetes集群上。让我们在下几节中看看如何以不同的身份访问Tanzu Kubernetes集群的。

 

3. “Tanzu集群管理员”对Tanzu Kubernetes集群的访问

Namespace管理员在特定的命名空间里创建了Tanzu Kubernetes集群以后,此Namespace管理员会缺省的成为这个Tanzu Kubernetes集群的管理员。 在这一节中,我们看看如何以两种不同的方式以管理员的权限来访问Tanzu Kubernetes集群。下面的实战练习需要几个前提条件:

 

3.1   Namespace管理员通过SSO账号登录Tanzu Kubernetes集群

  1. 在Namespace管理员在特定的命名空间里创建了Tanzu Kubernetes集群以后,此Namespace管理员会缺省的成为这个Tanzu Kubernetes集群的管理员。可以使用以下的命令通过Namespace管理员的SSO账号来登录Tanzu Kubernetes集群。

    kubectl vsphere login  \

    –server=SUPERVISOR-CLUSTER-CONTROL-PLANE-IP  \

    –tanzu-kubernetes-cluster-name TANZU-KUBERNETES-CLUSTER-NAME \

    –tanzu-kubernetes-cluster-namespace SUPERVISOR-NAMESPAC-NAME  \

    –vsphere-username NAMESPACE-ADMIN-SSO-USER-NAME \

        –insecure-skip-tls-verify

    例如:


    $
    kubectl vsphere login --server=10.117.233.1 --tanzu-kubernetes-cluster-name \
    my-tanzu-cluster --tanzu-kubernetes-cluster-namespace wangyu --vsphere-username \
    [email protected] --insecure-skip-tls-verify

    $ kubectl get nodes
    NAME                                        STATUS   ROLES    AGE    VERSION
    my-tanzu-cluster-control-plane-kffsj        Ready    master   6d4h   v1.16.8+vmware.1
    my-tanzu-cluster-workers-c5jwz-86b575c4bb   Ready    <none>   6d4h   v1.16.8+vmware.1
    my-tanzu-cluster-workers-c5jwz-86b575c4bb   Ready    <none>   6d4h   v1.16.8+vmware.1
    my-tanzu-cluster-workers-c5jwz-86b575c4bb   Ready    <none>   6d4h   v1.16.8+vmware.1
  2. 显示当前可以访问的集群配置信息

    $ kubectl config get-contexts
    CURRENT  NAME              CLUSTER        AUTHINFO                              NAMESPACE
            wangyu            10.117.233.1   wcp:10.117.233.1:[email protected] wangyu
    *        my-tanzu-cluster  10.117.233.3   wcp:10.117.233.3:[email protected]

    要注意的是:成功登录后vSphere的kubectl插件会保存一个登录凭证(token),这个凭证可以保证你在10小时内不需要重新登录系统就能直接访问集群。超过10小时则需要重新执行这条登录命令。

 

3.2  Namespace管理员通过kubeconfig文件登录Tanzu Kubernetes集群

这是用Tanzu集群管理员的身份来登录Tanzu Kubernetes集群的另外一种方式,这种方式不受10个小时的限制,每次访问Tanzu Kubernetes集群的时候不需要有登录的过程。虽然很方便,但是不太安全,一旦用户拿到这个管理员授权身份,就会一直有效。

  1. 用Namespace管理员的身份登录到Supervisor集群上:

    $ kubectl vsphere login --server=10.117.233.1 --vsphere-username [email protected]
  2. 用Namespace管理员的身份通过以下命令从Supervisor集群当中获取Tanzu集群管理员的秘钥信息,并将它保存到一个文件中:

    kubectl get secret CLUSTER-NAME-kubeconfig -o jsonpath='{.data.value}’ | base64 -d > KUBECONFIG-NAME
    例如:


    $ kubectl get secret my-tanzu-cluster-kubeconfig -o jsonpath='{.data.value}' | base64 -d \  
    > my-tanzu-cluster-kubeconfig.yaml
  3. 设置系统环境变量KUBECONFIG,指向上一步保存的文件,来直接访问Tanzu Kubernetes集群:

    $
    export KUBECONFIG =./my-tanzu-cluster-kubeconfig.yaml
    $ kubectl config get-contexts
    CURRENT   NAME                              CLUSTER            AUTHINFO         NAMESPACE
    *         kubernetes-admin@my-tanzu-cluster my-tanzu-cluster   kubernetes-admin
    $ kubectl get nodes
    NAME                                        STATUS   ROLES    AGE    VERSION
    my-tanzu-cluster-control-plane-kffsj        Ready    master   6d4h   v1.16.8+vmware.1
    my-tanzu-cluster-workers-c5jwz-86b575c4bbt  Ready    <none>   6d4h   v1.16.8+vmware.1
    my-tanzu-cluster-workers-c5jwz-86b575c4bb   Ready    <none>   6d4h   v1.16.8+vmware.1
    my-tanzu-cluster-workers-c5jwz-86b575c4bb   Ready    <none>   6d4h   v1.16.8+vmware.1

 

3.3 小结

在本节中,您已经知道如何以两种不同的方式来访问Tanzu Kubernetes集群。这两种方式的用户都属于Tanzu集群管理员。在日常开发工作中,开发人员访问Kubernetes集群的时候并不需要管理员的权限。在下节中,我么看看如何给Tanzu Kubernetes集群的开发人员赋予更加细粒度的访问权限。

 

4.“Tanzu集群开发者”对Tanzu Kubernetes集群的访问

创建Tanzu Kubernetes集群后,作为集群管理员,您将在集群上进行大量管理工作。例如:创建不同的命名空间(注意这是Tanzu集群的命名空间,要和Supervisor集群的命名空间区分开来),为其分配资源配额,并为不同的开发人员分配不同的权限。有两种方法可以使开发人员访问Tanzu Kubernetes集群,一种方法是向vSphere SSO用户分配权限,另一种方法是使用Kubernetes中的Service Account Token。下面的实战练习需要几个前提条件:

 

4.1    Tanzu集群开发者”通过SSO账号访问Tanzu Kubernetes集群

  1. 用Tanzu集群管理员的身份登录到Tanzu Kubernetes集群上。具体步骤请参考上一节。
  2. 在以下示例中,我们将创建两个命名空间(分别名为dev和test),一个角色(Role)(名为devrole),一些权限设置(在pods和deployments上的操作)和一个角色绑定(RoleBinding)。在RoleBinding中,我们将devrole与vSphere SSO用户“ dev”连接,这意味着我们将命名空间中的“ dev”权限授予了SSO用户“ [email protected]”。请注意,vSphere系统中必须已经存在这个名为“dev”的SSO用户。如何在vSphere中创建本地的SSO用户,请参见第二节

    $ kubectl create ns dev
    $ kubectl create ns test
    $ more devRolebindings.yaml
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
     name: devrole
     namespace: dev
    rules:
     - apiGroups: [""]
       resources: ["pods"]
       verbs: ["get", "create","list","update", "delete","watch"]
     - apiGroups: ["apps"]
       resources: ["deployments"]
       verbs: ["get", "create","list","update", "delete","watch"]
    ---
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
     name: rolebinding-dev
     namespace: dev
    roleRef:
     kind: Role
     name: devrole
     apiGroup: ""
    subjects:
    - kind: User
     name: sso:[email protected]
     apiGroup: rbac.authorization.k8s.io
    $ kubectl apply -f devRolebindings.yaml
    role.rbac.authorization.k8s.io/devrole created
    rolebinding.rbac.authorization.k8s.io/rolebinding-dev created
  3. 使用名为“dev”的vSphere SSO用户来登录Tanzu Kubernetes集群

    $ kubectl vsphere login --server=10.117.233.1 --tanzu-kubernetes-cluster-name \ my-tanzu-cluster --tanzu-kubernetes-cluster-namespace wangyu --vsphere-username \ [email protected] --insecure-skip-tls-verify

    要注意的是:成功登录后vSphere的kubectl插件会保存一个登录凭证(token),这个凭证可以保证你在10小时内不需要重新登录系统就能直接访问集群。超过10小时则需要重新执行这条登录命令。

  4. 验证一下当前的dev用户能够在dev的命名空间里部署Deployments和Pods资源:

    $ kubectl create deployment nginx --image=nginx -n dev
    deployment.apps/nginx created
    $ kubectl get deployments -n dev
    NAME    READY   UP-TO-DATE   AVAILABLE   AGE
    nginx   0/1     1            0           19s
    $ kubectl get pods -n dev
    NAME                     READY       STATUS       RESTARTS     AGE
    nginx-86c57db685-bczhq   1/1         Running      0            2m35s
  5. 验证一下当前的dev用户不能够在dev的命名空间里操作services资源

    $ kubectl get services -n dev
    Error from server (Forbidden): services is forbidden: User "sso:[email protected]" cannot list resource "services" in API group "" in the namespace "dev"
  6. 验证一下当前的dev用户不能够在其他命名空间里(例如test)操作deployments资源

    $  kubectl create deployment nginx --image=nginx -n test
    Error from server (Forbidden):  
    deployments.apps is forbidden: User "sso:[email protected]" cannot create resource "deployments" in API group "" in the namespace "test"

 

4.2   Tanzu集群开发者”通过Service Account Token访问Tanzu Kubernetes集群

  1. 用Tanzu集群管理员的身份登录到Tanzu Kubernetes集群上。具体步骤请参考上一节。
  2. 在以下示例中,我们将在名为“test”的命名空间中创建一个名为“ testaccount”的Service Account。然后我们创建一个名为“ testrole”的角色(Role),一些权限规则(rules)来对Pods和Deployments资源的进行操作。接着我们创建一个角色绑定(RoleBinding),将“ testvrole”与“ testaccount”连接起来,这意味着我们将命名空间“ test”的权限授予了名为“ testaccount”这个Service Account。

    $ more saToTest.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
    name: testaccount
    namespace: test
    ---
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
    name: testrole
    namespace: test
    rules:
    - apiGroups: [""]
       resources: ["pods"]
       verbs: ["get", "create","list","update", "delete","watch"]
    - apiGroups: ["apps"]
       resources: ["deployments"]
       verbs: ["get", "create","list","update", "delete","watch"]
    ---
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
    name: rolebinding-test
    namespace: test
    roleRef:
    kind: Role
    name: testrole
    apiGroup: ""
    subjects:
    - kind: ServiceAccount
    name: testaccount
    namespace: test
    $ kubectl apply -f satoTest.yaml -n test
    serviceaccount/testaccount created
    role.rbac.authorization.k8s.io/testrole created
    rolebinding.rbac.authorization.k8s.io/rolebinding-test created
  3. 获得这个Service Account Token的字符串

    $ TOKENNAME=`kubectl -n test get serviceaccount/testaccount -o jsonpath='{.secrets[0].name}’`
    $ TOKENVALUE=`kubectl -n test get secret $TOKENNAME -o jsonpath='{.data.token}'| base64 --decode`

    $ echo $TOKENVALUE
    eyJhbGciOiJSUzI1NiIsImtpZCI6Im1tNEZLTGtSYnIxMXNxW……….
  4. 获得Tanzu Kubernetes集群API Server的IP地址和证书信息:

    $  SERVERNAME=`kubectl config view --flatten --minify -o jsonpath='{.clusters[0].cluster.server}'`
    $ CERTIFICATE=`kubectl config view --flatten --minify -o jsonpath='{.clusters[0].cluster.certificate-authority-data}'`
    $ echo $SERVERNAME
    https://10.117.233.3:6443
    $ echo $CERTIFICATE
    LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JS…….
  5. 创建一个文件sa-kubeconfig.yaml,包含下面的内容,并且将文件中的占位符用上面·获得的字符串$TOKENVALUE, $SERVERNAME和$CERTIFICATE替换:
    apiVersion: v1
    kind: Config
    users:
    - name: testaccount
      user:
        token: <replace this with $TOKENVALUE>
    clusters:
    - cluster:
        certificate-authority-data: <replace this with $CERTIFICATE>
        server: <replace this with $SERVERNAME>
      name: my-tanzu-cluster
    contexts:
    - context:
        cluster: my-tanzu-cluster
        user: testaccount
      name: test-my-tanzu
    current-context: test-my-tanzu
  6. 将这个文件发给用户,让他设置系统环境变量,来直接访问Tanzu Kubernetes集群:
    $ export KUBECONFIG =./sa-kubeconfig.yaml
  7. 验证一下当前的service account用户能够在test的命名空间里部署Deployments和Pods资源:

    $ kubectl create deployment nginx --image=nginx -n test
    deployment.apps/nginx created
    $ kubectl get deployments -n test
    NAME    READY   UP-TO-DATE   AVAILABLE   AGE
    nginx   0/1     1            0           19s
    $ kubectl get pods -n test
    NAME                     READY  STATUS     RESTARTS  AGE
    nginx-86c57db685-bczhq   1/1    Running    0         2m35s
  8. 验证一下当前的service account用户不能够在test的命名空间里操作service资源

    $ kubectl get services -n test
    Error from server (Forbidden): services is forbidden: User "system:serviceaccount:test:testaccount" cannot list resource "services" in API group "" in the namespace "test"
  9. 验证一下当前的service account用户不能够在其他命名空间里(例如dev)操作Deployments资源

    $  kubectl create deployment nginx --image=nginx -n dev
    Error from server (Forbidden):  
    deployments.apps is forbidden: User "system:serviceaccount:test:testaccount" cannot create resource "deployments" in API group "" in the namespace "dev"

 

4.3 小结

在本节中,您已经知道如何以两种不同的方式来给Tanzu Kubernetes集群的开发人员分配权限。第一种方式一般用于给现有的用户来分配权限,要求对应的用户已经在vSphere SSO系统中存在。第二种方法常用于云管软件和Kubernetes集群的结合,可以根据具体的权限要求动态的产生用户登录所需要的配置文件。

5. 总结

用户对vSphere with Kubernetes的访问控制的了解,是用户开始使用这个产品最重要的环节之一。通过对系统不同层次的访问控制进行全面的了解,架构师和系统管理员才能进行数据中心安全的规划和设置