Docker Swarm kurulumu tek komutla başlar: yönetici (manager) olacak sunucuda docker swarm init --advertise-addr <MANAGER-IP> çalıştırırsınız, komutun yazdırdığı docker swarm join --token ... satırını işçi (worker) sunucularda çalıştırırsınız. Swarm modu Docker Engine'in içinde gelir, ayrı bir paket gerekmez. Sunucular arasında TCP 2377, TCP ve UDP 7946 ile UDP 4789 portlarının açık olması, yöneticinin sabit bir IP adresine sahip olması ve yüksek erişilebilirlik için üç veya beş yönetici kullanılması belgelerin temel önerileridir.

Bu yazıda Swarm kavramlarını (node, servis, görev, routing mesh), ağ ön koşullarını, swarm oluşturmayı, işçi ve yönetici eklemeyi, quorum hesabını, join token güvenliğini, node yönetimini, autolock ve yedeklemeyi anlatıyoruz. Compose dosyasıyla uygulama yayınlamak, yani docker stack deploy, ayrı bir yazının konusu: Docker stack deploy.

Swarm modunun temel kavramları

Docker'ın küme yönetimi ve orkestrasyon özellikleri, Engine'e gömülü olan SwarmKit projesiyle yapılır. Bir swarm, Swarm modunda çalışan birden çok Docker ana makinesinden oluşur ve her biri bir node olarak adlandırılır. Node'lar iki rolden birini ya da ikisini birden üstlenir: yöneticiler üyeliği ve görev dağıtımını yönetir, işçiler ise servisleri çalıştırır. Yöneticiler kendi aralarında orkestrasyonu yürütecek tek bir lider seçer. Varsayılan olarak yöneticiler de işçi gibi görev çalıştırır.

Servis, çalıştırılacak görevlerin tanımıdır ve Swarm'la etkileşimin merkezindedir: hangi imajın kullanılacağını, kaç kopya çalışacağını, hangi ağlara ve portlara bağlanacağını belirtirsiniz. Docker bu istenen durumu korumaya çalışır; bir işçi erişilemez olursa onun görevlerini başka node'lara planlar. Görev (task) bir container ve onun içinde çalışacak komuttur, Swarm'ın en küçük planlama birimidir. Belgelerin vurguladığı bir ayrıntı: bir görev bir node'a atandıktan sonra başka bir node'a taşınamaz, ya orada çalışır ya da başarısız olur. Kopyalı (replicated) servislerde istediğiniz sayıda görev dağıtılır; küresel (global) servislerde her uygun node'da bir görev çalışır.

Dışarıya açılan servisler için yönetici ingress yük dengelemesi kullanır. Bir port belirtmezseniz yönetici servise 30000-32767 aralığından bir port atar. Yayınlanan porta kümedeki herhangi bir node üzerinden ulaşılabilir; o node'da görev çalışmasa bile bağlantı çalışan bir göreve yönlendirilir. Ayrıca her servis Swarm'ın iç DNS bileşeninden bir kayıt alır ve küme içindeki istekler servis adına göre dengelenir. Swarm modunda da node'larda tek başına (standalone) container çalıştırmaya devam edebilirsiniz; fark, servisleri yalnızca yöneticilerin yönetebilmesidir.

Hazırlık: sunucular, IP adresi ve portlar

Hazırlık: sunucular, IP adresi ve portlar: 2377, 7946, 4789, IP protokol 50 (ESP)

Belgelerdeki öğretici üç Linux sunucu kullanır: bir yönetici, iki işçi. Her birinde Docker Engine kurulu olmalı ve ağ üzerinden birbirlerine ulaşabilmelidir; kurulum için Docker Ubuntu kurulumu yazısına bakabilirsiniz. Tek sunucuyla da swarm başlatıp servis oluşturabilir ve ölçekleyebilirsiniz, yalnızca çok node'lu komutlar çalışmaz. Diğer node'lar yöneticiye IP adresi üzerinden bağlandığı için yöneticinin IP adresi sabit olmalıdır. Yönetim kılavuzu bunun sebebini açıklar: tüm swarm yeniden başlar ve her yönetici yeni bir IP alırsa hiçbir node mevcut bir yöneticiye ulaşamaz ve swarm askıda kalır. İşçiler için dinamik IP sorun değildir.

