最佳实践

创建一个超级权限

  • 创建一个 ServiceAccount
    • kubectl create serviceaccount -n user-sa-manage test-admin
  • 将该 ServiceAccount 绑定到 cluster-admin 这个 clusterrole,以赋予最高权限
    • kubectl create clusterrolebinding test-admin –clusterrole=cluster-admin –serviceaccount=user-sa-manage:test-admin
  • 此时,sa 账户就具有超级权限了,可以通过该 sa 的 token 给应用程序使用,以便可以最大化操作集群
  • 获取 TOKEN
    • kubectl get secrets -n user-sa-manage -o jsonpath="{.items[?(@.metadata.annotations[‘kubernetes.io/service-account.name’]==‘test-admin’)].data.token}"|base64 -d

使用 Service Account 的 Token 创建非管理员用户

如果想要使用 Token 对集群进行操作,其实,并不一定要创建一个 KubeConfig 文件,在通过 Kubernetes API 获取集群信息时,直接使用 Token 认证的方式即可,比如:

  • kubernetes-dashboard 的 web 登录可以使用 Token
  • 通过 REST 访问 API 可以传递 Authorization: Bearer ${TOKEN} 请求头时使用 Token。

创建 SA,并为 SA 授权

创建一个名称空间,专门用来存放 SA。然后创建一个名为 lch 的 SA。

kubectl create namespace user-sa-manage
kubectl create serviceaccount lch -n user-sa-manage

为 SA 授予权限 在 test 名称空间创建 rolebinding,将 SA 与 cluster-admin 这个 ClusterRole 绑定,让 lch-sa 可以对 test 名称空间下所有组下的所有资源进行任何操作。

也可以使用其他 Role 或 ClusterRole,或者自己创建各种角色。

(可选)让 lch 这个 SA 与 view 这个 ClusterRole 绑定,以便可以查看集群内所有资源。如果不添加这个权限,lch 用户执行 kubectl get ns 命令是没有权限的。

kubectl create rolebinding lch-sa-admin -n test --clusterrole=cluster-admin --serviceaccount=user-sa-manage:lch
kubectl create clusterrolebinding lch-sa --clusterrole=view --serviceaccount=user-sa-manage:lch

**(可选)**为 SA 绑定超级权限 当绑定了 cluster-admin 这个 clusterrole 之后,上面的那些权限操作也就没用了,lch 将会拥有对集群操作的最高权限

kubectl create clusterrolebinding lch-sa-admin --clusterrole=cluster-admin --serviceaccount=user-sa-manage:lch

获取 SA 的 Token

获取名为 lch 这个 SA 的 Token

LCH_SA_TOKEN=$(kubectl get secrets -n user-sa-manage -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='lch')].data.token}" | base64 -d)

使用 SA 的 Token 创建 KubeConfig 文件

创建一个 KubeConfig 文件,并设置集群信息

  • **(可选)**使用集群 ca 证书。
    • 像 kubernetes-dashboard 这种集群内的应用,可以不设置集群的证书,因为 Pod 的 /run/secrets/kubernetes.io/serivceaccount 目录中默认包含 ca.crt。
kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/pki/ca.crt \
  --embed-certs=true \
  --server=https://172.19.42.234:6443 \
  --kubeconfig=./lch-sa.conf
  • 不使用集群 ca 证书
    • 在 [CA](/docs/7.信息安全/Cryptography(密码学)/公开密钥加密/证书%20 与%20PKI.md 与 PKI.md) 的描述中,任何人都是可以获取到 CA 的,CA 主要是用来验证的,并不是特别需要隐藏,一定不要让别人使用集群 CA 证书的场景暂时没想到囧。毕竟没有 CA 的私钥,也没法签发新的证书~
kubectl config set-cluster kubernetes \
  --insecure-skip-tls-verify=true \
  --server=https://172.19.42.234:6443 \
  --kubeconfig=./lch-sa.conf

建立用户的凭证信息

在该文件中使用 dashboard 的 token 建立用户的凭证信息,并自动建立一个名为 dashboard-admin 的用户

kubectl config set-credentials lch \
  --token=$LCH_SA_TOKEN \
  --kubeconfig=./lch-sa.conf

在该文件中创建 user 与 cluster 的关系的 context

kubectl config set-context lch@kubernetes \
  --cluster=kubernetes \
  --user=lch \
  --kubeconfig=./lch-sa.conf

设定当前的 context

kubectl config use-context lch@kubernetes \
--kubeconfig=./lch-sa.conf

总结

这个操作生成的 KubeConfig 和 其中生成的 Token 可以用来登录 kubernetes-dashboard 注意:Dashboard 在读取 kubeconfig 文件时,只会读取 token 作为认证

使用 SA 的 TOKEN 创建的不使用 CA 的 KubeConfig 文件也可以用于访问在 Nginx 后 K8S 集群。

使用 User Account 的证书创建非管理用户

Kubernetes 中的系统组件 etcd、kube-controller-manager 等等都是通过证书

创建 UA 所需证书,并为 UA 授权

注意:需要在具有集群的 ca 证书的节点上操作

(umask 077;openssl genrsa -out lch.key 2048)
openssl req -new -key lch.key -out lch.csr -subj "/CN=lch"
openssl x509 -req \
  -CA /etc/kubernetes/pki/ca.crt \
  -CAkey /etc/kubernetes/pki/ca.key \
  -CAcreateserial \
  -in lch.csr -out lch.crt -days 3650

为 UA 授予权限 创建 Role 以及 Rolebinding ,让 lch 可以对 test 名称空间下所有组下的所有资源进行任何操作。 并且让 lch 这个 UA 与 view 这个 ClusterRole 绑定,以便可以查看集群内所有资源。如果不添加这个权限,lch 用户执行 kubectl get ns 命令是没有权限的。

# 可以自己创建 role 并绑定
kubectl create role lch-ua -n test --verb=* --resource=*.*
kubectl create rolebinding lch-ua -n test --role=lch-ua --user=lch

# 也可以直接为 SA 绑定默认的 clusterrole,使用默认的更方便一些~
kubectl create clusterrolebinding lch-ua --clusterrole=view --user=lch

使用 UA 证书创建 KubeConfig 文件

创建一个新的 KubeConfig 文件,并设置集群信息

kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/pki/ca.crt \
  --embed-certs=true \
  --server=https://172.19.42.234:6443 \
  --kubeconfig=./lch-ua.conf

使用 lch 的证书在 KubeConfig 文件创建名为 lch 的用户。

kubectl config set-credentials lch \
  --client-certificate=./lch.crt \
  --client-key=./lch.key \
  --embed-certs \
  --kubeconfig=./lch-ua.conf

绑定 lch 用户 与 集群

kubectl config set-context lch@kubernetes \
  --cluster=kubernetes \
  --user=lch \
  --kubeconfig=./lch-ua.conf

切换该 KubeConfig 文件的当前环境

kubectl config use-context lch@kubernetes \
  --kubeconfig=./lch-ua.conf

总结

然后将当前目录的 lch-config 文件交给该用户,这个用户将只可以在 lch 这个 namespace 下的所有资源进行任何操作

示例总结

从上面的示例可以看出来,名为 lch 的 UA 与 SA,其实可以被统一抽象为一个用户,这个用户的名称就是 lch。只不过,两种用户的认证方式不一样罢了,一个是证书,一个 Token,其实就相当于是把 证书 和 Token 抽象为密码。