k8s版本v1.23

kubeadm的代码是放在kubernetes/kubernetes下面,github上那个kubernetes/kubeadm不是kubeadm的代码仓库

kubeadm init和kubeadm join --control-plane 源码笔记:

#app:kubernets/cmd/kubeadm/app/kubeadm.go
#kubeadm join --control-plane:添加新的master节点到已有集群
app.Run
  cmd.NewKubeadmCommand #创建kubeadm命令,会添加许多子命令,后面分析init命令和join命令源码流程
	cmds.newJoinData #初始化一些配置和参数以及给默认值  
    cmds.AddCommand(newCmdCertsUtility(out))
	cmds.AddCommand(newCmdCompletion(out, ""))
	cmds.AddCommand(newCmdConfig(out))
	cmds.AddCommand(newCmdInit(out, nil)) #添加init子命令
	cmds.AddCommand(newCmdJoin(out, nil)) #添加join子命令
	cmds.AddCommand(newCmdReset(in, out, nil))
	cmds.AddCommand(newCmdVersion(out))
	cmds.AddCommand(newCmdToken(out, err))
	cmds.AddCommand(upgrade.NewCmdUpgrade(out))
	cmds.AddCommand(alpha.NewCmdAlpha())
	options.AddKubeadmOtherFlags(cmds.PersistentFlags(), &rootfsPath)
	cmds.AddCommand(newCmdKubeConfigUtility(out))
  

