Bir Docker Kapsayıcısında Birden Çok Hizmet Nasıl Çalıştırılır
Yayınlanan: 2022-06-30Docker, yığınınızın bileşenlerini yalıtılmış kaplar olarak paketlemek için bir teknolojidir. İşlemlerinizin her birini kendi kapsayıcısında çalıştırarak bileşenler arasında temiz bir ayrım oluşturmak yaygın bir uygulamadır. Bu, modülerliği artırır ve konteynerleştirmenin ölçeklenebilirlik avantajlarına erişmenizi sağlar.
Yine de, tek bir kapsayıcıda birden çok hizmeti çalıştırmak istediğiniz durumlar olabilir. Bu, Docker ekosisteminde doğal olarak gelmese de, birden fazla uzun ömürlü sürece sahip kapsayıcılar oluşturmak için kullanabileceğiniz birkaç farklı yaklaşım göstereceğiz.
Sorunu Tanımlamak
Docker kapsayıcıları tek bir ön plan işlemi çalıştırır. Bu, görüntünün ENTRYPOINT
ve CMD
talimatlarıyla tanımlanır. ENTRYPOINT
, bir görüntünün Dockerfile
ayarlanırken, kapsayıcılar oluşturulurken CMD
geçersiz kılınabilir. Konteynerler, ön plan süreçleri çıktığında otomatik olarak durur.
CMD
diğer işlemleri başlatabilirsiniz, ancak kap yalnızca orijinal ön plan işlemi canlıyken çalışmaya devam eder. ENTRYPOINT/CMD
mekanizmasını kullanarak konteyneri iki bağımsız hizmetin birleşik ömrü boyunca çalışır durumda tutmak doğrudan mümkün değildir.
Birden Çok İşlemi Tek Bir Giriş Noktasında Sarma
Sarmalayıcı komut dosyaları, sorunun en basit çözümüdür. Tüm süreçlerinizi başlatan ve bitmesini bekleyen bir script yazabilirsiniz. Komut dosyasını Docker ENTRYPOINT
olarak ayarlamak, onu kapsayıcının ön plan işlemi olarak çalıştıracak ve kapsayıcıyı, sarılmış komut dosyalarından biri çıkana kadar çalışır durumda tutacaktır.
#!/bin/bash /opt/ilk süreç & /opt/ikinci süreç & bekle -n $ çıkış?
Bu betik, kap içindeki /opt/first-process
ve /opt/second-process
ikili dosyalarını başlatır. &
kullanımı, her işlemin çıkmasını beklemeden betiğin devam etmesine izin verir. wait
, işlemlerden biri sona erene kadar betiği askıya almak için kullanılır. Komut dosyası daha sonra bitmiş komut dosyası tarafından verilen durum koduyla çıkar.
Bu model, kapsayıcının biri çıkana kadar hem first-process
hem de second-process
süreci çalıştırmasıyla sonuçlanır. Bu noktada, diğer işlem hala çalışıyor olsa bile kapsayıcı duracaktır.
Bu betiği kullanmak için, Docker görüntünüzün ENTRYPOINT
ve CMD
kapsayıcının ön plan işlemi yapacak şekilde değiştirin:
GİRİŞ NOKTASI ["/bin/sh"] CMD ["./path/to/script.sh"]
--init
Kapsayıcı Seçeneği
Konteyner süreçlerini yönetmeyle ilgili bir zorluk, çıktıklarında etkili bir şekilde temizlemektir. Docker, CMD
işlem kimliği 1 olarak çalıştırır, bu da onu sinyalleri işlemekten ve zombileri ortadan kaldırmaktan sorumlu kılar. Komut dosyanız bu yeteneklere sahip değilse, kapsayıcınızın içinde devam eden yetim alt süreçlerle karşılaşabilirsiniz.
Docker docker run
komutu, giriş noktasını PID 1 olarak kullanmak için giriş noktasını değiştiren bir --init
bayrağına sahiptir. Bu, tini
çalıştıran, sinyal iletmeyi işleyen ve sürekli olarak zombileri CMD
minimal bir başlatma işlemi uygulamasıdır.
Birçok işlemin ortaya çıkmasını bekliyorsanız ve temizliği manuel olarak yapmak istemiyorsanız --init
kullanmaya değer. Tini, kaplar için tasarlanmış hafif bir başlangıç aromasıdır. systemd
ve upstart
gibi tam teşekküllü alternatiflerden çok daha küçüktür.
Özel Bir Süreç Yöneticisi Kullanma
Yönetilecek çok fazla işleminiz olduğunda, manuel komut dosyası oluşturma, hızla alt-optimal hale gelir. Bir süreç yöneticisini benimsemek, Docker kapsayıcılarınız içinde birkaç hizmeti çalıştırmanın başka bir yoludur. Süreç yöneticisi sizin ENTRYPOINT
olur ve çalışan süreçlerinizden sonra başlatma, sürdürme ve temizleme sorumluluğuna sahiptir.
Bu yaklaşımı uygularken kullanılabilecek birkaç seçenek vardır. supervisord
, /etc/supervisor/conf.d/supervisord.conf
dosyası aracılığıyla kolayca yapılandırılabilen popüler bir seçimdir:

