kubernetes二进宫系列——Kubernetes TLS BootStrapping流程引导分析

目录

Kubernetes TLS bootstrapping流程引导分析

一、TLS bootstrapping 简介

二、TLS bootstrapping 相关术语

2.1、kubelet server

2.2、CSR请求类型

2.3、KubernetesTLS与RBAC认证

2.4、证书及配置文件作用

三、kubelet初始化流程

四、TLS bootstrapping引导程序初始化流程


Kubernetes TLS bootstrapping流程引导分析

       该文章历时一周左右,通过研习多篇博客博文以及官方文档,加上自身学习总结,在原有内容基础上添加部分个人理解、详细注解、配置内容、结合实际生产区别输出,如有理解错误的地方,麻烦指出交流。

一、TLS bootstrapping 简介

在Kubernetes集群中,工作程序节点上的组件kubelet和kube-proxy需要与Kubernetes主组件(特别是kube-apiserver)进行通信。为了确保通信保持私密性而不受到干扰,并确保群集的每个组件都在与另一个受信任的组件通信,我们强烈建议在节点上使用客户端TLS证书。

引导这些组件通信的正常过程,尤其是需要证书的工作程序节点,以便它们可以与kube-apiserver安全通信,这是一个具有挑战性的过程,因为它通常不在Kubernetes的范围内,并且需要大量的额外工作。反过来,这可能使初始化或扩展群集变得颇具挑战性。为了简化流程,从版本1.4开始,Kubernetes引入了证书请求和签名API来简化流程。目前主要用于kubelet,kube-proxy还是由我们统一颁发一个证书。

当集群开启了TLS认证后,每个节点的kubelet组件都要使用由apiserver使用的CA签发的有效证书才能与apiserver通讯;此时如果节点多起来,为每个节点单独签署证书将是一件非常繁琐的事情;TLSbootstrapping功能就是让kubelet先使用一个预定的低权限用户连接到apiserver,然后向apiserver申请证书,kubelet的证书由apiserver动态签署;在配合RBAC授权模型下的工作流程大致如下所示:

 

二、TLS bootstrapping 相关术语

2.1、kubelet server

官方TLSbootstrapping文档中多次提到过kubeletserver这个东西;在经过翻阅大量文档以及TLSbootstrapping设计文档后得出,kubeletserver指的应该是kubelet的10250端口

kubelet组件在工作时,采用主动的查询机制,即定期请求apiserver获取自己所应当处理的任务,如哪些pod分配到了自己身上,从而去处理这些任务;同时kubelet自己还会暴露出两个本身api的端口,用于将自己本身的私有api暴露出去,这两个端口分别是10250与10255;对于10250端口,kubelet会在其上采用TLS加密以提供适当的鉴权功能;对于10255端口,kubelet会以只读形式暴露组件本身的私有api,并且不做鉴权处理

总结一下,就是说kubelet上实际上有两个地方用到证书,一个是用于与APIserver通讯所用到的证书,另一个是kubelet的10250私有api端口需要用到的证书

2.2、CSR请求类型

kubelet发起的CSR(证书签名请求)请求都是由controllermanager来做实际签署的,对于controllermanager来说,TLSbootstrapping下kubelet发起的CSR请求大致分为以下三种

  • nodeclient:kubelet以O=system:nodesCN=system:node:(nodename)形式发起的CSR请求
  • selfnodeclient:kubeletclientrenew自己的证书发起的CSR请求(与上一个证书就有相同的O和CN)
  • selfnodeserver:kubeletserverrenew自己的证书发起的CSR请求

nodeclient类型的CSR仅在第一次启动时会产生,selfnodeclient类型的CSR请求实际上就是kubeletrenew自己作为client跟apiserver通讯时使用的证书产生的,selfnodeserver类型的CSR请求则是kubelet首次申请或后续renew自己的10250api端口证书时产生的。

2.3、KubernetesTLS与RBAC认证

TLS作用:众所周知TLS的作用就是对通讯加密,防止中间人窃听;同时如果证书不信任的话根本就无法与apiserver建立连接,更不用提有没有权限向apiserver请求指定内容

