Skip to content

Repository files navigation

Ansible Kubernetes Cluster Template

A reusable Ansible template for bootstrapping a single-control-plane Kubernetes cluster on Rocky Linux 9 (or a closely compatible RHEL-family distribution), using containerd and Flannel.

This repository is intentionally environment-neutral. The example inventory uses reserved example.com names and will not work until you copy and edit it.

Important

This is a production-style learning and bootstrap template, not a claim of a production-ready cluster. Production normally requires multiple control planes, a stable API endpoint, backups, monitoring, policy, and tested upgrades.

What it configures

  • Required kernel modules and networking sysctls
  • Optional firewalld rules for the API, kubelet, Flannel, and NodePort
  • containerd with the systemd cgroup driver
  • Kubernetes packages from the selected upstream minor-release repository
  • One kubeadm control plane, one or more workers, and pinned-release Flannel

Requirements

  • Ansible Core on the control host
  • SSH access with privilege escalation
  • Rocky Linux 9 or a compatible RHEL-family target
  • Unique hostnames, reachable addresses, and synchronized clocks
  • At least one control-plane host and one worker
  • Swap disabled, unless the role is explicitly allowed to disable it

Install the required collections:

ansible-galaxy collection install -r requirements.yml

Configure before running

  1. Copy the example inventory; the local copy is ignored by Git:

    cp inventory/hosts.ini inventory/hosts.local.ini
  2. Replace the example names and addresses:

    [k8s_master]
    control-01 ansible_host=192.0.2.10
    
    [k8s_workers]
    worker-01 ansible_host=192.0.2.21
    worker-02 ansible_host=192.0.2.22
    
    [k8s_cluster:children]
    k8s_master
    k8s_workers
  3. Review group_vars/k8s_cluster.yml:

    Variable Default Meaning
    kubernetes_version 1.36 Upstream minor repository
    pod_network_cidr 10.244.0.0/16 Flannel network; fixed by this template
    flannel_version v0.28.8 Pinned Flannel release
    manage_firewall true Manage firewalld rules
    disable_swap false Modify hosts to disable swap
    control_plane_endpoint first master address Endpoint advertised by kubeadm
    fetch_admin_kubeconfig false Copy cluster-admin credentials locally
  4. Verify SSH host keys. Host-key checking is enabled. Connect interactively once or maintain a managed known_hosts file; do not globally disable verification.

  5. Verify targeting and escalation:

    ansible -i inventory/hosts.local.ini k8s_cluster -m ping
    ansible -i inventory/hosts.local.ini k8s_cluster -b -m command -a id

Use --ask-become-pass when appropriate. Unrestricted passwordless sudo is not a requirement and should only be granted after considering the threat model.

Run

Preview the target set and proposed changes:

ansible-playbook -i inventory/hosts.local.ini site.yml --list-hosts
ansible-playbook -i inventory/hosts.local.ini site.yml --check --diff

Some kubeadm and runtime operations cannot be fully predicted in check mode. Run:

ansible-playbook -i inventory/hosts.local.ini site.yml

Individual phases must be run in this order:

ansible-playbook -i inventory/hosts.local.ini common.yml
ansible-playbook -i inventory/hosts.local.ini containerd.yml
ansible-playbook -i inventory/hosts.local.ini kubernetes.yml
ansible-playbook -i inventory/hosts.local.ini master.yml worker.yml

The last two must share one invocation because the join command is held only in Ansible memory. Join tokens are credentials and are never stored in this repo.

Kubeconfig and verification

The playbook does not overwrite the control host's kubeconfig. To opt in to a copy in the ignored artifacts/ directory:

ansible-playbook -i inventory/hosts.local.ini site.yml \
  -e fetch_admin_kubeconfig=true
export KUBECONFIG="$PWD/artifacts/admin.conf"
kubectl get nodes
kubectl get pods --all-namespaces

Protect admin.conf: it grants cluster-admin privileges. Use scoped credentials for normal operation.

Security and adaptation notes

  • Packages use state: present, avoiding surprise upgrades on normal reruns.
  • Flannel is pinned to a release rather than a mutable branch.
  • The full NodePort range and trusted CNI interfaces are broad defaults. Narrow these rules when workload ports and source networks are known.
  • API audit logging, encryption at rest, Pod Security admission policy, NetworkPolicies, external secrets, and CIS remediation need site-specific work.
  • kubeadm init is guarded by /etc/kubernetes/admin.conf. Rebuilding or changing an initialized cluster is a lifecycle operation, not a routine rerun.

Validate contributions

ansible-playbook -i inventory/hosts.ini site.yml --syntax-check
yamllint .
ansible-lint

The last two are optional developer tools and may need local or CI installation.

License

MIT; see LICENSE.

About

Ansible playbooks to provision and configure a multi-node Kubernetes cluster on Rocky Linux — automates containerd installation, control plane initialization, worker node joining, and Flannel CNI setup.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors