kubectl认证配置流程

2,190 阅读4分钟

在 linux 系统中可能会包含很多用户,且不同用户有不同的权限,若需要为不同的用户设置不同的操作K8s的权限,就需要用到 K8s 的 rbac 机制。下面以创建一个 user 用户,为其设置在 default namespace 下的只读权限。

我们执行 kubectl 命令时会需要 kube-apiserver 的认证和授权,即利用用户的证书和 rbac 机制,因此若对系统用户进行权限控制,首先需要为用户创建证书。

证书创建

首先创建一个用户组和普通用户

groupadd usergroup
useradd user -g usergroup -m

为用户创建证书有两种方式,可以使用 K8s 推荐的 cfssl,也可以用 openssl。

openssl 创建证书

我们默认 K8s 部署时所创建的认证相关的密钥和证书都保存在/etc/kubernetes/ssl/中。

  1. 生成私钥
openssl genrsa -out user.key 2048
  1. 生成签名
export CA_DNAME="/CN=user/OU=Sysem/O=group:view/L=Beijing/ST=Beijing/C=CN"
openssl req -new -key user.key -subj $CA_DNAME -out user.csr

其中 CA_DNAME 显示签名的所有者,CN 为名字, 3. 生成证书

openssl x509 -req -CA /etc/kubernetes/ssl/ca.crt -CA /etc/kubernetes/ssl/ca.key -CAcreateserial -in user.csr -out user.crt -day 365

cfssl 创建证书

配置 K8s 上下文

切换到 user 用户后,配置访问的集群

kubectl config set-cluster <yourCluster> \
--certificate-authority=/etc/kubernetes/ssl/ca.crt \
--embed-certs=true \
--server=<your apiserver>

其中 certificate-authority 使用的是 K8s 生成的证书

cluster name 可以通过 kubectl config get-clusters 获取 apiserver 通过 kubectl cluster-info 获取

配置认证证书

kubectl config set-credentials user\
--client-certificate=user.crt \
--client-key=user.key \
--embed-cert=true

注意,此处的 user 并非系统用户名,而是 CA_DNAME 中的用户名,即在K8s的 rbac 中认证的名字。OU为组,同样关联 K8s rbac 认证的组

配置上下文

kubectl config set-context contextName \
--cluster=<your clustername> \
--user=user # 此处user 仍是 CA_DNAME 中的用户名

这样就配置好 user 用户的 kubectl 访问的上下文了。上下文信息默认保存在了 $HOME/.kube/config 中。 这几步中其实可以看出 K8s 的认证与系统用户名及其所在组毫无关系,K8s 只关心用户通过 kubectl 访问时所携带的证书,即 config 文件中所包含的认证信息。因此如果用户有权指定 root 用户下的 .kube/config 作为上下文配置,则可以拥有所有权限。

K8s rbac 配置

K8s 中使用 RBAC 授权器为用户授权,相关资源有 Role ClusterRole RoleBinding ClusterRoleBinding

Role & ClusterRole

RoleClusterRole用于描述角色权限的,即配置角色对于资源的可操作权限,Role可只属于某个namespace, ClusterRole隶属于全局。

一个 Role 对象只能用于授予对某一单一命名空间中资源的访问权限。 以下示例描述了”default”命名空间中的一个Role对象的定义,用于授予对pod的读访问权限:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # 空字符串""表明使用core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

ClusterRole对象可以授予与Role对象相同的权限,但由于它们属于集群范围对象, 也可以使用它们授予对以下几种资源的访问权限:

  • 集群范围资源(例如节点,即node)
  • 非资源类型endpoint(例如”/healthz”)
  • 跨所有命名空间的命名空间范围资源(例如pod,需要运行命令kubectl get pods --all-namespaces来查询集群中所有的pod) 在本例中,若使用ClusterRole,则如下所示:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: global-pod-reader
rules:
- apiGroups: [""] # 空字符串""表明使用core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

RoleBinding & ClusterRoleBinding

角色绑定将一个角色中定义的各种权限授予一个或者一组用户。 角色绑定包含了一组相关主体(即subject, 包括用户——User、用户组——Group、或者服务账户——Service Account)以及对被授予角色的引用。 在命名空间中可以通过RoleBinding对象授予权限,而集群范围的权限授予则通过ClusterRoleBinding对象完成。

RoleBinding可以引用在同一命名空间内定义的Role对象。 下面我们定义RoleBinding对象在”default”命名空间中将”pod-reader”角色授予用户”user”。 这一授权将允许用户”user”从”default”命名空间中读取pod。

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

若使用 ClusterRoleBinding,则如下所示:

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-pod-global
  namespace: default # 这里表明的是权限的作用域,而非所属哪个namespace,若没有这个字段,则表明作用域为全局。
subjects:
- kind: User   # 此处也可以更换为 Group ,对应之前 CA_DNAME 中的 OU
  name: user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: global-pod-reader
  apiGroup: rbac.authorization.k8s.io

在K8s中,系统包含默认的用户,如下

ClusterRole ClusterRoleBinding info
cluster-admin system:masters group 超级用户权限,允许对任何资源执行任何操作。 在ClusterRoleBinding中使用时,可以完全控制集群和所有命名空间中的所有资源。 在RoleBinding中使用时,可以完全控制RoleBinding所在命名空间中的所有资源,包括命名空间自己。
admin None 管理员权限,利用RoleBinding在某一命名空间内部授予。 在RoleBinding中使用时,允许针对命名空间内大部分资源的读写访问, 包括在命名空间内创建角色与角色绑定的能力。 但不允许对资源配额(resource quota)或者命名空间本身的写访问。
edit None 允许对某一个命名空间内大部分对象的读写访问,但不允许查看或者修改角色或者角色绑定。
view None 允许对某一个命名空间内大部分对象的只读访问。 不允许查看角色或者角色绑定。 由于可扩散性等原因,不允许查看secret资源。

参考自https://jimmysong.io/kubernetes-handbook/concepts/rbac.html

总结

至此我们已经实现了通过 rbac 对系统用户的权限控制,对于用户的权限,可以使用 kubectl auth can-i <verbs> <resource> 的命令进行验证。

此处个人推荐一本 ebook,kubernetes handbook