#kubeadm join --control-plane流程:这是加入master节点,如果是加入非master节点则简单得多
workflow.NewRunner #创建runner对象,一个runner对象包含依次执行的多个阶段即phase
cmd.newCmdJoin
  cmd.addJoinConfigFlags #添加命令行参数
  cmd.addJoinOtherFlags  #添加命令行参数
  phases.NewPreflightPhase #创建预检操作,可以通过设置参数来忽略预检失败
	phases.runPreflight #就是提前做一些检查,确保node可以成功加入集群,否则报错
	  preflight.RunJoinNodeChecks
		preflight.RunRootCheckOnly   #检查是不是root用户
		preflight.FileAvailableCheck #检查/etc/kubernetes/kubelet.conf是否存在,如果存在就报错
		preflight.FileAvailableCheck #检查/etc/kubernetes/bootstrap-kubelet.conf是否存在,如果存在就报错
		preflight.FileAvailableCheck #检查/etc/kubernetes/pki/ca.crt是否存在,如果存在就报错
	    preflight.FileContentCheck   #如果kubectl使用tsl bootstrapper则检查/proc/sys/net/bridge/bridge-nf-call-ip6tables文件的内容是不是1,不是1就报错
	    preflight.FileContentCheck   #如果kubectl使用tsl bootstrapper则检查/proc/sys/net/ipv6/conf/default/forwarding文件的内容是不是1,不是1就报错
	  phases.checkIfReadyForAdditionalControlPlane #如果节点是作为控制平面加入才执行此函数
												   #1:第一个通过kubeadm创建的master节点执行kubeadm iniit时必须使用--control-plane-endpoint参数
												   #2:如果命令行参数中证书为空,则尝试加载并校验指定目录下的证书和私钥,失败则报错,默认为/etc/kubernetes/pki目录
		certs.SharedCertificateExists              #加载/etc/kubernetes/pki下的证书和私钥公钥,并校验证书和私钥是否有效,是否是支持的类型,否则报错validateCACert
												   #可以通过查看kube-system下叫做kubeadm-config中的certificateDir字段来知晓证书存放路径,因为这是可配置的字段
		  certs.validateCACert			   		   #加载/etc/kubernetes/pki/ca.crt(证书)和/etc/kubernetes/pki/ca.key(证书对应的私钥),只支持ca证书
		  certs.validatePrivatePublicKey   		   #加载/etc/kubernetes/pki/sa.key(私钥)和/etc/kubernetes/pki/sa.pub(公钥),只支持RSA和ECDSA
		  certs.validateCACert			   		   #加载/etc/kubernetes/pki/front-proxy-ca.crt和/etc/kubernetes/pki/front-proxy-ca.key
		  certs.validateCACert			   		   #如果采用stacked模式的etcd而不是外部etcd集群则加载/etc/kubernetes/pki/etcd/ca.crt和/etc/kubernetes/pki/etcd/ca.key
	  preflight.RunInitNodeChecks          	  	   #检查对应的文件是否存在、端口是否开放、cpu或者memory是否足够
		preflight.NumCPUCheck                      #至少要有2个cpu
		preflight.MemCheck.Check                   #至少要有1700m内存
		preflight.KubernetesVersionCheck.Check     #检查k8s和kubeadm版本是否匹配
		preflight.FirewalldCheck.Check             #防火墙是否开启,如果开启防火墙则需保证kubelet所需的10250端口不被屏蔽
		preflight.PortOpenCheck.Check              #检查apiserver端口是否被占用,默认为6443端口
		preflight.PortOpenCheck.Check              #检查kube-scheduler端口是否被占用,默认为10259
		preflight.PortOpenCheck.Check              #检查controller-manager端口是否被占用,默认为10257
		preflight.HTTPProxyCheck.Check             #检查是是直接连接还是通过代理连接
		preflight.FileAvailableCheck.Check         #检查静态pod对应的yaml文件是否存在,默认为/etc/kubernetes/manifests/apiserver.yaml
		preflight.FileAvailableCheck.Check         #检查静态pod对应的yaml文件是否存在,默认为/etc/kubernetes/manifests/kube-scheduler.yaml
		preflight.FileAvailableCheck.Check         #检查静态pod对应的yaml文件是否存在,默认为/etc/kubernetes/manifests/kube-controller-manager.yaml
		preflight.FileAvailableCheck.Check         #检查静态pod对应的yaml文件是否存在,默认为/etc/kubernetes/manifests/etcd.yaml  
		preflight.PortOpenCheck.Check              #如果etcd是stacked模式即不是采用外部etcd集群,则检查etcd所需的2379端口是否被占用
		preflight.PortOpenCheck.Check              #如果etcd是stacked模式即不是采用外部etcd集群,则检查etcd所需的2380端口是否被占用
	    preflight.DirAvailableCheck.Check          #如果etcd是stacked模式即不是采用外部etcd集群,则检查etcd所需的本地目录是否存在,默认为/var/lib/etc
		//etcdctl  --cert=/etc/kubernetes/ssl/etcd/server.crt --key=/etc/kubernetes/ssl/etcd/server.key --cacert=/etc/kubernetes/ssl/etcd/ca.crt  
		preflight.FileExistingCheck.Check          #如果etcd是采用外部etcd集群,则检查对应的etcd ca.key文件是否存在,etcd根证书
		preflight.FileExistingCheck.Check          #如果etcd是采用外部etcd集群,则检查对应的etcd server.crt文件是否存在,服务器证书,验证服务器是否有效
		preflight.FileExistingCheck.Check          #如果etcd是采用外部etcd集群,则检查对应的etcd server.key文件是否存在,服务器证书对应的私钥
	  preflight.RunPullImagesCheck
		preflight.ImagePullCheck.Check             #检查对应的镜像是否存在,如果不存在能否成功拉取,包括apiserver/kube-scheduler/controller-manager/kube-proxy
  phases.NewControlPlanePreparePhase                       #创建控制平面准备阶段
    phases.newControlPlanePrepareDownloadCertsSubphase  
	  phases.runControlPlanePrepareDownloadCertsPhaseLocal #负责在控制平面准备阶段下载证书,以确保控制平面节点具有正确的证书
		phases.bootstrapClient                             #获取tslbootstrap使用的token,然后据此创建一个clientset
														   #就是kubeadm join --token=xxx中指定的token,这个token可以用于tlsbootstrap-token和discovery-token
		certs.DownloadCerts                                #从apiserver下载证书并保存到本地,默认目录为/etc/kubernetes/pki
		  certs.getSecret                                  #从apiserver获取kube-system命名空间下kubeadm-certs的secret,并把其中的证书、私钥、公钥保存到本地,就不用手动复制了
														   #kubeadm-certs是kubeadm自动创建的,具体内容如下:
														   #ca.crt、ca.key、sa.key、sa.pub、front-proxy-ca.crt、front-proxy-ca.key、etcd/ca.crt、etcd/ca.key
	phases.newControlPlanePrepareCertsSubphase
	  phases.runControlPlanePrepareCertsPhaseLocal 		   #这一块是证书,至于证书、私钥、公钥和代码里的CA、certs是什么关系不太清楚,这一块有些地方可能理解有偏差								 
		certs.CreatePKIAssets                              #创建pki相关证书:就是先尝试加载,如果加载失败就创建自签证书(比如如果没有kubeadm-certs secret就拿不到任何证书)
		  certs.GetDefaultCertList                         #获取需要创建的证书集合,可以查看/etc/kubernetes/pki目录下有哪些证书或者私钥,有些是可以从secret获取或者创建的。
													       #ca, apiserver、apiserver-kubelet-client、front-proxy-ca、front-proxy-client、apiserver-etcd-client
														   #etcd/ca、etcd/server、etcd/peer、etcd/healthcheck-client
		  certs.CreateTree
		    pkiutil.TryLoadCertFromDisk                    #尝试加载指定目录下的证书,默认/etc/kubernetes/pki												  	 
		    pkiutil.NewCertificateAuthority                #如果加载失败则创建自签证书(有疑问:如果拿不到ca.crt怎么办?是不是--token指定的token在这里有用?应该是哪个地方我漏看了)
			  certs.NewSelfSignedCACert                    #创建自签名ca证书
            certs.writeCertificateAuthorityFilesIfNotExist #把创建的ca证书写入磁盘,默认路径:/etc/kubernetes/pki
		    certs.KubeadmCert.CreateFromCA                 #从ca证书创建叶子证书 (/etc/kuberntes/pki目录下哪些是ca证书,哪些是叶子证书,这一块还不懂)
		  certs.CreateServiceAccountKeyAndPublicKeyFiles   #先尝试加载/etc/kubernetes/pki/sa.key,加载失败再尝试创建sa.key,创建成功后再写入磁盘
	phases.newControlPlanePrepareKubeconfigSubphase
	  phases.runControlPlanePrepareKubeconfigPhaseLocal
	    kubeconfig.CreateJoinControlPlaneKubeConfigFiles   #创建三个文件:管理员用的admin.conf、kube-scheduler用的scheduler.conf、controller-manager用的controller-manager.conf
														   #貌似这三个文件都是一样的,kubelet.conf由kublet自己的TLSbootstrap进程生成
	phases.newControlPlanePrepareControlPlaneSubphase
      phases.runControlPlanePrepareControlPlaneSubphase 
		controlplane.CreateStaticPodFiles 				   #创建apiserver/scheduler/controllermanager静态pod文件:读取模板文件,生成pod对象,根据参数修改字段,然后写入磁盘
  phases.NewCheckEtcdPhase                                 #创建检查etcd
	phases.runCheckEtcdPhase
	  joinData.ClientSet                                   #根据admin.conf创建一个clientset
	  etcd.CheckLocalEtcdClusterStatus                     #检查etcd集群是否健康,并创建一个etcdclient
		etcd.NewFromCluster                                #创建一个etcdclient
		  etcd.getEtcdEndpoints                            #获取已有etcd集群所有端点
														   #首先通过标签获取所有kube-system下面含有标签component=etcd以及tier=control-plane的节点
														   #然后从etcd的annotation中获取kubeadm.kubernetes.io/etcd.advertise-client-urls,这个字段记录了etcd的地址
														   #因为这个etcd是静态pod,是kubeadm自动生成的,所以肯定会含有指定标签和指定注释字段
		  etcd.New                                         #创建etcdclient
		etcd.CheckClusterHealth                            #遍历etcd集群所有etcd节点,然后检查状态是否有错,若无则一切良好
		  etcd.getClusterStatus                      
  phases.NewKubeletStartPhase
    phases.runKubeletStartJoinPhase                        #启动和执行kubeletTLS引导过程,完成后本节点节点将加入集群
	  phases.getKubeletStartJoinData                       #从启动参数中获取tlsbootstrap配置文件
	  phases.WriteToDisk                                   #把tlsbootstrap配置文件的内容写入磁盘上的/etc/kubernetes/bootstrap-kubelet.conf文件
	  kubelet.GetNodeNameAndHostname                       #获取本机hostname
	  clientset.CoreV1().Nodes().Get                       #查看本机hostname对应的节点是否已经存在了
	  kubelet.WriteConfigToDisk                            #把kubelet config信息写入磁盘上的/var/lib/kubelet/config.yaml,以便kubelet可以启动
	  kubelet.TryStartKubelet                              #尝试通过sysd来启动kubelet服务
	  apiclient.NewKubeWaiter                              #创建kubeWaiter对象,可以用来等待kublet执行完毕
														   #kubelet启动需要apiserver,所以需要准备好和apiserver通信的文件后才能启动成功
														   #bootstraper/token/admin.conf这一块到底用的哪个启动文件还不是很清楚
													       #貌似kublet启动过程中会自动生成/etc/kubernetes/kubelet.conf
      phases.waitForTLSBootstrappedClient                  #等待kubelet TLSbootstrapper启动完成,如果启动完成则/etc/kubernetes/kubelet.conf文件会被创建
	    kubeconfig.ClientSetFromFile                       #如果从/etc/kubernetes/kubelet.conf文件创建clientset成功,那么就说明kubeletTLSbootstrapper启动好了
	  apiclient.KubeWaiter.WaitForKubeletAndFunc           #访问http://localhost:10248/healthz来查看kubelet服务是否启动成功
	  kubelet.ClientSetFromFile                            #kubelet通过tlsbootstraper启动后会貌似会自动生成/etc/kubernetes/kubelet.conf(不确定),然后据此创建clientset
      patchnode.AnnotateCRISocket						   #给节点对象添加注释供以后提取信息:kubeadm.alpha.kubernetes.io/cri-socket=/var/run/containerd/containerd.sock
	  os.Remove                                            #删除bootstraper文件即/etc/kubernetes/bootstrap-kubelet.conf文件
  phases.NewControlPlaneJoinPhase  
    phases.newEtcdLocalSubphase
	  phases.runEtcdPhase								   #先通知etcd集群有新成员加入然后再把staticpodyaml写入静态pod目录即先通知,然后再启动
														   #etcd集群稍后会去尝试连接新节点
		etcd.CreateStackedEtcdStaticPodManifestFile
		  etcd.NewFromCluster                              #创建etcdclient
		  etcd.GetPeerURL                                  #获取待创建的etcd的url:http://Ip:2380 ,Ip就是本node的ip,因为静态pod使用的是hostNetWork即直接使用宿主机网络
		  etcd.Client.AddMember                            #调用etcd api,通知集群有新成员要加入
		  etcd.prepareAndWriteEtcdStaticPod                #把etcd静态podyaml文件写入kubelet静态pod目录,默认是/etc/kubernetes/manifests/etcd.yaml
		  etcd.Client.WaitForClusterAvailable              #就是不断检查etcd集群状态,如果ok就结束等待,否则如果新的etcd节点启动失败或者没有成功加入etcd集群,那么etcd集群状态就不ok
    phases.newUpdateStatusSubphase
	  phases.runUpdateStatusPhase						   #空函数,此阶段已废弃
    phases.newMarkControlPlaneSubphase
      phases.runMarkControlPlanePhase                      #给节点打上控制平面标签和添加污点
		phases.MarkControlPlane                            #打标签和加污点

