Docker Bölüm 8: Docker Swarm

Docker

Container mimarisinde çalışan servisleri yönetmek, ölçeklendirmek ve servislerin kesinti olmadan devamlılığını sağlamak için kullanılan cluster yönetim ve orkstrasyon aracıdır.

Docker Host üzerinde çalışan container’ler, Host’un fail olmasından sonra ayakta kalamaz ve servisler kesintiye uğrar. Hem high availibility hem ölçeklendirme hem de yedeklilik sağlayabilmek için Docker Host sayısını artırmalı, bunları cluster haline getirmeli ve yönetimini sağlıklı bir şekilde yapabilmemiz gerekir. Swarm, bu konuya bir çare olması için üretilmiştir.

Docker 2 mode olarak çalışabilmektedir. Bunlar:

  1. Single Mode
  2. Swarm Mode

Single Mode tahmin edeceğiniz gibi kurulumda default olarak seçilen mode’dur. Single mode elbette Swarm’ı desteklemez ve bu şekilde bir Swarm cluster’ına host dahil edilemez, bunun için öncelikle Single mode’u değiştirip Swarm mode’a geçiş yapmamız gerekir.

Docker Swarm ise birden fazla Swarm mode çalışan Docker Host’un bir araya gelmesiyle oluşturulur. Bu şekilde çalışan tüm sunucular tek bir havuz haline gelir ve t anında bir Docker Host fail olursa, diğer Docker Host’lar üzerine çalışan container’lar taşınır ve kesintisiz hizmet vermeye devam eder. Ayrıca tamamen ücretsizdir, Swarm kullanarak ek bir ücret ödemezsiniz.

Swarm’ın yönetimini ise SwarmKIT’i kullanarak gerçekleştirilir. Eski sürümlerde Klasik Swarm mevcuttu; fakat yönetimi ve kurulumu fazlasıyla karmaşık olduğu için 2016 yılında Docker SwarmKIT kullanıma sunuldu. Böylece kurulum ve yönetim işlemleri çok daha basit hale getirilmiş oldu.

Swarm çalışan node’lar üzerinde 2 farklı role bulunmaktadır:

  1. Manager
  2. Worker: Manager tarafından verilen görevleri yerine getirir.

Manager Node

Swarm yönetimi için kullanılan node’dur. Aynı zamanda worker gibi de hareket edebilmektedir; fakat production ortamları için bu şekilde kullanılması tavsiye edilmez.

Swarm ortamında ilk kurulan mode Manager olarak atanır ve en az 1 tane olmak zorundadır. Kritik durumdaki cluster’larda birden fazla olması gerekir. Manager sayısı ayrıca tek sayılar şeklinde olmalıdır (1 – 3 – 5 vb.).

Manager’lar da iki farklı şekilde çalışmaktadır

  1. Leader: 1 tane olmaktadır. Tüm işlemler Leader node üzerinden yönetilmektedir. İlk Swarm kurulumu yapılan node default olarak Leader node olur.
    Leader node aynı zamanda sertifika sunucusu da olur. Yeni eklenecek hostların güvenlikli hale getirilmesi için sertifikalar Leader tarafından sağlanır.
  2. Follower: Leader fail ettiğinde, bir şekilde networksel sorun yüzünden erişilemez hale geldiğinde Follower’lar oylama yaparak yeni bir Leader node seçerler ve Leader’in görevlerini devralır. Kısacası HA ve yedeklilik açısından önemlidir.

Manager Node aynı zamanda container’larla ilgili metadataları, worker kaynakları, hangi worker’da hangi container’ın koştuğu gibi bütün detayları da tutar. Bu bilgiler Raft Store adı verilen bir veritabanında saklanır ve tüm Manager node’lar arasından Raft Store, Raft Consensus Protocol üzerinden sync halde çalışırlar, bu şekilde birden fazla Manager’ın olduğu yapıya Raft Consensus Group adı verilir. Böylece Leader’e bir şey olursa rahatlıkla bir Follower görevi üstlenebilir.

Worker Node