RBAC作用:当TLS解决了通讯问题后,那么权限问题就应由RBAC解决;RBAC中规定了一个用户或者用户组(subject)具有请求哪些api的权限;在配合TLS加密的时候,实际上apiserver读取客户端证书的CN字段作为用户名,读取O字段作为用户组

从以上两点上可以总结出两点:第一,想要与apiserver通讯就必须采用由apiserverCA签发的证书,这样才能形成信任关系,建立TLS连接;第二,可以通过证书的CN、O字段来提供RBAC所需的用户与用户组。

2.4、证书及配置文件作用

token.csv

该文件为一个用户的描述文件,基本格式为 Token,用户名,UID,用户组;这个文件在 apiserver 启动时被 apiserver 加载,然后就相当于在集群内创建了一个这个用户;接下来就可以用 RBAC 给他授权;持有这个用户 Token 的组件访问 apiserver 的时候,apiserver 根据 RBAC 定义的该用户创建上述配置文件中token文件:

c47ffb939f5ca36231d9e3121a252940,kubelet-bootstrap,10001,"system:node-bootstrapper"

对应的系统的

kubectl get clusterrole -A | grep boot
NAME
:system:node-bootstrapper

kubectl describe clusterrole system:node-bootstrapper
Name:        system:node-bootstrapper
Labels:      kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:  [create get list watch]

kubectl get ClusterRoleBinding –A
name
:kubeadm:kubelet-bootstrap                             
role:ClusterRole/system:node-bootstrapper

kubectl describe ClusterRoleBinding kubeadm:kubelet-bootstrap
Name: kubeadm:kubelet-bootstrap
Role:Kind:  ClusterRole
Role:Name:  system:node-bootstrapper
Group
: system:bootstrappers:kubeadm:default-node-token

bootstarp.kubeconfig

该文件中内置了 token.csv 中用户的 Token,以及 apiserver CA 证书;kubelet 首次启动会加载此文件,使用 apiserver CA 证书建立与 apiserver 的 TLS 通讯,使用其中的用户 Token 作为身份标识像 apiserver 发起 CSR 请求

kubelet-client.crt

该文件在 kubelet 完成 TLS bootstrapping 后生成,此证书是由 controller manager 签署的,此后 kubelet 将会加载该证书,用于与 apiserver 建立 TLS 通讯,同时使用该证书的 CN 字段作为用户名,O 字段作为用户组向 apiserver 发起其他请求

kubelet.crt

该文件在 kubelet 完成 TLS bootstrapping 后并且没有配置 --feature-gates=RotateKubeletServerCertificate=true 时才会生成;这种情况下该文件为一个独立于 apiserver CA 的自签 CA 证书,有效期为 1 年;被用作 kubelet 10250 api 端口

kubelet-server.crt

该文件在 kubelet 完成 TLS bootstrapping 后并且配置了 --feature-gates=RotateKubeletServerCertificate=true 时才会生成;这种情况下该证书由 apiserver CA 签署,默认有效期同样是 1 年,被用作 kubelet 10250 api 端口鉴权

kubelet-client-current.pem

这是一个软连接文件,当 kubelet 配置了 --feature-gates=RotateKubeletClientCertificate=true 选项后,会在证书总有效期的 70%~90% 的时间内发起续期请求,请求被批准后会生成一个 kubelet-client-时间戳.pem;kubelet-client-current.pem 文件则始终软连接到最新的真实证书文件,除首次启动外,kubelet 一直会使用这个证书同 apiserver 通讯

kubelet-server-current.pem

同样是一个软连接文件,当 kubelet 配置了 --feature-gates=RotateKubeletServerCertificate=true 选项后,会在证书总有效期的 70%~90% 的时间内发起续期请求,请求被批准后会生成一个 kubelet-server-时间戳.pem;kubelet-server-current.pem 文件则始终软连接到最新的真实证书文件,该文件将会一直被用于 kubelet 10250 api 端口鉴权

三、kubelet初始化流程

