版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/M2l0ZgSsVc7r69eFdTj/article/details/79752981
kubeadm作为Kubernetes官方提供的集群部署管理工具,采用“一键式”指令进行集群的快速初始化和安装,极大地简化了部署过程,消除了集群安装的痛点。虽然kubeadm目前还不能用于生产,但社区一直在完善kubeadm的功能和稳定性, 刚刚发布的1.10版本中便包含了一系列优化补丁,预计在下一个版本可进入GA,能够用于Kubernetes生产环境的安装部署。本次分享针对kubeadm的基本原理和一些特性进行讲解,和大家一起体会这个安装部署的“最佳实践”设计思想。讲解内容有不足之处,欢迎大家批评指正,共同探讨,谢谢大家!
1. 基本原理
kubeadm init:初始化集群并启动master相关组件,在计划用做master的节点上执行。
kubeadm join:将节点加入上述集群,在计划用做node的节点上执行。
1.1 kubeadm init
如果不需要对集群做任何定制化的配置,直接在master节点上执行该命令即可。该命令的内部流程如下图所示:
在上图的第④步完成的时候,正常情况下,Kubernetes的master的各组件便启动起来了。这里会有一个雷区:由于kubeadm是以static pod的方式启动master各组件,这就涉及到组件容器镜像的拉取。kubeadm默认的镜像源是从Google的gcr.io镜像库,因此需要科学合理地去解决如何访问该镜像库的问题,或者为kubeadm指定可用的第三方镜像库(据个人所知,如下镜像库可用,比如要拉取apiserver的1.9.6版本镜像,地址为:registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver-amd64:v1.9.6)。由于该雷区的存在,可能会使得kubeadm的便捷性大打折扣。
后面的步骤主要是进行master节点的属性设置、为node节点的加入做准备、启动附属组件等。需要注意的是,网络插件的安装也不在kubeadm管理的范围以内,需要根据自己对网络方案的选择来另行安装相应的CNI插件组件。
定制启动配置参数
如果在启动集群的时候希望定制kubeadm本身的参数(比如前文所提到的指定镜像库地址),或者定制master各组件的启动参数,可以通过给kubeadm init命令传入--config来指定本地的配置文件,在该文件中对期望的参数进行设置。这种方式为kubeadm部署集群提供了很大的配置灵活性,但它目前还是一个实验性的功能,后续可能会发生变化。
另外,kubeadm还提供了phase命令,将init过程划分为模块化的各个阶段。如果想对部署过程进行细粒度的控制和干预,达到定制化的目的,则可以考虑使用该命令。phase命令组合起来与init的工作流是一致的,不过目前它也是一个alpha阶段的功能。
1.2 kubeadm join
join的流程就比较简单了,它主要用来启动节点并加入集群。该命令的内部流程如下图所示:
在node节点加入集群时,需要建立双向信任,它分成两部分:discovery(node信任master)和TLS bootstrap(master信任node)。
discovery
node连接master时使用discovery token和CA public key hash,用来获取集群CA证书并完成对master的信任过程,确认所连接的master是所期望的合法master。
除了token方式之外,还可以通过discovery file的方式来完成discovery过程。该文件是一个kubeconfig配置文件,其中只包含了apiserver的地址信息以及集群CA证书数据。
TLS bootstrap
node连接master时携带TLS bootstrap token(通常可以和discovery token使用同一个),用于kubelet向master发起certificate signing request(CSR)时的临时认证,kubeadm默认设置了master自动批准该CSR。当该CSR得到批准后,master便会为kubelet签发客户端证书,用于后续kubelet访问apiserver时的身份认证。
在kubeadm init过程完成后,会打印出包含上述token参数的join命令,形式如下:
kubeadm join --token 33737d.a1aade1da540d7a0 192.168.122.39:6443 --discovery-token-ca-cert-hash sha256:ba72cd9566cb3703337f6c443564a1c917640b86dbd8de2b9c847814af3f737c
如果后面找不到该命令了,可以通过如下命令重新生成相应的命令:
kubeadm token create --print-join-command
其中token为discovery和TLS bootstrap共用的token,192.168.122.39:6443 为apiserver的IP地址和安全端口,discovery-token-ca-cert-hash为CA证书的HASH,用于校验master的证书。
定制启动配置参数
与kubeadm init命令类似,也可以通过传入--config来指定本地配置文件的方式给kubeadm join命令定制启动参数,不再赘述。需要特别说明的是,该配置文件中并不包含kubelet组件的配置,如果要修改kubelet的参数,需要修改kubelet对应的系统服务文件,位置一般在/etc/systemd/system/kubelet.service.d/10-kubeadm.conf。
2. 让安全配置更简便
扫描二维码关注公众号,回复:
5256265 查看本文章
Kubernetes提供多种安全认证机制,为了对系统各组件间的通信进行加密,一般采用TLS进行双向认证,从前面的解析也已经可以零星的看到TLS和证书的影子。要部署一个TLS安全的Kubernetes集群,就需要生成并组织好CA、密钥、证书等一系列文件,并对Kubernetes组件的相关参数进行正确设置,而这些文件和参数数量繁多,稍不注意便容易配置错误,导致集群无法正常启动。
kubeadm则把这些细节全部都隐藏起来了,它直接在代码流程中实现相关证书和密钥的生成过程,并为各组件设置对应的安全参数。这种方式使用户不用进行安全相关的任何配置,在无需感知的情况下便可以启动一个通信安全的集群,从而大大简化了集群安全配置,将此处的痛点降低为零。
内置的证书生成流程如下图所示:
注:对于上图中的front proxy,没有在官方文档中找到明确的说明,我的理解应该指的就是kubectl proxy。用户可以通过这个proxy来间接的访问apiserver,因此与它相关的通信也是需要进行加密认证的。
kubeadm安装完集群后,生成的部分证书和密钥文件如下图所示。图中未显示etcd相关的证书,为etcd生成证书的功能是在1.10版本实现的。
3. self-hosting模式
使用self-hosting模式的优点在于利用了Kubernetes原生对象的特性,使集群master组件的管理、升级、回滚、高可用配置等等更加方便。注意,目前self-hosting模式的实现也有其显著的缺点:当master节点重启后,这些组件无法自行启动。这个缺点以及其他可能的限制会在以后的版本中逐步得到解决。
在self-hosting模式下,master组件是以DaemonSet对象来管理的。self-hosting模式的启动过程如下图所示(该图摘自社区@luxas的讲稿):
该流程描述如下:
通过feature gate启用该模式;
读取master组件在本地对应的static pod manifests(即Pod配置文件);
根据上述文件生成对应的DaemonSet配置文件;
创建DaemonSet资源对象,等待Pod启动;(在这里当apiserver Pod启动后会尝试绑定到6443端口,由于static pod的apiserver已经绑定对应的端口,因此DaemonSet的Pod会一直处于Crash Loopbackoff状态,直至后面的步骤完成)
删除原来的静态Pod配置文件,kubelet随之删除对应的静态Pod;
DaemonSet形式的master组件接管集群。
4. 如何支持HA
其思路如下图所示(该图摘自社区@luxas的讲稿):
主要步骤:
首先建立一个HA的etcd集群;
在首个master节点上使用kubeadm init启动;
将首master节点上的证书等文件拷贝至其他master节点;
在其他master节点使用kubeadm init启动;
为master节点建立LB;
将node节点加入集群。
至于kubeadm原生支持HA的设计方案参见:https://github.com/kubernetes/community/pull/1707 ,该方案还在review阶段,有兴趣的朋友可以阅读一下。
5. 集群升级
首先可以通过kubeadm upgrade plan命令查看升级计划,该命令会输出可升级的最新目标版本。
在上图中可以看到可升级的1.9系列最新版本为1.9.6。需要注意的有两点:1. 要执行升级,需要先将kubeadm升级到对应的版本;2. kubeadm并不负责kubelet的升级,需要在升级完master组件后,手工对kubelet进行升级。
在上图中可以看到可升级的最新稳定版本为1.10.0。注意点同上。
根据上面的结果以及自己的升级需求,选择相应的目标版本,执行kubeadm upgrade apply [version]即可启动升级过程。由于暂时未在个人环境上进行升级,这里就不贴出升级执行过程及结果了,大家可以在自己的环境上进行实验。
补充:
大家如果想实践kubeadm的功能但又受困于网络等问题的话,可以访问Play with Kubernetes(https://labs.play-with-k8s.com/)来进行体验,个人感觉非常好用。目前它的kubeadm版本是1.8.4,默认部署的Kubernetes版本是1.8.10。由于该环境是基于Docker-in-Docker来实现的,因此在其节点主机上的体验和实际的主机会有所不同。该实验环境是社区第三方提供的,因此版本也会有所滞后。
Q&A
Q:你们使用的网络插件是?A:我们使用的是中兴通讯自研的网络插件Knitter,该插件可以原生支持多网络平面,适合NFV的场景。
Q:kubeadm可以指定仓库地址,不然在国内就得先注入镜像,你可以试试。A:对的,在分享中关于雷区的说明中有提到可以为kubeadm指定可用的第三方镜像库,需要在启动参数中进行设置。
Q:一定要使用etcd吗,可以用其他的数据库代替吗?A:目前Kubernetes只支持使用etcd,在大约两年前,社区有关于支持Consul的讨论,不过后来不了了之。
Q:etcd默认有做故障恢复吗,如果没有,有没有好的方案?A:由kubeadm启动的etcd应该是没有做故障恢复,个人理解可以通过建立外部etcd高可用集群的方式达到目的。
Q:knitter能描述一下吗,跟Calico、Flannel有什么区别呢?你们有测试过多高的负载?A:knitter已经开源,可以在其项目地址查看其说明:https://github.com/ZTE/Knitter。不过由于刚刚开源不久,上面的文档还不是特别完善,敬请保持关注。
Q:CA证书过期怎么处理?A:kubeadm创建的CA证书默认的有效期是10年,一般情况下不需要考虑CA证书过期问题。不过apiserver的证书有效期默认的是1年,这个需要考虑过期问题。我在1.9中提过一个PR,在升级集群的时候,如果发现apiserver的证书到期时间小于180天,会重新生成其证书。
Q:我看过kubelet默认有主动注册的选项,如果提供证书密钥应该就不需要使用kubeadm join?A:是的,不过这个前提就是像你所提到的,需要它已经有相应的证书密钥,如果不使用kubeadm join的话,就需要手动去为它创建证书和密钥,可能还需要一些其他配置,过程比较繁琐。所以如果集群是由kubeadm来管理的话,还是建议使用kubeadm join来加入。
Q:kubeadm join使用的token是不是有时效的?A:对,我记得这个时效应该是24小时,如果超过时效,可以使用kubeadm token create来重新生成一个token。
Q:kubectl get daemonset -o wide --all-namespaces可以查到kube-apiserver-master的是self-hosting模式吗?A:如果通过该命令可以查到,那应该就是了。kubeadm在这些DaemonSet的名字中统一加了“self-hosted-”前缀。
Kubernetes零基础进阶培训
4月20日正式上课,点击阅读原文链接即可报名。