[program:apache2] komut=/usr/sbin/apache2 -DFOREGROUND [program:mysqld] komut=/usr/sbin/mysqld_safe
Bu yapılandırma dosyası, supervisord
Apache ve MySQL'i başlatacak şekilde yapılandırır. Bir Docker kapsayıcısında kullanmak için, gerekli tüm paketleri görüntünüze ekleyin, ardından supervisord
yapılandırma dosyanızı doğru konuma kopyalayın. Kapsayıcılar başladığında otomatik olarak çalıştırmak için supervisord
görüntünün CMD
olarak ayarlayın.
ubuntu'dan: en son RUN apt-get install -y apache2 mysql-server süpervizörü KOPYALA süpervizör.conf /etc/supervisor/conf.d/supervisord.conf GİRİŞ NOKTASI ["/bin/sh"] CMD ["/usr/bin/supervisord"]
supervisord
sürekli çalıştığı için, izlenen süreçlerinizden biri çıktığında kapsayıcıyı durdurmak mümkün değildir. Alternatif bir seçenek, bu yeteneğe sahip olan s6-overlay
. Hizmet komut dosyalarını doğrudan /etc/services.d
içine yerleştirdiğiniz bildirime dayalı bir hizmet modeli kullanır:
# Resminize s6-overlay ekleyin EKLE https://github.com/just-containers/s6-overlay/releases/download/v3.1.0.0/s6-overlay-noarch.tar.xz /tmp RUN tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz RUN printf "#!/bin/shn/usr/sbin/apache2 -DFOREGROUND" > /etc/services.d/first-service/run ÇALIŞTIR chmod +x /etc/services.d/first-service/run # Resminizin giriş noktası olarak s6-overlay'i kullanın GİRİŞ NOKTASI ["/init"]
Kapsayıcıyı docker stop
ile durdurmayı işlemek için hizmet dizinlerinize yürütülebilir bir finish
komut dosyası ekleyebilirsiniz. s6-overlay
, işlemi stop
komutu nedeniyle bir TERM
sinyali aldığında bu komut dosyalarını otomatik olarak çalıştırır.
Bitir komut dosyaları, hizmetlerinin çıkış kodunu ilk argümanları olarak alır. Yakalanmayan bir sinyal nedeniyle hizmet kesildiğinde kod 256'ya ayarlanır. Komut dosyasının son çıkış kodunu /run/s6-linux-init-container-results/exitcode
; s6-overlay bu dosyayı okur ve içindeki değerle çıkar ve bu kodun kapsayıcınızın durdurma kodu olarak kullanılmasına neden olur.
#!/bin/sh echo "$1" > /run/s6-linux-init-container-results/exitcode
Bir Kapsayıcıda Ne Zaman Birden Çok İşlem Çalıştırmalısınız?
Bu teknik en iyi şekilde, bağımsız kapsayıcılar olarak çalıştırmak için ayıramayacağınız sıkı bir şekilde birleştirilmiş işlemlerde kullanılır. Bir arka plan yardımcı yardımcı programına veya bireysel süreçlerin kendi yönetimini gerçekleştiren monolitik bir uygulamaya dayanan bir programınız olabilir. Yukarıda gösterilen teknikler, bu tür yazılımları kapsayıcı hale getirmenize yardımcı olabilir.
Bir kapta birden çok işlemi çalıştırmaktan yine de mümkün olduğunca kaçınılmalıdır. Tek bir ön plan işlemine bağlı kalmak, yalıtımı en üst düzeye çıkarır, bileşenlerin birbiriyle karışmasını önler ve belirli parçalarda hata ayıklama ve test etme yeteneğinizi geliştirir. Bileşenleri kapsayıcı düzenleyicileri kullanarak ayrı ayrı ölçeklendirebilir, bu da size kaynak açısından en yoğun süreçlerinizin daha fazla örneğini çalıştırma esnekliği sağlar.
Çözüm
Kapsayıcılar genellikle bir ön plan işlemine sahiptir ve canlı olduğu sürece çalışır. Bu model, en iyi konteynerleştirme uygulamalarıyla uyumludur ve teknolojiden en fazla faydayı elde etmenizi sağlar.
Bazı durumlarda, bir kapsayıcıda çalıştırmak için birden çok işleme ihtiyacınız olabilir. Tüm görüntülerin nihayetinde tek bir giriş noktası olduğundan, bir sarmalayıcı komut dosyası yazmanız veya hedef ikili dosyalarınızı başlatma sorumluluğunu alan bir süreç yöneticisi eklemeniz gerekir.
Süreç yöneticileri size ihtiyacınız olan her şeyi verir, ancak görüntülerinizi ekstra paketler ve yapılandırma ile şişirir. Sarmalayıcı komut dosyaları daha basittir ancak zombi sürecinin çoğalmasını önlemek için --init
bayrağıyla eşleştirilmesi gerekebilir.