使用 kubeconfig 或 token 进行用户身份认证

查看本文大纲

在开启了 TLS 的集群中,每当与集群交互的时候少不了的是身份认证,使用 kubeconfig(即证书)和 token 两种认证方式是最简单也最通用的认证方式,在 dashboard 的登录功能就可以使用这两种登录功能。

下文分两块以示例的方式来讲解两种登陆认证方式:

  • 为 brand 命名空间下的 brand 用户创建 kubeconfig 文件
  • 为集群的管理员(拥有所有命名空间的 amdin 权限)创建 token

使用 kubeconfig

如何生成kubeconfig文件请参考创建用户认证授权的 kubeconfig 文件

注意我们生成的 kubeconfig 文件中没有 token 字段,需要手动添加该字段。

比如我们为 brand namespace 下的 brand 用户生成了名为 brand.kubeconfig 的 kubeconfig 文件,还要再该文件中追加一行 token 的配置(如何生成 token 将在下文介绍),如下所示:

image
kubeconfig 文件

对于访问 dashboard 时候的使用 kubeconfig 文件如brand.kubeconfig 必须追到 token 字段,否则认证不会通过。而使用 kubectl 命令时的用的 kubeconfig 文件则不需要包含 token 字段。

生成 token

需要创建一个 admin 用户并授予 admin 角色绑定,使用下面的 yaml 文件创建 admin 用户并赋予他管理员权限,然后可以通过 token 访问 kubernetes,该文件见admin-role.yaml

生成 kubernetes 集群最高权限 admin 用户的 token

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: admin
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
  name: admin
  namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin
  namespace: kube-system
  labels:
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile

然后执行下面的命令创建 serviceaccount 和角色绑定,

kubectl create -f admin-role.yaml

创建完成后获取 secret 中 token 的值。

# 获取admin-token的secret名字
$ kubectl -n kube-system get secret|grep admin-token
admin-token-nwphb                          kubernetes.io/service-account-token   3         6m
# 获取token的值
$ kubectl -n kube-system describe secret admin-token-nwphb
Name:		admin-token-nwphb
Namespace:	kube-system
Labels:		<none>
Annotations:	kubernetes.io/service-account.name=admin
		kubernetes.io/service-account.uid=f37bd044-bfb3-11e7-87c0-f4e9d49f8ed0

Type:	kubernetes.io/service-account-token

Data
====
namespace:	11 bytes
token:		非常长的字符串
ca.crt:		1310 bytes

也可以使用 jsonpath 的方式直接获取 token 的值,如:

kubectl -n kube-system get secret admin-token-nwphb -o jsonpath={.data.token}|base64 -d

注意:yaml 输出里的那个 token 值是进行 base64 编码后的结果,一定要将 kubectl 的输出中的 token 值进行 base64 解码,在线解码工具 base64decode,Linux 和 Mac 有自带的 base64 命令也可以直接使用,输入 base64 是进行编码,Linux 中base64 -d 表示解码,Mac 中使用 base64 -D

我们使用了 base64 对其重新解码,因为 secret 都是经过 base64 编码的,如果直接使用 kubectl 中查看到的 token 值会认证失败,详见 secret 配置。关于 JSONPath 的使用请参考 JSONPath 手册。

更简单的方式是直接使用kubectl describe命令获取 token 的内容(经过 base64 解码之后):

kubectl describe secret admin-token-nwphb 

为普通用户生成 token

为指定 namespace 分配该 namespace 的最高权限,这通常是在为某个用户(组织或者个人)划分了 namespace 之后,需要给该用户创建 token 登陆 kubernetes dashboard 或者调用 kubernetes API 的时候使用。

每次创建了新的 namespace 下都会生成一个默认的 token,名为default-token-xxxxdefault就相当于该 namespace 下的一个用户,可以使用下面的命令给该用户分配该 namespace 的管理员权限。

kubectl create rolebinding $ROLEBINDING_NAME --clusterrole=admin --serviceaccount=$NAMESPACE:default --namespace=$NAMESPACE
  • $ROLEBINDING_NAME必须是该 namespace 下的唯一的
  • admin表示用户该 namespace 的管理员权限,关于使用clusterrole进行更细粒度的权限控制请参考RBAC——基于角色的访问控制
  • 我们给默认的 serviceaccount default分配 admin 权限,这样就不要再创建新的 serviceaccount,当然你也可以自己创建新的 serviceaccount,然后给它 admin 权限

参考

  • JSONPath 手册 - kubernetes.io
  • Kubernetes 中的认证 - kubernetes.io