kubeadm 组件超深度分析

基于 github.com/kubernetes/cmd/kubeadm/ 源码逐行解读
总计约 312 个 Go 文件(含测试),非测试文件约 170+ 个


一、模块定位

1.1 业务职责

kubeadm 是 Kubernetes 官方集群引导工具,核心职责是将一个裸机环境转变为一个运行中的 Kubernetes 集群。具体而言:

  • 初始化控制平面kubeadm init):在首节点上引导出完整的 Kubernetes 控制平面(API Server、Controller Manager、Scheduler、etcd),包括 PKI 证书体系、kubeconfig 文件、Static Pod 清单等
  • 节点加入集群kubeadm join):worker 节点或额外控制平面节点通过 Bootstrap Token 和 TLS Bootstrap 机制安全加入已有集群
  • 集群升级kubeadm upgrade):滚动升级控制平面组件和 kubelet 版本
  • 证书管理kubeadm certs):生成、续期、检查集群 PKI 资产
  • 配置管理kubeadm config):打印默认配置、上传/查看集群配置
  • 令牌管理kubeadm token):创建/删除/列出 Bootstrap Token
  • 重置节点kubeadm reset):回滚节点到未加入集群状态

1.2 在系统中的位置

kubeadm 在 Kubernetes 生态中处于基础设施层,位于底层容器运行时(containerd/Docker)与上层 Kubernetes 控制平面之间:

┌─────────────────────────────────────────────┐
│             用户 / 运维工具                    │
├─────────────────────────────────────────────┤
│              kubeadm CLI                     │  ← 本分析对象
├─────────────────────────────────────────────┤
│        kubelet / 容器运行时 (CRI)             │
├─────────────────────────────────────────────┤
│           操作系统 (Linux/Windows)            │
└─────────────────────────────────────────────┘

kubeadm 不负责:网络插件安装(CNI)、持久化存储配置、负载均衡器部署。它专注于将控制平面组件以 Static Pod 方式拉起,完成安全引导的"最后一公里"。


二、模块整体结构

2.1 目录树与包组织

cmd/kubeadm/
├── kubeadm.go                    # 程序入口 main()
├── app/
│   ├── kubeadm.go                # Run() 入口函数:初始化 flag、创建 cobra 根命令
│   ├── cmd/                      # CLI 命令层(cobra 命令定义)
│   │   ├── cmd.go                # NewKubeadmCommand():注册所有子命令
│   │   ├── init.go               # kubeadm init 命令定义 + initData
│   │   ├── join.go               # kubeadm join 命令定义 + joinData
│   │   ├── reset.go              # kubeadm reset 命令
│   │   ├── config.go             # kubeadm config 子命令
│   │   ├── token.go              # kubeadm token 子命令(create/list/delete/generate)
│   │   ├── certs.go              # kubeadm certs 子命令
│   │   ├── version.go            # kubeadm version
│   │   ├── completion.go         # shell 补全
│   │   ├── upgrade/              # kubeadm upgrade 子命令(plan/apply/node/diff)
│   │   ├── alpha/                # 实验性子命令
│   │   ├── options/              # 通用 CLI 选项常量和 flag 定义
│   │   ├── phases/               # 阶段子命令定义层
│   │   │   ├── workflow/         # ★ 核心:workflow 引擎(Runner/Phase)
│   │   │   ├── init/             # init 各阶段的 Phase 定义
│   │   │   ├── join/             # join 各阶段的 Phase 定义
│   │   │   ├── reset/            # reset 各阶段的 Phase 定义
│   │   │   └── upgrade/          # upgrade node 各阶段的 Phase 定义
│   │   └── util/                 # CLI 工具函数
│   ├── apis/                     # API 类型定义
│   │   ├── kubeadm/              # 内部 API 类型
│   │   │   ├── types.go          # InitConfiguration, ClusterConfiguration, JoinConfiguration 等
│   │   │   ├── register.go       # Scheme 注册
│   │   │   ├── bootstraptokenstring.go     # Token 字符串类型
│   │   │   ├── bootstraptokenhelpers.go    # Token 辅助函数
│   │   │   ├── apiendpoint.go    # APIEndpoint 类型
│   │   │   ├── scheme/           # Scheme 单例
│   │   │   ├── v1beta1/          # v1beta1 外部版本 API
│   │   │   ├── v1beta2/          # v1beta2 外部版本 API(当前默认)
│   │   │   ├── validation/       # 配置验证逻辑
│   │   │   └── fuzzer/           # 模糊测试
│   │   └── output/               # 输出 API 类型
│   │       ├── types.go
│   │       └── v1alpha1/
│   ├── phases/                   # ★ 核心业务逻辑层
│   │   ├── certs/                # 证书生成与管理
│   │   │   ├── certs.go          # CreatePKIAssets, CreateCACertAndKeyFiles 等
│   │   │   ├── certlist.go       # KubeadmCert 类型定义 + 证书清单
│   │   │   └── renewal/          # 证书续期
│   │   ├── kubeconfig/           # kubeconfig 文件生成
│   │   │   └── kubeconfig.go
│   │   ├── controlplane/         # 控制平面 Static Pod 清单生成
│   │   │   ├── manifests.go      # GetStaticPodSpecs, CreateStaticPodFiles
│   │   │   └── volumes.go        # HostPath 卷定义
│   │   ├── etcd/                 # etcd Static Pod 管理
│   │   │   └── local.go          # 本地 etcd 集群初始化/扩容
│   │   ├── kubelet/              # kubelet 启动/重启/配置
│   │   │   ├── kubelet.go        # TryStartKubelet, TryStopKubelet
│   │   │   ├── config.go         # kubelet 配置写入
│   │   │   └── flags.go          # kubelet 命令行参数
│   │   ├── uploadconfig/         # 上传集群配置到 ConfigMap
│   │   │   └── uploadconfig.go
│   │   ├── copycerts/            # 证书上传/下载(HA 控制平面)
│   │   │   └── copycerts.go      # UploadCerts, DownloadCerts
│   │   ├── bootstraptoken/       # Bootstrap Token 管理
│   │   │   ├── node/             # 节点 Token 创建
│   │   │   └── clusterinfo/      # cluster-info ConfigMap
│   │   ├── markcontrolplane/     # 控制平面标签/污点
│   │   ├── patchnode/            # 节点注解打补丁
│   │   ├── addons/               # 附加组件(CoreDNS、kube-proxy)
│   │   │   ├── dns/              # CoreDNS
│   │   │   └── proxy/            # kube-proxy
│   │   └── upgrade/              # 升级逻辑
│   │       ├── compute.go        # 版本计算
│   │       ├── policy.go         # 升级策略
│   │       ├── staticpods.go     # Static Pod 升级
│   │       ├── health.go         # 健康检查
│   │       └── postupgrade.go    # 升级后处理
│   ├── preflight/                # 预检查
│   │   ├── checks.go             # Checker 接口 + 各种检查实现
│   │   ├── checks_linux.go       # Linux 特有检查
│   │   └── utils.go
│   ├── discovery/                # 集群发现机制
│   │   ├── discovery.go          # For() 入口
│   │   ├── token/                # Token 发现
│   │   ├── file/                 # 文件发现
│   │   └── https/                # HTTPS 发现
│   ├── componentconfigs/         # 组件配置(kubelet、kube-proxy)
│   ├── constants/                # 常量定义
│   │   └── constants.go          # 路径、端口、超时、证书名等
│   ├── features/                 # Feature Gate 定义
│   ├── images/                   # 镜像拉取工具
│   └── util/                     # 工具函数
│       ├── apiclient/            # API 客户端封装(幂等操作、dry-run、wait)
│       ├── pkiutil/              # PKI 工具(证书生成/加载/验证)
│       ├── kubeconfig/           # kubeconfig 工具
│       ├── staticpod/            # Static Pod 工具
│       ├── etcd/                 # etcd 客户端工具
│       ├── config/               # 配置加载/解析
│       ├── crypto/               # 加密工具
│       └── ...
└── test/                         # 测试辅助

