目录

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/

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

  1. 《Kubernetes证书篇:使用TLS bootstrapping简化kubelet证书制作》

    一.背景 Master apiserver启用TLS认证后,Node节点kubelet和kube-proxy要与kube-apiserver进行通信,必须使用CA签发的有效证书才可以,当Node节点很 ...

  2. Kubernetes TLS bootstrapping

    文章目录 what && why? 启动引导过程 TLS 作用 RBAC 作用 kubelet 首次启动流程 手动签发证书 几个重要术语 kubelet server CSR 请求类型 ...

  3. Kubernetes生产实践系列之二十九:Kubernetes基础技术之容器关键技术实践

    一.前言 在文章<Kubernetes生产实践系列之二十八:Kubernetes基础技术之容器关键技术介绍>中,对于Docker容器技术依赖的namespace.cgroup和UnionF ...

  4. 菜鸟学Kubernetes(K8s)系列——(七)关于Kubernetes底层工作原理

    菜鸟学Kubernetes(K8s)系列--(七)关于Kubernetes底层工作原理 Kubernetes系列文章 主要内容 菜鸟学Kubernetes(K8s)系列--(一)关于Pod和Names ...

  5. 容器编排技术 -- Kubernetes kubectl create secret tls 命令详解

    容器编排技术 -- Kubernetes kubectl create secret tls 命令详解 1 create secret tls 2 语法 3 示例 4 Flags create sec ...

  6. Kubernetes生产实践系列之二十二:Service Mesh之在Kubernetes部署Linkerd2进行service mesh

    一.前言 service mesh是为复杂微服务系统提供基础设施服务的方法,支持Kubernetes的service mesh实现包括文章<kubernetes系列之十八:使用helm安装ist ...

  7. 【Kubernetes | Pod 系列】Pod 的基本管理(2)——对 Pod 的查询

    目录 2.2 查看 Pod (1)查看当前名字空间的 Pod 参数说明 (2)查看指定名字空间的 Pod (3)查看所有名字空间的 Pod (4)查看 Pod 详细信息 参数说明 (5)获得一个 Po ...

  8. JAVA网格化服务架构,高级进阶必看 Java服务网格化系列-Kubernetes

    Java开发的前景毋庸置疑,一直处于编程排行榜首位的Java语言,吸引越来越多的年轻人去学习这门有含金量的技术,对于有基础的学习者或者开发者来说,进阶学习更深入的知识对未来的职业发展非常有帮助,然而能 ...

  9. Kubernetes安装系列之coredns安装

    这篇文章整理一下coredns插件的安装与设定方法,本文以脚本的方式进行固化,内容仍然放在github的easypack上. 整体操作 https://blog.csdn.net/liumiaocn/ ...

最新文章

  1. 获取go语言官方文档的两个方法
  2. 过河 2005年NOIP全国联赛提高组(离散化+dp)
  3. 二叉树的先序/中序/后序/层次遍历
  4. *CI框架装载器Loader.php源码分析
  5. python 列表 换行_python基础语法学习——参考Python Crash Course
  6. 实用的it知识学习_怎样能更快更好的学习好书法?分享一些比较实用的理论知识...
  7. Target runtime com.genuitec.runtime.generic.jee60 is not defined.报错解决
  8. [转帖] 启动多个Tomcat 需要修改的端口
  9. A. httpd常见的几个操作
  10. 学习date , clock , hwclork , cal, ls ,cd , pwd, tty, whereis , which ,stat, e
  11. 清华大学刘云浩教授——人工智能打开了潘多拉的盒子吗?
  12. 串口调试助手、网络调试助手
  13. Windows的cmd统计文件行数
  14. java输战舰_什么是最好的战舰AI?
  15. 手把手教你批量下载微博视频
  16. 基于matlab的系统校正,基于MATLAB的控制系统校正_毕业论文
  17. Day06_动态组件_插槽_自定义指令_tabbar案例
  18. Leetcode--Java--340. 至多包含 K 个不同字符的最长子串
  19. mysql插入中文报错处理办法
  20. 在线帮助中心,轻松解决售后服务问题

热门文章

  1. 安装驱动提示文件的哈希值不在指定的目录文件中;需强制禁止驱动签名;在高级启动中强制禁止驱动签名;
  2. 基于opencascade的偏心四棱柱的周身倒角
  3. nmn是科学还是智商税,nmn最新消息
  4. 【软件定义汽车】【操作系统篇】QNX
  5. 解析Linux中的 likely 和 unlikely
  6. CRM项目记录(九)
  7. Web-python+selenium-自动化测试技术-考试系统测试脚本
  8. 异议:“XP应该是老板的最爱,而不是程序员的首选“
  9. Unity Gizmos 绘制 Camera 的 视口、视锥和 FOV
  10. CAN邮箱的自动化配置相对最优解方案