文章 86
评论 0
浏览 124462
TLS bootstrapping原理详解

TLS bootstrapping原理详解

一、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 执行以下操作

  1. 寻找自己的 kubeconfig 文件
  2. 检索 API 服务器的 URL 和凭据,通常是来自 kubeconfig 文件中的 TLS 密钥和已签名证书
  3. 尝试使用这些凭据来与 API 服务器通信

假定 kube-apiserver 成功地认证了 kubelet 的凭据数据,它会将 kubelet 视为 一个合法的节点并开始将 Pods 分派给该节点。

注意,签名的过程依赖于:

  • kubeconfig 中包含密钥和本地主机的证书
  • 证书被 kube-apiserver 所信任的一个证书机构(CA)所签名

负责部署和管理集群的人有以下责任:

  1. 创建 CA 密钥和证书
  2. 将 CA 证书发布到 kube-apiserver 运行所在的主控节点上
  3. 为每个 kubelet 创建密钥和证书;强烈建议为每个 kubelet 使用独一无二的、 CN 取值与众不同的密钥和证书
  4. 使用 CA 密钥对 kubelet 证书签名
  5. 将 kubelet 密钥和签名的证书发布到 kubelet 运行所在的特定节点上

本文中描述的 TLS 启动引导过程有意简化甚至完全自动化上述过程,尤其是第三步之后的操作,因为这些步骤是初始化或者扩缩集群时最常见的操作。

1.2 启动引导初始话过程

在启动引导初始化过程中,会发生以下事情:

  1. kubelet 启动
  2. kubelet 看到自己 没有 对应的 kubeconfig 文件
  3. kubelet 搜索并发现 bootstrap-kubeconfig 文件
  4. kubelet 读取该启动引导文件,从中获得 API 服务器的 URL 和用途有限的 一个“令牌(Token)”
  5. kubelet 建立与 API 服务器的连接,使用上述令牌执行身份认证
  6. kubelet 现在拥有受限制的凭据来创建和取回证书签名请求(CSR)
  7. kubelet 为自己创建一个 CSR,并将其 signerName 设置为 kubernetes.io/kube-apiserver-client-kubelet
  8. CSR 被以如下两种方式之一批复:
  • 如果配置了,kube-controller-manager 会自动批复该 CSR
  • 如果配置了,一个外部进程,或者是人,使用 Kubernetes API 或者使用 kubectl 来批复该 CSR
  1. kubelet 所需要的证书被创建
  2. 证书被发放给 kubelet
  3. kubelet 取回该证书
  4. kubelet 创建一个合适的 kubeconfig,其中包含密钥和已签名的证书
  5. kubelet 开始正常操作
  6. 可选地,如果配置了,kubelet 在证书接近于过期时自动请求更新证书
  7. 更新的证书被批复并发放;取决于配置,这一过程可能是自动的或者手动完成

二、TLS启动引导配置

TLS启动引导有俩种方式,并不可以同时使用

  1. 启动引导令牌(Bootstrap Token)只介绍这个
  2. 令牌认证文件

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

标题:TLS bootstrapping原理详解
作者:Carey
地址:HTTPS://zhangzhuo.ltd/articles/2022/01/10/1641786877445.html

生而为人

取消