Docker'ı Kullanmaya Başlarken: DevOps'u Basitleştirme

Yayınlanan: 2022-03-11

Balinaları seviyorsanız veya yazılımınızın üretime hızlı ve sorunsuz bir şekilde sürekli teslimi ile ilgileniyorsanız, sizi bu giriş niteliğindeki Docker Eğitimini okumaya davet ediyorum. Her şey, yazılım kapsayıcılarının BT'nin geleceği olduğunu gösteriyor gibi görünüyor, o halde hadi kap balinaları Moby Dock ve Molly ile hızlı bir dalış yapalım.

Dost görünümlü bir balina ile bir logo ile temsil edilen Docker

Dost görünümlü bir balinaya sahip bir logo ile temsil edilen Docker, uygulamaların yazılım kapsayıcıları içinde dağıtımını kolaylaştıran açık kaynaklı bir projedir. Temel işlevselliği, Linux çekirdeğinin kaynak izolasyon özellikleri tarafından etkinleştirilir, ancak bunun üzerine kullanıcı dostu bir API sağlar. İlk sürüm 2013'te piyasaya sürüldü ve o zamandan beri son derece popüler hale geldi ve eBay, Spotify, Baidu ve daha fazlası gibi birçok büyük oyuncu tarafından yaygın olarak kullanılıyor. Son finansman turunda Docker, 95 milyon dolarlık devasa bir gelir elde etti ve DevOps hizmetlerinin bir parçası olma yolunda ilerliyor.

Mal Taşıma Analojisi

Docker'ın arkasındaki felsefe, aşağıdaki basit bir benzetmeyle gösterilebilir. Uluslararası taşımacılık sektöründe, malların forklift, kamyon, tren, vinç, gemi gibi farklı araçlarla taşınması gerekmektedir. Bu mallar farklı şekil ve boyutlarda gelir ve farklı depolama gereksinimlerine sahiptir: şeker çuvalları, süt kutuları, bitkiler vb. Tarihsel olarak, yükleme ve boşaltma için her geçiş noktasında manuel müdahaleye bağlı olarak sancılı bir süreçti.

Bir at arabası, bir kamyonet ve bir nakliye kamyonu, tümü malları taşıyor

Her şey intermodal konteynerlerin alımıyla değişti. Standart boyutlarda geldikleri ve nakliye düşünülerek üretildikleri için ilgili tüm makineler, minimum insan müdahalesi ile bunları işlemek üzere tasarlanabilir. Mühürlü kapların ek yararı, hassas mallar için sıcaklık ve nem gibi iç ortamı koruyabilmeleridir. Sonuç olarak, taşımacılık endüstrisi malların kendileri için endişelenmeyi bırakabilir ve onları A noktasından B noktasına götürmeye odaklanabilir.

Kara ve deniz yoluyla nakliye konteynırları kullanılarak nakliye

İşte burada Docker devreye giriyor ve yazılım endüstrisine benzer faydalar sağlıyor.

Sanal Makinelerden Farkı Nedir?

Hızlı bir bakışta sanal makineler ve Docker kapsayıcıları birbirine benzeyebilir. Ancak, aşağıdaki şemaya baktığınızda temel farklılıkları ortaya çıkacaktır:

Sanal makinelerin (VM'ler) ve kapsayıcıların karşılaştırma tablosu

Hiper yönetici dışında sanal makinelerde çalışan uygulamalar, işletim sisteminin tam bir örneğini ve destekleyici kitaplıkları gerektirir. Konteynerler ise işletim sistemini ana bilgisayarla paylaşır. Hipervizör, kapsayıcıların yaşam döngüsünü yönetmesi açısından kapsayıcı motoruyla (görüntüde Docker olarak gösterilir) karşılaştırılabilir. Önemli fark, kapsayıcıların içinde çalışan işlemlerin tıpkı ana bilgisayardaki yerel işlemler gibi olması ve hiper yönetici yürütmeyle ilişkili herhangi bir ek yük getirmemesidir. Ayrıca, uygulamalar kitaplıkları yeniden kullanabilir ve verileri kapsayıcılar arasında paylaşabilir.

Her iki teknolojinin de farklı güçleri olduğundan, sanal makineleri ve kapsayıcıları birleştiren sistemler bulmak yaygındır. Mükemmel bir örnek, Docker yükleme bölümünde açıklanan Boot2Docker adlı bir araçtır.

Docker Mimarisi

Docker Mimarisi

Mimari diyagramın en üstünde kayıtlar var. Varsayılan olarak, ana kayıt defteri, genel ve resmi görüntüleri barındıran Docker Hub'dır. Kuruluşlar dilerlerse özel kayıtlarını da barındırabilirler.

Sağ tarafta resimlerimiz ve kaplarımız var. Görüntüler, kayıtlardan açıkça ( docker pull imageName ) veya bir kapsayıcı başlatılırken dolaylı olarak indirilebilir. Görüntü indirildikten sonra yerel olarak önbelleğe alınır.

Kaplar, görüntülerin örnekleridir - onlar yaşayan şeydir. Aynı görüntüye dayalı olarak çalışan birden fazla kapsayıcı olabilir.

Merkezde, kapsayıcıların oluşturulmasından, çalıştırılmasından ve izlenmesinden sorumlu Docker arka plan programı vardır. Ayrıca görüntülerin oluşturulması ve depolanmasıyla da ilgilenir. Son olarak, sol tarafta bir Docker istemcisi var. HTTP aracılığıyla arka plan programıyla konuşur. Unix soketleri aynı makinedeyken kullanılır, ancak HTTP tabanlı API aracılığıyla uzaktan yönetim mümkündür.

Docker'ı Yükleme

En son talimatlar için her zaman resmi belgelere başvurmalısınız.

Docker yerel olarak Linux üzerinde çalışır, bu nedenle hedef dağıtıma bağlı olarak sudo apt-get install docker.io kadar kolay olabilir. Ayrıntılar için belgelere bakın. Normalde Linux'ta, Docker komutlarını sudo ile hazırlarsınız, ancak netlik için bu makalede bunu atlayacağız.

Docker arka plan programı Linux'a özgü çekirdek özelliklerini kullandığından, Docker'ı Mac OS veya Windows'ta yerel olarak çalıştırmak mümkün değildir. Bunun yerine Boot2Docker adlı bir uygulama yüklemelisiniz. Uygulama bir VirtualBox Sanal Makinesi, Docker'ın kendisi ve Boot2Docker yönetim yardımcı programlarından oluşur. Bu platformlara Docker yüklemek için MacOS ve Windows için resmi kurulum talimatlarını takip edebilirsiniz.

Docker'ı kullanma

Bu bölüme hızlı bir örnekle başlayalım:

 docker run phusion/baseimage echo "Hello Moby Dock. Hello Molly."

Bu çıktıyı görmeliyiz:

 Hello Moby Dock. Hello Molly.

Ancak, sahne arkasında düşündüğünüzden çok daha fazlası oldu:

  • 'Phusion/baseimage' görüntüsü Docker Hub'dan indirildi (zaten yerel önbellekte değilse)
  • Bu resme dayalı bir kapsayıcı başlatıldı
  • Eko komutu kapsayıcı içinde yürütüldü
  • Komut çıkıldığında kapsayıcı durduruldu

İlk çalıştırmada, metnin ekrana yazdırılmasından önce bir gecikme fark edebilirsiniz. Görüntü yerel olarak önbelleğe alınmış olsaydı, her şey bir saniyenin çok küçük bir bölümünü alırdı. Son kapsayıcıyla ilgili ayrıntılar, docker ps -l çalıştırılarak alınabilir:

 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES af14bec37930 phusion/baseimage:latest "echo 'Hello Moby Do 2 minutes ago Exited (0) 3 seconds ago stoic_bardeen

Sonraki Dalışı Yapmak

Anlayabileceğiniz gibi, Docker'da basit bir komut çalıştırmak, onu doğrudan standart bir terminalde çalıştırmak kadar kolaydır. Daha pratik bir kullanım örneğini göstermek için, bu makalenin geri kalanında basit bir web sunucusu uygulamasını dağıtmak için Docker'ı nasıl kullanabileceğimizi göreceğiz. İşleri basit tutmak için, '/ping' için HTTP GET isteklerini işleyen ve 'pong\n' dizesiyle yanıt veren bir Java programı yazacağız.

 import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; public class PingPong { public static void main(String[] args) throws Exception { HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); server.createContext("/ping", new MyHandler()); server.setExecutor(null); server.start(); } static class MyHandler implements HttpHandler { @Override public void handle(HttpExchange t) throws IOException { String response = "pong\n"; t.sendResponseHeaders(200, response.length()); OutputStream os = t.getResponseBody(); os.write(response.getBytes()); os.close(); } } }