PortProtokolGörevi
2377TCPYöneticilerle ve yöneticiler arası iletişim
7946TCP ve UDPOverlay ağında node keşfi
4789UDP (değiştirilebilir)Overlay ağ trafiği (VXLAN, data path port)
IP protokol 50 (ESP)IPsecYalnızca şifreli overlay ağı (--opt encrypted) kullanılıyorsa

Yalnızca şifreli overlay ağları kullanıyorsanız belgeler ek sertleştirme olarak data path portunda şifresiz paketleri reddeden bir kural örneği verir; kural sırası ve diğer araçlar özelleştirme gerektirebilir:

bash
iptables -I INPUT -m udp --dport 4789 -m policy --dir in --pol none -j DROP

Bu portları ve Docker'ın kendi iptables kurallarını UFW ile birlikte yönetirken dikkat edilecekler için Docker iptables ve UFW yazısına bakabilirsiniz. İki not daha: rootless modda overlay ağı desteklenmez, bu yüzden çok node'lu bir swarm için rootful Docker gerekir; Engine 29 ile gelen deneysel nftables güvenlik duvarı arka ucu ise belgelere göre overlay kuralları henüz taşınmadığı için Swarm modunda açılamaz.

Swarm oluşturmak: docker swarm init

Yönetici sunucuda şu komutu çalıştırırsınız. Sistemde tek IP adresi varsa Docker onu 2377 portuyla kullanır; birden çok IP adresi varsa yöneticiler arası iletişim ve overlay ağı için doğru adresi --advertise-addr ile belirtmeniz gerekir. Diğer node'ların yöneticiye ulaştığı adres yöneticinin kendini gördüğü adresten farklıysa (örneğin bölgeler arası bir bulut kurulumunda iç ve dış adresler) dış adresi vermeniz gerekir:

bash
docker swarm init --advertise-addr <MANAGER-IP>

docker swarm init şu işleri yapar: geçerli node'u Swarm moduna alır, default adlı bir swarm oluşturur, node'u lider yönetici yapar ve ana makine adıyla adlandırır, yöneticiyi aktif bir ağ arayüzünde 2377 portunda dinletir, node'un erişilebilirliğini Active yapar, swarm durumunu tutan dağıtık iç veri deposunu başlatır, varsayılan olarak kendinden imzalı bir kök CA ile işçi ve yönetici join token'larını üretir ve servis portlarını dışarıya açmak için ingress adlı bir overlay ağı oluşturur. Belgelerdeki çıktı, işçileri eklemek için gereken komutu da içerir:

bash
docker swarm init
Swarm initialized: current node (dxn1zf6l61qsb1josjja83ngz) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \
    192.168.99.100:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

Varsayılan adres havuzu

Swarm, alt ağ belirtilmeyen küresel kapsamlı (overlay) ağlar için varsayılan olarak 10.0.0.0/8 havuzunu kullanır ve her ağa bu havuzdan sırayla bir alt ağ ayırır. Bu aralık mevcut ağınızla çakışıyorsa havuzu yalnızca swarm başlatılırken --default-addr-pool ile değiştirebilirsiniz. Seçenek birden çok kez verilebilir; --default-addr-pool-mask-length her ağın alt ağ uzunluğunu belirler. Belgelerdeki örnekte /26 maskesiyle oluşturulan ilk overlay ağı 10.20.0.0/26, ikincisi 10.20.0.64/26 alt ağını alır:

bash
docker swarm init --default-addr-pool 10.20.0.0/16 --default-addr-pool 10.30.0.0/16 --default-addr-pool-mask-length 26

İşçi node eklemek

İşçi join komutunu yönetici üzerinde istediğiniz zaman yeniden görebilirsiniz. Çıktıdaki komutu işçi sunucuda çalıştırdığınızda node swarm'a katılır:

bash
docker swarm join-token worker

docker swarm join \
  --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \
  192.168.99.100:2377

This node joined a swarm as a worker.

docker swarm join node'u Swarm moduna alır, yöneticiden bir TLS sertifikası ister, node'u ana makine adıyla adlandırır, token'a göre yöneticinin dinleme adresindeki swarm'a katılır, erişilebilirliği Active yapar ve ingress overlay ağını bu node'a genişletir. İşçi eklemek kapasiteyi artırır ve yöneticiler arasındaki Raft uzlaşmasını etkilemez.

