Kubernetes RBAC用户和授权

注意事项 佩雷夫 :继续使用最近讨论的有关Kubernetes尤其是RBAC的安全性主题,我们正在发布Adaltas大数据公司的一名法国顾问的材料翻译。 作者详细说明了如何创建用户,授予用户权限并继续为其提供服务。

设置和启动Kubernetes集群仅仅是开始:它也需要被利用。 为了保护对群集的访问,您需要设置用户凭据并正确管理身份验证和授权设置。

(插图摘自CNCF博客 -大约翻译)。

本文介绍如何使用X.509客户端证书创建用户,以及如何使用Kubernetes中的基本RBAC API管理授权。 我们还将讨论一些简化集群管理的开源项目:rakkess,kubectl-who-can,rbac-lookup和RBAC Manager。

前提条件和假设


首先,必须做出几个假设:


如果您没有现成的Kubernetes集群,我建议您参考同事的文章(Arthur BUSSER),他在其中谈论使用Vagrant 在CentOS 7上安装Kubernetes

我们集群中有4个节点:1个主节点和3个工人。 该向导还将用作与群集交互的边缘节点。

RBAC API


基于角色的访问控制(RBAC)是一种基于公司中各个用户的角色来控制对计算机和网络资源的访问的方法。 RBAC可以与所有支持CRUD(创建,读取,更新,删除)的Kubernetes资源一起使用。 此类资源的示例:

  • 命名空间
  • 豆荚
  • 部署
  • 持久卷(PersistentVolumes);
  • ConfigMaps

以下是一些可能的操作示例:

  • create ;
  • get
  • delete (delete) ;
  • list list 视图)
  • update

为了在Kubernetes中管理RBAC,我们需要声明:

  • RoleClusterRole 。 这些只是代表一组权限的规则集。 Role只能用于提供对名称空间内资源的访问。 ClusterRole可以提供与Role相同的权限,还可以访问整个集群中的可用资源以及所谓的非资源终结点(例如/healthz 。)
  • Subjects 主体是将在集群中执行操作的实体。 它可以是用户,服务甚至组。
  • RoleBindingClusterRoleBinding 。 顾名思义,这只是对象与Role或ClusterRole的绑定。

Kubernetes具有以下默认角色:

  • view :只读访问,不包含秘密;
  • edit :以上内容+编辑大多数资源的能力,不包括角色和角色绑定;
  • admin :具有以上能力以及在名称空间级别管理角色和角色映射的能力;
  • cluster-admin :所有可能的特权。

当然,您可以创建自己的RolesClusterRoles ,但是我们建议您在情况允许的情况下尽可能多地使用默认角色。 否则,您会很快对此感到困惑。

使用范例


我们将创建两个名称空间: my-project-devmy-project-prod ,以及两个用户jeansarah在这些名称空间中具有不同的角色:

  • my-project-dev:
    • 吉恩:编辑
  • 我的项目产品:
    • 吉恩(Jean):查看
    • 莎拉:编辑

使用X.509客户端证书创建和认证用户


通常,有两种类型的用户:由Kubernetes管理的服务帐户和普通用户。 我们将专注于后者。 官方文档中对它们的描述如下:

假定常规用户由外部独立服务管理。 该角色可以由管理员分发私钥,用户存储库(例如Keystone或Google帐户),甚至是包含用户名和密码列表的文件来扮演。 在这方面,Kubernetes没有代表普通用户的对象。 不能通过API调用将普通用户添加到群集中。

有几种管理普通用户的方法:

  • 基本身份验证
    • 使用以下(或类似的)内容将配置转移到API服务器:密码,用户名,uid,组;
  • X.509客户端证书:
    • 创建用户的密钥和证书签名请求;
    • 在证书颁发机构(Kubernetes CA)中进行证书以获得用户证书;
  • 承载令牌(JSON Web令牌,JWT):
    • OpenID连接
    • OAuth 2.0之上的身份验证层;
    • 网络挂钩

