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