İçeriğe geç

Docker İçerisinde Supervisor Kullanarak Birden Fazla Servis Çalıştırmak

Bazı durumlarda ufak servislerinizin farklı container içerisine dağılmadan tek bir container içerisinde çalışmasını isteyebilirsiniz.

Gerçekten bir birine sıkı sıkıya bağlı veya zorunlu olarak kullanmanız gereken durumlarda bu tarz bir yaklaşımda bulunmanızı tavsiye ediyoruz.

Docker Ne Öneriyor?

Docker container’ı içerisinde main process olarak ENTRYPOINT veya CMD ile verdiğiniz process’ler çalışmaktadır.

Genel olarak tavsiye edilen görevlerine göre bölerek her bir container içerisinde sadece bir tane servis çalıştırmaktır. 
Docker container’larının network ve volume’larını birbirine bağlayabilirsiniz.

Docker Neden Böyle Söylüyor?

Docker aslında işini düzgün yapacak bir main process olsun diyor. Bu process başlangıçta düzgün olarak çalışsın yeni bir child process başlatmak isterse kendisi başlatsın işleri bittiğinde kapatsın, container’a kapatma sinyali geldiğinde bunların hepsini muntazam bir şekilde sonlandırsın.

Daha fazla detay isterseniz buradan başlayabilirsiniz

https://docs.docker.com/config/containers/multi-service_container/

Dockerfile Oluşturuyoruz

Senaryo olarak iki farklı servisimiz olduğunu varsayalım.
Birinci servisimiz bir dotnet core API uygulaması olsun.
İkinci uygulamamız external bir kaynaktan gelen paketlenmiş bir SpringFramework API olsun.

Bu iki servisi kendi case’inize göre düşünebilirsiniz. Herhangi iki farklı process olması yeterli.

#base image (with java) https://cloud.docker.com/u/nesbilgi/repository/docker/nesbilgi/alpine
FROM nesbilgi/alpine:aspnetcore-2.2.5 AS base
WORKDIR /app
FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /src
COPY src/MyApplication.csproj MyApplication/
FROM build AS publish
WORKDIR /src/MyApplication
RUN dotnet publish MyApplication.csproj -c Release -o /app
FROM base AS final
WORKDIR /app
COPY –from=publish /app .
# SECOND SERVICE
COPY /ext/second-service.jar /ext/second-service.jar
# SUPERVISOR
RUN mkdir -p /var/run/java/ /var/run/dotnet/
COPY /scripts/supervisor-kill-container.py /scripts/supervisor-kill-container.py
COPY /src/MyApplication/supervisord.conf /etc/supervisor/supervisord.conf
CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"]
view raw Dockerfile hosted with ❤ by GitHub

Dikkat ederseniz Docker imajını oluşturmak için projelerin hepsini derledik kopyaladık ama ihtiyacımız olan ENTRYPOINT yada CMD ile çalışacak komutlar yerini supervisor’a bırakıyor.

# SUPERVISORRUN 
mkdir -p /var/run/java/ /var/run/dotnet/

COPY /scripts/supervisor-kill-container.py /scripts/supervisor-kill-container.py

COPY /src/MyApplication/supervisord.conf /etc/supervisor/supervisord.conf

CMD [“supervisord”, “-c”, “/etc/supervisor/supervisord.conf”]

Supervisor Ayarlarının Yapılması

Supervisor için gerçekleştirebileceğiniz birçok ayar var. 
Öncelikle buraya dokümantasyon linkini bırakıyorum http://supervisord.org/index.html

Supervisor config dosyasının isimlendirmesini sizden supervisord.conf şeklinde yapmanızı talep ediyor. Daha sonra bu dosya ismini önceden belirli pathlerde arıyor.

$CWD/supervisord.conf
$CWD/etc/supervisord.conf
/etc/supervisord.conf
/etc/supervisor/supervisord.conf (since Supervisor 3.3.0)
../etc/supervisord.conf (Relative to the executable)
../supervisord.conf (Relative to the executable)
[supervisord]
nodaemon=true
[program:java]
command=java -jar /ext/second-service.jar -DFOREGROUND
stderr_logfile=/var/run/java/err.log
stdout_logfile=/var/run/java/out.log
autorestart=false
[program:dotnet]
command=dotnet /app/MyApplication.dll –urls http://0.0.0.0:80
stderr_logfile=/var/run/dotnet/err.log
stdout_logfile=/var/run/dotnet/out.log
autorestart=false
[eventlistener:dotnet_exit]
command=/scripts/supervisor-kill-container.py
process_name=dotnet
events=PROCESS_STATE_EXITED
[inet_http_server]
port=*:9001
username=admin
password=admin
view raw supervisord.conf hosted with ❤ by GitHub

Ayar dosyasında iki farklı process’in çalıştığını bunları çalıştırmak için gerekli olan komutu ayrıcı log’ların yazılması için bazı ayarlar koyduk.

Main Process Kapanırsa Diğer Process’lerin Kapanması

Biz istedik ki main process olarak gördüğümüz dotnet projemizin herhangi bir şekilde kapanması durumunda bir script çalışsın ve supervisor içerisinde bulunan diğer process’leride sonlandırsın.

#!/usr/bin/env python
import sys
import os
import signal
def write_stdout(s):
sys.stdout.write(s)
sys.stdout.flush()
def write_stderr(s):
sys.stderr.write(s)
sys.stderr.flush()
def main():
while 1:
write_stdout('READY\n')
line = sys.stdin.readline()
write_stdout('This line kills supervisor: ' + line);
try:
pidfile = open('/var/run/supervisord.pid','r')
pid = int(pidfile.readline());
os.kill(pid, signal.SIGQUIT)
except Exception as e:
write_stdout('Could not kill supervisor: ' + e.strerror + '\n')
write_stdout('RESULT 2\nOK')
if __name__ == '__main__':
main()
import sys

Çerez

Supervisor aynı zamanda basit bir ayarla size bir HTTP server oluşturabiliyor. TCP isteklerini dinleyerek process’lerini durumunu görüp müdahale edebiliyorsunuz.

Portları docker dışarısına açmayı unutmayın 🙂


Referanslar
Tarih:Docker

İlk Yorumu Siz Yapın

Bir Cevap Yazın