在本文中,由于其简单性,我们将使用X.509和OpenSSL证书。 创建用户的过程分为几个阶段-我们将遍历所有阶段。 应使用具有群集管理员权限的用户帐户(cluster-admin)执行操作。 这是创建用户的所有步骤(以jean为例):

  • 在向导上创建一个用户,然后转到其主目录以完成其余步骤:

     useradd jean && cd /home/jean 
  • 创建一个私钥:

     openssl genrsa -out jean.key 2048 
  • 创建一个证书签名请求(CSR)。 CN是用户名, O是组。 您可以按组设置权限。 例如,如果您有许多具有相同权限的用户,这将简化工作:

     #   openssl req -new -key jean.key \ -out jean.csr \ -subj "/CN=jean" #     $group openssl req -new -key jean.key \ -out jean.csr \ -subj "/CN=jean/O=$group" #       openssl req -new -key jean.key \ -out jean.csr \ -subj "/CN=jean/O=$group1/O=$group2/O=$group3" 
  • 在Kubernetes CA中签署CSR。 我们必须使用通常在/etc/kubernetes/pki找到的CA证书和密钥。 该证书有效期为500天:

     openssl x509 -req -in jean.csr \ -CA /etc/kubernetes/pki/ca.crt \ -CAkey /etc/kubernetes/pki/ca.key \ -CAcreateserial \ -out jean.crt -days 500 
  • 创建.certs目录。 我们将在其中存储用户的公钥和私钥:

     mkdir .certs && mv jean.crt jean.key .certs 
  • 在Kubernetes中创建一个用户:

     kubectl config set-credentials jean \ --client-certificate=/home/jean/.certs/jean.crt \ --client-key=/home/jean/.certs/jean.key 
  • 为用户设置上下文:

     kubectl config set-context jean-context \ --cluster=kubernetes --user=jean 
  • 编辑用户配置文件。 它包含在集群中进行身份验证所需的信息。 您可以使用群集配置文件,该文件通常位于/etc/kubernetescertificate-authority-dataserver变量应与上述文件中的相同:

     apiVersion: v1 clusters: - cluster: certificate-authority-data: {  } server: {  } name: kubernetes contexts: - context: cluster: kubernetes user: jean name: jean-context current-context: jean-context kind: Config preferences: {} users: - name: jean user: client-certificate: /home/jean/.certs/jean.cert client-key: /home/jean/.certs/jean.key 

    现在,您需要将上面的配置复制到.kube目录:

     mkdir .kube && vi .kube/config 
  • 仍然需要使用户成为所有已创建文件和目录的所有者:

     chown -R jean: /home/jean/ 

用户jean成功创建。 我们也会为sarah做同样的事情。 有很多步骤,创建大量用户可能需要很长时间。 因此,我编写了使该过程自动化的Bash脚本:可以在GitHub存储库中找到它们

注意事项 佩雷夫 :正如我们在最近的文章中所写,可以通过kubeadm控制台实用程序新功能,以更“原生”的方式对Kubernetes简化此过程。 但是,请记住,在发布此翻译时,它们以alpha形式提供。 创建用户的命令示例是kubeadm alpha kubeconfig user

现在我们有了用户,我们可以继续创建两个名称空间:

 kubectl create namespace my-project-dev kubectl create namespace my-project-prod 

由于我们尚未确定用户授权,因此他们不应有权访问群集资源:

 User: Jean kubectl get nodes Error from server (Forbidden): nodes is forbidden: User "jean" cannot list resource "nodes" in API group "" at the cluster scope kubectl get pods -n default Error from server (Forbidden): pods is forbidden: User "jean" cannot list resource "pods" in API group "" in the namespace "default" kubectl get pods -n my-project-prod Error from server (Forbidden): pods is forbidden: User "jean" cannot list resource "pods" in API group "" in the namespace "my-project-prod" kubectl get pods -n my-project-dev Error from server (Forbidden): pods is forbidden: User "jean" cannot list resource "pods" in API group "" in the namespace "my-project-dev" 

 User: Sarah kubectl get nodes Error from server (Forbidden): nodes is forbidden: User "sarah" cannot list resource "nodes" in API group "" at the cluster scope kubectl get pods -n default Error from server (Forbidden): pods is forbidden: User "sarah" cannot list resource "pods" in API group "" in the namespace "default" kubectl get pods -n my-project-prod Error from server (Forbidden): pods is forbidden: User "sarah" cannot list resource "pods" in API group "" in the namespace "my-project-prod" kubectl get pods -n my-project-dev Error from server (Forbidden): pods is forbidden: User "sarah" cannot list resource "pods" in API group "" in the namespace "my-project-dev" 

创建角色和ClusterRole


