BetterManEddy

导航

 

前提:

   早期的k8s的版本默认是存在安全端口与非安装端口的,但是最新的k8s已经默认关闭本地8080非安全端口,只允许ApiServer的6443安全端口,使用 TLS,用 --tls-cert-file 设置证书,用 --tls-private-key-file 设置密钥,请求须经身份认证,请求须经准入控制模块处理,和鉴权组件处理;k8s集群认证方式有多种,比如X509 client certs(就是集群外部用户认证)、Static Token File、Bootstrap Tokens、Bootstrap Tokens、OpenId Connect Tokens、Service Account Tokens(就是集群内管理用户认证)、Bearer Token、Webhook Token Authentication、Authticating Proxy、Client-go credential plugins等;鉴权、准入参考k8s认证、鉴权、准入

    k8s集群开启了TLS双向认证以后,所有与ApiServer通信的组件都需要双向认证;在k8s集群扩充工作节点的时候,使用二进制部署的集群,是需要手动给工作节点颁发证书或者通过TLS bootstrapping机制实现自动颁发证书的;在讲解TLS Bootstrapping的工作原理前,先说明一下kubelet与kube-proxy的原理

  1. Kubelet是工作节点上的主要服务,定期从kube-apiserver组件接收新的或修改的Pod规范,并确保Pod及其容器在期望规范下运行。同时该组件作为工作节点的监控组件,向kube-apiserver汇报主机的运行状况;
  2. Kube-proxy维护节点上的网络规则,实现了Kubernetes Service 概念的一部分 。它的作用是使发往 Service 的流量(通过ClusterIP和端口)负载均衡到正确的后端Pod;

kubelet启动需要经过以下步骤:【自动颁发证书的细节参考https://blog.csdn.net/Michaelwubo/article/details/113769391

  1. 寻找所在工作节点的 kubeconfig 文件;
  2. 检索 kube-apiserver的 URL 和凭据,通常是来自 kubeconfig 文件中的 TLS 密钥和已签名证书;
  3. 尝试使用这些凭据来与 kube-apiserver通信;

基于此流程,在k8s1.4版本后引入了TLS Bootstrapping的功能后,在集群加入新节点后,kubelet第一次启动的完整过程:(目前主要用于kubelet,kube-proxy还是统一颁发一个证书

  1. kubelet 启动
  2. kubelet 查找本地没有 对应的 kubeconfig 文件
  3. kubelet 搜索并发现 bootstrap-kubeconfig 文件(此时需要区分是否开启bootstrapping,没有开启且是二进制部署的需要在新增节点进行手动token生成,配置自动颁发证书)
  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

如果没有配置,需要手动执行命令批准(kubectl certificate approve)

  1. kubelet 所需要的证书被创建
  2. 证书被发放给 kubelet
  3. kubelet 取回该证书
  4. kubelet 创建一个合适的 kubeconfig,其中包含密钥和已签名的证书
  5. kubelet 开始正常操作
  6. 可选地,如果配置了,kubelet 在证书接近于过期时自动请求更新证书
  7. 更新的证书被批复并发放;取决于配置,这一过程可能是自动的或者手动完成

 

kubelet 首次启动通过加载 bootstrap.kubeconfig 中的用户 Token 和 apiserver CA 证书发起首次 CSR 请求,这个 Token 被预先内置在 apiserver 节点的 token.csv 中,其身份为 kubelet-bootstrap 用户和 system:bootstrappers 用户组;想要首次 CSR 请求能成功,则需要先将 kubelet-bootstrap 用户和 system:node-bootstrapper 内置 ClusterRole 绑定;

对于首次 CSR 请求可以手动签发,也可以将 system:bootstrappers 用户组与 approve-node-client-csr ClusterRole 绑定实现自动签发(1.8 之前这个 ClusterRole 需要手动创建,1.8 后 apiserver 自动创建,并更名为 system:certificates.k8s.io:certificatesigningrequests:nodeclient)

默认签署的的证书只有 1 年有效期,如果想要调整证书有效期可以通过设置 kube-controller-manager 的 --experimental-cluster-signing-duration 参数实现,该参数默认值为 8760h0m0s

对于证书轮换,需要通过协调两个方面实现;第一,想要 kubelet 在证书到期后自动发起续期请求,则需要在 kubelet 启动时增加 --feature-gates=RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true 来实现;第二,想要让 controller manager 自动批准续签的 CSR 请求需要在 controller manager 启动时增加 --feature-gates=RotateKubeletServerCertificate=true 参数,并绑定对应的 RBAC 规则;同时需要注意的是 1.7 版本的 kubelet 自动续签后需要手动重启 kubelet 以使其重新加载新证书,而 1.8 后只需要在 kublet 启动时附带 --rotate-certificates 选项就会自动重新加载新证书

 

posted on 2022-12-06 15:45  BetterManEddy  阅读(160)  评论(0)    收藏  举报