Kubernetes访问控制之认证
访问Kubernetes系统主要经过认证、授权和准入控制机制
认证即是身份验证,常用身份认证策略:X509客户证书、静态令牌、启动引导令牌、服务账号令牌、OpenID Connect令牌、Webhook令牌身份认证和身份认证代理.
Kubernetes允许同时启用多种身份认证方法,通常至少两种,服务账号令牌(默认启动),推荐使用X509客户证书更加安全可靠
Kubernetes 集群有两类用户:服务账号和普通用户
- 服务账号:受Kubernetes管理的,对应的对象是ServiceAccount,空间级别
- 普通用户:kubernetes不包含用来代表普通用户账号的对象,所以无法通过API添加到集群中
一、X509客户证书
- 1.创建私钥
openssl genrsa -out myuser.key 2048
- 2.生成签名请求 CN 是用户名,O 是该用户归属的组
openssl req -new -key myuser.key -out myuser.csr -subj="/O=mygroup/O=mygroup1/CN=myuser"
- 3.创建 CertificateSigningRequest
cat <<EOF | kubectl apply -f - apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: name: myuser spec: request: xxxx #cat myuser.csr | base64 | tr -d "\n" signerName: kubernetes.io/kube-apiserver-client usages: - client auth EOF
- 4.批准证书签名请求
kubectl certificate approve myuser
- 5.取得证书
kubectl get csr myuser -o jsonpath='{.status.certificate}'| base64 -d > myuser.crt
- 6.给用户组或者用户授权
- 7.添加到kubeconfig
kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true
授权
system:masters
组 kube-apiserver需要关闭CertificateSubjectRestriction准入控制器
--disable-admission-plugins=CertificateSubjectRestriction
二、服务账号令牌
-
用途:主要用于Pod访问 kube-apiserver
-
服务账号通常由 API 服务器自动创建(创建命名空间会自动创建一个
default
名字的服务账号)并通过 ServiceAccount 准入控制器关联到集群中运行的 Pod 上(Pod创建未指定spec.serviceAccountName
时 默认就是default
) -
服务账号的token(JWT)是通过
Secret
对象管理,ServiceAccount
绑定Secret
, 通过Secret
挂载到Pod容器中, token令牌是没有过期时间的kubectl describe sa/default #查看secret
kubectl describe secret/default-token-tgs6q #查看token值

ca.crt 用于验证kube-apiserver证书合法性;
namespace 命名空间;
token是sa.key
签发的,kube-apiserver通过sa.pub
验签
- 服务账号被身份认证后,所确定的用户名为
system:serviceaccount:<名字空间>:<服务账号>
, 并被分配到用户组system:serviceaccounts
和system:serviceaccounts:<名字空间>
服务账号令牌也可以在集群外部使用,在API请求头部加入令牌,参考静态令牌方式
kubernets1.20(含)之前,sa创建的secret通过投射卷挂载到Pod,secret里的token是永久有效的
kubernets1.21-1.23版本,创建sa还是会自动创建secret,但是pod里面不会使用,而是由kubelet到TokenRequest API去申请一个token,默认有效期是1年,Pod每一个小时会更新一次token
kuberenets1.24版本以上,创建sa不再自动创建secret,只能由kubelet到TokenRequest API去申请token
ServiceAccount控制器
ServiceAccount 控制器管理名字空间内的 ServiceAccount,并确保每个活跃的名字空间中都存在名为 “default” 的 ServiceAccount
令牌控制器
服务账号令牌控制器作为 kube-controller-manager 的一部分运行,以异步的形式工作,主要职责是:
- 监测 ServiceAccount 的创建/删除并创建/删除相应的服务账号令牌 Secret
- 监测服务账号令牌 Secret 的添加,保证相应的 ServiceAccount 存在,如有需要, 向 Secret 中添加令牌。
- 监测 Secret 的删除,如有需要,从相应的 ServiceAccount 中移除引用
kube-controller-manager 服务通过参数
--service-account-private-key-file
设置服务账号的私钥文件,用于为所生成的服务账号令牌签名,kube-apiserver通过参数--service-account-key-file
公钥 进行验签
三、启动引导令牌
启动引导令牌是一种简单的持有者令牌(Bearer Token),这种令牌是在新建集群 或者在现有集群中添加新节点时使用的。通过kube-apiserver参数--enable-bootstrap-token-auth
启用(默认是启用)
-
令牌格式:
abcdef.0123456789abcdef
符合正则表达式 [a-z0-9]{6}.[a-z0-9]{16}, 第一部分是Token ID, 第二部分是令牌密钥Token Secret -
令牌存储在Kube-system名字空间中secret对象
bootstrap-token-<token id>
,默认有限期是24小时,过期 tokencleaner 控制器会自动清除 -
令牌认证为用户名
system:bootstrap:<token id>
并且是组system:bootstrappers
的成员,通过Authorization: Bearer 07401b.f395accd246ae52d
用于API服务器身份认证 -
kubeadm init
和kubeadm token create --print-join-command
会创建boostrap-token
四、静态令牌
kube-apiserver 设置参数 --token-auth-file=SOMEFILE.csv
, 令牌文件格式如下:
token,user,uid,"group1,group2,group3"
在请求中放入持有者令牌, 假设令牌为31ada4fd-adec-460c-809a-9e56ceb75269
Authorization: Bearer 31ada4fd-adec-460c-809a-9e56ceb75269
更改令牌文件内容,需要重启apiserver服务