我们将使用ClusterRole ,默认情况下可用。 但是,我们还将展示如何创建自己的RoleClusterRole 。 本质上, RoleClusterRole只是允许某些资源和名称空间使用的一组动作(称为verbs ,即逐字动词) 。 这是一个示例YAML文件:

 apiVersion: rbac.authorization.k8s.io/v1beta1 kind: Role metadata: name: list-deployments namespace: my-project-dev rules: - apiGroups: [ apps ] resources: [ deployments ] verbs: [ get, list ] --------------------------------- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: name: list-deployments rules: - apiGroups: [ apps ] resources: [ deployments ] verbs: [ get, list ] 

要创建它们,请运行以下命令:

 kubectl create -f /path/to/your/yaml/file 

将角色或ClusterRole绑定到用户


现在,将默认的ClusterRoleeditview )绑定到我们的用户,如下所示:

  • jean
    • edit -在名称空间my-project-dev
    • 在命名空间my-project-prod view
  • sarah
    • edit -在my-project-prod命名空间中。

RoleBindings必须由名称空间而不是用户指定。 换句话说,要授权Jean,我们将创建两个RoleBindings。 一个YAML文件的示例,该文件为jean定义了RoleBindings:

 apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: jean namespace: my-project-dev subjects: - kind: User name: jean apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: edit apiGroup: rbac.authorization.k8s.io --------------------------------- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: jean namespace: my-project-prod subjects: - kind: User name: jean apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: view apiGroup: rbac.authorization.k8s.io 

我们允许jean view my-project-prod并编辑my-project-dev 。 授权sarah也需要做同样的事情。 要激活它们,请运行以下命令:

 kubectl apply -f /path/to/your/yaml/file 

在这种情况下,使用了kubectl apply而不是kubectl create 。 两者之间的区别在于, create创建对象,不执行其他任何操作,然后apply -不仅创建对象(如果不存在),还可以在必要时进行更新。