2.2 核心接口与依赖注入

2.2.1 workflow.RunData 接口体系

kubeadm 采用 Phase Workflow 模式,通过 RunData 接口实现阶段间数据共享与依赖注入:

// Runner 引擎使用 RunData = interface{} 作为数据传递载体
type RunData = interface{}

// InitData 接口(init 命令使用)
type InitData interface {
    UploadCerts() bool
    CertificateKey() string
    SetCertificateKey(key string)
    SkipCertificateKeyPrint() bool
    Cfg() *kubeadmapi.InitConfiguration
    DryRun() bool
    SkipTokenPrint() bool
    IgnorePreflightErrors() sets.String
    CertificateWriteDir() string
    CertificateDir() string
    KubeConfigDir() string
    KubeConfigPath() string
    ManifestDir() string
    KubeletDir() string
    ExternalCA() bool
    OutputWriter() io.Writer
    Client() (clientset.Interface, error)
    Tokens() []string
    PatchesDir() string
}

initData 结构体实现 InitData,持有运行时上下文:

  • cfg *kubeadmapi.InitConfiguration:核心配置
  • client clientset.Interface:Kubernetes API 客户端(懒初始化单例)
  • dryRun bool:干跑模式
  • externalCA bool:外部 CA 标记
  • 各种路径(certificatesDir, kubeconfigDir, manifestDir 等)

joinData 类似地实现 JoinData 接口,额外持有:

  • tlsBootstrapCfg *clientcmdapi.Config:TLS 引导 kubeconfig
  • initCfg *kubeadmapi.InitConfiguration:从集群拉取的 Init 配置
  • clientSet *clientset.Clientset:API 客户端
2.2.2 workflow.Phase 结构体
type Phase struct {
    Name           string                    // 阶段名称
    Aliases        []string                  // 别名
    Short          string                    // 短描述
    Long           string                    // 长描述
    Example        string                    // 示例
    Hidden         bool                      // 是否隐藏
    Phases         []Phase                   // 嵌套子阶段
    RunAllSiblings bool                      // 是否运行所有同级阶段
    Run            func(data RunData) error  // 执行函数
    RunIf          func(data RunData) (bool, error)  // 条件执行
    InheritFlags   []string                  // 从父命令继承的 flag
    LocalFlags     *pflag.FlagSet            // 本地 flag
    ArgsValidator  cobra.PositionalArgs      // 参数验证器
}
2.2.3 KubeadmCert 证书描述器
type KubeadmCert struct {
    Name           string
    LongName       string
    BaseName       string
    CAName         string
    configMutators []configMutatorsFunc      // 运行时配置修改器
    config         pkiutil.CertConfig        // 基础证书配置
}

证书系统采用树形结构CertificateTree map[*KubeadmCert]Certificates,CA 证书作为根,叶子证书由 CA 签发。

2.3 核心方法清单

方法 作用
app Run() 初始化日志/flag,创建根命令并执行
cmd NewKubeadmCommand() 注册 init/join/reset/token/certs/config/upgrade/alpha/version 子命令
cmd newCmdInit() 定义 init 命令,注册 13 个 Phase
cmd newCmdJoin() 定义 join 命令,注册 5 个 Phase
cmd newInitData() 校验 flag → 加载/合并配置 → 返回 initData
cmd newJoinData() 校验 flag → 发现配置 → 返回 joinData
workflow Runner.Run() 遍历 Phase 列表,按序执行
workflow Runner.BindToCommand() 为 Phase 生成 cobra 子命令
certs CreatePKIAssets() 创建完整 PKI 证书树
certs CertificateTree.CreateTree() 按 CA→leaf 顺序创建证书
kubeconfig CreateKubeConfigFile() 生成单个 kubeconfig
kubeconfig getKubeConfigSpecs() 构建 4 个 kubeconfig 规格
controlplane GetStaticPodSpecs() 生成 3 个控制平面 Pod 规格
controlplane CreateStaticPodFiles() 写 Static Pod 清单到磁盘
etcd CreateLocalEtcdStaticPodManifestFile() 生成初始 etcd Static Pod
etcd CreateStackedEtcdStaticPodManifestFile() 扩容 etcd 成员
copycerts UploadCerts() 加密上传证书到 Secret
copycerts DownloadCerts() 下载解密证书
uploadconfig UploadConfiguration() 上传 ClusterConfiguration 到 ConfigMap
bootstraptoken UpdateOrCreateTokens() 创建/更新 Bootstrap Token Secret
discovery For() 集群发现入口 → 返回 TLS Bootstrap kubeconfig
preflight RunInitNodeChecks() 执行 init 预检查
pkiutil NewCertificateAuthority() 生成 CA 证书+密钥
pkiutil NewCertAndKey() 由 CA 签发证书+密钥

2.4 内部调用关系

