며칠 전, 저는 LXC 기반의 운영 체제 레벨 가상화 기술인 Docker에 대한 길고 철저한 가이드를 발표했습니다, 이는 컨테이너화된 애플리케이션을 프로비저닝하는 빠르고, 가볍고, 안전한 방법을 제공합니다. 사랑스럽습니다.
이제, 우리가 첫 서비스들, SSH와 Apache를 테스트할 때 직면한 문제들 중 하나는 이 서비스들의 제어였습니다. 우리는 컨테이너 내부에서 init 스크립트나 systemd를 사용할 수 없었고, 솔직히, 우리는 그것들을 원하지 않을 수도 있습니다. 하지만 우리는 우리 서비스들을 시작, 중지 등을 할 어떤 종류의 메커니즘을 원합니다. Supervisord를 소개합니다, 따라서 이 튜토리얼입니다. 저를 따라오세요. p>
Supervisord 요약
Supervisord는 프로세스를 모니터링하고 제어하기 위해 설계된 프로세스 제어 시스템입니다. 그것은 init을 대체하는 것을 목표로 하지 않으며, 대신 프로세스들을 자체 프레임워크 내에 캡슐화하고, 우리가 원하는 것처럼 부팅 시에 그것들을 시작할 수 있습니다. 이 시점에서 소프트웨어에 대해 더 깊이 들어갈 이유는 없습니다. p>
Supervisord 설정
기본적으로, supervisord는 파이썬 모듈입니다. 그것은 setuptools의 일부인 easy_install을 사용하여 설치될 수 있으며, 이는 파이썬 distutils 패키지의 확장입니다. 네, 이 시점에서 꽤 복잡해집니다. 다행히, 대부분의 리눅스 배포판들은 CentOS를 포함하여 easy_install과 함께 제공되며, 이것이 오늘 우리의 테스트 플랫폼입니다. p>
시작하기 위해, 우리는 컨테이너 내부에서 supervisord를 설치해야 할 것입니다. 그런 다음, 우리는 이미지를 커밋하고 그것을 우리의 빌드에 대한 베이스라인으로 사용할 것이며, 이것은 앞서 언급한 SSH와 Apache 같은 서비스들을 포함할 것입니다. 만약 당신이 호스트에서 supervisord를 설치하려고 시도한다면, 당신은 어떤 문제 없이 성공해야 합니다: p>
easy_install supervisor
Searching for supervisor
Reading https://pypi.python.org/simple/supervisor/
Best match: supervisor 3.1.3
Downloading https://pypi.python.org/packages/source/s/supervisor/
supervisor-3.1.3.tar.gz#md5=aad263c4fbc070de63dd354864d5e552
Processing supervisor-3.1.3.tar.gz
Writing /tmp/easy_install-vbOcMG/supervisor-3.1.3/setup.cfg
Running supervisor-3.1.3/setup.py -q bdist_egg --dist-dir /tmp/easy_install-vbOcMG/supervisor-3.1.3/egg-dist-tmp-i96mIs
warning: no previously-included files matching '*' found under directory 'docs/.build'
Adding supervisor 3.1.3 to easy-install.pth file
Installing echo_supervisord_conf script to /usr/bin
Installing pidproxy script to /usr/bin
Installing supervisorctl script to /usr/bin
Installing supervisord script to /usr/bin
Installed
/usr/lib/python2.7/site-packages/supervisor-3.1.3-py2.7.egg
Processing dependencies for supervisor
Searching for meld3>=0.6.5
Reading https://pypi.python.org/simple/meld3/
Best match: meld3 1.0.2
Downloading https://pypi.python.org/packages/source/m/meld3/
meld3-1.0.2.tar.gz#md5=3ccc78cd79cffd63a751ad7684c02c91
Processing meld3-1.0.2.tar.gz
Writing /tmp/easy_install-wnhLVS/meld3-1.0.2/setup.cfg
Running meld3-1.0.2/setup.py -q bdist_egg --dist-dir /tmp/easy_install-wnhLVS/meld3-1.0.2/egg-dist-tmp-Lp88cX
zip_safe flag not set; analyzing archive contents...
Adding meld3 1.0.2 to easy-install.pth file
Installed /usr/lib/python2.7/site-packages/meld3-1.0.2-py2.7.egg
Finished processing dependencies for supervisor p>
컨테이너 내부에서, 당신은 에러를 얻을 것입니다, 왜냐하면 컨테이너에 추가된 파이썬 프레임워크가 완전하지 않고, 일부 모듈들이 누락되어 있기 때문입니다. p>
# easy_install supervisor
Traceback (most recent call last):
File "/usr/bin/easy_install", line 5, in <module>
from pkg_resources import load_entry_point
ImportError: No module named pkg_resources p>
이는 우리가 수동으로 easy_install을 설정해야 함을 의미합니다: p>
wget https://bitbucket.org/pypa/setuptools/raw/ ->
-> bootstrap/ez_setup.py -O - | python p>
Supervisord 구성
다음 단계는 컨테이너를 위한 구성을 만드는 것입니다. 우리는 호스트에서 파일을 생성할 수 있고, 그런 다음 Dockerfile에서 COPY 명령어를 사용하여 빌드 과정 동안 그것을 우리 이미지에 복사할 것입니다. p>
COPY ./supervisord.conf /etc/supervisord.conf p>
구성 자체는 다음과 같은 것이 될 것입니다: p>
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
[program:httpd]
command=/bin/bash -c "exec /usr/sbin/httpd -DFOREGROUND" p>
여기서 무엇이 있습니까? 각 대괄호 쌍은 섹션을 정의합니다. supervisord 자체에 대해, 우리는 그것이 데몬화되어 백그라운드 서비스가 되는 대신 포그라운드에서 시작하도록 정의합니다. p>
sshd라는 이름의 프로그램에 대해, 우리는 관련 명령어를 실행합니다, 본질적으로 SSHD를 백그라운드에서 실행합니다. httpd라는 이름의 프로그램에 대해, 우리는 별도의 셸에서 포그라운드로 서버를 시작합니다. 많은 다른 옵션들이 있지만, 현재로서는 이것이 supervisord로 시작하는 데 필요한 최소한입니다. p>
컨테이너 실행 및 트러블슈팅
우리가 이미지를 빌드하고 실행한 후, supervisord가 작동하여 우리 프로세스들을 시작해야 합니다. 하지만 먼저, 몇 가지 일반적인 에러들을 처리해 봅시다. 당신이 볼 수 있는 것 중 하나는: p>
docker run -ti -p 22 -p 80 image-3:latest
/usr/lib/python2.7/site-packages/supervisor-3.1.3-py2.7.egg/
supervisor/options.py:296: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security.
'Supervisord is running as root and it is searching '
Error: No config file found at default paths (/usr/etc/supervisord.conf, /usr/supervisord.conf, supervisord.conf, etc/supervisord.conf, /etc/supervisord.conf); use the -c option to specify a config file at a different path
For help, use /usr/bin/supervisord -h p>
만약 당신이 supervisord.conf 파일에 대한 잘못된 경로를 지정했거나, 잘못된 이름을 사용했다면, 서비스는 실행될 수 없을 것입니다. 당신은 COPY 명령어를 편집하고, 이미지를 다시 빌드하고, 처음부터 다시 시작해야 할 것입니다. 그런 다음, 당신이 마주칠 수 있는 다음 에러는: p>
# docker run -ti -p 22 -p 80 image-3:latest
/usr/lib/python2.7/site-packages/supervisor-3.1.3-py2.7.egg/
supervisor/options.py:296: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security.
'Supervisord is running as root and it is searching '
372 CRIT Supervisor running as root (no user in config file)
375 INFO supervisord started with pid 1
378 INFO spawned: 'httpd' with pid 9
381 INFO spawned: 'sshd' with pid 10
602 INFO exited: httpd (exit status 1; not expected)
606 INFO spawned: 'httpd' with pid 11
606 INFO success: sshd entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
671 INFO exited: httpd (exit status 1; not expected)
676 INFO spawned: 'httpd' with pid 12
742 INFO exited: httpd (exit status 1; not expected)
749 INFO spawned: 'httpd' with pid 13
825 INFO exited: httpd (exit status 1; not expected)
826 INFO gave up: httpd entered FATAL state, too many start retries too quickly
gave up: httpd entered FATAL state, too many start retries too quickly p>
우리가 여기서 가지고 있는 것은 Apache 스레드들이 종료되어, supervisord가 그것들을 다시 시작하도록 강요하고, 결국 포기하게 되어, 치명적인 상태로 이어진다는 것입니다. 우리의 컨테이너는 이 시점에서 꽤 쓸모없습니다. p>
여기서, 해결책은 supervisord.conf 파일을 편집하고 httpd 프로그램 섹션에 추가 지시어들을 도입하여 프로세스 생성을 더 우아하게 처리하는 것입니다. p>
[program:httpd]
startsecs = 0
autorestart = false
command=/bin/bash -c "exec /usr/sbin/httpd -DFOREGROUND" p>
우리는 startsecs = 0과 autorestart = false를 추가했습니다. 첫 번째 지시어는 우리에게 말합니다: p>
프로그램이 시작 후 실행 상태를 유지해야 하는 총 초 수로, 시작이 성공적이라고 간주되기 위함입니다. 프로그램이 시작한 후 이 많은 초 동안 실행 상태를 유지하지 못하면, 심지어 예상된 종료 코드로 종료되더라도 (exitcodes 참조), 시작은 실패로 간주될 것입니다. p>
두 번째는 supervisord가 Apache 스레드 재시작을 다루지 않을 것임을 의미하며, 이것들은 들어오는 HTTP 요청을 처리하면서 웹 서버 자체에 의해 처리될 것입니다. p>
false, unexpected, 또는 true 중 하나일 수 있습니다. false라면, 프로세스는 결코 자동 재시작되지 않을 것입니다. unexpected라면, 프로세스는 이 프로세스 구성과 연관된 종료 코드들 중 하나가 아닌 종료 코드로 프로그램이 종료될 때 재시작될 것입니다 (exitcodes 참조). true라면, 프로세스는 종료 코드에 관계없이 무조건 재시작될 것입니다. p>
이제, 우리는 컨테이너를 다시 실행해 볼 수 있습니다. 원래 가이드에서 우리가 마주친 /run/httpd 이슈를 기억하세요? 제자리에 /run 디렉토리가 없으면, 당신은 다음 메시지들을 보게 될 것입니다: p>
docker run -ti -p 22 -p 80 image-3:latest
/usr/lib/python2.7/site-packages/supervisor-3.1.3-py2.7.egg/
supervisor/options.py:296: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security.
'Supervisord is running as root and it is searching '
913 CRIT Supervisor running as root (no user in config file)
916 INFO supervisord started with pid 1
919 INFO spawned: 'httpd' with pid 8
921 INFO spawned: 'sshd' with pid 9
079 INFO success: httpd entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
105 INFO exited: httpd (exit status 0; expected)
120 INFO reaped unknown pid 10
122 INFO success: sshd entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) p>
이 시점에서, 당신은 연결해야 합니다 (attach 또는 exec a BASH 셸) 컨테이너에, 로그를 확인하고, 왜 서비스가 예상대로 실행되지 않는지 이해하려고 노력해야 합니다. p>
성공적인 테스트
그리고 나서, 우리가 결국 모든 것을 정리하면: p>
결론
이것은 꽤 너드스러운 튜토리얼입니다. 하지만 그것은 우리 무기고에 또 다른 유용한 도구를 도입합니다, 우리는 이제 systemd 같은 복잡하고 비싼 프레임워크를 설치하지 않고도 컨테이너 내부의 서비스들을 견고하고 우아한 방식으로 제어할 수 있습니다. 그것은 또한 Docker에 대해, 어떻게 일하고 문제를 트러블슈팅하는지 등에 대해 더 많이 가르칩니다. p>
Supervisord는 엄격하게 필수적인 것은 아닙니다, 왜냐하면 우리는 그것 없이도 sshd와 httpd 프로세스들을 실행할 수 있었기 때문입니다, 하지만 일부 사람들은 이 방법을 선호할 수 있습니다, 특히 그들이 그들의 서비스들을 꽤 자주 시작하고 재시작해야 한다면. 어느 쪽이든, 유틸리티에 익숙해지는 것은 Docker 메커니즘에 대한 이해와 자신감을 구축하는 데 도움이 됩니다. 이 가이드가 유용하기를 바랍니다, 그리고 우리가 다음에 무엇을 탐구해야 할지에 대한 당신의 요청들을 보내주세요. p>
치어스. p>