Worker node’lar yalnızca container’ların üzerinde koştuğu node’lardır. Hangi Worker, hangi container’ı taşıyacak emri Manager node tarafından belirlenir. Worker node’lar aralarındaki iletişimi ise Control Plane adı verillen bir network yapısı ile sağlarlar. İletişim async olarak yapılır. Her Worker node, kendi durumunu 3 komşu node ile paylaşmaktadır.

Resimde görüleceği gibi Swarm node’lar arasındaki iletişimin sağlanmasını sağlayan Swarn Agent’tır. Agent’lar üzerinde bir token bulunmaktadır ve token’ları aynı olan node’lar birbirleriyle iletişim kurabilmektedir. İletişim için de Swarm Discovery Subsystem adı verilen yapıyla tüm bilgiler node’lar arasından gerekli şekilde taşınmaktadır.

Docker Swarm Yönetim Komutları

Tüm yönetim komutları docker swarm ile başlar. Bu şekilde yazıp enter tuşuna bastığınızda kullanılabilecek komutlar listelenecektir.

init

Yeni bir Swarm kurulumu yapmak için kullanılır.

Yayın yapacağı adres için:

Zorulu olmamakla birlikte listen edilecek ip adresini de belirtebiliriz:

İlk kez oluşturulduğunda node doğal olarak Manager node olacaktır ve join işlemi için gereken token bilgisi gösterilecektir.

join-token

Bir node Swarm üzerine dahil ediliyorsa, Swarm için gereken token bilgisini almamız gerekir. Bunun öğrenebilmek için:

Burada token kimin için oluşturulacak ise o seçilmeli. Kastettiğim node değil, rol. Çünkü Manager ve Worker için gereken token bilgileri farklı olduğundan ekleyeceğiniz node’un görevi ne olacak ise ona göre işlemi token’ı görmeniz gerekir.

Sadece token bilgisini görmek için ise sonuna -q eklemeniz yeterlidir:

join

Swarm ortamına ilk node’dan sonraki node’ları eklemek için kullanılır.

leave

Bir node’u swarm ortamından çıkarmak için kullanılır.

update

Swarm üzerindeki özellikleri güncellemek için kullanılır.

Bu şekilde enter’a bastığımızda kullanılabilecek komut listesini görebiliriz.

node

Swarm node’larını yönetmek için kullanılır.

Swarm node listesi için:

Worker olan bir node’u Manager olarak atamak için:

Manager olan bir node’u Worker haline getirmek istersek:

Node üzerinde güncelleme yapmak için kullanılır. Mesela Worker node’u Manager yapmak istedik, yukarıdaki yerine şu şekilde de belirtebiliriz:

Yine update ile bir node’u pasif hale getirip üzerine yeni taleplerin gelmesini durdurabiliriz:

Burada 3 seçenek vardır: active, pause ve drain. Drain pause ile benzer; ama ek olarak üzerine yeni bir talep gelmesini engeller.

Task’leri görüntülemek için:

Docker Swarm Kurulumu

Swarm kurulumu yapabilmemiz için elimizde birden fazla Docker Host olması gerekir; ama maalesef benim elimde yok. 😊 Bu yüzden Swarm kurulumunu test etmek, öğrenmek için çalışabileceğimiz bazı ortamlar mevcut. Bunlar:

  • https://labs.play-with-docker.com/ Web browser ile çalışmaları yapabiliyoruz. 4 saatlik bir session açar ve süre bitiminde yaptığınız her şeyi yok eder.
  • Docker-Machine + VirtualBox. Tamamen ücretsizdir ve lokalde çalışır.

Docker Machine

Bilgisayarınızda, aynı anda birden fazla, farklı Docker Engine kurmanıza, yönetmenize ve test etmenize imkan sağlayan bir çözümdür.

Docker Machine kurulumu yapabilmek için öncelikle VirtualBox’ı sistemimize kurmamız gerekir. Bu kurulumdan sonra Docker Machine kurulumu yapabilmek için: https://docs.docker.com/machine/install-machine/ sayfasındaki kurulum direktiflerini uygulayarak gerçekleştirebiliriz. Tabii bir önemli husuta bu kurulumu Windows üzerinde yapacaksak Git Bash kullanmak gerekiyor: https://gitforwindows.org/

Git Bash üzerinden benim gibi kurulum yaptıysanız, docker-machine version komutunun çıktısını görebiliyorsanız kurulum başarıyla tamamlanmış demektir.

Windows için kurulum C:\Users\{KullanıcıAdı}\bin klasörüne yapılmaktadır.

Şimdi yeni bir node1 adında bir node kuralım.

Bende gördüğünüz gibi hata oluştu, bu kaynakların yönetimi ile ilgili bir problem. Bu sebeple biz kaynakları verirsek bu sorunu da kaldırmış oluruz.

Aynı yöntemle 4 node daha oluşturalım ve isimlendime kısmında da yine node2, node3, node4 ve node5 şeklinde isimlendirelim.

Benim kaynak sorunum olduğu için işlemlere devam edemiyorum. Play With Docker üzerinden de kopyala + yapıştır işlemleri yapılamadığı için çok eziyetli olduğundan oradan da işlemi yapamadım maalesef. Fakat Swarm Yönetim Kodları kısmında kurulum komutları mevct olduğu için oldukça kolay ilerleniyor.

Swarm Service ve Task

Swarm Service

Docker Swarm üzerinde çalıştıracağımız uygulamayı ifade eder. Swarm mode aktif edildiğinde çalıştıracağımız her uygulamanın ismi service olarak geçmektedir. Bir servis, kapsamlı uygulamalar kullanmak için geliştirien mikro servislerin image’i olarak düşünülebilir.

Bir servis oluştururken:

  • Servis ismi
  • Kopya sayısı
  • Donanım limitleri
  • Network
  • Port
  • Container image bilgisi

Gibi detaylar tanımlanmaktadır.

Swarm Task

Servisin kaç kopya olarak çalışacağı ile ilgili kavramdır. Her bir kopya, bir task’e denk gelmektedir. Task ve Container birbiri ile ilişkilidir, ne kadar task varsa, o task’in de temsil ettiği bir container vardır.

Örneğin elimizde kopya sayısı 6 olan bir web servis olsun ve 3 Worker node’umuz olsun. Swarm bu task’leri dengeli bir şekilde node’lara dağıtır.

Bir task fail olduğunda yani container sorun yaşadığında yenisi hemen uygun olan yerde tekrar ayağa kaldırılır.

Bir service oluşturulmak istendiğinde nasıl işlediğini şu resim göstermektedir:

Docker üzerinde 2 tip servis vardır, bunlar: global ve replicated’dır.

Global service oluşturduğumuzda tüm node’lar üzerinde bir kopyası bulunan servisi ifade eder, buna Manager’da dahildir. Doğal olarak bu servis oluşturulurken kaç kpya olması gerektiğini belirtmezsiniz.

Replicated service oluşturacağımız zaman replica option’ı kullanılır ve servisimizin kaç kopya halinde çalışacağı belirtilir. Eğer kopya sayısı belirtilmezse default olarak 1 atanır. Ayrıca servisin ne tür olacağını belirtmezsek otomatik olarak replicated service olarak oluşturulur.

Swarm Service ve Task Yönetim Komutları

Service yönetimi için kullanılacak tüm komutlar docker service ile başlar.

create

Servis oluşturmak için kullanılır:

–name parametresiyle servis ismi verebiliyoruz.

–publish parametresi ile de port yönlendirmesini yapabiliriz:

Daha önce servislerin iki tip oluşturulabildiğinden ve özellikle belirtilmezse replicated türünden oluşturduğundan bahsetmiştik. Servisi bu haliyle oluştur dediğimizde bilmeliyiz ki replicated türünde bir servisimiz olacak.

–replicas parametresi ile servisimizi kaç kopya olarak yayınlamak isteyeceğimizi belirtiriz.

Eğer servisimizi global olarak oluşturmak isteseydik:

–constraint parametresi ile dilersek belirli bir node üzerinde çalışmasını sağlayabiliriz:

Aynı şekilde belirli bir node üzerinde çalışmasın dersek:

Veya sadece Manager üzerinde çalışsın dersek:

ls

Var olan servisleri listelemek için kullanılır.

ps

Task detaylarını göstermek için kullanılır, dolayısıyla container detaylarını da görmüş oluruz.

scale

Çalışan bir servisin kaynaklarını yetmediği zaman yeni kopyalar oluşturarak ölçekleyebilir ve daha fazla sayıda isteğe cevap verebilir hale getirebiliriz.

6, toplamda olacak kopya sayısını belirtir, yani var olan değerin üzerine ekleme yapmaz.

update

Servis ile ilgili güncelleme yapmak istediğimizde kulanırız.

Örneğin yukarıdaki gibi kopya sayısını artırmak istiyoruz, o zaman:

Docker Swarm Yönetim – Monitör Araçları

Docker Swarm yönetimi çok zor olmamakla birlikte hayatımızı daha da kolaylaştıracak yönetim araçları da mevcuttur. Bunları detaylı olarak anlatmayacağım ama en azından isimlerini burada dile getirmiş olacağım

Docker Swarm Visualizer: https://github.com/dockersamples/docker-swarm-visualizer

Portainer: https://www.portainer.io/

Sematext: https://sematext.com/

Overlay Multi – Host Network Yapılandırma

Birden fazla Docker Host bulunan yapılarda, aynı network üzerinden birbirleriyle iletişim sağlayabilmeleri için kullanılırlar. Böyle bir network içinde çalışan container’lar güvenli ve şifreli bir şekilde birbirleriyle iletişim kurabilmektedirler.

Bir overlay network oluşturmak istersek:

Daha sonra farklı hostlarda da çalışsa oluşturacağımız servisleri bu network’ü kullanacak şekilde tanımladığımızda, servislerimiz birbirleriyle konuşabilecektir.

Docker Swarm Rolling Update

Swarm gibi ortamlarda herhangi bir güncelleme yapılırken sıfır kesinti ile yapılması beklenir. Aksi halde kullanımı çok efektif olmayacaktır.

Rolling update bize eski versiyon image ile çalışan servislerimizi, herhangi bir kesinti olmadan yeni versiyon image ile güncellenmesini sağlayabilmektedir.

Şimdi çalışan bir servisi nasıl güncelleyeceğimize gelelim. Bunun için docker service update komutunu kullanacağız.

Komutla birlikte 2 parametre daha kullanacağız. İlki –update-parallelism aynı anda kaç kopyanın yani task’in güncelleneceğini söyleyeceğiz. Diyelim ki 6 kopyamız var, burada 2 seçebiliriz. Default olarak 1 gelir, yani aynı anda 1 tane yapacaksanız bunu belirtmeniz gerekmiyor.

İkinci olarakta –update-delay parametresiyle güncelleştirilecek task’ler arasındaki bekleme süresini belirtmemizi sağlar. S saniye, m dakika, h saat olarak türünü belirtebiliriz.

Swarm Routing Mesh

Routing Mesh bir load balancer servisidir. Swarm içerisinde kullanılan servis portlarını global hale getirir. Bu sayede bir servis ayağa kaldırdığımızda tüm node’lar üzerinden o servise ulaşabiliriz.

Routing Mesh özelliği her node üzerinde otomatik olarak aktifleştirilmektedir. Bu sayede gelen her talebi dinler, portun hangi servise ve hangi node üzerinde koştuğunu bularak yönlendirme işlemini gerçekleştirir. Bunu yapabiliyor olması overlay network alt yapısını kullanıyor olabilmesinden kaynaklanıyor.

Şimdi örnek modelimizdeki gibi 2 Task’lik adı web olan bir servisimiz var. Biz create ettiğimizde Swarm bunların hangi node’larda oluşması gerektiğine karar verir, burada node1 ve node2 seçildi.

Bunlar kendi aralarında frontend adında bir overlay network ile haberleşiyorlar; ama Swarm altyapısında otomatik olarak kurulan Ingress adında bir overlay network bulunuyor. Bu Task’ler çalıştıkları ip ve port bilgilerini IPVS aracılığı ile broadcast ederler ve ağdaki node’lar bunu kendi routing tablolarına kayıt ederler. Böylece ağdaki her node, çalışan her task hakkında bilgi sahbidir.

