0

Запуск docker-контейнера по http запросу

В этой заметке опишу процесс создания docker контейнера по http запросу. Полезно, когда некий сервис не нужен постоянно, и его нужно запустить в тот момент, когда к нему обращаются.

В этом поможет технология Socket Activation из состава systemd. В двух словах, это возможность systemd запускать некий сервис при активности в сокете. Сама по себе эта идея запускать сервис по запросу не нова, но в реализации systemd она хороша.

Первым делом нужно создать новый socket unit. Для этого создаю файл /etc/systemd/system/a-test.socket :

[Unit]
Description=a-test Demo
PartOf=a-test.service

[Socket]
ListenStream=127.0.0.1:9000

[Install]
WantedBy=sockets.target

Сокет будет висеть на localhost:9000 порту, и является частью сервиса a-test.service. PartOf говорит о том, что при перезапуске или остановке a-test.service будет перезапущен или остановлени a-test.socket.

Далее описываю a-test.service. /etc/systemd/system/a-test.service:

[Unit]
Requires=a-test-docker.service
After=a-test-docker.service

[Service]
ExecStart=/lib/systemd/systemd-socket-proxyd 127.0.0.1:8000

Этот unit будет запускать proxy на 127.0.0.1:8000 после того, как будет запущен a-test-docker.service

Настало время описать unit, который будет запускать сам docker контейнер — /etc/systemd/system/a-test-docker.service:

[Unit]
Description=a-test-docker
After=network.target a-test.socket
Requires=a-test.socket

[Service]
ExecStart=/usr/bin/docker run --rm -d -m 200mb --name a-test -p 8000:80 a-test
ExecStartPost=/bin/sleep 5

Описанные выше units работают следующим образом.
a-test.socket запущен и слушает входящие запросы на порт 9000. Как только такой запрос появляется, активируется unit a-test.service, который в свою очередь запускает и дожидается запуска a-test-docker.service. Как только контейнер будет запущен запустится a-test.service, проксирующий трафик на docker контейнер.

[root@dkr1 ~]# curl -I localhost:9000
HTTP/1.1 503 Service Temporarily Unavailable
Server: webkaos
Date: Sun, 20 Aug 2017 13:40:09 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
X-Powered-By: PHP/7.0.21
Status: 503 Service Temporarily Unavailable
Retry-After: 300
Vary: User-Agent

В моем случае ошибка 503, но это уже ответ от docker контейнера, что и требовалось.
Следующим постом опишу для чего это делалось и что в итоге получилось.

Alexey Egorychev

FreeBSD and Linux sysadmin. Know many systems like mailsystems, DB, WWW stack. Automation with salt, ansible. Monitoring with nagios, zabbix.