kubeadm.go:main()
  └→ app.Run()
       └→ cmd.NewKubeadmCommand()
            ├→ newCmdInit()
            │    └→ workflow.Runner
            │         ├→ Phase: preflight     → preflight.RunInitNodeChecks()
            │         ├→ Phase: certs         → certs.CreatePKIAssets()
            │         │    └→ CertificateTree.CreateTree()
            │         │         ├→ pkiutil.NewCertificateAuthority()  (CA)
            │         │         └→ KubeadmCert.CreateFromCA()  (leaf)
            │         │              └→ pkiutil.NewCertAndKey()
            │         ├→ Phase: kubeconfig    → kubeconfig.CreateKubeConfigFile()
            │         ├→ Phase: kubelet-start → kubelet.WriteKubeletConfig()
            │         ├→ Phase: control-plane → controlplane.CreateStaticPodFiles()
            │         │    └→ GetStaticPodSpecs()
            │         ├→ Phase: etcd          → etcd.CreateLocalEtcdStaticPodManifestFile()
            │         ├→ Phase: wait-control-plane → wait for API Server
            │         ├→ Phase: upload-config → uploadconfig.UploadConfiguration()
            │         ├→ Phase: upload-certs  → copycerts.UploadCerts()
            │         ├→ Phase: mark-control-plane → markcontrolplane.MarkControlPlane()
            │         ├→ Phase: bootstrap-token → bootstraptoken.UpdateOrCreateTokens()
            │         ├→ Phase: kubelet-finalize → kubelet 配置收尾
            │         └→ Phase: addons        → dns + proxy 安装
            ├→ newCmdJoin()
            │    └→ workflow.Runner
            │         ├→ Phase: preflight           → preflight.RunJoinNodeChecks()
            │         ├→ Phase: control-plane-prepare → download-certs + certs + kubeconfig + control-plane
            │         ├→ Phase: check-etcd           → etcd.CheckLocalEtcdClusterStatus()
            │         ├→ Phase: kubelet-start        → kubelet.WriteConfig + 启动
            │         └→ Phase: control-plane-join   → etcd 扩容 + 标记节点
            └→ upgrade/.../...

2.5 数据流入流出