Son kullanıcı web servisimize erişmek istiyor veya harici load balancer üzerinden Task’lerin bulunmadığı node3’e yönlendiriliyor. Node3 üzerindeki IPVS servisi isteği alıyor ve kendi routing tablosundan karşılaştırma yapıyor. Çalışmakta olduğu 2 node olduğunu görüyor ve 1 tanesini seçiyor, node1.

Seçilen node1’e doğru yönlendirme yapılarak isteğin başarılı bir şekilde gerçekleşmesini ve servise ulaşılmasını sağlıyor.

Docker Swarm Stack

Docker Stack, anı anda, belli bir amaca yönelik oluşturulmuş mikro servislerin, networklerin, volume’lerin tek bir dosyada tanımlanması ve bu dosya üzerinden ayağa kaldırılmasıdır. Docker Compose tool’u kullanılarak yapılandırılır ve ayağa kaldırılır.

Swarm Stack Dosyası ve Yönetim Komutları

Varsayılan olarak Stack dosyasının adı docker-stack.yml’dır. Kullanılan komutlar, Docker Compose’a ek olarak kullanılan birkaç komuttur. Docker Compose dokümanında deploy başlığı Stack komutları görülebilir. İncelediğinizde replicas, mode gibi komutlar tanıdık gelecektir. En yaygın kullanılanlardan bahsedersek:

replicas

Kaç replica halinde yayınyanacağını ifade eder.

mode

Global veya replicated mode olacak şekilde iki tipten birini seçerek çalışma şeklini ifade eder.

labels

Servis için etiketleme yapılmasını ifade eder.

placement

Kısıtları ve tercihleri ifade eder.

resources

Kaynaklar için koyduğumuz sınırlamaları ifade eder.

Yönetim Komutları

Docker Stach yönetim komutları docker stack ile başlar.

deploy

Yeni bir stack ortamı veya var olan bir stack ortamını yenilemek istediğimizde kullanırız.

ls

Stack’leri listelemek için kullanılır.

ps

Stack’lerin içindeki Task’leri listelemek için kullanılır.

services

Stack içindeki servisleri listelemek için kullanılır.

rm

Oluşturduğumuz Stack’leri silmek için kullanılır.

Güzel bir örnek için şu Stack YAML dosyasına bakılabilir: https://github.com/dockersamples/example-voting-app/blob/master/docker-stack.yml

Docker Swarm Secret

Yalnızca Swarm ortamından kullanılabilirler. Container’ların içerisinde saklanması gereken, Docker Compose veya Dockerfile içerisinde yer almaması gereken önemli verileri yönetmek için geliştirilmiştir. Image güvenliği ve güvenilirliği için kullanılır. Kullanım amacı şu verileri güvende tutmaktır:

  • Kullanıcı bilgileri ve şifreleri
  • TLS sertifikası ve key
  • SSH Key

Linux 1.13+, Windows 17.06+ sürümleri ve sonrasında entegre bir şekilde gelmektedir. İçerik karakter boyutu 500kb’tan küçüktür.

Daha önceki örneklerimizde anımsıyorsanız database bağlantısı ve hatta root şifrelerini YAML dosyasına, Dockerfile’a açıkça yazmıştık. Bu açıkça bir güvenlik zaafiyetidir. Böyle bir image’i kim kullanabilir ve güvenliğinden endişe duymaz ki? İşte bu sebeple Docker Swarm Secret kullanımı çok önemlidir.

Şimdi kısaca Swarm ortamında Secret nasıl çalışıyor ona bakalım.

Elimizde şifrelememiz gereken bir db-user ve db-password bilgileri olsun. İlk olarak Swarm ortamındaki Manager üzerinde:

Komutunu çalıştırdığımızda, çalıştığımız Manager’da oluşturulur. Sonrasında ise Raft database’inin sync olması aracılığı ile diğer Manager node’lara iletilmiş olur. Gelelim sonraki aşamaya, create ettiğimiz bu keyleri nasıl kullanıyoruz?

