kubeadm join和init源码阅读笔记
kubeadm的代码是放在kubernetes/kubernetes下面,github上那个kubernetes/kubeadm不是kubeadm的代码仓库。k8s版本v1.23。
·
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
更多推荐
已为社区贡献6条内容
所有评论(0)