数据流入

  1. CLI 参数(--config, --token, --apiserver-advertise-address 等)
  2. 配置文件(YAML 格式 InitConfiguration / JoinConfiguration
  3. 已有集群的 ConfigMap(kubeadm-configcluster-info
  4. 磁盘上的已有证书/kubeconfig 文件
  5. 环境变量(KUBEADM_INIT_DRYRUN_DIR 等)

数据流出

  1. 磁盘文件:证书(/etc/kubernetes/pki/)、kubeconfig(/etc/kubernetes/)、Static Pod 清单(/etc/kubernetes/manifests/)、kubelet 配置
  2. Kubernetes API 对象:Secret(Bootstrap Token、kubeadm-certs)、ConfigMap(kubeadm-config、cluster-info)、RBAC(Role/RoleBinding)
  3. Node 对象:标签(node-role.kubernetes.io/master)、注解(kubeadm 相关)、污点

三、核心业务逻辑深度解析

3.1 kubeadm init 完整执行流程

3.1.1 入口路径
// kubeadm.go
func main() {
    kubeadmutil.CheckErr(app.Run())
}

// app/kubeadm.go
func Run() error {
    klog.InitFlags(nil)
    pflag.CommandLine.SetNormalizeFunc(cliflag.WordSepNormalizeFunc)
    pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
    pflag.Set("logtostderr", "true")
    // 隐藏内部 flag...
    cmd := cmd.NewKubeadmCommand(os.Stdin, os.Stdout, os.Stderr)
    return cmd.Execute()
}

Run() 做了四件事:

  1. 初始化 klog 日志 flag
  2. 设置 flag 名规范化函数(将 --foo-bar--foo_bar 等价)
  3. 合并 Go flag 到 pflag
  4. 创建并执行 cobra 根命令
3.1.2 命令注册

NewKubeadmCommand() 构建命令树:

cmds.AddCommand(newCmdCertsUtility(out))
cmds.AddCommand(newCmdCompletion(out, ""))
cmds.AddCommand(newCmdConfig(out))
cmds.AddCommand(newCmdInit(out, nil))
cmds.AddCommand(newCmdJoin(out, nil))
cmds.AddCommand(newCmdReset(in, out, nil))
cmds.AddCommand(newCmdVersion(out))
cmds.AddCommand(newCmdToken(out, err))
cmds.AddCommand(upgrade.NewCmdUpgrade(out))
cmds.AddCommand(alpha.NewCmdAlpha(in, out))

PersistentPreRunE 支持 --rootfs 参数,在执行任何子命令前 chroot 到指定目录,这在容器化场景中很有用。

3.1.3 init 命令的 Phase 注册
initRunner.AppendPhase(phases.NewPreflightPhase())           // 1. 预检查
initRunner.AppendPhase(phases.NewCertsPhase())                // 2. 证书生成
initRunner.AppendPhase(phases.NewKubeConfigPhase())           // 3. kubeconfig 生成
initRunner.AppendPhase(phases.NewKubeletStartPhase())         // 4. kubelet 启动
initRunner.AppendPhase(phases.NewControlPlanePhase())         // 5. 控制平面清单
initRunner.AppendPhase(phases.NewEtcdPhase())                 // 6. etcd 初始化
initRunner.AppendPhase(phases.NewWaitControlPlanePhase())     // 7. 等待控制平面就绪
initRunner.AppendPhase(phases.NewUploadConfigPhase())         // 8. 上传配置
initRunner.AppendPhase(phases.NewUploadCertsPhase())          // 9. 上传证书
initRunner.AppendPhase(phases.NewMarkControlPlanePhase())     // 10. 标记控制平面
initRunner.AppendPhase(phases.NewBootstrapTokenPhase())       // 11. 创建 Bootstrap Token
initRunner.AppendPhase(phases.NewKubeletFinalizePhase())      // 12. kubelet 收尾
initRunner.AppendPhase(phases.NewAddonPhase())                // 13. 安装附加组件

用户可通过 --skip-phases 跳过特定阶段,或通过 kubeadm init phase <phase-name> 单独执行某个阶段。

3.1.4 initData 构建

newInitData() 是 init 命令的核心数据准备函数,逐步解析:

func newInitData(cmd *cobra.Command, args []string, options *initOptions, out io.Writer) (*initData, error) {
    // Step 1: 重新应用默认值(设置未通过 flag 暴露的默认值)
    kubeadmscheme.Scheme.Default(options.externalInitCfg)
    kubeadmscheme.Scheme.Default(options.externalClusterCfg)

    // Step 2: 解析 Feature Gates 字符串
    options.externalClusterCfg.FeatureGates, err = features.NewFeatureGate(...)

    // Step 3: 校验混合参数(不能同时用 --config 和其他 flag 覆盖相同字段)
    validation.ValidateMixedArguments(cmd.Flags())

    // Step 4: 应用 Bootstrap Token 选项到 InitConfiguration
    options.bto.ApplyTo(options.externalInitCfg)

    // Step 5: 加载配置文件或合并默认配置
    cfg, err := configutil.LoadOrDefaultInitConfiguration(
        options.cfgPath, options.externalInitCfg, options.externalClusterCfg)

    // Step 6: 为新集群设置 kubelet cgroup driver 为 systemd
    componentconfigs.MutateCgroupDriver(&cfg.ClusterConfiguration)

    // Step 7: 校验忽略的预检查列表
    ignorePreflightErrorsSet, err := validation.ValidateIgnorePreflightErrors(...)

    // Step 8: 校验 API Server 绑定地址
    configutil.VerifyAPIServerBindAddress(cfg.LocalAPIEndpoint.AdvertiseAddress)

    // Step 9: 校验 Feature Gate 版本兼容性
    features.ValidateVersion(features.InitFeatureGates, cfg.FeatureGates, cfg.KubernetesVersion)

    // Step 10: 干跑模式创建临时目录
    if options.dryRun {
        dryRunDir, err = kubeadmconstants.CreateTempDirForKubeadm(...)
    }

    // Step 11: 检测外部 CA(CA cert 存在但 CA key 不存在)
    externalCA, err := certsphase.UsingExternalCA(&cfg.ClusterConfiguration)

    // Step 12: 检测外部 Front-Proxy CA
    externalFrontProxyCA, err := certsphase.UsingExternalFrontProxyCA(&cfg.ClusterConfiguration)

    // Step 13: 外部 CA 模式下禁止 upload-certs
    if options.uploadCerts && (externalCA || externalFrontProxyCA) {
        return nil, errors.New("can't use upload-certs with external CA")
    }

    return &initData{...}, nil
}

关键设计决策

  • 外部 CA 检测:通过文件存在性判定——ca.crt 存在但 ca.key 不存在 → 外部 CA 模式
  • cgroup driver 变异:新集群默认使用 systemd cgroup driver,但升级时不改变(避免重启 kubelet 导致已有节点异常)
  • 混合参数校验:防止用户同时用 --config 和 CLI flag 设置同一字段产生歧义
3.1.5 Runner 执行引擎

workflow.Runner 是 kubeadm 的核心编排引擎:

func (e *Runner) Run(args []string) error {
    e.prepareForExecution()  // 构建 phaseRunner 列表

    // 根据FilterPhases/SkipPhases计算哪些阶段需要执行
    phaseRunFlags, err := e.computePhaseRunFlags()

    // 构建运行时数据
    data, err := e.InitData(args)

    // 遍历执行
    err = e.visitAll(func(p *phaseRunner) error {
        if !phaseRunFlags[p.generatedName] { return nil }  // 跳过
        if p.RunIf != nil {
            ok, err := p.RunIf(data)  // 条件检查
            if !ok { return nil }
        }
        if p.Run != nil {
            return p.Run(data)  // 执行阶段
        }
        return nil
    })
    return err
}

phaseRunner 包含运行时上下文:

  • parent *phaseRunner:父阶段
  • level int:嵌套层级
  • generatedName string:全路径名(如 control-plane/apiserver
  • use string:相对路径名

BindToCommand() 将 Phase 树映射为 cobra 子命令树,自动生成 kubeadm init phase control-plane apiserver 等子命令。

3.2 证书管理深度解析

3.2.1 证书清单

kubeadm 生成以下证书体系:

CA 证书 签发的叶子证书
ca (Kubernetes Root CA) apiserver (服务端证书), apiserver-kubelet-client (客户端证书)
front-proxy-ca front-proxy-client
etcd/ca etcd/server, etcd/peer, etcd/healthcheck-client, apiserver-etcd-client

另外还有 Service Account 密钥对:sa.key / sa.pub(非 x509 证书,独立处理)。

当使用外部 etcd 时,etcd 相关证书不生成;当使用外部 CA 时,仅生成 CSR 和私钥。

3.2.2 证书树创建流程
func CreatePKIAssets(cfg *kubeadmapi.InitConfiguration) error {
    // 根据是否有本地 etcd 选择证书列表
    var certList Certificates
    if cfg.Etcd.Local == nil {
        certList = GetCertsWithoutEtcd()  // 5 个证书
    } else {
        certList = GetDefaultCertList()   // 10 个证书
    }

    // 构建证书树:CA → 叶子证书映射
    certTree, err := certList.AsMap().CertTree()

    // 创建证书树
    certTree.CreateTree(cfg)

    // 单独处理 Service Account 密钥
    CreateServiceAccountKeyAndPublicKeyFiles(cfg.CertificatesDir, cfg.ClusterConfiguration.PublicKeyAlgorithm())
}

CertTree() 将扁平列表转换为树:

func (m CertificateMap) CertTree() (CertificateTree, error) {
    caMap := make(CertificateTree)
    for _, cert := range m {
        if cert.CAName == "" {
            // CA 证书,作为根节点
            caMap[cert] = []*KubeadmCert{}
        } else {
            // 叶子证书,挂到对应 CA 下
            ca := m[cert.CAName]
            caMap[ca] = append(caMap[ca], cert)
        }
    }
    return caMap, nil
}

CreateTree() 逐个处理 CA:

func (t CertificateTree) CreateTree(ic *kubeadmapi.InitConfiguration) error {
    for ca, leaves := range t {
        // 尝试从磁盘加载已有 CA 证书
        caCert, err := pkiutil.TryLoadCertFromDisk(ic.CertificatesDir, ca.BaseName)
        if err == nil {
            // CA 已存在:验证 IsCA → 尝试加载 CA Key
            if !caCert.IsCA { return error }
            caKey, err := pkiutil.TryLoadKeyFromDisk(...)
            if err != nil {
                // CA Key 不存在(外部 CA)→ 验证所有叶子证书已存在
                for _, leaf := range leaves {
                    validateSignedCertWithCA(cl, caCert)
                }
                continue
            }
            // CA Key 存在 → 用它签发缺失的叶子证书
        } else {
            // CA 不存在 → 创建新 CA
            caCert, caKey, err = pkiutil.NewCertificateAuthority(cfg)
            writeCertificateAuthorityFilesIfNotExist(...)
        }
        // 签发所有叶子证书
        for _, leaf := range leaves {
            leaf.CreateFromCA(ic, caCert, caKey)
        }
    }
}

关键逻辑

  • 幂等性:已有证书不会覆盖,先加载验证,匹配则跳过
  • 外部 CA 检测:CA cert 存在 + CA key 不存在 → 外部 CA 模式,此时必须所有叶子证书已预置
  • 证书验证:检查有效期、SAN、CA 签名链
3.2.3 KubeadmCert 定义示例
// API Server 证书
func KubeadmCertAPIServer() *KubeadmCert {
    return &KubeadmCert{
        Name:     "apiserver",
        LongName: "certificate for serving the Kubernetes API",
        BaseName: "apiserver",
        CAName:   "ca",               // 由 Kubernetes Root CA 签发
        config: pkiutil.CertConfig{
            Config: certutil.Config{
                CommonName: "kube-apiserver",
                Usages:     []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
            },
        },
        configMutators: []configMutatorsFunc{
            makeAltNamesMutator(pkiutil.GetAPIServerAltNames),  // 运行时填充 SAN
        },
    }
}

configMutators 是关键——在运行时根据 InitConfiguration 动态修改证书配置。例如 API Server 证书的 SAN 需要包含:AdvertiseAddress、Service CIDR 的第一个 IP、各种 DNS 名称等,这些只能在运行时确定。

3.3 kubeconfig 生成深度解析

kubeadm 生成 4 个 kubeconfig 文件:

文件名 用户/身份 连接目标 组织
admin.conf kubernetes-admin ControlPlaneEndpoint system:masters
kubelet.conf system:node:<nodename> ControlPlaneEndpoint system:nodes
controller-manager.conf system:kube-controller-manager LocalAPIEndpoint -
scheduler.conf system:kube-scheduler LocalAPIEndpoint -

注意:admin.confkubelet.conf 使用 ControlPlaneEndpoint(全局负载均衡地址),而 controller-manager.confscheduler.conf 使用 LocalAPIEndpoint(本地 API Server 地址),因为控制平面组件应直接连接本地实例以避免负载均衡器单点故障。

生成流程:

func createKubeConfigFiles(outDir string, cfg *kubeadmapi.InitConfiguration, kubeConfigFileNames ...string) error {
    specs, _ := getKubeConfigSpecs(cfg)  // 构建规格
    for _, name := range kubeConfigFileNames {
        spec := specs[name]
        config, _ := buildKubeConfigFromSpec(spec, cfg.ClusterName)  // 构建 kubeconfig 对象
        createKubeConfigFileIfNotExists(outDir, name, config)         // 写入磁盘(幂等)
    }
}

幂等逻辑:如果文件已存在,验证 CA 和 Server URL 是否匹配,匹配则跳过,不匹配则报错。

3.4 控制平面 Static Pod 生成深度解析

3.4.1 GetStaticPodSpecs

为三个组件构建 Pod 规格:

kube-apiserver

staticPodSpecs[kubeadmconstants.KubeAPIServer] = staticpodutil.ComponentPod(v1.Container{
    Name:            "kube-apiserver",
    Image:           images.GetKubernetesImage("kube-apiserver", cfg),
    Command:         getAPIServerCommand(cfg, endpoint),  // ★ 核心命令构建
    VolumeMounts:    staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts("kube-apiserver")),
    LivenessProbe:   staticpodutil.LivenessProbe(..., "/livez", ...),
    ReadinessProbe:  staticpodutil.ReadinessProbe(..., "/readyz", ...),
    StartupProbe:    staticpodutil.StartupProbe(...),
    Resources:       staticpodutil.ComponentResources("250m"),
    Env:             kubeadmutil.GetProxyEnvVars(),
}, mounts.GetVolumes("kube-apiserver"), annotations)

API Server 命令构建 (getAPIServerCommand):

  • 基础参数:--advertise-address, --secure-port, --enable-admission-plugins=NodeRestriction
  • 证书路径:--tls-cert-file, --tls-private-key-file, --client-ca-file, --kubelet-client-certificate
  • etcd 连接:根据 External/Local etcd 选择不同参数
  • Front Proxy:--requestheader-*, --proxy-client-*
  • Service Account:--service-account-key-file, --service-account-signing-key-file
  • 授权模式:默认 Node,RBAC
  • ExtraArgs 通过 BuildArgumentListFromMap 合并,用户可覆盖默认值

kube-controller-manager

  • 默认 --port=0(禁用不安全端口)
  • --bind-address=127.0.0.1(仅本地访问)
  • --leader-elect=true
  • --controllers=*,bootstrapsigner,tokencleaner
  • 外部 CA 时清空 --cluster-signing-key-file--cluster-signing-cert-file
  • 如果设置了 PodSubnet,启用 --allocate-node-cidrs

kube-scheduler

  • 类似配置:--port=0, --bind-address=127.0.0.1, --leader-elect=true

3.5 etcd 集群初始化深度解析

3.5.1 初始节点(init)

CreateLocalEtcdStaticPodManifestFile 生成单节点 etcd Static Pod:

func getEtcdCommand(cfg, endpoint, nodeName, initialCluster) []string {
    defaultArguments := map[string]string{
        "name":                        nodeName,
        "listen-client-urls":          "http://127.0.0.1:2379,https://<advertise>:2379",
        "advertise-client-urls":       "https://<advertise>:2379",
        "listen-peer-urls":            "https://<advertise>:2380",
        "initial-advertise-peer-urls": "https://<advertise>:2380",
        "data-dir":                    cfg.Etcd.Local.DataDir,
        "cert-file":                   "etcd/server.crt",
        "key-file":                    "etcd/server.key",
        "trusted-ca-file":             "etcd/ca.crt",
        "client-cert-auth":            "true",
        "peer-cert-file":              "etcd/peer.crt",
        "peer-key-file":               "etcd/peer.key",
        "peer-trusted-ca-file":        "etcd/ca.crt",
        "peer-client-cert-auth":       "true",
    }
    if len(initialCluster) == 0 {
        // init 场景:只有自己
        defaultArguments["initial-cluster"] = fmt.Sprintf("%s=https://<advertise>:2380", nodeName)
    } else {
        // join 场景:已有成员列表
        defaultArguments["initial-cluster"] = strings.Join(endpoints, ",")
        defaultArguments["initial-cluster-state"] = "existing"  // ★ 关键标志
    }
}
3.5.2 扩容 etcd 成员(join --control-plane)

CreateStackedEtcdStaticPodManifestFile 是 HA 控制平面加入时的核心:

  1. 通过 API Server 连接已有 etcd 集群
  2. ListMembers() 获取当前成员列表
  3. 检查新成员是否已存在(通过 peer URL 匹配)
  4. 如果不存在,AddMember() 向集群添加新成员
  5. 构建包含新成员的 initial-cluster 列表
  6. 生成 Static Pod 清单,设置 initial-cluster-state=existing
  7. 等待新 etcd 成员加入集群(最多 5s × 8 = 40s

3.6 kubeadm join 完整执行流程

3.6.1 发现机制

discovery.For() 实现双向信任建立:

func For(cfg *kubeadmapi.JoinConfiguration) (*clientcmdapi.Config, error) {
    // Step 1: 获取已验证的 kubeconfig(建立 Node → API Server 信任)
    config, err := DiscoverValidatedKubeConfig(cfg)

    // Step 2: 使用 TLSBootstrapToken 建立 API Server → Node 信任
    if len(cfg.Discovery.TLSBootstrapToken) != 0 {
        return kubeconfigutil.CreateWithToken(
            clusterinfo.Server, ..., cfg.Discovery.TLSBootstrapToken), nil
    }
    // 或者使用 discovery file 中嵌入的认证信息
}

发现有两种模式:

  • Token 发现--discovery-token <token> <api-server-endpoint> → 从 cluster-info ConfigMap 获取 CA 证书,通过 --discovery-token-ca-cert-hash 验证
  • File 发现--discovery-file <path-or-https-url> → 从 kubeconfig 文件直接获取
3.6.2 joinData 构建
func newJoinData(cmd, args, opt, out, adminKubeConfigPath) (*joinData, error) {
    // 合并 token 到 discovery 和 TLS bootstrap
    if len(opt.token) > 0 {
        opt.externalcfg.Discovery.TLSBootstrapToken = opt.token
        opt.externalcfg.Discovery.BootstrapToken.Token = opt.token
    }

    // 如果 admin.conf 已存在(控制平面节点),跳过发现
    if _, err := os.Stat(adminKubeConfigPath); err == nil && opt.controlPlane {
        tlsBootstrapCfg, _ = clientcmd.LoadFromFile(adminKubeConfigPath)
    }

    // 加载/合并配置
    cfg, _ := configutil.LoadOrDefaultJoinConfiguration(opt.cfgPath, opt.externalcfg)
}
3.6.3 Join Phase 执行
1. Preflight          → 系统预检查
2. ControlPlanePrepare → 仅 --control-plane 时:
   a. download-certs  → 从 kubeadm-certs Secret 下载证书
   b. certs           → 生成缺失证书
   c. kubeconfig      → 生成 admin/controller-manager/scheduler kubeconfig
   d. control-plane   → 生成 Static Pod 清单
3. CheckEtcd          → 检查 etcd 集群健康
4. KubeletStart       → 写入 kubelet 配置,启动 kubelet
5. ControlPlaneJoin   → 仅 --control-plane 时:
   a. etcd 扩容       → 添加新 etcd 成员
   b. 更新 kubeadm-config ConfigMap
   c. 标记节点

3.7 证书上传/下载机制(HA 控制平面)

UploadCerts 用于 kubeadm init --upload-certs,将共享证书加密后存储到 Secret:

func UploadCerts(client, cfg, key) error {
    // 1. 创建短期 Bootstrap Token(用于管理 Secret 的 TTL)
    tokenID, _ := createShortLivedBootstrapToken(client)

    // 2. 从磁盘读取证书并加密
    secretData, _ := getDataFromDisk(cfg, decodedKey)
    // 加密的证书列表:ca.crt, ca.key, front-proxy-ca.crt, front-proxy-ca.key,
    //                sa.pub, sa.key, etcd/ca.crt, etcd/ca.key

    // 3. 创建 Secret,设置 OwnerReference 为 Token Secret(Token 过期 → Secret 自动清理)
    apiclient.CreateOrUpdateSecret(client, &v1.Secret{
        ObjectMeta: metav1.ObjectMeta{
            Name:            "kubeadm-certs",
            Namespace:       "kube-system",
            OwnerReferences: ref,  // 引用 Bootstrap Token Secret
        },
        Data: secretData,  // 加密后的证书
    })

    // 4. 创建 RBAC 允许 Bootstrap Token 读取 Secret
    createRBAC(client)
}

DownloadCerts 在 join 控制平面时下载解密:

func DownloadCerts(client, cfg, key) error {
    secret, _ := getSecret(client)  // 获取 kubeadm-certs Secret
    secretData, _ := getDataFromSecret(secret, decodedKey)  // 解密
    for certOrKeyName, certOrKeyPath := range certsToTransfer(cfg) {
        writeCertOrKey(certOrKeyPath, secretData[certOrKeyName])  // 写入磁盘
    }
}

安全设计

  • 证书用 32 字节随机 key 加密(AES)
  • Secret 的 OwnerReference 指向 Bootstrap Token Secret(默认 2 小时 TTL → Secret 自动被 GC)
  • RBAC 限制只有 system:bootstrappers:kubeadm:default-node-token 组可读取

3.8 配置上传机制

UploadConfiguration 将集群配置持久化到 kubeadm-config ConfigMap:

func UploadConfiguration(cfg, client) error {
    // 1. 准备 ClusterConfiguration(清除 ComponentConfig 避免冗余)
    clusterConfigurationToUpload := cfg.ClusterConfiguration.DeepCopy()
    clusterConfigurationToUpload.ComponentConfigs = kubeadmapi.ComponentConfigMap{}

    // 2. 准备 ClusterStatus(记录控制平面节点端点)
    clusterStatus := &kubeadmapi.ClusterStatus{
        APIEndpoints: map[string]kubeadmapi.APIEndpoint{
            cfg.NodeRegistration.Name: cfg.LocalAPIEndpoint,
        },
    }

    // 3. 创建或更新 ConfigMap
    apiclient.CreateOrMutateConfigMap(client, &v1.ConfigMap{
        Data: map[string]string{
            "ClusterConfiguration": clusterConfigurationYaml,
            "ClusterStatus":        clusterStatusYaml,
        },
    }, func(cm) {
        cm.Data["ClusterConfiguration"] = clusterConfigurationYaml
        // 更新 ClusterStatus,追加新端点
        cs.APIEndpoints[cfg.NodeRegistration.Name] = cfg.LocalAPIEndpoint
    })

    // 4. 创建 RBAC 允许节点读取 ConfigMap(用于 join 和 upgrade)
}

3.9 Token 管理深度解析

Bootstrap Token 本质是 kube-system namespace 中类型为 bootstrap.kubernetes.io/token 的 Secret:

  • 格式:[a-z0-9]{6}.[a-z0-9]{16}(前 6 位是 Token ID,后 16 位是 Secret)
  • Secret 名称:bootstrap-token-<token-id>
  • Token 有 TTL,过期后由 tokencleaner controller 自动清理
  • 用途(Usages):signing(签名 cluster-info)、authentication(TLS Bootstrap 认证)
  • 组成员(Groups):默认加入 system:bootstrappers:kubeadm:default-node-token

3.10 预检查系统

preflight 包实现了一套 Checker 接口体系:

type Checker interface {
    Check() (warnings, errorList []error)
    Name() string
}

内置检查器包括:

  • ContainerRuntimeCheck:容器运行时是否运行
  • ServiceCheck:kubelet 服务是否启用
  • PortOpenCheck:端口是否可用
  • DirAvailableCheck:目录是否可用(如 /etc/kubernetes/
  • FileAvailableCheck:文件是否不存在
  • SystemVerificationCheck:内核参数、cgroup 等
  • IsPrivilegedUserCheck:是否以 root 运行
  • SwapCheck:是否关闭 swap
  • MemCheck:内存是否足够
  • ExternalEtcdVersionCheck:外部 etcd 版本
  • ImagePullCheck:镜像是否可拉取

RunInitNodeChecksRunJoinNodeChecks 分别组装不同的检查器列表执行。


四、Mermaid 图

图1:kubeadm 整体架构图

Utilities

API Types

Business Logic Phases

Workflow Engine

CLI Layer (cobra)

kubeadm root command

kubeadm init

kubeadm join

kubeadm reset

kubeadm upgrade

kubeadm token

kubeadm certs

configutil

kubeadm version

kubeadm alpha

workflow.Runner

workflow.Phase

RunData interface

preflight

certs

kubeconfig

control-plane

etcd

kubelet

upload-config

copy-certs

bootstrap-token

addons

InitConfiguration

ClusterConfiguration

JoinConfiguration

ClusterStatus

BootstrapToken

pkiutil

staticpod

apiclient

discovery

图2:kubeadm init 流程图

Yes

No

kubeadm init

解析 CLI 参数 / 配置文件

校验 InitConfiguration

1. Preflight Checks
系统/端口/运行时/镜像

2. Generate Certificates
CA → leaf certs + SA keys

3. Generate KubeConfig Files
admin/controller-manager/scheduler/kubelet

4. Write Kubelet Config
+ 启动 kubelet

5. Generate Control Plane Static Pods
apiserver/controller-manager/scheduler

6. Generate etcd Static Pod

7. Wait for Control Plane
轮询 /livez /readyz

8. Upload Config
kubeadm-config ConfigMap

8b. Upload Certs?
--upload-certs

加密证书 → kubeadm-certs Secret

9. Mark Control Plane
label + taint

10. Create Bootstrap Tokens
Secret + RBAC + cluster-info

11. Kubelet Finalize
切换到自动证书轮换

12. Install Addons
CoreDNS + kube-proxy

Print Join Command

完成

图3:kubeadm join 流程图

Token

File

Yes

No

Yes

No

No

Yes

kubeadm join

解析 CLI 参数

发现模式?

Token Discovery
连接 API Server → 获取 cluster-info
验证 CA cert hash

File Discovery
从 kubeconfig 文件读取

TLS Bootstrap
使用 Bootstrap Token CSR

1. Preflight Checks

--control-plane?

2. Control Plane Prepare

4. Kubelet Start

2a. Download Certs
有 --certificate-key?

从 kubeadm-certs Secret
下载 + 解密证书

2b. 生成缺失证书
CreatePKIAssets

2c. 生成 KubeConfig
admin/cm/scheduler

2d. 生成 Static Pod 清单
apiserver/cm/scheduler

3. Check etcd Health

--control-plane?

Worker Node 加入完成

5. Control Plane Join
etcd 扩容 + 更新 ClusterStatus + 标记节点

Control Plane Node 加入完成

图4:证书管理流程图

Yes

No

No

Yes

Yes

No

No

Yes

Yes

No

Yes

No

CreatePKIAssets

Local Etcd?

获取完整证书列表
10 certs

获取无 etcd 证书列表
5 certs

构建证书树
CertificateMap.CertTree

遍历每个 CA

尝试从磁盘加载 CA cert

CA cert 存在?

NewCertificateAuthority
生成 CA cert + key

写入 ca.crt + ca.key

用 CA key 签发叶子证书
遍历 leaves

验证 IsCA 属性

CA key 存在?

外部 CA 模式
验证所有叶子证书已预置

对每个 leaf

leaf 已存在?

NewCertAndKey
签发 cert + key

写入 .crt + .key

验证 SAN + CA 签名
有效期

还有 leaf?

还有 CA?

生成 Service Account 密钥对
sa.key + sa.pub

PKI 资产创建完成

图5:配置文件处理流程图

输出目标

处理流程

输入源

版本转换

v1beta2 外部版本
用户 YAML

转换函数
zz_generated.conversion.go

内部版本
kubeadm api

CLI Flags
--apiserver-advertise-address
--pod-network-cidr
--token 等

配置文件
InitConfiguration.yaml
JoinConfiguration.yaml

内部默认值
Scheme.Default()

合并配置
LoadOrDefaultInitConfiguration
LoadOrDefaultJoinConfiguration

配置验证
ValidateInitConfiguration
ValidateJoinConfiguration

Feature Gates
解析 + 版本校验

Mutation
MutateCgroupDriver

内部类型
kubeadmapi.InitConfiguration

kubeadm-config ConfigMap
ClusterConfiguration + ClusterStatus

磁盘文件
证书/kubeconfig/清单

图6:Control Plane 部署流程图

Yes

No

Scheduler 构建

getSchedulerCommand

--port=0 --bind-address=127.0.0.1
--leader-elect=true
--kubeconfig

合并 ExtraArgs

Controller Manager 构建

Yes

No

Yes

No

getControllerManagerCommand

基础参数
--port=0 --bind-address=127.0.0.1
--leader-elect=true

外部 CA?

清空 signing key

--cluster-signing-cert-file/key-file

PodSubnet 设置?

--allocate-node-cidrs
--cluster-cidr

合并 ExtraArgs

API Server 构建

External

Local

getAPIServerCommand

基础参数
--advertise-address
--secure-port=6443
--enable-admission-plugins=NodeRestriction

证书参数
--tls-cert-file
--client-ca-file
--kubelet-client-certificate

Etcd 模式?

--etcd-servers=外部端点
--etcd-cafile/certfile/keyfile

--etcd-servers=https://127.0.0.1:2379
本地 etcd 证书路径

Front Proxy 参数
--requestheader-*
--proxy-client-*

授权模式
默认 Node,RBAC

合并 ExtraArgs

control-plane Phase

GetStaticPodSpecs
构建 3 个 Pod 规格

kube-apiserver Pod

kube-controller-manager Pod

kube-scheduler Pod

patchesDir?

PatchStaticPod
应用 JSON/strategic merge patch

WriteStaticPodToDisk
写入 /etc/kubernetes/manifests/

Static Pod 文件已创建
kubelet 自动拉起 Pod

图7:etcd 集群初始化流程图

reset 场景(移除 etcd 成员)

Yes

No

RemoveStackedEtcdMemberFromCluster

创建 etcd 客户端

ListMembers

只剩 1 个成员?

跳过移除
最后成员无需 RemoveMember

GetMemberID
通过 peer URL 匹配

RemoveMember
通知集群移除成员

成员移除完成

join --control-plane 场景(扩容 etcd)

Yes

No

Yes

No

CreateStackedEtcdStaticPodManifestFile

创建 etcd 客户端
NewFromCluster

ListMembers
获取现有成员列表

新成员
已存在?

跳过 AddMember

AddMember
通知集群添加新成员

Announced new member
Updated member list

GetEtcdPodSpec
含新成员的 initial-cluster

--initial-cluster=member1=peerURL1,member2=peerURL2,...
--initial-cluster-state=existing
★ 关键:不是 new 而是 existing

patchesDir?

PatchStaticPod

写入 etcd.yaml

WaitForClusterAvailable
5s × 8 = 40s 超时

etcd 成员加入完成

init 场景(首个控制平面节点)

Yes

No

CreateLocalEtcdStaticPodManifestFile

检查 Etcd.External == nil

GetEtcdPodSpec
单节点 etcd

getEtcdCommand

--name=nodename
--initial-cluster=name=peerURL
--listen-client-urls=127.0.0.1:2379+advertise:2379
--client-cert-auth=true
--peer-client-cert-auth=true

patchesDir?

PatchStaticPod

写入 etcd.yaml
/etc/kubernetes/manifests/

etcd Static Pod 启动
单节点集群就绪

图8:Token 管理流程图

Upload Certs Token

kubeadm init --upload-certs

创建短期 Token
TTL: 2h
用途: 管理 kubeadm-certs Secret 生命周期

kubeadm-certs Secret
OwnerReference → Token Secret
Token 过期 → Secret 自动 GC

Token 使用流程

kubeadm init 创建默认 Token

创建 cluster-info ConfigMap
包含 CA 证书 + API Server 地址
用 Token 签名

创建 RBAC
允许 bootstrap token 读取 cluster-info

join 节点使用 Token

Token Discovery
读取 cluster-info → 验证 CA hash

TLS Bootstrap
Token 认证 → CSR → 自动签发 kubelet 证书

Token Delete

kubeadm token delete

解析 token ID
完整 token 或仅 ID

构造 Secret 名称
bootstrap-token-

Delete Secret from API Server

Token List

kubeadm token list

FieldSelector: type=bootstrap.kubernetes.io/token

列出 kube-system Secrets

BootstrapTokenFromSecret
解析每个 Secret

格式化输出
TOKEN / TTL / EXPIRES / USAGES / DESCRIPTION / GROUPS

Token Create

No

Yes

Yes

No

kubeadm token create

指定 token?

GenerateBootstrapToken
随机生成 token
格式: abcdef.0123456789abcdef

解析用户指定 token

构建 BootstrapToken 结构体

构建 Secret 对象
类型: bootstrap.kubernetes.io/token
名称: bootstrap-token-abcdef
包含: token-secret, usages, groups, expiration

CreateOrUpdateSecret
写入 API Server

--print-join-command?

打印完整 kubeadm join 命令

仅打印 token 字符串


五、核心设计模式总结

5.1 Phase Workflow 模式

kubeadm 最核心的架构模式。将复杂的 init/join 流程拆解为有序的 Phase 序列,每个 Phase 可独立执行、跳过或条件执行。Runner 引擎管理 Phase 的注册、排序、过滤和执行,并自动生成 CLI 子命令。

5.2 幂等性设计

几乎所有写入操作都遵循"先检查后写入"模式:

  • 证书:writeCertificateFilesIfNotExist → 已存在则验证有效性,有效则跳过
  • kubeconfig:createKubeConfigFileIfNotExists → 已存在则验证 CA/ServerURL
  • Static Pod:WriteStaticPodToDisk 直接覆盖(期望内容相同)
  • API 对象:CreateOrUpdate* → 存在则更新,不存在则创建

5.3 外部 CA 适配

通过文件存在性检测外部 CA:

  • ca.crt 存在 + ca.key 不存在 → 外部 CA 模式
  • 外部 CA 模式下:跳过证书生成,只生成 CSR + 私钥;禁止 upload-certs;清空 controller-manager 的 signing key

5.4 Dry-Run 支持

initDataDryRun() 标志影响所有路径选择:

  • 证书/kubeconfig/清单 写入临时目录而非真实路径
  • API 客户端使用 DryRunClient(仅打印操作不实际执行)
  • InitDryRunGetter 模拟部分 GET 请求(节点、ConfigMap 等)

5.5 配置层叠

配置合并优先级(从高到低):

  1. CLI flag 显式设置
  2. 配置文件 YAML
  3. 内部默认值(Scheme.Default()
  4. 运行时变异(MutateCgroupDriver 等)

5.6 安全引导(TLS Bootstrap)

双向信任建立流程:

  1. Node → API Server:通过 Discovery(Token 或 File)获取 CA 证书,验证 API Server 身份
  2. API Server → Node:通过 TLS Bootstrap(CSR 自动签发)让 API Server 信任 Node

六、关键常量参考

常量 含义
KubernetesDir /etc/kubernetes Kubernetes 配置根目录
CertificateValidity 10 年 所有签发证书有效期
DefaultControlPlaneTimeout 4 分钟 等待控制平面就绪超时
APICallRetryInterval 500ms API 调用重试间隔
EtcdListenClientPort 2379 etcd 客户端端口
EtcdListenPeerPort 2380 etcd 对等端口
DefaultCertTokenDuration 2 小时 上传证书 Token TTL
TLSBootstrapTimeout 5 分钟 TLS Bootstrap 超时
ClusterConfigurationConfigMapKey ClusterConfiguration ConfigMap 中 ClusterConfiguration 键
ClusterStatusConfigMapKey ClusterStatus ConfigMap 中 ClusterStatus 键
KubeadmCertsSecret kubeadm-certs 加密证书 Secret 名称
KubeadmConfigConfigMap kubeadm-config 集群配置 ConfigMap 名称
CertificateKeySize 32 字节 证书加密密钥长度

本文档严格基于 github.com/kubernetes/cmd/kubeadm/ 源码分析,覆盖了 CLI 层、Workflow 引擎、各 Phase 业务逻辑、API 类型体系、工具函数层的核心实现。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