该流程主要梳理了token、secret、bootstrap config、clusterrole、clusterrolebinding联系。

1、在集群内创建特定的 Bootstrap Token Secret,该 Secret 将替代以前的 token.csv 内置用户声明文件。

   kubeadm在该过程中做了如下操作:执行命令kubeadm token create [token]创建类似token.csv内容,可以通过kubeadm token list查看;然后将token加密存储在一个secret对象中供集群调用kubectl get secret -n kube-system。可以通过解密查看secret密文echo 'xxxxxxxxxxxx==' | base64 --decode                                                                                                                                                              

2、在集群内创建首次 TLS Bootstrap 申请证书的 ClusterRole、后续 renew Kubelet client/server 的 ClusterRole,以及其相关对应的 ClusterRoleBinding;并绑定到对应的组或用户

clusterrole为一组不受namespace限制的权限的集合,目的是创建具有申请证书权限的clusterrole角色,再通过clusterrolebind将token中指定的用户和用户组绑定到这个角色中,这样的话token的用户和用户组也可以申请证书认证了。

授权kubelet-bootstrap用户允许请求证书

kubectl create clusterrolebinding kubelet-bootstrap\

--clusterrole=system:node-bootstrapper\

--user=kubelet-bootstrap

3、调整kube-apiserver和 Controller Manager 配置,以使其能自动签署相关证书和自动清理过期的 TLS Bootstrapping Token

3.1、kube-apiserver使用static token或者bootstrap token:

    使用static token需要指定--token-auth-file文件

    使用bootstrap token需要开启对应功能: --enable-bootstrap-token-auth=true

3.2、kube-controller-manager需要指定和kube-apiserver相同的--client-ca-file,同时需要指定--cluster-signing-cert-file和--cluster-signing-key-file用户签发kubelet证书;

kube-controller-manager自动approve需要为system:bootstrappers用户组和system:nodes用户组绑定对应的角色:

system:certificates.k8s.io:certificatesigningrequests:nodeclient,system:certificates.k8s.io:certificatesigningrequests:selfnodeclient;

同时csr的签发者为kubernetes.io/kube-apiserver-client-kubelet

4、生成特定的包含 TLS Bootstrapping Token 的 bootstrap.kubeconfig 以供 kubelet 启动时使用

4.1、二进制生成bootstrap.kubeconfig文件

KUBE_APISERVER="https://172.10.10.129:6443"#apiserverIP:PORT

TOKEN="c47ffb93xxxxx231d9e3121a252940"#与token.csv里保持一致

kubectlconfigset-clusterkubernetes\

--certificate-authority=/opt/kubernetes/ssl/ca.pem\

--embed-certs=true\

--server=${KUBE_APISERVER}\

--kubeconfig=bootstrap.kubeconfig

kubectlconfigset-credentials"kubelet-bootstrap"\

--token=${TOKEN}\

--kubeconfig=bootstrap.kubeconfig

kubectlconfigset-contextdefault\

--cluster=kubernetes\

--user="kubelet-bootstrap"\

--kubeconfig=bootstrap.kubeconfig

kubectlconfiguse-contextdefault--kubeconfig=bootstrap.kubeconfig

4.2、kubeadm生成bootstrap.kubeconfig文件

apiVersion:v1

kind:Config

clusters:

-cluster:

certificate-authority:/var/lib/kubernetes/ca.pem

server: 172.10.10.129:6443

name:bootstrap

contexts:

-context:

cluster:bootstrap

user:kubelet-bootstrap

name:bootstrap

current-context:bootstrap

preferences:{}

users:

-name:kubelet-bootstrap

user:

token:07401b.f395accd246ae52d

5、调整 Kubelet 配置,使其首次启动加载bootstrap.kubeconfig并使用其中的 TLS Bootstrapping Token 完成首次证书申请

[Service]

Environment="KUBELET_KUBECONFIG_ARGS=

--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf

--kubeconfig=/etc/kubernetes/kubelet.conf"

6、证书被 Controller Manager 签署,成功下发,Kubelet自动重载完成引导流程

