Cluster Swarm kita berjalan, tetapi di luar sana — di lowongan pekerjaan, di dokumentasi penyedia cloud, di rapat arsitektur — nama yang paling sering disebut adalah Kubernetes. Kabar baiknya: kita tidak memulai dari nol. Kubernetes dan Docker berbagi fondasi yang sama (image OCI dan runtime container) dan membagi sebagian besar konsep yang baru saja kita praktikkan di Swarm — desired state, reconciliation loop, penjadwalan lintas node. Yang berbeda adalah kosakata dan bentuk perintahnya. Chapter ini adalah kamus penerjemah: kita memetakan setiap istilah Kubernetes ke padanannya di dunia Docker yang sudah kita kuasai, membedah arsitektur control plane yang menjalankan semuanya, dan menjalankan Deployment pertama dari sebuah manifest YAML yang bentuknya akrab bagi siapa pun yang sudah menulis compose.yaml.

Kamus Docker ke Kubernetes #

Delapan istilah berikut menutup hampir seluruh percakapan Kubernetes sehari-hari:

Istilah KubernetesPadanan di dunia Docker kita
Podcontainer — unit terkecil yang dijadwalkan, walaupun satu pod bisa memuat beberapa container
Deploymentservice Compose plus replikanya — deklarasi berapa banyak salinan aplikasi yang harus hidup
Servicenetwork alias plus load balancer — satu nama stabil di depan replika-replika yang berganti-ganti
ConfigMap dan Secretenvironment variable, configs, dan secrets Compose — konfigurasi dan kredensial yang disuntikkan ke pod
Namespaceproject Compose — ruang nama yang mengelompokkan dan memisahkan kumpulan objek
Nodehost — satu mesin anggota cluster
Ingressreverse proxy di depan stack — satu pintu HTTP dengan aturan jalur menuju service internal
kubectldocker CLI — klien baris perintah yang berbicara ke otak cluster

Kamus ini benar untuk percakapan sehari-hari, tetapi dua selisih nyata perlu dibedah agar penerjemahan kita tidak menyesatkan. Pertama, pod bukan container: pod adalah kelompok container yang dijadwalkan sebagai satu kesatuan ke satu node, berbagi network namespace (saling menemukan di localhost), dan boleh berbagi volume. Pola sidecar lahir dari sini — container pencatat log atau proxy yang menempel erat pada aplikasi jadi satu pod, sesuatu yang di Compose kita modelkan sebagai service terpisah dengan network sendiri. Kedua, identitas objek berbasis label dan selector: sebuah Deployment tidak “memiliki” pod lewat nama atau prefix project, melainkan lewat label app: web yang dicocokkan oleh selector; siapa pun yang berlabel itu dianggap anggota. Identitas menjadi kueri, bukan penamaan — dan seluruh mekanisme Service, scaling, dan rolling update di Kubernetes dibangun di atas pasangan label-selector ini.

Arsitektur Control Plane dan Node #

Tabel docker node ls di chapter sebelumnya memperlihatkan dua peran — manager dan worker; Kubernetes memecah peran manager menjadi komponen yang lebih terperinci:

Mari kita telaah peran tiap komponen dan panahnya:

  1. API server — pintu tunggal seluruh cluster: kubectl, scheduler, dan controller semuanya berbicara lewat API ini; tidak ada komponen yang menulis langsung ke etcd.
  2. etcd — penyimpan desired state dan status cluster — padanan pembukuan Raft di manager Swarm; seluruh kebenaran cluster hidup di sini.
  3. scheduler — memilih node untuk setiap pod yang baru lahir, memakai pembukuan kapasitas yang kita kenal dari Chapter Resource di Swarm.
  4. controller-manager — kumpulan reconciliation loop: pengawas replika Deployment, node yang mati, sampai service endpoint — paradigma desired state yang sama, dikerjakan berlapis-lapis.
  5. kubelet — agen di tiap node yang mengawasi “pod apa saja milikku” dan memastikan container-nya benar-benar berjalan; padanannya adalah peran daemon di worker Swarm.
  6. kube-proxy — menjaga aturan jaringan di node agar nama Service selalu mengarah ke pod yang sehat.
  7. containerd — runtime yang menjalankan container — komponen yang sama persis yang hidup di bawah dockerd sepanjang Course ini; kita menenggelamkannya lebih dalam di Chapter Container Runtime.

Paralelnya dengan Swarm nyata: control plane adalah manager yang dipecah tugasnya, node worker tetap worker, dan satu-satunya bahasa yang melintasi keduanya adalah deklarasi melalui API. Bahkan cara berpikir operatornya pun sama — kita mendeklarasikan keadaan, sistem merekonsiliasi.

Manifest Deployment Pertama #

Di Docker kita menulis compose.yaml; di Kubernetes kita menulis manifest. Berkas deployment.yaml berikut mendeklarasikan tiga replika nginx:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:1.27
          ports:
            - containerPort: 80

