Skip to main content

Setup Kubernetes Cluster dengan Kubeadm dan cri-dockerd

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

Selanjutnya install package.

yum -y install vim bash-completion wget curl yum-utils lvm2 device-mapper-persistent-data iproute-tc

Install Docker Engine Runtime
#

Kluster kubernetes membutuhkan setidaknya satu dari container runtime seperti berikut.

  • CRI-O
  • Containerd
  • Docker Engine (using cri-dockerd)

Pada simulasi ini akan menggunakan Docker Engine.

Eksekusi perintah berikut pada semua node

Install docker.

curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

Lalu install cri-dockerd.

yum -y install https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.4/cri-dockerd-0.3.4-3.el8.x86_64.rpm

Setting driver cgroup dengan membuat file /etc/docker/daemon.json lalu salin konfigurasi berikut.

{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "insecure-registries": [
     "k8s.gcr.io",
     "docker.io",
     "quay.io",
     "registry.access.redhat.com"
  ]
}

Start dan enable service docker cri-docker

systemctl enable --now docker cri-docker

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 /run/cri-dockerd.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 flannel 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

Unduh manifest flannel

wget https://github.com/flannel-io/flannel/releases/download/v0.22.0/kube-flannel.yml

Edit network 10.244.0.0/16 menyesuaikan POD_CIDR.

  net-conf.json: |
    {
      "Network": "10.10.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }

Deploy flannel network plugin ke cluster

kubectl apply -f kube-flannel.yml

Tunggu beberapa saat lalu cek pods pada namespace kube-system untuk memastikan flannel sudah berhasil di-deploy.

# kubectl get pods -n kube-flannel
NAME                    READY   STATUS    RESTARTS     AGE
kube-flannel-ds-9r9f5   1/1     Running   1 (9h ago)   9h

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

Related