kubeadm init:
cmd.newCmdInit:
  phases.NewPreflightPhase #预检操作,和join相比,少了一个phases.checkIfReadyForAdditionalControlPlane操作,即少了一个证书检查操作,因为第一个master节点是使用自签证书
	phases.runPreflight   
	  preflight.RunInitNodeChecks
	  preflight.RunPullImagesCheck
  phases.NewCertsPhase
	phases.newCertSubPhases
	  certs.GetDefaultCertList              #会返回一个列表,就是ca、etcd/cs等证书配置,然后一个for循环,根据根证书和配置来创建对应的证书或者公钥私钥文件
	  phases.runCertPhase                   #检查指定目录下ca.crt是否存在且有效,否则创建
      phases.CreateCertAndKeyFilesWithCA    #根据根证书创建证书或者私钥公钥
    phases.runCertsSa                       #创建sa.key和sa.pub并写入磁盘指定目录下即/etc/kubernetes/pki
  phases.NewKubeConfigPhase                 #创建控制平面所需的xx.conf文件
	phases.NewKubeConfigFilePhase           #创建admin.conf
	phases.NewKubeConfigFilePhase           #创建kubelet.conf,init表示该节点是集群的第一个master节点,所以kubelet所需的kubelet.conf直接创建
                                            #而不是通过bootstraper方式创建
	phases.NewKubeConfigFilePhase           #创建controller-manaeger.conf
	phases.NewKubeConfigFilePhase           #创建scheduler.conf
  phases.NewKubeletStartPhase               #启动kubelet
	phases.runKubeletStart 
	  kubelet.WriteConfigToDisk             #把配置信息写入 /var/lib/kubelet/config.yaml 
	  kubelet.TryStartKubelet               #启动kublet
  phases.NewControlPlanePhase               #创建静态yaml文件并写入指定目录 /etc/kubernetes/manifests/
	phases.newControlPlaneSubphase          #创建/etc/kubernetes/manifests/kube-apiserver.yaml
	phases.newControlPlaneSubphase          #创建/etc/kubernetes/manifests/kube-controller-manager.yaml
	phases.newControlPlaneSubphase          #创建/etc/kubernetes/manifests/kube-scheduler.yaml
  phases.NewEtcdPhase                       #创建/var/lib/etcd作为数据目录并且创建etcd静态pod文件并写入/etc/kubernetes/manifests/etcd.yaml
  phases.NewWaitControlPlanePhase           #等待kublet和apiserver启动成功
	apiclient.KubeWaiter.WaitForAPI         #如果http://apiserverIP:port/healthz返回ok就说明apiserve启动好了
	apiclient.KubeWaiter.WaitForKubeletAndFunc  ##访问http://localhost:10248/healthz来查看kubelet服务是否启动成功
  phases.NewUploadConfigPhase               #1:把相关配置写入集群叫做kubeadm-config的configmap中
									        #2:创建指定kube-sytem命名空间下叫做kubeadm:nodes-kubeadm-config的role
									        #3:创建rolebinding:绑定<system:bootstrappers:kubeadm:default-node-token,kubeadm:nodes-kubeadm-config>
									        #   和<system:nodes,kubeadm:nodes-kubeadm-config>
  phases.NewUploadCertsPhase		        #如果参数配置了需要上传证书那么就上传证书
    apiclient.CreateOrUpdateSecret	        #1: 在kube-system命名空间下创建叫做kubeadm-certs的secret
	copycerts.createRBAC			 
	  apiclient.CreateOrUpdateRole	        #2: 创建角色kubeadm:kubeadm-certs
       apiclient.CreateOrUpdateRoleBinding  #3: 创建叫做kubeadm:kubeadm-certs的角色绑定,绑定<system:bootstrappers:kubeadm:default-node-token,kubeadm:kubeadm-certs>
									        #综上:system:bootstrappers:kubeadm:default-node-token用户可以同时拥有kubeadm-certs和kubeadm:nodes-kubeadm-config这两个角色的权限
  phases.NewMarkControlPlanePhase           #给master节点打上控制平面的标签以及污点
  phases.NewBootstrapTokenPhase   
	phases.runBootstrapToken                #创建bootstrappertoken并绑定到指定角色
	  node.UpdateOrCreateTokens             #创建或者更新bootstrappertoken
	  node.AllowBoostrapTokensToGetNodes	#在Kube-system命名空间下创建都叫做kubeadm:get-nodes的角色和角色绑定,
                                            #绑定<system:bootstrappers:kubeadm:default-node-token,kubeadm:get-nodes>
	  node.AllowBootstrapTokensToPostCSRs   #kube-system ns下创建叫做kubeadm:kubelet-bootstrap的角色和角色绑定,
										    #并绑定<system:bootstrappers:kubeadm:default-node-token,system:node-bootstrapper>
	  node.AutoApproveNodeBootstrapTokens   #kube-system下创建叫做kubeadm:node-autoapprove-bootstrap的角色绑定
										    #绑定<system:bootstrappers:kubeadm:default-node-token,system:certificates.k8s.io:certificatesigningrequests:nodeclient>
	  node.AutoApproveNodeCertificateRotation #kube-system下创建叫做kubeadm:node-autoapprove-certificate-rotation的角色绑定
											  #绑定<system:certificates.k8s.io:certificatesigningrequests:selfnodeclient,system:nodes>
	  clusterinfo.CreateBootstrapConfigMapIfNotExists #kube-public ns下创建叫做cluster-info的configmap,保存了bootstrapertoken和其他信息
	  clusterinfo.CreateClusterInfoRBACRules  #kube-public命名空间下创建叫做kubeadm:bootstrap-signer-clusterinfo的角色绑定
											  #绑定了<system:anonymous,kubeadm:bootstrap-signer-clusterinfo>
  phases.NewKubeletFinalizePhase              #证书轮换相关,就是用/var/lib/kubelet/pki/kubelet-client-current.pem下面的文件来更新/etc/kubernetes/kubelet.conf
  phases.NewAddonPhase
	phases.runCoreDNSAddon                    #在kube-system下创建叫做coredns的deployment以及叫做coredns的service
    phases.runKubeProxyAddon                  #创建kubeproxy
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