Yönetici eklemek ve quorum hesabı

Yönetici eklemek ve quorum hesabı: 1, 2, 2, 3

Yöneticiler hata toleransını artırır. Swarm durumunu Raft uzlaşma algoritmasıyla paylaşırlar ve önerilen her güncelleme için yöneticilerin çoğunluğunun, yani quorum'un onayı gerekir. Lider düşerse kalan yöneticiler yeni bir lider seçer. Belgeler yüksek erişilebilirlik için üç veya beş yönetici önerir ve sayının tek olmasını ister, çünkü bir sonraki çift sayı quorum'u korumayı kolaylaştırmaz:

Yönetici sayısıGereken çoğunlukKaybedilebilecek yönetici
110
220
321
431
532
642
743

Yönetici sayısının bir üst sınırı yoktur, ancak her ek yönetici yazma performansını düşürür, çünkü her güncellemeyi daha fazla node onaylamak zorundadır. Quorum kaybedilirse mevcut işçilerdeki görevler çalışmaya devam eder, fakat node eklenemez, güncellenemez, çıkarılamaz ve görevler başlatılamaz, durdurulamaz, taşınamaz veya güncellenemez. Belgeler yöneticileri en az üç erişilebilirlik bölgesine dağıtmayı da önerir: 3 yönetici için 1-1-1, 5 için 2-2-1 dağılımı gibi. Yönetici olarak katılmak için token'ı yönetici üzerinde alırsınız:

bash
docker swarm join-token manager

Yöneticiler Raft verisini tutarlı biçimde çoğalttığı için kaynak yetersizliğine hassastır. Küçük ve kritik olmayan kümelerde yöneticilere görev atamak, CPU ve bellek sınırlarıyla planlandığı sürece düşük risklidir. Aksi halde yöneticiyi Drain durumuna alarak yalnızca yönetim işi yapmasını sağlayabilirsiniz.

Join token güvenliği

Join token'ları swarm'a katılmak için gereken sırlardır; işçi ve yönetici token'ları farklıdır. Yönetici token'ı özellikle hassastır, çünkü yeni bir yöneticinin katılıp tüm swarm'ın denetimini almasına izin verir. Belgeler token'ların sürüm kontrolüne eklenmesinin kötü bir uygulama olduğunu söyler. Token yalnızca katılma anında kullanılır; token'ı yenilemek mevcut node'ların üyeliğini etkilemez, yalnızca eski token'la yeni node katılmasını engeller.

Token'ı yanlışlıkla bir depoya, sohbet grubuna veya loglara sızdırdıysanız, bir node'un ele geçirildiğinden şüpheleniyorsanız ya da artık yeni node katılmasını istemiyorsanız token'ı yenileyin. Belgeler ayrıca düzenli bir rotasyon takvimi ve en az altı ayda bir yenileme önerir. --quiet yalnızca token'ı yazdırır:

bash
docker swarm join-token --rotate worker
docker swarm join-token --rotate manager
docker swarm join-token --quiet worker

Node yönetimi

Node yönetimi: AVAILABILITY Active, AVAILABILITY Pause, AVAILABILITY Drain, MANAGER STATUS boş

Yönetici üzerinde docker node ls tüm node'ları listeler. Belgelerdeki örnek çıktı şöyledir:

bash
docker node ls

ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
46aqrk4e473hjbt745z53cr3t    node-5    Ready   Active        Reachable
61pi3d91s0w3b90ijw3deeb2q    node-4    Ready   Active        Reachable
a5b2m3oghd48m8eu391pefq5u    node-3    Ready   Active
e7p8btxeu3ioshyuj6lxiv6g0    node-2    Ready   Active
ehkv3bcimagdese79dn78otj5 *  node-1    Ready   Active        Leader
Sütun ve değerAnlamı
AVAILABILITY ActivePlanlayıcı node'a görev atayabilir
AVAILABILITY PauseYeni görev atanmaz, mevcut görevler çalışmaya devam eder
AVAILABILITY DrainYeni görev atanmaz, mevcut görevler kapatılıp başka node'lara planlanır
MANAGER STATUS boşYönetime katılmayan işçi
MANAGER STATUS LeaderTüm yönetim ve orkestrasyon kararlarını veren birincil yönetici
MANAGER STATUS ReachableQuorum'a katılan, lider düşerse seçilebilecek yönetici
MANAGER STATUS UnavailableDiğer yöneticilerle iletişim kuramayan yönetici

