E-NO
Kubeadm Init CI/CD 7 Min Read

Kubeadm Init CI/CD Automation with Practical Examples: A Practical Implementation Guide

calendar_today Published: 2026-08-26
update Last Updated: 2026-08-26
analytics SEO Efficiency: 100%
Technical guide illustration for Kubeadm Init CI/CD Automation with Practical Examples: A Practical Implementation Guide.

Introduction

Kubeadm init is the foundation for bootstrapping Kubernetes control planes, but running it manually in production introduces inconsistency, configuration drift, and unrepeatable deployments. Automating kubeadm init within a CI/CD pipeline addresses these risks by enforcing version control, preflight validation, and automated rollback. This article provides a practical implementation guide for DevOps engineers, platform teams, and technical startup leads who need to manage kubeadm init as code. We focus on operational safety: observe before changing, limit blast radius, use placeholders instead of secrets, verify results, and document recovery paths.

You will learn how to inventory your environment, manage kubeadm configuration safely, verify cluster health, handle common failure modes, and build an operations checklist. Every section includes concrete commands, expected output, failure signals, and recovery decisions tailored to kubeadm init automation.

Version and Environment Inventory

Before automating kubeadm init, you must know exactly what you are working with: installed Kubernetes version, container runtime, network plugin, OS, and hardware topology. This inventory prevents version mismatches and ensures your pipeline uses the correct binaries and configuration.

Step 1: Capture Installed Versions

Run these read-only commands on the target node to record the current state:

# Kubernetes components
kubeadm version -o short   # e.g., v1.28.2
kubelet --version          # e.g., Kubernetes v1.28.2
kubectl version --client   # e.g., Client Version: v1.28.2

# Container runtime (example for containerd)
containerd --version       # e.g., containerd 1.7.7

# OS and kernel
cat /etc/os-release | head -n 2   # e.g., Ubuntu 22.04.3 LTS
uname -r                          # e.g., 5.15.0-91-generic

Expected output: version strings matching your planned cluster version. Record these in a machine-readable file, e.g., inventory.yaml, and commit it to your configuration repository.

Step 2: Verify Prerequisites

Kubeadm requires specific kernel parameters, ports, and system settings. Check them with:

# Ensure required kernel modules are loaded
lsmod | grep br_netfilter    # Expected: br_netfilter

# Verify sysctl settings for networking
sysctl net.bridge.bridge-nf-call-iptables net.ipv4.ip_forward
# Expected: net.bridge.bridge-nf-call-iptables = 1, net.ipv4.ip_forward = 1

# Check swap is disabled (required)
swapon --show                # Expected: no output

# Verify necessary ports are not in use (e.g., 6443 for API server)
ss -tulpn | grep 6443        # Expected: no output before init

If any prerequisite fails, fix it before proceeding. For example, to disable swap permanently:

sudo sed -i '/ swap / s/^/#/' /etc/fstab
sudo swapoff -a

Step 3: Identify Deployment Topology

Document the cluster topology: single control-plane node vs. multi-master, node IP addresses, and network ranges. Example:

  • Control plane node IP: 192.168.1.10
  • Pod network CIDR: 10.244.0.0/16 (for Flannel)
  • Service CIDR: 10.96.0.0/12
  • Container runtime endpoint: unix:///run/containerd/containerd.sock

Store these values as variables in your CI/CD pipeline (e.g., CONTROL_PLANE_IP, POD_CIDR).

Blast Radius and Recovery

Changing versions or topology affects the entire cluster. Limit changes to one component at a time. For example, if you upgrade containerd, test it with a non-production node first. Have a rollback plan: keep previous binaries and configuration snapshots so you can restore the node if the upgrade fails.

Quick check 1 of 2

What happens during the first step of the `kubeadm init` workflow?

According to reference [1], the first step in the `kubeadm init` workflow is to run a series of pre-flight checks to validate the system state before making changes.

Safe Configuration Path

Kubeadm uses a configuration file (kubeadm-config.yaml) to define cluster parameters. Automating kubeadm init requires this file to be version-controlled, validated, and applied consistently.

Step 1: Generate Base Configuration

Use kubeadm config print init-defaults to get the default configuration for your version, then customize it. Example for Kubernetes v1.28:

kubeadm config print init-defaults --kubeconfig /dev/null > kubeadm-config.yaml

The output includes sections like apiVersion, kind, clusterName, controlPlaneEndpoint, networking, etc. Edit the file with your topology values:

apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.1.10
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///run/containerd/containerd.sock
  name: control-plane-01
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.2
controlPlaneEndpoint: "192.168.1.10:6443"
networking:
  podSubnet: "10.244.0.0/16"
  serviceSubnet: "10.96.0.0/12"
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd

Save this file in your Git repository, e.g., kubeadm/init-config.yaml.

Step 2: Validate Configuration Before Applying

Run kubeadm config validate to check for syntax and version compatibility:

kubeadm config validate --config kubeadm/init-config.yaml

Expected output: no errors. If validation fails, the command exits with a non-zero code and prints the specific problem.

Step 3: Apply Configuration in Dry-Run Mode

Before actual init, run a dry-run to see what kubeadm would do:

kubeadm init --config kubeadm/init-config.yaml --dry-run

Expected output: a description of actions without making changes. Review the output for any unexpected actions.

Step 4: Automate in CI/CD Pipeline

Your pipeline should:

  1. Checkout the configuration file from Git.
  2. Run kubeadm config validate.
  3. Run dry-run.
  4. If all pass, apply the configuration on a designated node.
  5. Capture the kubeadm init output, which includes the kubeadm join command and admin kubeconfig location.

Example Jenkins pipeline stage:

stage('Kubeadm Init') {
    steps {
        sh 'kubeadm config validate --config kubeadm/init-config.yaml'
        sh 'kubeadm init --config kubeadm/init-config.yaml --dry-run'
        sh 'kubeadm init --config kubeadm/init-config.yaml'
    }
}

Important: never hardcode secrets like tokens in the configuration file. Use placeholders and inject secrets from your CI/CD secret manager. For example, the bootstrapTokens section can be omitted; kubeadm generates a token automatically. If you need a specific token, use a variable like $KUBEADM_TOKEN and set it in the pipeline environment.

Blast Radius and Recovery

Applying a configuration can disrupt the entire cluster if wrong. Restrict pipeline execution to a controlled environment (e.g., a test node) and require manual approval for production. Keep previous configuration versions in Git; you can revert by checking out an older commit and reapplying after a kubeadm reset.

Verification and Diagnostics

After kubeadm init, verify that the cluster is healthy before proceeding with any other automation.

Step 1: Check Cluster Status

Set up kubeconfig for the admin user:

mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

export KUBECONFIG=$HOME/.kube/config

Then run:

kubectl get nodes

Expected output: the control-plane node appears with status Ready (may take a minute). If status is NotReady, check the node conditions with kubectl describe node <node-name>.

Check the control plane pods:

kubectl get pods -n kube-system

Expected: all pods Running, including kube-apiserver, kube-controller-manager, kube-scheduler, etcd, and the network plugin pods (e.g., Flannel). If any pod is CrashLoopBackOff, investigate its logs.

Step 2: Verify CoreDNS and Network

Ensure DNS is working:

kubectl get pods -n kube-system -l k8s-app=kube-dns

Expected: CoreDNS pods running. Test DNS resolution:

kubectl run -it --rm dns-test --image=busybox:1.28 -- nslookup kubernetes.default

Expected output: the service IP for kubernetes.default is returned.

Check the network plugin pods:

kubectl get pods -n kube-system | grep flannel   # if using Flannel

Expected: flannel pods running.

Step 3: Verify Kubelet Health

On the node, check kubelet service status:

systemctl status kubelet

Expected: active (running). Check kubelet logs for errors:

journalctl -u kubelet -n 50 --no-pager

Step 4: Diagnostic Commands for Common Issues

  • API server not responding: curl -k https://<control-plane-ip>:6443/healthz should return ok.
  • etcd issues: kubectl -n kube-system exec -it etcd-<node-name> -- etcdctl endpoint health.
  • Node not ready: kubectl describe node <node-name> to see conditions and events.

Blast Radius and Recovery

Verification commands are read-only and safe. If verification fails, avoid making changes until you diagnose the root cause. Use the diagnostics commands to gather information, then decide on a recovery action from the Failure Modes section.

Quick check 2 of 2

What command can be used to invoke each task of `kubeadm init` individually?

Reference [2] states that the `kubeadm init phase` command allows users to invoke each task individually.

Failure Modes and Recovery

Automated kubeadm init can fail for various reasons. Here are common failure modes, their symptoms, and recovery steps.

Failure Mode 1: Preflight Checks Fail

Symptom: kubeadm init exits with an error like [ERROR Port-6443]: Port 6443 is in use or [ERROR Swap]: running with swap on is not supported.

Recovery:

  • Identify the specific error from output.
  • Fix the issue, e.g., free port 6443 by stopping the conflicting process, or disable swap as shown earlier.
  • Re-run the pipeline.