让我们检查我们的用户是否已收到必要的权限。

  • 用户: sarah (在my-project-prod edit
    • my-project-prod
      • 可以列出豆荚(1);
      • 可以创建部署(2)。
    • my-project-dev
      • 无法列出豆荚(4);
      • 无法创建部署(5)。

 (1) kubectl get pods -n my-project-prod No resources found. (2) kubectl run nginx --image=nginx --replicas=1 -n my-project-prod deployment.apps/nginx created (3) kubectl get pods -n my-project-prod NAME READY STATUS RESTARTS AGE nginx-7db9fccd9b-t14qw 1/1 Running 0 4s (4) kubectl get pods -n my-project-dev Error from server (Forbidden): pods is forbidden: User "sarah" cannot list resource "pods" in API group "" in the namespace "my-project-dev" (5) kubectl run nginx --image=nginx --replicas=1 -n my-project-dev Error from server (Forbidden): deployments.apps is forbidden: User "sarah" cannot create resource "deployments" in API group "apps" in the namespace "my-project-dev" 

  • 用户: jean (在my-project-prod view并在my-project-dev edit
    • my-project-prod
      • 可以列出豆荚(1);
      • 可以列出部署'ov(2);
      • 无法删除部署(3)。
    • my-project-dev:
      • 可以列出豆荚(4);
      • 可以创建部署(5);
      • 可以列出部署'ov(6);
      • 可以删除部署(7)。

 (1) kubectl get pods -n my-project-prod NAME READY STATUS RESTARTS AGE nginx-7db9fccd9b-t14qw 1/1 Running 0 101s (2) kubectl get deploy -n my-project-prod NAME READY UP-TO-DATE AVAILABLE AGE nginx 1/1 1 1 110s (3) kubectl delete deploy/nginx -n my-project-prod Error from server (Forbidden): deployments.extensions "nginx" is forbidden: User "jean" cannot delete resource "deployments" in API group "extensions" in the namespace "my-project-prod" (4) kubectl get pods -n my-project-dev No resources found. (5) kubectl run nginx --image=nginx --replicas=1 -n my-project-dev deployment.apps/nginx created (6) kubectl get deploy -n my-project-dev NAME READY UP-TO-DATE AVAILABLE AGE nginx 0/1 1 0 13s (7) kubectl delete deploy/nginx -n my-project-dev deployment.extensions "nginx" deleted (8) kubectl get deploy -n my-project-dev No resources found. 

用户管理和授权


因此,我们已经成功设置了各种角色和用户授权。 问题出现了:现在如何管理所有这些? 我如何知道特定用户的权限设置是否正确? 我怎么知道谁有权执行特定操作? 如何大致了解用户权限?

我们需要所有这些问题的答案,以确保群集安全。 使用kubectl auth can-i命令kubectl auth can-i用户是否可以执行特定操作:

 # kubectl auth can-i $action $resource --as $subject (1) kubectl auth can-i list pods (2) kubectl auth can-i list pods --as jean 

第一个命令(1)允许用户确定他是否可以执行某些操作。 第二个(2)-允许管理员模拟用户以查明他是否可以执行特定操作。 仅具有群集管理员特权的用户才能使用此“轮回”。

几乎可以使用内置工具包完成所有操作。 因此,我将介绍一些开源项目,这些项目将扩展kubectl auth can-i团队提供的功能。 在介绍它们之前,让我们建立依赖关系: GoKrew

去安装


Go是一种开源编程语言,可让您创建简单,可靠和高效的软件。 它是由Google在C和Pascal的启发下根据Robert GriesemerRob PikeKen Thompson的原始概念开发的。

 wget https://dl.google.com/go/go1.12.5.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1.12.5.linux-amd64.tar.gz export PATH=$PATH:/usr/local/go/bin 

机组人员安装


Krew是可简化kubectl插件使用的工具 。 Krew帮助您查找,安装和管理插件。 在功能上,它类似于apt,dnf或brew等工具。 Krew仅与1.12及更高版本的kubectl兼容。

 set -x; cd "$(mktemp -d)" && curl -fsSLO "https://storage.googleapis.com/krew/v0.2.1/krew.{tar.gz,yaml}" && tar zxvf krew.tar.gz && ./krew-"$(uname | tr '[:upper:]' '[:lower:]')_amd64" install \ --manifest=krew.yaml --archive=krew.tar.gz export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH" 

瑞克斯


该项目使您可以查看已授予用户的所有权限。 例如,它有助于回答jean能做什么的问题。 首先,让我们安装它:

 kubectl krew install access-matrix 

项目文档可以在GitHub存储库中找到 。 这是他的工作示例:

 kubectl access-matrix -n my-project-dev --as jean 



谁能


该项目使我们能够找出哪些用户可以执行特定操作。 它有助于回答以下问题:“谁可以做到这一点?” 安装方式:

 go get -v github.com/aquasecurity/kubectl-who-can 

该文档位于GitHub存储库中 。 工作示例:

 kubectl-who-can list pods -n default No subjects found with permissions to list pods assigned through RoleBindings CLUSTERROLEBINDING SUBJECT TYPE SA-NAMESPACE cluster-admin system:masters Group rbac-manager rbac-manager ServiceAccount rbac-manager system:controller:attachdetach-controller attachdetach-controller ServiceAccount kube-system system:controller:clusterrole-aggregation-controller clusterrole-aggregation-controller ServiceAccount kube-system system:controller:cronjob-controller cronjob-controller ServiceAccount kube-system system:controller:daemon-set-controller daemon-set-controller ServiceAccount kube-system system:controller:deployment-controller deployment-controller ServiceAccount kube-system system:controller:endpoint-controller endpoint-controller ServiceAccount kube-system system:controller:generic-garbage-collector generic-garbage-collector ServiceAccount kube-system system:controller:horizontal-pod-autoscaler horizontal-pod-autoscaler ServiceAccount kube-system system:controller:job-controller job-controller ServiceAccount kube-system system:controller:namespace-controller namespace-controller ServiceAccount kube-system system:controller:node-controller node-controller ServiceAccount kube-system system:controller:persistent-volume-binder persistent-volume-binder ServiceAccount kube-system system:controller:pod-garbage-collector pod-garbage-collector ServiceAccount kube-system system:controller:pvc-protection-controller pvc-protection-controller ServiceAccount kube-system system:controller:replicaset-controller replicaset-controller ServiceAccount kube-system system:controller:replication-controller replication-controller ServiceAccount kube-system system:controller:resourcequota-controller resourcequota-controller ServiceAccount kube-system system:controller:statefulset-controller statefulset-controller ServiceAccount kube-system system:coredns coredns ServiceAccount kube-system system:kube-controller-manager system:kube-controller-manager User system:kube-scheduler system:kube-scheduler User 

查询


该项目概述了RBAC规则。 它有助于回答以下问题:“ jeansarah属于哪个角色?”,“所有用户都属于哪个角色?”,“整个团队属于哪个角色?”。 要安装,请运行以下命令:

 kubectl krew install rbac-lookup 

该文档位于GitHub存储库中 。 这是工作示例:

 kubectl-rbac_lookup jean SUBJECT SCOPE ROLE jean my-project-dev ClusterRole/edit jean my-project-prod ClusterRole/view kubectl-rbac_lookup sarah SUBJECT SCOPE ROLE sarah my-project-prod ClusterRole/edit kubectl-rbac_lookup --kind user SUBJECT SCOPE ROLE jean my-project-dev ClusterRole/edit jean my-project-prod ClusterRole/view sarah my-project-prod ClusterRole/edit system:anonymous kube-public Role/kubeadm:bootstrap-signer-clusterinfo system:kube-controller-manager kube-system Role/extension-apiserver-authentication-reader system:kube-controller-manager kube-system Role/system::leader-locking-kube-controller-manager system:kube-controller-manager cluster-wide ClusterRole/system:kube-controller-manager system:kube-proxy cluster-wide ClusterRole/system:node-proxier system:kube-scheduler kube-system Role/extension-apiserver-authentication-reader system:kube-scheduler kube-system Role/system::leader-locking-kube-scheduler system:kube-scheduler cluster-wide ClusterRole/system:kube-scheduler system:kube-scheduler cluster-wide ClusterRole/system:volume-scheduler kubectl-rbac_lookup --kind group SUBJECT SCOPE ROLE system:authenticated cluster-wide ClusterRole/system:basic-user system:authenticated cluster-wide ClusterRole/system:discovery system:authenticated cluster-wide ClusterRole/system:public-info-viewer system:bootstrappers:kubeadm:default-node-token cluster-wide ClusterRole/system:node-bootstrapper system:bootstrappers:kubeadm:default-node-token cluster-wide ClusterRole/system:certificates.k8s.io:certificatesigningrequests:nodeclient system:bootstrappers:kubeadm:default-node-token kube-system Role/kube-proxy system:bootstrappers:kubeadm:default-node-token kube-system Role/kubeadm:kubelet-config-1.14 system:bootstrappers:kubeadm:default-node-token kube-system Role/kubeadm:nodes-kubeadm-config system:masters cluster-wide ClusterRole/cluster-admin system:nodes kube-system Role/kubeadm:kubelet-config-1.14 system:nodes kube-system Role/kubeadm:nodes-kubeadm-config system:nodes cluster-wide ClusterRole/system:certificates.k8s.io:certificatesigningrequests:selfnodeclient system:unauthenticated cluster-wide ClusterRole/system:public-info-viewer 

RBAC经理


正如该项目的名称所暗示的那样,他是RBAC的经理。 它简化了许多必要的操作。 也许最重要的是创建RoleBindings。 前面我们看到,为用户创建不同的角色时,有必要创建不同的RoleBindings。 RBAC Manager通过允许您一次创建一个具有所有授权的RoleBinding来提供帮助。 要安装,必须从GitHub上的存储库下载YAML文件:

 kubectl apply -f /path/to/rbac/manager/yaml/file 

官方文档位于GitHub存储库中 。 工作示例:

 apiVersion: rbacmanager.reactiveops.io/v1beta1 kind: RBACDefinition metadata: name: jose rbacBindings: - name: jose subjects: - kind: User name: jose roleBindings: - namespace: my-project-prod clusterRole: edit - namespace: my-project-dev clusterRole: edit 

结论


我们使用带有OpenSSL的X​​.509客户端证书在Kubernetes集群中创建了用户,并授权了他们。 为了方便用户创建,您可以使用我在GitHub上的存储库中可用的脚本(或实验性kubeadm命令 -大约Transl。) 。 对于集群管理,您可以使用本文介绍的开放源代码项目:

  • kubectl auth can-i :确定用户是否可以执行某些操作;
  • rakkess :找出用户可以执行的所有动作;
  • kubectl-who-can :确定哪些用户可以执行某些操作;
  • rbac-lookup :获得RBAC的概述;
  • RBAC Manager :通过组合权限绑定,自动更改RBAC,使用标签作为选择器来分配权限来简化配置。

创建用户可能会变成一项非常耗时的任务,尤其是在您需要一次设置大量用户(或经常创建用户)的情况下。 为了缓解这种情况,可以将公司LDAP连接到Kubernetes集群。 一些开源项目( Kismatic [ 对象 看起来像废弃的 对象 ]ObjectifLibre )提供了Kubernetes Webhooks,它们允许通过LDAP进行直接身份验证。 另一个可能的解决方案是使用公司LDAP作为后端配置OpenID服务器。

译者的PS


另请参阅我们的博客:

Source: https://habr.com/ru/post/zh-CN470503/


All Articles