docker dosyası

Kendi Docker görüntünüzü oluşturmadan önce, Docker Hub'da veya erişiminiz olan herhangi bir özel kayıt defterinde mevcut bir görüntü olup olmadığını kontrol etmek iyi bir uygulamadır. Örneğin, Java'yı kendimiz yüklemek yerine resmi bir resim kullanacağız: java:8 .

Bir imaj oluşturmak için öncelikle kullanacağımız temel imaja karar vermemiz gerekiyor. FROM komutu ile gösterilir. Burada, Docker Hub'dan Java 8 için resmi bir görüntüdür. Bir COPY komutu vererek onu Java dosyamıza kopyalayacağız. Daha sonra RUN ile derleyeceğiz. EXPOSE komutu, görüntünün belirli bir bağlantı noktasında hizmet sağlayacağını belirtir. ENTRYPOINT , bu görüntüye dayalı bir kapsayıcı başlatıldığında yürütmek istediğimiz bir komuttur ve CMD , ona ileteceğimiz varsayılan parametreleri belirtir.

 FROM java:8 COPY PingPong.java / RUN javac PingPong.java EXPOSE 8080 ENTRYPOINT ["java"] CMD ["PingPong"]

Bu talimatları “Dockerfile” adlı bir dosyaya kaydettikten sonra, aşağıdakileri yürüterek ilgili Docker görüntüsünü oluşturabiliriz:

 docker build -t toptal/pingpong .

Docker'ın resmi belgelerinde Dockerfile yazmakla ilgili en iyi uygulamalara ayrılmış bir bölüm vardır.

Çalışan Konteynerler

İmaj oluşturulduğunda, onu bir kapsayıcı olarak hayata geçirebiliriz. Kapsayıcıları çalıştırmanın birkaç yolu vardır, ancak basit bir tanesiyle başlayalım:

 docker run -d -p 8080:8080 toptal/pingpong

burada -p [host-on-the-port]:[port-in-the-container] , sırasıyla ana bilgisayardaki ve kapsayıcıdaki bağlantı noktaları eşlemesini belirtir. Ayrıca, Docker'a -d belirterek kapsayıcıyı arka planda bir arka plan programı olarak çalıştırmasını söylüyoruz. 'http://localhost:8080/ping' adresine erişmeye çalışarak web sunucusu uygulamasının çalışıp çalışmadığını test edebilirsiniz. Boot2docker'ın kullanıldığı platformlarda, 'localhost'u Docker'ın çalıştığı sanal makinenin IP adresiyle değiştirmeniz gerekeceğini unutmayın.

Linux'ta:

 curl http://localhost:8080/ping

Boot2Docker gerektiren platformlarda:

 curl $(boot2docker ip):8080/ping

Her şey yolunda giderse, yanıtı görmelisiniz:

 pong