Failure Mode 2: Timeout During Init

Symptom: kubeadm init hangs and eventually times out, often due to network issues or container runtime problems.

Recovery:

  • Check container runtime status: systemctl status containerd.
  • Check logs: journalctl -u kubelet -n 100.
  • Verify network connectivity to required endpoints (e.g., registry.k8s.io).
  • If the issue persists, run kubeadm reset to clean up partial state, then retry.

Failure Mode 3: Certificate Errors

Symptom: kubeadm init fails with certificate-related errors, such as expired certs or wrong permissions.

Recovery:

  • Certificates are generated during init. If re-initializing after a reset, ensure old certs are removed (kubeadm reset does this).
  • If you need to renew certificates post-init, use kubeadm certs renew all.

Failure Mode 4: Network Plugin Not Working

Symptom: Nodes are Ready but pods cannot communicate; CoreDNS pods are Pending or CrashLoopBackOff.

Recovery:

  • Check that the pod network CIDR matches your network plugin's expectation (e.g., Flannel expects 10.244.0.0/16).
  • Reinstall the network plugin with correct manifests.
  • If necessary, reset and re-init with correct CIDR.

General Rollback Strategy

If a failed init leaves the node in an inconsistent state, perform a full reset:

kubeadm reset -f
sudo rm -rf /etc/cni/net.d
sudo ip link delete cni0
sudo systemctl restart containerd

Then re-run the pipeline from a clean slate. Document the rollback steps in your runbook and test them periodically.

Blast Radius and Recovery

Always attempt recovery in a non-production environment first. If a production node fails, follow your incident response plan, which should include notifying stakeholders and possibly restoring from a snapshot if available.

Operations Checklist

Use this checklist before and after every kubeadm init automation run.

Pre-Run Checklist

  • [ ] Inventory captured: versions of kubeadm, kubelet, containerd, OS kernel (verified with commands in Section 1).
  • [ ] Prerequisites met: swap disabled, kernel modules loaded, sysctl settings correct, ports free.
  • [ ] Configuration file kubeadm/init-config.yaml committed and validated with kubeadm config validate.
  • [ ] Dry-run executed and output reviewed.
  • [ ] Secrets managed: no hardcoded tokens or keys in configuration; secret injection configured.
  • [ ] Blast radius assessed: changes limited to target node, rollback plan ready (e.g., kubeadm reset command documented).
  • [ ] Approval obtained for production execution.

Post-Run Checklist

  • [ ] kubeadm init completed without errors; output saved to log file.
  • [ ] Admin kubeconfig copied and permissions set correctly.
  • [ ] kubectl get nodes shows control-plane node Ready.
  • [ ] All control plane pods running (kubectl get pods -n kube-system).
  • [ ] CoreDNS resolution test passed.
  • [ ] Network plugin pods running.
  • [ ] Kubelet service active and logs free of critical errors.
  • [ ] Cluster join command securely stored for future worker nodes.
  • [ ] Documentation updated with any deviations or additional steps.

Example Operations Runbook Entry

For a typical init on a fresh Ubuntu 22.04 node:

StepCommandExpected ResultFailure SignalRecovery
1. Inventorykubeadm version -o shortv1.28.2Command not foundInstall matching kubeadm package
2. Validate configkubeadm config validate --config kubeadm/init-config.yamlNo outputValidation errorsFix config syntax
3. Dry-runkubeadm init --config kubeadm/init-config.yaml --dry-runDescription outputUnexpected actionsAdjust config
4. Initkubeadm init --config kubeadm/init-config.yamlSuccess message, kubeconfig pathError (e.g., preflight failure)Diagnose, reset if needed
5. Verify nodeskubectl get nodesNode ReadyNotReadyCheck kubelet, network plugin
6. Verify podskubectl get pods -n kube-systemAll RunningPods CrashLoopInvestigate logs

Conclusion

Automating kubeadm init in CI/CD pipelines transforms cluster bootstrap from a manual, error-prone process into a repeatable, auditable operation. By versioning configuration, validating before applying, verifying post-init, and planning for failure, you ensure consistency and reduce downtime. This guide provided a structured approach with concrete commands and checklists. Start with one low-risk verification: capture your current environment inventory, run the documented checks, and compare results. Then gradually integrate the steps into your pipeline. Remember that a reliable technical workflow makes failure visible, protects sensitive values, limits changes to intended resources, and defines recovery verification before an incident forces the decision.

Related Research

Article Quality Score

Reader usefulness 100%
  • check_circle Reader-ready guide
  • check_circle Practical examples included
  • check_circle Clean SEO article URL