kubeadm init原理
在k8s master中,会先启动一个kubelet,控制面组件通过kubelet static pod特性启动
初始化一个工作流执行如下阶段工作: 也可以使用 kubeadm init phase 分阶段执行
// cmd/kubeadm/app/cmd/init.go-NewCmdInit()...// initialize the workflow runner with the list of phases// 1.环境检查initRunner.AppendPhase(phases.NewPreflightPhase())// 2.配置并启动kubeletinitRunner.AppendPhase(phases.NewKubeletStartPhase()) // 3.证书生成initRunner.AppendPhase(phases.NewCertsPhase()) // 4.kubeconfig文件生成initRunner.AppendPhase(phases.NewKubeConfigPhase()) // 5.控制面组件yaml生成initRunner.AppendPhase(phases.NewControlPlanePhase())// 6.etcd组件yaml生成initRunner.AppendPhase(phases.NewEtcdPhase()) // 7.等待控制面组件运行initRunner.AppendPhase(phases.NewWaitControlPlanePhase())// 8.上传配置initRunner.AppendPhase(phases.NewUploadConfigPhase())// 9.上传CA证书/私钥 initRunner.AppendPhase(phases.NewUploadCertsPhase())// 10.master节点打污点initRunner.AppendPhase(phases.NewMarkControlPlanePhase())// 11.生成bootstrap token和ca证书configmap initRunner.AppendPhase(phases.NewBootstrapTokenPhase())// 12.更换kubelet证书 initRunner.AppendPhase(phases.NewKubeletFinalizePhase())// 13.安装AddoninitRunner.AppendPhase(phases.NewAddonPhase()) ...
1、Preflight phase
相当于执行命令 kubeadm init phase preflight --config kubeadm-config.yml,首先要做的是一系列的检查工作,以确定这台机器可以用来部署 Kubernetes。
这阶段还做了拉取kubeadm部署所需的镜像
1、CPU 控制面至少需要2CPU
2、内存至少需要1700M
3、版本检查,kubeadm 和 kubernetes 的版本是否匹配
4、确认firewalld没有开启
5、确认localAPedpoint 绑定端口6443没有被占用
6、确认schedler端口10259
7、确认controller-manager端口10257
8、确认/etc/kubernetes/manifests/目录下静态pod文件:kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml
9、etcd外部或者local检查
10、容器运行时,内核参数检查 /proc/sys/net/bridge/bridge-nf-call-iptables, /proc/sys/net/ipv4/ip_forward,swap检查, contrack ip iptables mount nsenter kublet以及10250检查
11、拉取kubeadm部署所需的镜像
2、配置并启动kubelet
创建kubelet启动所需的配置文件,并启动kubeletkubeadm使用了systemd的方式部署启动kubelet;# systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node AgentLoaded: loaded (/usr/lib/systemd/system/kubelet.service; disabled; vendor preset: enabled)Drop-In: /usr/lib/systemd/system/kubelet.service.d└─10-kubeadm.confActive: active (running) ...
为什么master上还需要配置启动kubelet呢?
因为kubeadm init的时候需要将master控制面组件:
kube-apiserver、kube-controller-manager、kube-scheduler、etcd以pod的方式运行起来,
而现在又没有在运行的控制面以及kubelet,kubeadm的做法是,给master节点上也安装启动kubelet,
然后使用kubelet static pod特性将master控制面组件运行起来。
3、Certs phase
kubeadm 会生成 kubernetes对外提供服务所需的各种证书和对应的目录:
(default /etc/kubernetes/pki):- ca.crt- ca.key- apiserver.crt- apiserver.key- apiserver-kubelet-client.crt- apiserver-kubelet-client.key- apiserver-etcd-client.crt- apiserver-etcd-client.key- etcd/ca.crt- etcd/ca.key- etcd/server.crt- etcd/server.key- etcd/peer.crt- etcd/peer.key- etcd/healthcheck-client.crt- etcd/healthcheck-client.key- sa.pub- sa.key- front-proxy-ca.crt- front-proxy-ca.key- front-proxy-client.crt- front-proxy-client.key
4、kubeconfig配置生成
即生成master节点上:kube-controller-manager、kube-scheduler、kubelet组件等访问kube-apiserver的kubeconfig文件,
(default /etc/kubernetes):- admin.conf- kubelet.conf- scheduler.conf- controller-manager.confmaster上的kubelet启动后,使用kubeadm生成的kubeconfig与kube-apiserver进行通信,
通过证书轮换,向kube-apiserver申请新的证书,由kube-controller-manager签发证书返回。注意:这里master上的kubelet不会使用TLS bootstrap特性。
5、控制面组件yaml文件生成
即kubeadm为4个控制面组件kube-apiserver、kube-controller-manager、kube-scheduler生成pod yaml文件,放到/etc/kubernetes/manifests目录下,然后kubelet会根据static pod特性,使用pod的方式将它们部署起来;
# ls /etc/kubernetes/manifests
kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml
- etcd组件yaml文件生成(使用local etcd时才有)
如果使用 local 配置,而不是 External,则这里会创建静态 Pod manifest yaml 文件即kubeadm为etcd组件生成pod yaml文件,放到/etc/kubernetes/manifests目录下,
然后kubelet会根据static pod特性,使用pod的方式将etcd部署起来;
7、等待控制面组件运行。kubeadm会不间断检查localhost:6443/healthz这个url,等待master组件完全启动;
8、上传配置
这里会创建2个configmap,都创建在kube-system命名空间下,名称分别是:
kubeadm-config:分别存储着kubeadm的集群配置信息
kubelet-config-xxx(k8s版本):kubelet的配置信息;
9、上传CA证书/私钥。
该步骤默认不执行,通过增加——upload-certs参数启用,
它会将相关的CA证书/私钥加密后作为data,在kube-system命名空间下创建名称为:
kubeadm-certs的secret,给后续的master节点kubeadm join使用,
这样join时可以直接从secret中解密出CA证书/私钥,然后签发其他证书,
而无需手工复制相关CA证书/私钥;kubeadm init执行完成后,会输出一个名称为certificateKey的值,然后在其他master节点join时,
加上--certificate-key参数即可。certificateKey是在添加新的master节点时用来解密kubeadm-certs secret中的证书的秘钥。kubeadm-certs示例如下,其中的证书和私钥均已加密,通过certificateKey解密即可使用:
apiVersion: v1
data:ca.crt: KfdZpEDF1wJfaexXls5...ca.key: VXfm7luIyM3QT+Rd04+...etcd-ca.crt: wwSzqCcltkrP26...etcd-ca.key: gqusZazZLF33Ip...front-proxy-ca.crt: EmfgKP6...front-proxy-ca.key: wKMYSrk...sa.key: pscxeFTGoCFZ6hrE1XK...sa.pub: keey1WPkWdj2TjEb/oM...
kind: Secret
metadata:name: kubeadm-certsnamespace: kube-systemownerReferences:- apiVersion: v1blockOwnerDeletion: truecontroller: truekind: Secretname: bootstrap-token-xxxxxx......
type: Opaque
10、master节点打污点。将该master节点打上污点,不作为计算节点数据面使用;
11、生成bootstrap token和ca证书configmap。
kubeadm会为该k8s集群生成一个bootstrap token并打印出来,
后续的node节点通过这个token,通过kubeadm join命令,
使用TLS bootstrap特性即可加入到这个k8s集群中这里还包括了为该token创建RBAC的各个对象,赋予该token创建CSR证书签名请求的权限、
自动批复CSR请求的权限、轮换证书请求自动批复的权限等kubeadm init执行完成后,也可以通过以下命令获取token: kubeadm token listkubeadm还会将ca.crt、apiserver url等信息,保存到一个configmap当中,给后续加入该k8s集群的node节点使用,configmap名称为cluster-info,位于kube-public命名空间下;
# kubectl get configmap -n kube-public -o yaml cluster-info
apiVersion: v1
data:kubeconfig: |apiVersion: v1clusters:- cluster:certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0F...server: https://192.168.1.10:6443name: ""contexts: nullcurrent-context: ""kind: Configpreferences: {}users: null
kind: ConfigMap
metadata:
12、更换kubelet证书
master上的kubelet启动后,使用kubeadm生成的kubeconfig与kube-apiserver进行通信,
通过证书轮换,向kube-apiserver申请新的证书,由kube-controller-manager签发证书返回。而这里说的更换kubelet证书,其实就是将kubelet与kube-apiserver通信的kubeconfig文件中的证书替换成由kube-controller-manager签发返回的证书,即将kubeconfig文件中的client-certificate与
client-key的值都替换成/var/lib/kubelet/pki/kubelet-client-current.pem;apiVersion: v1
clusters:
- cluster:certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0F...server: https://192.168.1.10:6443name: test-cluster
contexts:
- context:cluster: test-clusteruser: system:node:test-cluster-master-1name: system:node:test-cluster-master-1
current-context: system:node:test-cluster-master-1
kind: Config
preferences: {}
users:
- name: system:node:test-cluster-master-1user:client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pemclient-key: /var/lib/kubelet/pki/kubelet-client-current.pem
13、安装Addon
安装coredns与kube-proxy,kubeadm init流程结束。