Mari kita telaah manifest tersebut:

  1. apiVersion: apps/v1 dan kind: Deployment — setiap objek Kubernetes dinyatakan dengan grup API dan jenisnya; apps/v1 adalah rumah objek-objek aplikasi seperti Deployment.
  2. metadata.name: web — nama objek di dalam namespace, padanan nama service di compose.yaml.
  3. spec.replicas: 3 — desired state jumlah pod; kalimat “saya ingin 3 replika” yang sama dengan --replicas 3 di Swarm.
  4. selector.matchLabels — Deployment mengklaim seluruh pod berlabel app: web sebagai wilayahnya.
  5. template.metadata.labels — pod yang diciptakan Deployment diberi label app: web; label ini wajib cocok dengan selector, dan API menolak manifest yang mismatch dengan galat validasi.
  6. template.spec.containers — image nginx:1.27 dan containerPort: 80; containerPort bersifat dokumentasi seperti EXPOSE di Dockerfile yang kita bahas di Chapter EXPOSE dan Port — penerbitan port ke luar tetap urusan objek Service atau Ingress.

Manifest itu dikirim ke cluster dengan satu perintah deklaratif:

bash
$ kubectl apply -f deployment.yaml

Output yang Dihasilkan:

text
deployment.apps/web created
bash
$ kubectl get pods

Output yang Dihasilkan:

text
NAME                  READY   STATUS    RESTARTS   AGE
web-25abb3706-8ko0t   1/1     Running   0          48s
web-25abb3706-q713x   1/1     Running   0          48s
web-25abb3706-w1wf7   1/1     Running   0          48s

Mari kita telaah tabel pod tersebut:

  1. Nama web-25abb3706-8ko0t — Deployment menciptakan ReplicaSet (hash 25abb3706) yang menciptakan pod (akhiran acak); tiga tingkatan identitas ini yang membuat rolling update bersih — versi baru berarti ReplicaSet baru dengan hash baru.
  2. READY 1/1 — jumlah container di pod yang siap dibandingkan totalnya; pod dengan sidecar tampil 2/2.
  3. RESTARTS 0 — penghitung self-healing; pod yang crash dihidupkan ulang oleh kubelet dan angkanya bertambah — indikator crash loop yang kita kenal dari Chapter Mengatasi Container Crash.
  4. AGE 48s — umur pod, yang pada rolling update akan memperlihatkan dua generasi umur berdampingan seperti kolom CREATED di Compose.

Skala berubah dengan menggeser desired state — pola yang sama, perintah yang lebih pendek:

bash
$ kubectl scale deployment web --replicas=5

Output yang Dihasilkan:

text
deployment.apps/web scaled

Pengendali replika melihat selisih dua pod, menjadwalkan keduanya, dan kubectl get pods beberapa saat kemudian menampilkan lima baris. Menurunkan angka menghapus pod ekstra — cabang “aktual lebih dari desired” dari diagram reconciliation kita, tanpa satu baris kode tambahan.

Padanan Harian #

Sebagian besar pekerjaan harian operator dapat diterjemahkan langsung:

Kebutuhan sehari-hariDi DockerDi Kubernetes
Melihat yang sedang berjalandocker pskubectl get pods
Memeriksa detail dan kejadiandocker inspectkubectl describe pod
Membaca logdocker logskubectl logs
Masuk ke dalam containerdocker exec -it ... shkubectl exec -it ... -- sh
Mengganti image rilis barudocker service update --imagekubectl set image atau edit manifest lalu apply
Mundur dari rilis burukdocker service rollbackkubectl rollout undo deployment/web
Mendeploy dari berkasdocker stack deploy -c compose.yamlkubectl apply -f deployment.yaml

Dua baris terakhir menunjukkan selisih filosofi yang halus namun penting. docker service update --image adalah perintah imperatif — kita mengubah keadaan cluster dari terminal, dan compose.yaml di laptop mulai berbohong. kubectl apply -f adalah perintah deklaratif — berkas manifest adalah sumber kebenaran, diulang berkali-kali hasilnya tetap sama, dan kebiasaan menyimpan manifest di Git melahirkan pola GitOps yang kita bocorkan di Chapter Pengantar Container Orchestration.

Tabel Perintah kubectl Dasar #

PerintahPeran
kubectl get pods / get deployments / get svcdaftar objek cluster beserta status ringkasnya
kubectl describe pod <nama>rincian objek lengkap dengan kejadian (events) terakhir
kubectl logs <pod>membaca log satu pod
kubectl apply -f <berkas>mendeklarasikan atau memperbarui objek dari manifest
kubectl scale deployment <nama> --replicas=Nmengubah jumlah replika
kubectl rollout status / rollout undomengamati dan memundurkan sebuah rilis
kubectl exec -it <pod> -- shmembuka shell di dalam pod
kubectl delete -f <berkas>membongkar objek yang dideklarasikan berkas
kubectl config use-context <nama>berpindah antar cluster — padanan docker context use

Baik Swarm maupun Kubernetes sesungguhnya tidak menjalankan container dengan tangan mereka sendiri — keduanya mendelegasikan pekerjaan itu ke container runtime yang berdiri di setiap node. Kubelet berbicara ke containerd lewat antarmuka bernama CRI, dan containerd adalah nama yang sudah lama kita lihat di output docker version. Chapter Container Runtime membuka lapisan itu: apa itu runtime, standar OCI yang menyatukan image Docker dengan Kubernetes, dan rantai containerd-runc yang bekerja di bawah segalanya.

Referensi #

  • Kubernetes Components — pembacaan resmi control plane dan komponen node.
  • Pods — unit penjadwalan terkecil dan pola multi-container di dalamnya.
  • Deployments — desired state replika, rolling update, dan ReplicaSet.
  • kubectl Overview — referensi perintah kubectl untuk operasi harian.