Yaşasın, ilk özel Docker konteynerimiz yaşıyor ve yüzüyor! Kapsayıcıyı etkileşimli bir mod -i -t ile de başlatabiliriz. Bizim durumumuzda, giriş noktası komutunu geçersiz kılacağız , böylece bir bash terminali ile karşılaşacağız. Artık istediğimiz komutları uygulayabiliriz, ancak konteynerden çıkmak onu durduracaktır:

 docker run -i -t --entrypoint="bash" toptal/pingpong

Kapsayıcıları başlatmak için kullanılabilecek daha birçok seçenek vardır. Birkaç tane daha ele alalım. Örneğin, verileri kapsayıcının dışında tutmak istiyorsak, ana bilgisayar dosya sistemini -v kullanarak kapsayıcıyla paylaşabiliriz. Varsayılan olarak, erişim modu okuma-yazma şeklindedir, ancak kapsayıcı içi birim yoluna :ro eklenerek salt okunur moda değiştirilebilir. Birimler, görüntüde saklanmaması gereken, kapların içinde kimlik bilgileri ve özel anahtarlar gibi güvenlik bilgilerini kullanmamız gerektiğinde özellikle önemlidir. Ek olarak, örneğin yerel Maven deponuzu kapsayıcıya eşleyerek, sizi İnternet'i iki kez indirmekten kurtarmak için verilerin çoğaltılmasını da önleyebilir.

Docker ayrıca kapsayıcıları birbirine bağlama yeteneğine de sahiptir. Bağlantılı kapsayıcılar, bağlantı noktalarından hiçbiri açıkta olmasa bile birbirleriyle konuşabilir. –link other-container-name ile elde edilebilir. Aşağıda, yukarıda belirtilen parametreleri birleştiren bir örnek verilmiştir:

 docker run -p 9999:8080 --link otherContainerA --link otherContainerB -v /Users/$USER/.m2/repository:/home/user/.m2/repository toptal/pingpong

Diğer Konteyner ve İmaj İşlemleri

Şaşırtıcı olmayan bir şekilde, kaplara ve görüntülere uygulanabilecek işlemlerin listesi oldukça uzundur. Kısaca, bunlardan sadece birkaçına bakalım:

  • stop - Çalışan bir kapsayıcıyı durdurur.
  • start - Durdurulmuş bir kapsayıcıyı başlatır.
  • taahhüt - Bir kapsayıcının değişikliklerinden yeni bir görüntü oluşturur.
  • rm - Bir veya daha fazla kapsayıcıyı kaldırır.
  • rmi - Bir veya daha fazla resmi kaldırır.
  • ps - Kapsayıcıları listeler.
  • görüntüler - Görüntüleri listeler.
  • exec - Çalışan bir kapsayıcıda bir komut çalıştırır.

Son komut, çalışan bir kapsayıcının bir terminaline bağlanmanıza izin verdiği için hata ayıklama amacıyla özellikle yararlı olabilir:

 docker exec -i -t <container-id> bash

Mikro Hizmet Dünyası için Docker Oluşturma

Birbirine bağlı birkaç konteynerden daha fazlasına sahipseniz, docker-compose gibi bir araç kullanmak mantıklıdır. Bir yapılandırma dosyasında, kapsayıcıların nasıl başlatılacağını ve bunların birbirleriyle nasıl ilişkilendirilmesi gerektiğini açıklarsınız. İlgili kapsayıcıların miktarından ve bağımlılıklarından bağımsız olarak, hepsini tek bir komutla çalışır duruma getirebilirsiniz: docker-compose up .

Vahşi doğada liman işçisi

Proje yaşam döngüsünün üç aşamasına bakalım ve dost balinamızın nasıl yardımcı olabileceğini görelim.

Gelişim