Bakım için bir node'u boşaltmak, etiket eklemek ve rol değiştirmek docker node update ile yapılır. Node etiketleri yalnızca swarm içindeki node nesnesine uygulanır ve servis yerleşim kısıtlarında kullanılabilir; belgelerin vurguladığı gibi ele geçirilmiş bir işçi node etiketlerini değiştiremediği için kritik işleri belirli node'larla sınırlamak için uygundur. docker node promote ve docker node demote, --role manager ve --role worker güncellemelerinin kısayollarıdır:

bash
docker node update --availability drain node-1
docker node update --label-add foo --label-add bar=baz node-1
docker node promote node-3 node-2
docker node demote node-3 node-2

Bir node'u çıkarmak için önce o node'da docker swarm leave çalıştırılır, ardından yöneticide docker node rm ile listeden silinir. Yönetici bir node ayrılırken quorum uyarısı alırsınız; uyarıyı --force ile geçebilirsiniz, ancak son yönetici ayrılırsa swarm kullanılamaz hale gelir. Erişilemeyen veya ele geçirilmiş bir node'u kapatmadan çıkarmak için docker node rm --force kullanılır; bir yöneticiyi zorla çıkarmadan önce onu işçiye indirmeniz gerekir. Belgeler bir yöneticiyi başka bir node'dan raft dizini kopyalayarak yeniden başlatmamanızı da söyler; doğru yol demote, rm ve temiz bir docker swarm join sırasıdır.

İlk servis ve routing mesh

Swarm'ı denemek için belgelerdeki örnek, nginx container'ının 80 portunu kümedeki her node'un 8080 portuna yayınlayan iki kopyalı bir servis oluşturur. Herhangi bir node'un 8080 portuna gelen istek, routing mesh tarafından çalışan bir göreve yönlendirilir:

bash
docker service create \
  --name my-web \
  --publish published=8080,target=80 \
  --replicas 2 \
  nginx

Routing mesh'i atlamak isterseniz uzun --publish sözdiziminde mode=host kullanırsınız; bu durumda port yalnızca görevin çalıştığı node'da dinlenir ve aynı node'da birden çok görev çalışacaksa sabit bir port veremezsiniz. Dışarıda kendi yük dengeleyicinizi kullanmak için de iki yol vardır: yük dengeleyiciyi tüm node'ların yayınlanan portuna yönlendirmek ya da --endpoint-mode dnsrr ile tek sanal IP yerine DNS round-robin kullanmak. Servis tanımlarını kalıcı bir dosyada tutmak ve güncellemeleri yönetmek stack deploy yazısının konusudur.

Autolock ve swarm yedeği

Yöneticilerin Raft logları diskte varsayılan olarak şifrelidir. Docker yeniden başladığında hem node'lar arası iletişimin TLS anahtarı hem Raft şifreleme anahtarı yöneticinin belleğine yüklenir. Autolock bu anahtarların sahipliğini size verir: Docker yeniden başladıktan sonra yöneticiyi docker swarm unlock ile ve swarm kilitlenirken üretilen anahtarla açmanız gerekir. Kilitli bir swarm'da servis komutları "Swarm is encrypted and needs to be unlocked" hatası verir. Anahtarı bir parola yöneticisi gibi güvenli bir yerde saklayın:

bash
docker swarm init --autolock
docker swarm update --autolock=true

Swarm durumu ve yönetici logları /var/lib/docker/swarm/ dizininde tutulur ve bu dizin Raft loglarını şifreleyen anahtarları da içerir; bu anahtarlar olmadan swarm geri yüklenemez. Belgelerin yedekleme adımları şöyledir: autolock açıksa kilit açma anahtarını güvenli bir yere alın, verinin değişmemesi için yöneticide Docker'ı durdurun, /var/lib/docker/swarm dizininin tamamını yedekleyin ve yöneticiyi yeniden başlatın. Yönetici kapalıyken swarm bir yönetici kaybına daha açık olduğundan, düzenli yedek alıyorsanız belgeler beş yöneticili bir swarm düşünmenizi önerir.