7、后续 Kubelet 自动 renew 相关证书

8、可选的: 集群搭建成功后立即清除 Bootstrap Token Secret,或等待 Controller Manager 待其过期后删除,以防止被恶意利用

 

四、TLS bootstrapping引导程序初始化流程

细节参见官方文档:https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/

初始化流程:

  1. kubelet启动
  2. 查询自己有没有证书,有证书直接启动,如果没有kubeconfig文件
  3. kubelet根据启动参数配置路径寻找bootstrap-kubeconfig文件
  4. 读取bootstrap-kubeconfig中的apiserver地址和bootstrap token
    在 apiserver 配置中指定了一个 token.csv 文件,该文件中是一个预设的用户配置;同时该用户的 Token 和 apiserver 的 CA 证书被写入了 kubelet 所使用的bootstrap.kubeconfig 配置文件中;这样在首次请求时,kubelet 使用 bootstrap.kubeconfig 中的 apiserver CA 证书来与 apiserver 建立 TLS 通讯,使用 bootstrap.kubeconfig 中的用户 Token 来向 apiserver 声明自己的 RBAC 授权身份
  5. 使用bootstrap token作为凭证访问apiserver
  6. 该token有权限去创建和获取证书签名请求(CSR) —— bootstrap token的命名具有特定的格式,可以被apiserver识别,username为system:bootstrap:<token id>,属于system:bootstrappers用户组,该用户组需要绑定system:node-bootstrapper的clusterrole,以便可以拥有创建csr的权限
  7. kubelet为自己创建一个CSR,签发者(csr.Spec.SignerName)为kubernetes.io/kube-apiserver-client-kubelet
  8. CSR被自动或者手动approved
    4.1、controller-manager自动approve,需要system:bootstrappers用户组绑定system:certificates.k8s.io:certificatesigningrequests:nodeclient的clusterrole。controller-manager的CSRApprovingController会通过SubjectAccessReview API的方式来校验csr中的username和group是否有对应权限,同时检查签发者是否为kubernetes.io/kube-apiserver-client-kubelet
    4.2、通过kubectl等手动approve
  9. kubelet证书在approved之后由controller-manager创建
  10. controller-manager将证书更新到csr的status字段中
  11. kubelet从apiserver获取证书
  12. kubelet根据取回来的key和证书生成对应的kubeconfig
  13. kubelet使用生成的kubeconfig开始正常工作
  14. 如果配置了证书自动续期,则kubelet会在证书快过期的时候利用旧的kubeconfig来续约旧的证书
  15. 续约的证书被自动或者手动approved签发 —— 自动approve需要system:nodes用户组绑定system:certificates.k8s.io:certificatesigningrequests:selfnodeclient的clusterrole(system:nodes是kubelet之前申请的证书的group,即证书的组织O为system:nodes)
  16. 涉及的用户,用户组,权限
  17. bootstrap token的username为system:bootstrap:<token id>
  18. system:bootstrappers用户组,bootstrap token都属于该用户组
  19. clusterrole system:node-bootstrapper,拥有创建和获取CSR的权限,system:bootstrappers用户组一般需要绑定该role
  20. clusterrole system:certificates.k8s.io:certificatesigningrequests:nodeclient,属于该group的user申请的CSR可以被controller-manager自动approve,system:bootstrappers用户组一般需要绑定该role
  21. system:nodes用户组,kubelet从apiserver获取的证书一般都属于该用户组,即证书的组织O为system:nodes
  22. clusterrole system:certificates.k8s.io:certificatesigningrequests:selfnodeclient,属于该group的user在证书续期时可以被controller-manager自动approve,system:nodes用户组一般需要绑定该role

 

 

参考文档:

https://blog.csdn.net/paopaohll/article/details/89022920

https://mritd.com/2018/08/28/kubernetes-tls-bootstrapping-with-bootstrap-token/

https://cloud.tencent.com/developer/article/1656007

https://mritd.com/2018/01/07/kubernetes-tls-bootstrapping-note/

https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

情绪零碎碎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值