Docker, yerel geliştirme ortamınızı temiz tutmanıza yardımcı olur. Java, Kafka, Spark, Cassandra vb. gibi farklı hizmetlerin birden çok sürümünün yüklenmesi yerine, gerektiğinde gerekli bir kapsayıcıyı başlatabilir ve durdurabilirsiniz. Bağımlılık sürümlerinin karışmasını önleyerek işleri bir adım daha ileri götürebilir ve birden çok yazılım yığınını yan yana çalıştırabilirsiniz.

Docker ile zamandan, emekten ve paradan tasarruf edebilirsiniz. Projenizin kurulumu çok karmaşıksa, onu "dockerize edin". Bir Docker görüntüsü oluşturmanın acısını bir kez yaşayın ve bu noktadan sonra herkes anında bir kapsayıcı başlatabilir.

Ayrıca yerel olarak (veya CI üzerinde) çalışan bir "tümleştirme ortamına" sahip olabilir ve saplamaları Docker kapsayıcılarında çalışan gerçek hizmetlerle değiştirebilirsiniz.

Test / Sürekli Entegrasyon

Dockerfile ile yeniden üretilebilir yapılar elde etmek kolaydır. Jenkins veya diğer CI çözümleri, her yapı için bir Docker görüntüsü oluşturacak şekilde yapılandırılabilir. Gelecekte başvurmak üzere bazı veya tüm görüntüleri özel bir Docker kayıt defterinde saklayabilirsiniz.

Docker ile sadece test edilmesi gerekenleri test eder ve ortamı denklemden çıkarırsınız. Çalışan bir kapsayıcı üzerinde testler yapmak, işleri çok daha öngörülebilir tutmaya yardımcı olabilir.

Yazılım kapsayıcılarına sahip olmanın bir başka ilginç özelliği de, aynı geliştirme kurulumuyla bağımlı makinelerin döndürülmesinin kolay olmasıdır. Kümelenmiş dağıtımların yük testi için özellikle yararlı olabilir.

Üretim

Docker, geliştiriciler ve operasyon personeli arasında bir sürtünme kaynağını ortadan kaldıran ortak bir arayüz olabilir. Ayrıca, boru hattının her adımında aynı görüntünün/ikili dosyaların kullanılmasını teşvik eder. Ayrıca, ortam farklılıkları olmadan tamamen test edilmiş kapsayıcıyı dağıtabilmek, oluşturma sürecinde hiçbir hatanın ortaya çıkmamasını sağlamaya yardımcı olur.

Uygulamaları üretime sorunsuz bir şekilde geçirebilirsiniz. Bir zamanlar sıkıcı ve lapa lapa bir süreç olan bir şey artık şu kadar basit olabilir:

 docker stop container-id; docker run new-image

Ve yeni bir sürümü dağıtırken bir şeyler ters giderse, her zaman hızlı bir şekilde geri alabilir veya başka bir kapsayıcıya geçebilirsiniz:

 docker stop container-id; docker start other-container-id

… geride herhangi bir karışıklık bırakmamayı veya işleri tutarsız bir durumda bırakmamayı garanti eder.

Özet

Docker'ın yaptıklarının iyi bir özeti, kendi sloganına dahil edilmiştir: İnşa Et, Gönder, Çalıştır.

  • Build - Docker, geliştirme ve üretim ortamları arasındaki tutarsızlıklar konusunda endişelenmeden ve herhangi bir platforma veya dile kilitlenmeden uygulamanızı mikro hizmetlerden oluşturmanıza olanak tanır.
  • Ship - Docker, uygulama geliştirme, test etme ve dağıtım döngüsünün tamamını tasarlamanıza ve tutarlı bir kullanıcı arayüzü ile yönetmenize olanak tanır.
  • Çalıştır - Docker, ölçeklenebilir hizmetleri çok çeşitli platformlarda güvenli ve güvenilir bir şekilde dağıtma olanağı sunar.

Balinalarla yüzerken iyi eğlenceler!

Bu çalışmanın bir kısmı, Adrian Mouat'ın Docker'ı Kullanmak adlı mükemmel kitabından esinlenmiştir.