Cara Install Kubernetes dengan Ansible di 2 Server (Master dan Worker)

📅 Pendahuluan
Membangun cluster Kubernetes secara manual bisa memakan waktu dan rawan kesalahan. Dengan menggunakan Ansible, proses instalasi menjadi lebih otomatis, efisien, dan dapat direplikasi. Artikel ini membahas cara install Kubernetes dengan Ansible di 2 server, yaitu satu node master dan satu node worker.
🌐 Prasyarat
Sebelum memulai, pastikan:
- 💻 Memiliki 2 server dengan sistem operasi CentOS 8, Rocky Linux, AlmaLinux, atau RHEL.
- 🚀 Koneksi antar server berjalan dengan baik.
- 🔒 SSH root akses aktif, atau user dengan password yang dikonfigurasi pada file inventory.
- 🔎 Ansible sudah terinstal di server lain (sebagai control node).
Contoh Topologi:
- 🚜 Master:
master-k8s
(IP: 192.168.1.10) - 🚜 Worker:
worker-k8s
(IP: 192.168.1.20)
🔧 Struktur Project Ansible
root@ansible:~/k8s-ansible# tree
.
├── inventory
│ └── hosts.ini
├── playbook.yml
├── reset-k8s.yml
└── roles
├── common
│ └── tasks
│ └── main.yml
├── containerd
│ └── tasks
│ └── main.yml
├── cri-tools
│ └── tasks
│ └── main.yml
├── kubernetes
│ └── tasks
│ └── main.yml
├── master-init
│ └── tasks
│ └── main.yml
└── worker-join
└── tasks
└── main.yml
📜 Isi File Konfigurasi
Bagian ini berisi seluruh konfigurasi utama untuk deployment Kubernetes menggunakan Ansible. Mulai dari file inventory yang menentukan host master dan worker, playbook utama yang mengatur urutan eksekusi role, hingga reset playbook untuk membersihkan cluster. Setiap file memiliki fungsi spesifik dalam proses instalasi Kubernetes secara otomatis dan konsisten.
📂 inventory/hosts.ini
⚠️ Note: Jangan lupa ganti
ansible_host
,ansible_user
, danansible_ssh_pass
sesuai IP, username, dan password server yang kamu gunakan.
[master]
master-k8s ansible_host=192.168.1.10 ansible_user=root ansible_ssh_pass=passwd
[worker]
worker-k8s ansible_host=192.168.1.20 ansible_user=root ansible_ssh_pass=passwd
[all:vars]
ansible_python_interpreter=/usr/bin/python3
📄 playbook.yml
- name: Install dependencies and Kubernetes components
hosts: all
become: yes
roles:
- common
- containerd
- cri-tools
- kubernetes
- name: Initialize Kubernetes master
hosts: master
become: yes
roles:
- master-init
- name: Join worker node to cluster
hosts: worker
become: yes
roles:
- worker-join
🔄 reset-k8s.yml
Digunakan untuk reset cluster jika ingin install ulang.
- name: Reset Kubernetes Cluster
hosts: all
become: yes
tasks:
- name: Reset kubeadm
command: kubeadm reset -f
- name: Remove Kubernetes config
file:
path: "{{ item }}"
state: absent
loop:
- /etc/cni/net.d
- /root/.kube
- /etc/kubernetes
- /var/lib/etcd
- /var/lib/kubelet
- /var/lib/cni
- /run/containerd
- name: Reload containerd and kubelet
systemd:
name: "{{ item }}"
state: restarted
enabled: yes
loop:
- containerd
- kubelet
- name: Clear iptables rules
shell: |
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X
- name: Clear IPVS rules
shell: ipvsadm --clear
ignore_errors: yes
- name: Clean network interfaces
shell: |
ip link delete cni0 || true
ip link delete flannel.1 || true
ip link delete kube-bridge || true
ignore_errors: yes
📄 Isi File roles/common/tasks/main.yml
- name: Install required system packages
package:
name:
- tar
- wget
- curl
- iproute
- iproute-tc
- iptables
state: present
- name: Set hostname
hostname:
name: "{{ inventory_hostname }}"
- name: Update /etc/hosts
lineinfile:
path: /etc/hosts
line: "{{ item }}"
state: present
loop:
- "192.168.1.10 master-k8s"
- "192.168.1.20 worker-k8s"
- name: Overwrite resolv.conf with reliable nameservers
copy:
dest: /etc/resolv.conf
content: |
nameserver 8.8.8.8
nameserver 8.8.4.4
owner: root
group: root
mode: '0644'
- name: Enable kernel modules
copy:
dest: /etc/modules-load.d/k8s.conf
content: |
overlay
br_netfilter
- name: Load kernel modules
modprobe:
name: "{{ item }}"
loop:
- overlay
- br_netfilter
- name: Apply sysctl params
copy:
dest: /etc/sysctl.d/k8s.conf
content: |
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
- name: Reload sysctl
command: sysctl --system
- name: Disable swap
shell: |
swapoff -a
sed -i.bak -r 's/(.+ swap .+)/#\1/' /etc/fstab
(crontab -l 2>/dev/null; echo "@reboot /sbin/swapoff -a") | crontab -
📄 Isi File roles/containerd/tasks/main.yml
- name: Install required packages for containerd
package:
name: yum-utils
state: present
- name: Add Docker repository
shell: yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
args:
creates: /etc/yum.repos.d/docker-ce.repo
- name: Install containerd
package:
name: containerd.io
state: present
- name: Create containerd config directory
file:
path: /etc/containerd
state: directory
mode: '0755'
- name: Generate default containerd config
command: containerd config default
register: containerd_config
- name: Write containerd config file
copy:
dest: /etc/containerd/config.toml
content: "{{ containerd_config.stdout }}"
owner: root
group: root
mode: '0644'
- name: Set SystemdCgroup to true
replace:
path: /etc/containerd/config.toml
regexp: 'SystemdCgroup = false'
replace: 'SystemdCgroup = true'
- name: Restart and enable containerd
systemd:
name: containerd
enabled: true
state: restarted
📄 Isi File roles/cri-tools/tasks/main.yml
- name: Download crictl
get_url:
url: https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.33.0/crictl-v1.33.0-linux-amd64.tar.gz
dest: /tmp/crictl.tar.gz
- name: Extract crictl
unarchive:
src: /tmp/crictl.tar.gz
dest: /usr/local/bin
remote_src: yes
- name: Remove crictl archive
file:
path: /tmp/crictl.tar.gz
state: absent
- name: Create crictl config
copy:
dest: /etc/crictl.yaml
content: |
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 2
debug: true
📄 Isi File roles/kubernetes/tasks/main.yml
- name: Disable SELinux temporarily
command: setenforce 0
ignore_errors: yes
- name: Disable SELinux permanently
replace:
path: /etc/selinux/config
regexp: '^SELINUX=enforcing'
replace: 'SELINUX=permissive'
- name: Add Kubernetes repo
copy:
dest: /etc/yum.repos.d/kubernetes.repo
content: |
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/repodata/repomd.xml.key
- name: Install Kubernetes components
yum:
name:
- kubelet
- kubeadm
- kubectl
state: present
disable_excludes: kubernetes
- name: Enable and start kubelet
systemd:
name: kubelet
enabled: yes
state: started
📄 Isi File roles/master-init/tasks/main.yml
- name: Pull kubeadm images
command: kubeadm config images pull --cri-socket unix:///var/run/containerd/containerd.sock
- name: Initialize the Kubernetes Master
command: kubeadm init --pod-network-cidr=10.244.0.0/16 --cri-socket unix:///var/run/containerd/containerd.sock
register: kubeadm_init_output
args:
creates: /etc/kubernetes/admin.conf
- name: Set up kube config directory
file:
path: /root/.kube
state: directory
mode: '0700'
- name: Copy admin.conf to kube config
copy:
src: /etc/kubernetes/admin.conf
dest: /root/.kube/config
remote_src: yes
owner: root
group: root
mode: '0600'
- name: Deploy Calico network plugin
shell: kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
environment:
KUBECONFIG: /etc/kubernetes/admin.conf
- name: Generate kubeadm join command
shell: kubeadm token create --print-join-command
register: join_command
- name: Set join command fact
set_fact:
kube_join_command: "{{ join_command.stdout }} --cri-socket unix:///var/run/containerd/containerd.sock"
📄 Isi File roles/worker-join/tasks/main.yml
- name: Run join command on worker
command: "{{ hostvars['master-k8s']['kube_join_command'] }}"
🏃 Langkah Menjalankan Playbook
ansible-playbook -i inventory/hosts.ini playbook.yml
Hasil akhir setelah proses selesai akan menampilkan status semua task yang telah dijalankan.

🔄 Untuk Reset Cluster:
ansible-playbook -i inventory/hosts.ini reset-k8s.yml
🎯 Verifikasi Cluster Kubernetes
kubectl get nodes --kubeconfig=/etc/kubernetes/admin.conf

🏙️ Kesimpulan
Dengan pendekatan ini, kamu bisa dengan mudah membuat cluster Kubernetes hanya dengan satu perintah. Ansible membantu mengurangi kesalahan manual dan mempercepat proses deployment. 💡
mantap
Siap mas bro