Panduan ini akan membahas cara membangun kubernetes cluster dengan kubeadm.
Kubeadm merupakan alat untuk membantu menyiapkan kluster kubernetes yang dapat berfungsi dalam waktu yang lebih singkat.
Kubeadm Setup Prerequisites
Simulasi ini memerlukan setidaknya 2 VM, 1 sebagai master dan 1 lagi sebagai worker dengan ketentuan seperti berikut.
- Master node minimal memilki 2 vCPU dan RAM 2GB
- Worker node minimal 1vCPU dan 2 GB RAM
Enable iptables Bridged Traffic
Eksekusi perintah berikut pada semua node.
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
sudo modprobe ip_vs
sudo modprobe ip_vs_rr
sudo modprobe ip_vs_wrr
sudo modprobe ip_vs_sh
sudo modprobe nf_conntrack
# sysctl params required by setup, params persist across reboots
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
# Apply sysctl params without reboot
sudo sysctl --system
Install CRI-O Runtime
Kluster kubernetes membutuhkan setidaknya satu dari container runtime seperti berikut.
- CRI-O
- Containerd
- Docker Engine (using cri-dockerd)
Pada simulasi ini akan menggunakan CRI-O.
Eksekusi perintah berikut pada semua node
OS="CentOS_8"
VERSION="1.26"
# setting repo
cat <<EOF | sudo tee /etc/yum.repos.d/crio.repo
[devel_kubic_libcontainers_stable]
name=Stable Releases of Upstream github.com/containers packages
type=rpm-md
baseurl=https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/
gpgcheck=1
gpgkey=https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/repodata/repomd.xml.key
enabled=1
[devel_kubic_libcontainers_stable_cri-o_$VERSION]
name=devel:kubic:libcontainers:stable:cri-o:$VERSION ($OS)
type=rpm-md
baseurl=https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/
gpgcheck=1
gpgkey=https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/repodata/repomd.xml.key
enabled=1
EOF
# Install crio
sudo yum -y install cri-o iproute-tc
OS
dan VERSION
dapat Anda sesuaikan mengikuti referensi pada url berikut cri-o.io
Edit file /etc/cni/net.d/100-crio-bridge.conflist
untuk mengubah cri-o subnet menjadi 192.168.0.0/16
{
"cniVersion": "1.0.0",
"name": "crio",
"plugins": [
{
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"hairpinMode": true,
"ipam": {
"type": "host-local",
"routes": [
{ "dst": "0.0.0.0/0" },
{ "dst": "::/0" }
],
"ranges": [
[{ "subnet": "10.10.0.0/16" }],
[{ "subnet": "1100:200::/24" }]
]
}
}
]
}
Tambahkan registries pada file /etc/containers/registries.conf
unqualified-search-registries = ["registry.access.redhat.com", "registry.redhat.io", "docker.io", "k8s.gcr.io", "quay.io"]
Selanjutnya aktifkan service cri-o
systemctl enable --now crio
Install Kubeadm & Kubelet & Kubectl
Eksekusi setiap langkah dibawah ini pada semua node
Buat file repo /etc/yum.repos.d/kubernetes.repo
lalu edit seperti berikut.
[kubernetes]
name=Kubernetes
baseurl=http://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
Konfig exclude
membuat package tidak dapat diupdate secara langsung sehingga versi kubeadm
dengan container runtime tetap sama.
Selanjutnya install kubelet
, kubeadm
, kubectl
yum -y --disableexcludes=kubernetes install kubelet kubeadm kubectl cri-tools-1.26.0-0
Enable kubelet service
systemctl enable kubelet
Initialize Kubeadm Master Node
Setting environment berikut dan ganti bagian IPADDR dengan IP Master node
IPADDR="192.168.100.11"
NODENAME=$(hostname -s)
POD_CIDR="10.10.0.0/16"
Setup master node sebagai control plane
kubeadm init --apiserver-advertise-address=$IPADDR \
--apiserver-cert-extra-sans=$IPADDR \
--pod-network-cidr=$POD_CIDR --node-name $NODENAME \
--control-plane-endpoint control-plane.srv1.host \
--cri-socket /var/run/crio/crio.sock
Pastikan control-plane.srv1.host sudah disetting A record ke IP master node. Jika tidak memiliki DNS local maka opsi –control-plane-endpoint tidak perlu dipakai. {: .prompt-tip }
Setelah proses init selesai, Anda akan mendapatkan output berserta lokasi file kubeconfig dan perintah join untuk dieksekusi pada Worker node.
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.100.11:6443 --token owlp40.q6v9qu0yik7zucks \
--discovery-token-ca-cert-hash sha256:59b3839365a47f92c81d038c6c5cede20cb575828819b7a45edd8934c9936cab
Simpan output tersebut untuk digunakan ketika menghubungkan control plane ke worker.
Selanjutnya jalankan perintah berikut agar kubectl dapat berinteraksi dengan cluster API
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Atau bisa juga dengan cara alternatif seperti
export KUBECONFIG=/etc/kubernetes/admin.conf
Verifikasi kubeconfig dengan menjalankan perintah kubectl
pada namespace kube-system
kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-5d78c9869d-gjpfr 1/1 Running 0 20m
coredns-5d78c9869d-xwt74 1/1 Running 0 20m
etcd-man 1/1 Running 1 20m
kube-apiserver-man 1/1 Running 1 20m
kube-controller-manager-man 1/1 Running 1 20m
kube-proxy-92w5l 1/1 Running 0 20m
kube-scheduler-man 1/1 Running 1 20m
Untuk cek status health cluster
kubectl get --raw='/readyz?verbose'
Cek info cluster
kubectl cluster-info
Cek pods di semua namespace
kubectl get pods -A
Cek logs pods
kubectl logs -n kube-system kube-controller-manager-man
Cek events pods
kubectl get events -n kube-system
Masuk ke mode terminal container
kubectl exec -it -n kube-system pod/etcd-man -- bash
Install Calico Network Plugin
Setelah membuat cluster dengan kubeadm. Selanjutnya Anda dapat men-deploy network pod ke cluster.
Untuk referensi plugin network dan plugin lain dapat Anda cek melalui Addon Kubernetes
Untuk install calico network plugin ke cluster
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml
Tunggu beberapa saat lalu cek pods pada namespace kube-system untuk memastikan calico sudah berhasil di-deploy.
# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-85578c44bf-bs4wg 1/1 Running 0 77m
calico-node-p7csl 1/1 Running 0 77m
coredns-5d78c9869d-2mnfk 1/1 Running 0 156m
coredns-5d78c9869d-cbkxs 1/1 Running 0 156m
etcd-man 1/1 Running 1 156m
kube-apiserver-man 1/1 Running 1 156m
kube-controller-manager-man 1/1 Running 5 (69m ago) 156m
kube-proxy-vk5tr 1/1 Running 0 156m
kube-scheduler-man 1/1 Running 5 (69m ago) 156m
Join Worker Nodes To Kubernetes Master Node
Untuk menambahkan worker ke master node, gunakan perintah join yang Anda dapat setelah membuat cluster dengan kubeadm.
kubeadm join 192.168.100.11:6443 --token owlp40.q6v9qu0yik7zucks \
--discovery-token-ca-cert-hash sha256:59b3839365a47f92c81d038c6c5cede20cb575828819b7a45edd8934c9936cab
Jika Anda kehilangan token atau lupa menyalinnya. Anda dapat membuat token dengan perintah
kubeadm token create --print-join-command
kubeadm join 192.168.100.11:6443 --token ryrezn.kj86cqm9p39wlmb0 \
--discovery-token-ca-cert-hash sha256:1edc1ac23b1cf0ff3b00742de1f7d894f19286a19acf6a1a692a74f057e48732
Cek node pada cluster kubernetes
kubectl get nodes
NAME STATUS ROLES AGE VERSION
man Ready control-plane 173m v1.27.3
worker1 Ready <none> 2m23s v1.27.3
Roles <none>
sama dengan role worker. Anda juga dapat menabambahkan label untuk menandai jika node tersebut merupakan worker dengan perintah
kubectl label node worker1 node-role.kubernetes.io/worker=worker
NAME STATUS ROLES AGE VERSION
man Ready control-plane 3h v1.27.3
worker1 Ready worker 9m10s v1.27.3
Setup Kubernetes Metrics Server
Kubernetes Metrics Server berfungsi untuk mengetahui pemakaian resource pada setiap nodes dan pods.
Untuk install metric server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.3/components.yaml
Selanjutnya edit pod metric server dengan menambahkan konfig hostNetwork
dan --kubelet-insecure-tls
KUBE_EDITOR="nano" kubectl edit \
-n kube-system \
-f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.3/components.yaml
- apiVersion: apps/v1
kind: Deployment
metadata:
...
spec:
hostNetwork: true
containers:
- args:
- --cert-dir=/tmp
- --secure-port=4443
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
- --kubelet-insecure-tls=true
...
Edit pod metric apabila Anda mendapatkan error because it doesn’t contain any IP SANs" node="" yang menyebabkan pod tidak ready. {: .prompt-tip }
Tunggu pod metric server ready. Lalu coba test dengan perintah
kubectl top node
kubectl top pods -A
Deploy A Sample Nginx Application
Setelah semua komponen untuk membuat klaster kubernetes sudah di-deploy dan berfungsi. Selanjutnya buat sampel aplikasi dengan menggunakan Nginx untuk pengetesan.
Buat file deployment.yaml
. Edit seperti berikut
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Lalu buat file service.yaml
dan edit untuk mengekspos Nginx deployment ke external IP.
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
allocateLoadBalancerNodePorts: true
externalIPs:
- 172.12.70.129
externalTrafficPolicy: Cluster
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- nodePort: 31460
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
sessionAffinity: None
type: LoadBalancer
status:
loadBalancer: {}
External IP yang akan digunakan harus terpasang pada interface salah satu node didalam cluster {: .prompt-tip }
Deploy ke dalam cluster
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
Contoh full script dapat Anda temukan pada sample-app.yaml
Setelah pods running di node worker. Test akses nginx melalui http://172.12.70.129
Reset Cluster
Untuk reset atau menghapus cluster agar dapat dimulai dari awal (‘kubeadm init’ or ‘kubeadm join’)
kubeadm reset -f
Lalu hapus beberapa file pada path /etc/cni/net.d
dan sisakan hanya file 100-crio-bridge.conflist dan 200-loopback.conflist