kubernetes/kubernetes
kubeadm
kubeadm bootstraps and upgrades minimum-viable conformant Kubernetes clusters. It does not manage nodes (that's the user's job), provision infrastructure, or configure CNI. Its scope is the control plane and the node-join handshake.
Directory layout
cmd/kubeadm/
├── kubeadm.go # main: builds command, calls cli.Run
└── app/
├── cmd/ # Top-level subcommands: init, join, reset, upgrade, certs, config, version, completion, kubeconfig, alpha, token
├── phases/ # Each subcommand is a sequence of phases; each phase is its own package
│ ├── certs/
│ ├── controlplane/
│ ├── etcd/
│ ├── kubeconfig/
│ ├── kubelet/
│ ├── markcontrolplane/
│ ├── upload-certs/
│ ├── upload-config/
│ ├── waitcontrolplane/
│ ├── join/
│ ├── upgrade/
│ └── ...
├── apis/ # ClusterConfiguration, InitConfiguration, JoinConfiguration types
├── componentconfigs/ # KubeletConfiguration, KubeProxyConfiguration handling
├── constants/ # Versioning constants, default ports, etc.
├── images/ # Default image references and tag computation
├── util/ # Helpers (kubeconfig, image pull, version detection, …)
└── ...The phase model
Every kubeadm command is a sequence of phases. A phase is:
- A name (
certs/ca,kubeconfig/admin,kubelet-start,etcd/local, …) - A description
- A
Runfunction - An optional list of dependency phases
Users can list, filter, or skip phases:
kubeadm init phase certs ca
kubeadm init --skip-phases=preflight,kubelet-start
kubeadm init phase preflightThis is essential for embedding kubeadm into higher-level tooling (cluster-api, automation pipelines) — they reach into specific phases instead of running the whole init.
What kubeadm init does
graph TD
Pre[preflight checks] --> Ca[generate CA + server/client certs]
Ca --> Kc[generate kubeconfigs<br/>admin / controller-manager / scheduler / kubelet]
Kc --> Etcd[render etcd static-pod manifest]
Etcd --> Cp[render control-plane static-pod manifests<br/>apiserver / kcm / scheduler]
Cp --> Wait[wait for kube-apiserver healthy]
Wait --> UploadConfig[upload ClusterConfiguration ConfigMap]
UploadConfig --> UploadCerts[upload control-plane certs Secret]
UploadCerts --> Bootstrap[create bootstrap-token, RBAC]
Bootstrap --> Markcp[mark this node as control-plane]
Markcp --> Addons[install kube-proxy + CoreDNS addons]The control-plane components are rendered as static pods under /etc/kubernetes/manifests/, picked up by the local kubelet. This is why kubelet must be running first; kubeadm doesn't operate kubelet, it just lays down the manifests.
What kubeadm join does
For control-plane nodes:
- Download the cluster's
cluster-infoConfigMap (signed by the cluster CA). - Use a bootstrap token to authenticate to the apiserver.
- Download the uploaded control-plane certs Secret.
- Generate node-specific certs and kubeconfigs.
- Render etcd + control-plane manifests.
- Wait for the new components to be healthy.
- Mark the node as control-plane.
For worker nodes:
- Download
cluster-infoand authenticate via bootstrap token. - Issue a CSR for kubelet client cert; wait for approval.
- Generate kubelet kubeconfig.
- Start kubelet (or restart it with the new config).
What kubeadm upgrade does
kubeadm upgrade is unique among phases-machines: it must coordinate across nodes. The flow is:
kubeadm upgrade plan— compute available upgrade paths from the current ClusterConfiguration's version.kubeadm upgrade apply v1.X.Y— on the first control-plane:- Update the static-pod manifests in place; kubelet rolls them.
- Migrate any deprecated config fields.
- Update the
cluster-infoConfigMap version.
kubeadm upgrade node— on every other node, including remaining control planes and workers.
A kubeadm upgrade does not upgrade kubelet itself; the operator does that out-of-band.
ClusterConfiguration
The single source of truth for a kubeadm cluster is the ClusterConfiguration object (declared in cmd/kubeadm/app/apis/kubeadm/v1beta4/types.go). It holds:
- Etcd config (local vs external)
- Networking config (pod subnet, service subnet, DNS domain)
- API server, controller-manager, scheduler extra args
- Image repository
- Certificates dir
- Feature gates
A single rendered ClusterConfiguration is uploaded to the cluster as a ConfigMap so subsequent join operations can read the same view.
Key source files
| File | Purpose |
|---|---|
cmd/kubeadm/kubeadm.go |
main |
cmd/kubeadm/app/cmd/init.go |
kubeadm init command + phase composition |
cmd/kubeadm/app/cmd/join.go |
kubeadm join |
cmd/kubeadm/app/cmd/upgrade/ |
Upgrade subcommand tree |
cmd/kubeadm/app/phases/certs/certs.go |
Cert generation phase |
cmd/kubeadm/app/phases/controlplane/manifests.go |
Static-pod manifests for kube-apiserver, KCM, scheduler |
cmd/kubeadm/app/phases/etcd/local.go |
Local-etcd static-pod manifest |
cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go |
Kubeconfig generators |
cmd/kubeadm/app/apis/kubeadm/v1beta4/types.go |
ClusterConfiguration / InitConfiguration |
cmd/kubeadm/app/constants/constants.go |
Default ports, paths, versions |
Integration points
- kubelet — kubeadm relies on kubelet running and watching
/etc/kubernetes/manifests/. - CNI — kubeadm doesn't install one. The user runs
kubectl apply -f <cni>afterkubeadm init. - CoreDNS / kube-proxy — installed as managed addons by kubeadm.
- External etcd — kubeadm can either run a local etcd as a static pod or use an external etcd cluster you provide.
Entry points for modification
- New phase: drop a package under
cmd/kubeadm/app/phases/<name>/exposing aNewPhasefunction, then register it in the parent command's phase tree (e.g.cmd/kubeadm/app/cmd/init.go). - New ClusterConfiguration field: bump the apiVersion (
v1beta5), add the field with conversion + validation, update phase code that reads it. - New default image: edit
cmd/kubeadm/app/constants/constants.goandcmd/kubeadm/app/images/images.go.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.