Resimde senaryoyu görüyoruz, öncelikle bir service create işlemi yapıyoruz, create ederken de –secret parametresi ile db-user ve db-password için oluşturduğumuz Secret Key’leri belirtiyoruz.

Manager, 2 kopya olması söylendiği için 2 Worker node seçer ve bu sunucularda Task’lerin ayağa kalkmasını sağlar, sonra da bu keyler Worker’lar tarafından açılarak container’ın içine mount edilirler. Linux için bu dizin /run/secrets, Windows için ise C:\ProgramData\Docker\Secrets dizinidir. Bu bilgiler Linux sistemlerde memory üzerinde saklanır, Windows’ta ise diskte saklanıyor.

Olası bir durumda bu servisleri silmek istediğinizde key bilgileri de memory ve disk üzerinden silinmektedir.

Docker Swarm Secret Yönetim Komutları

Tüm Secret işlemleri docker secret ile başlar. Burada kullanabileceğimiz komutlar şöyledir:

create

Secret key oluşturmak için kullanılır. Bu şifreler bir text dosya içinde olur ve dosya içindeki veri Secret aracılığı ile Raft database’inde şifreli şekilde saklanır.

Örneklendirecek olursak, diyelim ki şifrelerimizi /etc/secret/password dosyamızda olsun. Secret ismi olarak db-pass’ı kullanalım:

Manager bu komut sonrasında bize bir id bilgisi dönecektir.

Diyelim ki biz şifrelerimizi bir dosyada da saklamak istemiyoruz, komut satırında girdiğimiz değerin saklanmasın istiyoruz. O zaman şöyle yapmamız gerekiyor:

Sona koyduğumuz – işareti ile komut satırında yazdığımız şifreyi almasını söylemiş oluyoruz.

inspect

Secret ile ilgili detaylı bilgi almak için kullanılır.

ls

Sistemde kayıt Secret bilgilerini listelemek için kullanılır.

rm

Oluşturduğumuz Secret’leri silmek için kullanılırız.

Servislerde Secret Kullanımı

Bir servis oluşturacağımız zaman Secret’ı kullanmak istersek:

Servis create ederken source ve target olarakta belirtebiliyoruz, örneğin MySQL servisimiz için yapalım. User için: db-user, şifresi için de db-pass Secret’larını kullanacak olalım:

Çalışan bir servis üzerine Secret’ı eklemek istersek:

Çalışan bir servisten kaldırmak istersek:

Çalışan bir servisten eskini kaldırırken yenisini eklemek istersek:

Docker Compose ve Swarm Stack’te Secret Kullanımı

Docker Compose konusunda şu şekilde konfgürasyon dosyaları oluşturmuştuk:

Gördüğünüz gibi açık bir şekilde bunları yazdık. Bunun yerine Secret ile yazmak daha güvenli. Docker Compose içerisinde Secret ile yeniden konfigüre edelim. Oluşturacağımız Secret bilgileri şöyle olsun:

Database user için: db-user

Database user şifresi için: db-pass

Database root şifresi için: db-root-pass

Bu bilgilere göre konfigürasyonumuzu düzenlersek:

Sonda eklediğimiz file bilgileri ise bu secretların oluşturulacağı dosyalardır. Böylece Secret’ı Docker Compose üzerinde kullanmış olduk. Stack için de tanımlamalarda herhangi bir değişiklik olmuyor, aynı şekilde kullanabiliyoruz.

Not: Kaynak olarak Murat AKSU’dan faydalanılmıştır.

Data Science Earth

Data Science Earth ekibi, üst düzey Veri Bilim çözümleri üretmek amacı ile toplanmış akademisyenler ve uzmanlardan oluşmaktadır. Öncelikli olarak veri bilincini geliştirmeyi ve küreselleşen rekabet ortamında verinin gücünün doğru kullanılmasını sağlamayı amaçlamaktadır.

Sponsor

QuestionPro 35 farklı soru seçim özelliği ile anket çalışmalarımıza güç katmaktadır.