kubeadm init源码分析

来源:互联网 发布:大数据平台建设方案 编辑:程序博客网 时间:2024/05/16 18:55

为了了解kubeadm token的存储看了一下源码

kubeadm.go是kubeadm命令的入口文件实际调用了app包中的Run方法,在run方法中通过NewKubeadmCommand返回一个cobra.command对象,在NewKubeadmCommand中我们可以看到:

//设置一个全局标准函数,更改含有_的参数并提示
cmds.SetGlobalNormalizationFunc(flag.WarnWordSepNormalizeFunc)

        //添加init相关参数
cmds.AddCommand(NewCmdInit(out))

       //添加join相关参数
cmds.AddCommand(NewCmdJoin(out))

       //添加version参数
cmds.AddCommand(NewCmdVersion(out))


为了知道master生成的token 生成后存储的位置我们从init参数入手,在NewCmdInit函数中定义了所有init相关的参数,在具体调用时实际上运行的是RunInit

在runinit中包括两个主要内容一个是类型为 MasterConfiguration的cfg参数,一个是cmd参数,我们发现在MasterConfiguration是包含一个Secrets结构,实际上生成的token就存储在这里面。

1.ChooseHostInterface函数通过默认路由设置监听ip地址

2.设置云相关配置,未完善。

3.通过CreateTokenAuthFile创建secret

<span style="font-size:18px;">func CreateTokenAuthFile(s *kubeadmapi.Secrets) error {tokenAuthFilePath := path.Join(kubeadmapi.GetEnvParams()["host_pki_path"], "tokens.csv")if err := generateTokenIfNeeded(s); err != nil {return fmt.Errorf("<master/tokens> failed to generate token(s) [%v]", err)}if err := os.MkdirAll(kubeadmapi.GetEnvParams()["host_pki_path"], 0700); err != nil {return fmt.Errorf("<master/tokens> failed to create directory %q [%v]", kubeadmapi.GetEnvParams()["host_pki_path"], err)}serialized := []byte(fmt.Sprintf("%s,kubeadm-node-csr,%s,system:kubelet-bootstrap\n", s.BearerToken, uuid.NewUUID()))// DumpReaderToFile create a file with mode 0600if err := cmdutil.DumpReaderToFile(bytes.NewReader(serialized), tokenAuthFilePath); err != nil {return fmt.Errorf("<master/tokens> failed to save token auth file (%q) [%v]", tokenAuthFilePath, err)}return nil}</span>

首先生成了配置文件路径,然后在generateTokenIfNeeded函数中判断是否制定了token,通过UseGivenTokenIfValid判断token是否符合默认标准,在UseGivenTokenIfValid中我们可以看到

<span style="font-size:18px;">func UseGivenTokenIfValid(s *kubeadmapi.Secrets) (bool, error) {if s.GivenToken == "" {return false, nil // not given}fmt.Println("<util/tokens> validating provided token")givenToken := strings.Split(strings.ToLower(s.GivenToken), ".")// TODO(phase1+) print desired format// TODO(phase1+) could also print more specific messages in each caseinvalidErr := "<util/tokens> provided token is invalid - %s"if len(givenToken) != 2 {return false, fmt.Errorf(invalidErr, "not in 2-part dot-separated format")}if len(givenToken[0]) != TokenIDLen {return false, fmt.Errorf(invalidErr, fmt.Sprintf("length of first part is incorrect [%d (given) != %d (expected) ]",len(givenToken[0]), TokenIDLen))}tokenBytes := []byte(givenToken[1])s.TokenID = givenToken[0]s.BearerToken = givenToken[1]s.Token = tokenBytesreturn true, nil // given and valid}</span>

判断用户自定义的token是否符合标准,若符合标准则赋值给s.Secrets,token以.分隔,第一部分赋值给TokenId,第二部分赋值给BearerToken ,token则是由BearerToken 转化为字节数组

<span style="font-size:18px;">type Secrets struct {GivenToken  string // dot-separated `<TokenID>.<Token>` set by the userTokenID     string // optional on master side, will be generated if not specifiedToken       []byte // optional on master side, will be generated if not specifiedBearerToken string // set based on Token}</span>


如果不符合标准则通过GenerateToken生成新的token赋值给s.Secrets。

s.Secrets赋值完成后创建pki目录,序列化生成的BearerToken 存储到tokens.csv


4.WriteStaticPodManifests函数在manifests中写入需要的static podyaml文件

5.CreatePKIAssets函数创建ca证书

6.CreateCertsAndConfigForClients创建客户端证书,创建kubeconfig配置文件(admin.conf  kubelet.conf)

7.CreateClientAndWaitForAPI待服务启动完成初始化clientset,超时时间为500秒

8.UpdateMasterRoleLabelsAndTaints 通过attemptToUpdateMasterRoleLabelsAndTaints 设置master节点的label以及调度策略()

9.CreateDiscoveryDeploymentAndSecret创建DiscoveryDeployment和Secret

我们可以看到client.Secrets(api.NamespaceSystem).Create(kd.Secret)创建了一个secret

api.NamespaceSystem实际就是kube-system那么kd.Secret是什么呢?

kd := newKubeDiscovery(s, caCert)

在newKubeDiscovery中调用了encodeKubeDiscoverySecretData函数中可以看到

tokenMap[s.Secrets.TokenID] = s.Secrets.BearerToken

data["token-map.json"], _ = json.Marshal(tokenMap)

所以完整的token存储在kd.Secret.Data中,而kd这个结构实际包含一个Deployment和一个Secret,而Secret.ObjectMeta.name为kubeDiscoverySecretName即

const (
kubeDiscoveryName       = "kube-discovery"
kubeDiscoverySecretName = "clusterinfo"
)

10.CreateEssentialAddons创建kubeProxyDaemonSet、kubeDNSDeployment、kubeDNSService


到目前为止init的基本流程讲述完毕。token存储在名为clusterinfo的secret中

0 0