一、TLS启动引导介绍
官方文档:https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/
启动引导这些组件的正常过程,尤其是需要证书来与 kube-apiserver 安全通信的工作节点,可能会是一个具有挑战性的过程,因为这一过程通常不受 Kubernetes 控制, 需要不少额外工作。 这也使得初始化或者扩缩一个集群的操作变得具有挑战性。
为了简化这一过程,从 1.4 版本开始,Kubernetes 引入了一个证书请求和签名 API 以便简化此过程。
1.1 kubelet 初始化过程
当工作节点启动时,kubelet 执行以下操作
- 寻找自己的
kubeconfig
文件 - 检索 API 服务器的 URL 和凭据,通常是来自
kubeconfig
文件中的 TLS 密钥和已签名证书 - 尝试使用这些凭据来与 API 服务器通信
假定 kube-apiserver 成功地认证了 kubelet 的凭据数据,它会将 kubelet 视为 一个合法的节点并开始将 Pods 分派给该节点。
注意,签名的过程依赖于:
kubeconfig
中包含密钥和本地主机的证书- 证书被 kube-apiserver 所信任的一个证书机构(CA)所签名
负责部署和管理集群的人有以下责任:
- 创建 CA 密钥和证书
- 将 CA 证书发布到 kube-apiserver 运行所在的主控节点上
- 为每个 kubelet 创建密钥和证书;强烈建议为每个 kubelet 使用独一无二的、 CN 取值与众不同的密钥和证书
- 使用 CA 密钥对 kubelet 证书签名
- 将 kubelet 密钥和签名的证书发布到 kubelet 运行所在的特定节点上
本文中描述的 TLS 启动引导过程有意简化甚至完全自动化上述过程,尤其是第三步之后的操作,因为这些步骤是初始化或者扩缩集群时最常见的操作。
1.2 启动引导初始话过程
在启动引导初始化过程中,会发生以下事情:
- kubelet 启动
- kubelet 看到自己 没有 对应的
kubeconfig
文件 - kubelet 搜索并发现
bootstrap-kubeconfig
文件 - kubelet 读取该启动引导文件,从中获得 API 服务器的 URL 和用途有限的 一个“令牌(Token)”
- kubelet 建立与 API 服务器的连接,使用上述令牌执行身份认证
- kubelet 现在拥有受限制的凭据来创建和取回证书签名请求(CSR)
- kubelet 为自己创建一个 CSR,并将其 signerName 设置为
kubernetes.io/kube-apiserver-client-kubelet
- CSR 被以如下两种方式之一批复:
- 如果配置了,kube-controller-manager 会自动批复该 CSR
- 如果配置了,一个外部进程,或者是人,使用 Kubernetes API 或者使用
kubectl
来批复该 CSR
- kubelet 所需要的证书被创建
- 证书被发放给 kubelet
- kubelet 取回该证书
- kubelet 创建一个合适的
kubeconfig
,其中包含密钥和已签名的证书 - kubelet 开始正常操作
- 可选地,如果配置了,kubelet 在证书接近于过期时自动请求更新证书
- 更新的证书被批复并发放;取决于配置,这一过程可能是自动的或者手动完成
二、TLS启动引导配置
TLS启动引导有俩种方式,并不可以同时使用
- 启动引导令牌(Bootstrap Token)只介绍这个
- 令牌认证文件
2.1 TLS启动引导使用的相关服务前置配置
kube-apiserver的相关配置
主要是开启启动引导功能
--enable-bootstrap-token-auth=true #启用启动引导功能
kube-controller-manager配置
主要作用,kubelet的证书实际是有控制器进行签发签发证书时需要使用kube-apiserver证书的CA文件
--cluster-signing-cert-file=/etc/kubernetes/pki/ca.pem #需要提供kube-apiserver证书文件的CA证书文件
--cluster-signing-key-file=/etc/kubernetes/pki/ca-key.pem
--controllers=*,bootstrapsigner,tokencleaner #启用控制器,*表示默认启动的控制器,其余俩个是启动引导使用的
--cluster-signing-duration=8760h0m0s #所签名的证书有效期,默认1年,如果修改不要修改过长又可能不生效
kubelet的相关配置
--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig #引导认证文件
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig #需要指定真实的认证文件,通过认证后生成证书后会自动生成
#配置文件中的配置,证书到期后是否自动轮换证书,需要相关权限
rotateCertificates: true
2.2 生成启动引导令牌(Bootstrap Token)
引导令牌的token的格式为({a-Z}*{0-9}*){6}.({a-Z}*{0-9}*){16}
,在k8s中创建的相应资源为Secret
类型比较特殊是专门给TLS启动引导使用的bootstrap.kubernetes.io/token
,对于Sercet
的名称也是有要求的token的前6个编号必须在Sercet名称的最后面格式为.*-{a-Z}*{0-9}*){6}
。
注意:创建资源后并不能正常使用,需要绑定相关权限才可以正常使用,如果没有配置证书自动签发,证书的签发需要管理员手动同意命令如下,如果需要实现证书的自动同意,或者证书的到期自动轮询需要绑定相关的权限,并且打开某些的服务功能。
kubectl get csr
:查看证书请求kubectl certificate approve
:同意证书请求
具体创建示例文件如下
如果为了安全可以设置有效期,如果不设置有效期限这个token的值是一直可以被使用的。
a=`head -c 16 /dev/urandom | od -An -t x | tr -d ' ' | head -c6` #生成6位编号
b=`head -c 16 /dev/urandom | od -An -t x | tr -d ' ' | head -c16` #生成16位编号
#生成权限绑定文件
apiVersion: v1 #api版本号
kind: Secret #资源类型
metadata: #元数据定义
name: bootstrap-token-$a #前面的内容可以自定义但是最后的编号必须与token的前6位一致
namespace: kube-system #命名空间,必须在kube-system中
type: #类型固定
stringData: #实际定义内容
description: "The default bootstrap token generated by 'kubelet '." #描述
expiration: "2017-03-10T03:22:11Z" #可选,过期的时间,不写永久有效除非手动删除
token-id: $a #token的ID,必须6位
token-secret: $b #token的值,必须16位
usage-bootstrap-authentication: "true" #必须填写,固定
usage-bootstrap-signing: "true" #必须填写,固定
auth-extra-groups: system:bootstrappers:default-node-token,system:bootstrappers:worker,system:bootstrappers:ingress #他所拥有的身份,这里必须所属于system:bootstrappers组。可以写多个但是一般第一个权限会被使用
2.3 生成引导启动配置文件
kubelet需要指定--bootstrap-kubeconfig
引导启动配置文件,生成过程如下
kubectl config set-cluster kubernetes \
--certificate-authority=../ca/ca.pem \
--embed-certs=true \
--server=https://127.0.0.1:6443 \
--kubeconfig=bootstrap-kubelet.kubeconfig
kubectl config set-credentials tls-bootstrap-token-user \
--token=$a.$b \ #主要是这里token的值需与Sercet的token值一致
--kubeconfig=bootstrap-kubelet.kubeconfig
kubectl config set-context tls-bootstrap-token-user@kubernetes \
--cluster=kubernetes \
--user=tls-bootstrap-token-user \
--kubeconfig=bootstrap-kubelet.kubeconfig
kubectl config use-context tls-bootstrap-token-user@kubernetes \
--kubeconfig=bootstrap-kubelet.kubeconfig
2.4 引导启动的相关权限绑定
创建相关的权限也就是创建k8s中的ClusterRoleBinding资源,所绑定的ClusterRole都是apiserver启动时就已经默认创建的权限无需自己创建。
允许启动引导节点(kubelet节点)创建CSR请求
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubelet-bootstrap
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:node-bootstrapper #绑定的权限,固定
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group #权限组
name: system:bootstrappers:default-node-token #组名称,需要与引导Sercet中的组名称一致
自动批复system:bootstrappers
组所有的CSR
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: node-autoapprove-bootstrap
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:certificates.k8s.io:certificatesigningrequests:nodeclient
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:bootstrappers:default-node-token
允许 kubelet 对其客户端证书执行续期操作
kubelet续期需要配置kubelet配置文件rotateCertificates: true
默认是关闭的
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: node-autoapprove-certificate-rotation
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:nodes