Belajar Docker Swarm: Service, Routing Mesh, dan Rolling Update
Belajar Docker Swarm dari dasar: manager dan Raft, service dan replica, routing mesh, rolling update, serta file Compose nyata yang dibaca sebagai stack.
Oleh Matthews WongDitinjau pada
Poin utama
Docker Swarm adalah mode cluster bawaan Docker Engine: manager menyimpan state cluster dengan Raft dan menjadwalkan task, lalu worker menjalankannya. Anda mendeklarasikan service dengan jumlah replica, port yang dipublikasikan di node mana pun sampai ke replica itu lewat routing mesh, dan update berjalan bertahap beberapa task sekaligus. File Compose di-deploy sebagai stack.
Setelah pelajaran ini, Anda bisa
- Menjelaskan manager, worker, service, task, dan routing mesh, serta kenapa jumlah manager sebaiknya ganjil.
- Membuat, men-scale, meng-update, dan me-rollback service replicated di swarm latihan satu node.
- Membaca file Compose sebagai file stack: key mana yang diabaikan Swarm, mana yang pindah ke bawah deploy, dan apa yang berubah untuk port dan volume.
Ikuti diagramnya langkah demi langkah
Tekan Putar, atau melangkah dengan panah. Setiap langkah juga ditulis di bawah diagram.
Satu request, tiga node: routing mesh dan rolling update
Sebuah service meminta dua replica dan manager menempatkannya di dua node. Request ke port yang dipublikasikan di node ketiga tetap sampai ke salah satunya lewat routing mesh, dan update mengganti task satu per satu.
Tombol: ← → langkah · Home / End · K putar atau jeda
Tiga Docker Engine membentuk satu swarm. Manager menyimpan state cluster dengan Raft dan secara default ikut menjalankan task. Setiap node bergabung ke ingress routing mesh.
Anda mendeklarasikan desired state: service web, dua replica, port 8080 dipublikasikan. Manager memberi satu task untuk dirinya sendiri dan satu untuk worker-a. Worker-b tidak dapat.
docker service create --name web --replicas 2 --publish published=8080,target=80 nginxTebak langkah berikutnya Sebuah request sampai di worker-b pada port 8080, padahal worker-b tidak menjalankan task. Apa yang terjadi? (Koneksi ditolak · Mesh meneruskannya ke task yang berjalan · Swarm menyalakan task di worker-b dulu)Setiap node menerima koneksi di port yang dipublikasikan. Worker-b tidak menjalankan task, jadi routing mesh meneruskan request lewat jaringan ingress ke task di node lain.
curl http://localhost:8080docker service scale mengubah jumlah yang diinginkan, bukan container. Manager melihat dua task padahal yang diminta tiga, lalu menjadwalkan yang ketiga, di sini pada worker-b.
docker service scale web=3docker service update --image memulai rolling update. Dengan parallelism 1, Swarm menghentikan satu task, menyalakan penggantinya dengan image baru, menunggu delay, lalu lanjut.
docker service update --image nginx:alpine --update-parallelism 1 --update-delay 10s webTebak langkah berikutnya Task baru berikutnya gagal health check. Dengan failure action default, apa yang dilakukan Swarm? (Menjeda update · Rollback dengan sendirinya · Melewati task itu dan lanjut)Container yang gagal health check mengakhiri task-nya. Ketika sebuah task gagal di tengah update, failure action default, yaitu pause, menghentikan rollout di titik itu.
docker service ps webdocker service rollback mengembalikan service ke spec sebelum update terakhir, jadi semua task kembali menjalankan v1. Menyetel failure_action ke rollback melakukannya otomatis.
docker service rollback web
Apa itu Docker Swarm, dan kenapa jumlah manager sebaiknya ganjil?
Docker Swarm adalah mode cluster yang sudah ada di dalam Docker Engine, jadi Anda tidak perlu memasang software orkestrasi tambahan. Swarm terdiri dari beberapa host Docker yang berjalan dalam swarm mode, dan masing-masing disebut node. Node manager mengurus orkestrasi dan manajemen cluster, lalu memilih satu leader di antara mereka. Node worker menjalankan task yang diberikan manager. Secara default manager juga ikut menjalankan task, karena itu swarm satu mesin sudah cukup untuk latihan.
Baca selengkapnya (2)Tutup
Manager menjaga satu salinan state cluster yang konsisten dengan algoritma konsensus Raft. Raft butuh mayoritas (N/2)+1 manager untuk sepakat, jadi tahan terhadap (N-1)/2 kegagalan: tiga manager tetap jalan saat satu hilang, lima manager tetap jalan saat dua hilang. Panduan admin Docker meminta jumlah ganjil, karena manager keempat tidak menambah toleransi dibanding tiga, dan jumlah ganjil membuat quorum lebih mungkin bertahan saat jaringan terbelah. Setiap manager tambahan juga menurunkan performa penulisan, karena lebih banyak manager yang harus menyetujui setiap perubahan.
Kehilangan quorum tidak mematikan aplikasi Anda: task yang sudah berjalan tetap berjalan. Yang berhenti adalah perubahan. Sampai mayoritas manager kembali, swarm tidak bisa menjadwalkan task baru, menyeimbangkan ulang setelah ada kegagalan, atau menambah, mengubah, dan menghapus node. Satu manager tidak masalah di laptop. Di production, satu mesin itu adalah seluruh control plane, dan panduan admin menyebut mengecilkan swarm ke satu manager sebagai operasi yang tidak aman dan tidak disarankan.
Apa itu service, task, dan replica?
Di swarm Anda tidak menyalakan container secara manual. Anda membuat service, yaitu definisi apa yang harus berjalan, lalu Swarm mengubahnya menjadi task. Task adalah slot yang diisi scheduler dengan tepat satu container. Service replicated menjalankan sejumlah task sesuai permintaan Anda; service global menjalankan satu task di setiap node.
Baca selengkapnya (2)Tutup
Swarm bersifat deklaratif. Manager terus membandingkan desired state dengan yang benar-benar berjalan lalu memperbaiki selisihnya: kalau sebuah task gagal, orchestrator menghapus task beserta container-nya lalu membuat task baru. docker service scale web=5 hanya mengubah jumlah yang diinginkan, sama persis dengan docker service update --replicas=5 web.
Tidak ada yang mengubah angka itu untuk Anda. Docker menyebut scaling sebagai mendeklarasikan jumlah task, bukan autoscaling. Di platform Java Spring Boot yang saya load test di atas Swarm untuk skripsi, setiap service tetap di satu replica sampai ada yang menjalankan perintah scale, jadi saya menulis daemon kecil berbasis CPU untuk melakukannya. Pengujian yang sama memperlihatkan batas replica: dari satu ke dua replica, latensi p95 turun dari 8,40 ke 4,50 detik, tetapi throughput hanya naik dari 1,72 ke 1,88 iterasi per detik, karena setiap request menunggu satu baris database yang terkunci.
Bagaimana routing mesh mengantar request ke node yang tepat?
Ketika sebuah service mempublikasikan port, setiap node di swarm menerima koneksi di port itu, termasuk node yang tidak menjalankan task service tersebut. Routing mesh meneruskan setiap request lewat jaringan ingress, yaitu overlay network khusus, ke task yang aktif di mana pun ia berjalan. Karena itu load balancer eksternal bisa diarahkan ke node mana saja, atau ke semuanya. Kalau Anda tidak menentukan nomor port, manager memilih satu di rentang 30000-32767.
Baca selengkapnya (2)Tutup
Mesh mendengarkan port yang dipublikasikan di setiap alamat yang dimiliki node. Pada alamat yang bisa dijangkau dari luar, port itu terbuka ke luar; pada alamat lain, hanya dari dalam host. Kalau Anda ingin task terikat ke port di node-nya sendiri, publikasikan dengan mode=host, yang melewati mesh dan menyerahkan load balancing kepada Anda.
Service yang hanya saling berbicara tidak perlu mempublikasikan apa pun. Hubungkan ke overlay network buatan sendiri, yang dibuat dengan docker network create --driver overlay, dan mereka saling menjangkau lewat nama service. Di antara node, buka 2377/tcp untuk komunikasi dengan dan antar manager, 7946 lewat TCP dan UDP untuk penemuan node, dan 4789/udp untuk lalu lintas overlay.
Bagaimana rolling update dan rollback bekerja?
docker service update --image memulai rolling update. Secara default scheduler meng-update satu task setiap kali: menghentikan task, menyalakan container dari spec baru, dan begitu task itu berstatus RUNNING ia menunggu update delay sebelum lanjut ke task berikutnya. Kalau ada task yang berstatus FAILED selama update, update dijeda, dan docker service update pada service yang sama menjalankannya lagi.
Baca selengkapnya (2)Tutup
Di file stack, pengaturan yang sama ada di bawah deploy.update_config: parallelism adalah berapa task yang berganti sekaligus, delay adalah jeda antar batch, failure_action bisa continue, rollback, atau pause dengan pause sebagai default, dan monitor adalah berapa lama Swarm mengawasi setiap task yang di-update untuk mendeteksi kegagalan. order default-nya stop-first; start-first menyalakan task baru sebelum yang lama berhenti, jadi keduanya sempat berjalan bersamaan sebentar.
Di swarm, health check punya peran nyata. Container yang gagal health check mengakhiri task-nya, orchestrator menggantinya, dan saat update kegagalan itulah yang menjeda atau me-rollback rollout. docker service rollback mengembalikan service ke konfigurasi sebelum docker service update terakhir, dan rollback_config mengatur cara rollback itu berjalan.
Apa yang dilakukan docker stack deploy terhadap file Compose?
docker stack deploy membuat atau memperbarui stack, yaitu sekumpulan service, dari file Compose, dan harus dijalankan di manager. Perintah ini membaca format lama Compose file versi 3, dan dokumentasi Docker menyebut Compose Specification yang terbaru tidak kompatibel dengannya, jadi perlakukan file stack sebagai file tersendiri. Setiap service, network, dan volume diberi awalan nama stack: web di stack bernama site menjadi site_web.
Baca selengkapnya (1)Tutup
Perintah ini tidak mem-build image. Key build diabaikan, dan karena swarm terdiri dari banyak Docker Engine, image harus berasal dari registry yang bisa di-pull semua node; --with-registry-auth mengirim kredensial registry Anda ke node-node itu. Sisanya berbeda per key, dan contoh nyata di bawah membaca file compose situs ini dengan cara itu.
Bagaimana secret bekerja di swarm?
Swarm punya fitur secret bawaan, jawabannya untuk password yang tersimpan di file env. Secret disimpan di Raft log milik manager, yang terenkripsi, dan hanya service yang diberi akses yang bisa membacanya. Di dalam container, secret muncul sebagai file di bawah /run/secrets, pada mount tmpfs di memori. Secret hanya tersedia untuk service swarm, bukan untuk container biasa.
Baca selengkapnya (1)Tutup
Buat secret dari standard input dengan docker secret create db_password -, lalu cantumkan di key secrets milik service. Di file stack, entri secrets di level teratas bisa menunjuk ke file lokal atau mendeklarasikan secret sebagai external, artinya sudah dibuat sebelumnya.
Compose, Swarm, atau Kubernetes: mana yang Anda butuhkan?
Docker Compose menjalankan semua service di host saat ini; Compose tidak memakai swarm mode untuk menyebarkan service ke beberapa node. Situs ini berjalan seperti itu, dengan satu VPS, satu file compose, dan nginx di depannya, dan untuk satu server itu sudah cukup. Pelajaran ini membaca file compose tersebut sebagai stack hanya untuk menunjukkan apa yang akan berubah.
Baca selengkapnya (1)Tutup
Swarm cocok ketika Anda sudah butuh lebih dari satu host tetapi ingin tetap memakai bentuk Compose dan Docker CLI: replica di banyak node, routing mesh, rolling update, dan secret, semuanya di dalam engine yang sudah Anda jalankan. Kubernetes cocok ketika Anda butuh yang tidak dibawa Swarm, misalnya HorizontalPodAutoscaler, yang men-scale workload sesuai beban dengan loop 15 detik secara default. Apa pun pilihannya, cari bottleneck dulu: kalau batasnya satu baris database, orchestrator mana pun tidak menaikkan plafonnya.
Konfigurasi nyata di balik pelajaran ini
Kutipan dari repositori yang membangun dan men-deploy situs ini, apa adanya.
image: ${IMAGE:-ghcr.io/matthews-wong/matthews-porto-nextjs:latest}
# Matches the existing container so deploys UPDATE it in place (no duplicate).
container_name: matthewswong-portfolio
restart: unless-stopped
env_file: .envImage-nya sudah berasal dari registry, yang memang dibutuhkan swarm, tetapi nilai ${IMAGE} diisi dari file .env di sebelahnya, dan referensi versi 3 menyebut fitur .env tidak bekerja dengan docker stack deploy. container_name dan restart sama-sama diabaikan di swarm mode: task diberi nama dari service-nya, misalnya web.1, dan restart diatur deploy.restart_policy, yang condition-nya default any. env_file tidak punya catatan swarm di referensi itu.
ports:
# Bind to loopback only — nginx terminates TLS and proxies to this port.
- "127.0.0.1:${APP_PORT:-3002}:3000"
mem_limit: 512m
cpus: "1.0"Dua key yang tidak terbawa. Binding loopback menjaga aplikasi tetap di belakang nginx, tetapi routing mesh mendengarkan di setiap alamat pada setiap node, dan sintaks port panjang versi 3 tidak punya field alamat host. Di swarm, publikasikan proxy-nya saja dan biarkan proxy menjangkau aplikasi lewat nama di overlay network. Di versi 3, deploy.resources menggantikan mem_limit, dan cpus hanya ada di bawah deploy.resources.limits, jadi keduanya pindah ke sana.
healthcheck:
test:
[
"CMD",
"wget",
"--no-verbose",
"--tries=1",
"--spider",
"http://127.0.0.1:3000/robots.txt",
]
interval: 30s
timeout: 5s
retries: 3
start_period: 20sFormat versi 3 punya key healthcheck yang sama, dengan start_period sejak 3.4, dan di swarm health check mendapat tugas: container yang gagal health check mengakhiri task-nya, dan task yang gagal menjeda rolling update. Baca angka waktunya dengan itu dalam pikiran. Kegagalan di 20 detik pertama tidak dihitung, dan butuh tiga kegagalan berturut-turut, berjarak 30 detik, untuk menandai container unhealthy, jadi beri monitor di update_config waktu yang cukup untuk melihatnya.
volumes:
next-image-cache:Named volume dengan driver local bawaan hanya berlaku di satu node. Di swarm, setiap node tempat task mendarat membuat salinannya sendiri kalau belum ada, dan task yang pindah ke node lain mulai dengan volume yang berbeda. Untuk cache image ini tidak masalah. Untuk data yang harus dipakai bersama semua replica, pakai volume driver multi-host atau kunci service ke satu node dengan placement constraint.
Kesalahan yang benar-benar membuang waktu
Dua manager lebih buruk dari satu
Mayoritas dari dua manager adalah dua, jadi dua manager tidak tahan satu kegagalan pun, sama seperti satu manager, dan malah memberi dua mesin yang bisa merusak quorum. Empat manager tahan satu kegagalan, sama dengan tiga. Pakai satu manager untuk latihan, dan tiga atau lima saat control plane harus tetap hidup ketika satu mesin hilang.
Port yang tadinya hanya loopback jadi terbuka ke publik
Di Compose, 127.0.0.1 pada pemetaan port membuat aplikasi hanya bisa dijangkau lewat nginx. Port yang dipublikasikan swarm melewati routing mesh, yang mendengarkan di setiap alamat pada setiap node, jadi pada alamat yang bisa dirutekan dari luar aplikasi terbuka ke publik. Publikasikan proxy saja, taruh aplikasi di overlay network, dan pasang firewall di node.
Node lain tidak menemukan image-nya
docker stack deploy mengabaikan build, jadi image yang Anda build di manager hanya ada di sana. Task yang dijadwalkan di node lain tidak punya apa pun untuk di-pull. Push image ke registry yang bisa dijangkau semua node sebelum deploy, dan tambahkan --with-registry-auth kalau registry itu privat.
Update yang dijeda terlihat seperti deploy yang macet
Dengan failure_action default, satu task yang gagal menjeda rollout, sehingga sebagian task tetap di image lama sementara yang lain sudah di image baru. Tidak ada yang bergerak sampai Anda bertindak. Baca docker service ps untuk melihat task mana yang gagal beserta kolom ERROR-nya, lalu perbaiki dan jalankan docker service update lagi, atau jalankan docker service rollback.
Datanya tertinggal di node lama
Driver volume local bawaan hanya berlaku di satu node. Ketika sebuah task dijadwalkan ulang ke node lain, Docker membuat volume baru dengan nama yang sama di sana, tanpa data lama, dan aplikasi terlihat seperti kehilangan datanya. Pakai volume driver multi-host, atau placement constraint yang menahan service di node yang memiliki volume itu.
| Docker Compose | Docker Swarm | Kubernetes | |
|---|---|---|---|
| Tempat berjalan | Semua service di host saat ini | Cluster Docker Engine, yaitu swarm | Cluster node yang dikelola control plane |
| Yang dipasang | Docker dan Compose | Tidak ada tambahan: swarm mode ada di Docker Engine | API server, etcd, scheduler, controller manager, kubelet di tiap node |
| Format konfigurasi | Compose Specification | Compose file versi 3 (lama), lewat docker stack deploy | Objek Kubernetes, misalnya Deployment |
| State cluster | Tidak ada: satu host | Raft log di manager; 3 tahan 1 kegagalan, 5 tahan 2 | etcd, penyimpan semua data API server |
| Scaling | Container di satu host saja | Jumlah replica yang dideklarasikan; tanpa autoscaler | Lewat perintah, atau otomatis dengan HorizontalPodAutoscaler |
| Cocok ketika | Satu server sudah cukup, seperti situs ini | Beberapa host, dan tim sudah terbiasa menulis file Compose | Anda butuh autoscaling atau tooling yang menyasar Kubernetes |
Lakukan di komputer Anda sendiri
Anda cukup butuh Docker di satu mesin. Swarm satu node sudah cukup untuk semua langkah di sini, dan langkah terakhir mematikan swarm mode lagi. Pakai mesin latihan, bukan server yang menjalankan sesuatu yang penting.
Jadikan Docker Engine ini swarm satu node lalu tampilkan daftar node. Tanda bintang menandai node tempat Anda terhubung. Kalau init menyebut mesin punya beberapa alamat, jalankan lagi dengan --advertise-addr diikuti nama network interface atau alamat yang akan dipakai node lain.
docker swarm init docker node lsBuat service dengan tiga replica yang dipublikasikan di port 8080, lihat di mana task-nya berjalan, lalu akses lewat routing mesh.
docker service create --name web --replicas 3 --publish published=8080,target=80 nginx docker service ps web curl http://localhost:8080Ubah jumlah yang diinginkan dan lihat kolom REPLICAS menyusul.
docker service scale web=5 docker service lsRilis image baru satu task setiap kali, berjarak 10 detik. Jalankan docker service ps selama prosesnya, lalu rollback ke spec sebelumnya.
docker service update --image nginx:alpine --update-parallelism 1 --update-delay 10s web docker service ps web docker service rollback webSimpan ini sebagai stack.yml. Stack deploy membaca format versi 3, dan order butuh versi 3.4 atau lebih baru; batas resource ada di bawah deploy, bukan di mem_limit.
version: "3.8" services: web: image: nginx:alpine ports: - "8080:80" deploy: replicas: 2 update_config: parallelism: 1 delay: 10s order: start-first resources: limits: memory: 128MHapus service tadi agar port 8080 bebas, deploy stack-nya, lalu tampilkan service-nya. Nama service-nya demo_web.
docker service rm web docker stack deploy -c stack.yml demo docker stack services demoBersihkan. Manager butuh --force untuk keluar, yang menurut dokumentasi hanya untuk swarm yang tidak akan dipakai lagi, seperti swarm latihan ini.
docker stack rm demo docker swarm leave --force
Tiga pertanyaan sebelum lanjut
Pilih jawaban untuk melihat kenapa benar atau salah. Tidak ada nilai, jadi tebak saja dengan bebas; jawaban yang salah disimpan di browser ini agar kursus bisa menanyakannya lagi nanti.
Dua pertanyaan dari pelajaran sebelumnya
Mengingat kembali pelajaran lama setelah jeda membuatnya lebih melekat. Jawab dari ingatan sebelum mencari apa pun.
Jawab dalam hati, lalu cek
1.Kenapa swarm sebaiknya punya manager dalam jumlah ganjil?Lihat jawabannya
Jawaban:Raft butuh mayoritas untuk sepakat, jadi jumlah genap menambah mesin tanpa menambah toleransi: empat manager tahan satu kegagalan, sama seperti tiga. Jumlah ganjil juga membuat quorum lebih mungkin bertahan saat jaringan terbelah.
2.Apa yang diubah docker service scale web=5, dan apa yang menjaganya tetap benar?Lihat jawabannya
Jawaban:Perintah itu mengubah jumlah task yang diinginkan. Manager lalu menambah atau mengurangi task sampai lima berjalan, dan mengganti task yang gagal. Tidak ada yang mengubah angka itu dengan sendirinya; Swarm tidak punya autoscaler.
3.Kenapa binding port 127.0.0.1 tidak bisa melindungi aplikasi di swarm?Lihat jawabannya
Jawaban:Port yang dipublikasikan melewati routing mesh, yang mendengarkan di setiap alamat pada setiap node, dan sintaks panjang versi 3 tidak punya field alamat host. Publikasikan proxy saja dan jangkau aplikasi lewat nama service di overlay network.
Bahasan mendalam terkait di situs ini
Sumber
Sumber primer yang diperiksa pada tanggal riset. Ikuti tautannya untuk versi terbaru.
- Dokumentasi Docker: konsep utama swarm mode
- Dokumentasi Docker: konsensus Raft di swarm mode
- Dokumentasi Docker: mengelola dan merawat swarm
- Dokumentasi Docker: cara kerja service
- Dokumentasi Docker: routing mesh di swarm mode
- Dokumentasi Docker: network untuk service swarm
- Dokumentasi Docker: rolling update pada service
- Dokumentasi Docker: Compose Deploy Specification
- Dokumentasi Docker: deploy stack ke swarm
- Docker Compose: referensi lama Compose file versi 3
- Dokumentasi Docker: docker service create
- Dokumentasi Docker: docker service rollback
- Dokumentasi Docker: mengelola data sensitif dengan Docker secrets
- Dokumentasi Kubernetes: Horizontal Pod Autoscaling