Engine 29 sürümlerinde Swarm ile ilgili notlar

Engine 29 sürüm notları Swarm kullananları ilgilendiren birkaç değişiklik içerir. 29.0.0 overlay ağının ve routing mesh'in güvenilirliğini büyük ölçüde iyileştirdiğini ve SwarmKit'in iç TLS yapılandırmasından bilinen güvensiz şifre takımlarının çıkarıldığını yazar. 29.8.0 ile servis ağında yayınlanan portlar yerel container'larda yayınlanan portlarla aynı altyapıyı kullanmaya başladı. 29.9.0 notlarına göre userland proxy açıkken Swarm servislerinin yayınlanan portlarına ana makinenin IPv6 adreslerinden de erişilebilmesi test edilmiş ve desteklenen bir özelliktir. 29.9.3 ise geçerli bir işçi sertifikasına sahip bir saldırganın lider değişiminden kısa süre sonra yönetici sertifikası elde edebildiği bir SwarmKit açığını ve firewalld Docker'ın iptables kurallarını temizledikten sonra şifreli overlay ağlarının korumasız kalmasına yol açan bir açığı kapatır. Swarm çalıştırıyorsanız güncel 29.x sürümünde kalmak bu yüzden önemlidir; sürümün tamamı için Docker Engine 29 yenilikleri yazısına bakabilirsiniz.

Sık yapılan hatalar

  • Çift sayıda yönetici: 4 yönetici 3'ten daha fazla hata toleransı sağlamaz; tek sayı kullanın.
  • Yöneticiye dinamik IP: Tüm yöneticiler yeni IP alırsa swarm askıda kalır; --advertise-addr için sabit IP kullanın.
  • 4789 portunu internete açmak: VXLAN kimlik doğrulama yapmaz; bu portu yalnızca güvenilen ağa açın.
  • Yönetici token'ını paylaşmak: Bu token yeni bir yöneticinin tüm swarm'ı yönetmesine izin verir; sızdıysa --rotate ile yenileyin.
  • Son yöneticiyi zorla çıkarmak: Son yönetici ayrılırsa swarm kullanılamaz ve felaket kurtarma gerekir.
  • raft dizinini kopyalamak: Veri dizini node kimliğine özgüdür; yöneticiyi demote, rm ve join ile temiz biçimde yeniden ekleyin.

Sık Sorulan Sorular

Tek sunucuda Swarm kullanmanın anlamı var mı?

Belgelere göre tek node'lu bir swarm'da swarm başlatabilir, servis oluşturabilir ve ölçekleyebilirsiniz; secrets ve configs gibi yalnızca Swarm servislerine açık özellikler de kullanılabilir. Ancak hata toleransı yoktur: tek yönetici düşerse yönetim işleri durur. Bu özelliklere ihtiyacınız yoksa tek sunucuda Compose ile çalışmaya devam edebilirsiniz; belgelere göre Compose Swarm modunu kullanmaz ve her şeyi tek node'a yerleştirir.

Yöneticiler de container çalıştırır mı?

Evet, varsayılan olarak yöneticiler işçi gibi görev alır. Yönetim işini kaynak sıkıntısından korumak için yöneticiyi docker node update --availability drain ile yalnızca yönetici yapabilirsiniz.

Swarm'dan nasıl çıkarım?

İşçide docker swarm leave yeterlidir; ardından yöneticide docker node rm ile node listeden silinir. Test için tek node'lu bir swarm kurduysanız docker swarm leave --force ile Swarm modundan çıkabilirsiniz.

Swarm mı Kubernetes mi?

Docker belgeleri bu iki sistemi karşılaştırmaz; Swarm'ın Engine'e gömülü olduğunu ve Compose dosyalarıyla stack tanımlanabildiğini anlatır. Kubernetes kavramları için Kubernetes temelleri yazısına bakabilirsiniz.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: Docker öğrenme rehberi · Docker stack deploy · Docker iptables ve UFW · Docker network türleri · Docker Engine 29 yenilikleri · Kubernetes temelleri