개요
Inception의 마지막으로 docker compose를 보며 docker 컨테이너와 pid 1번 등 cli 기반으로 살펴보려고 합니다.
docker-compose.yml
services:
mariadb:
image: mariadb
container_name: mariadb
build: ./requirements/mariadb/
expose:
- "3306"
env_file: .env
volumes:
- mariadb_vlm:/var/lib/mysql/
networks:
- inception
init: true
restart: always
wordpress:
image: wordpress
container_name: wordpress
build: ./requirements/wordpress/
expose:
- "9000"
env_file: .env
volumes:
- wordpress_vlm:/var/www/wordpress/
networks:
- inception
init: true
restart: always
depends_on:
- mariadb
nginx:
image: nginx
container_name: nginx
build: ./requirements/nginx/
ports:
- '443:443'
env_file: .env
volumes:
- wordpress_vlm:/var/www/wordpress/
networks:
- inception
init: true
restart: always
depends_on:
- wordpress
volumes:
mariadb_vlm:
driver: local
driver_opts:
type: none
o: bind
device: ~/Desktop/data/mariadb
wordpress_vlm:
driver: local
driver_opts:
type: none
o: bind
device: ~/Desktop/data/wordpress
networks:
inception:
driver: bridge
각 서비스는 독립적으로 구성되어야 하며, 의존성을 명시해두어 docker-compose 파일에 명시된 순서에 상관없이 안정적인 순서로 실행할 수 있도록 구성할 수 있습니다.
컨테이너 이름은 해당 서비스의 이름과 동일해야 합니다. 재시작의 경우에도 "always"로 두면 가상머신을 종료하고 다시 시작했을때 컨테이너가 자동 실행됩니다.
볼륨은 Makefile에서 빈 디렉토리를 만들고 docker-compose에 명시하여 컨테이너가 사용할 볼륨을 가상머신(로컬)볼륨과 bind로 묶어 사용할 수 있도록 합니다.
네트워크는 Docker에서 사용하는 네트워크를 사용하여 Docker 자체가 네트워크 감시와 트레픽제어 등 스스로 관리할 수 있도록 합니다. bridge네트워크는 도커의 서비스가 독립적으로 사용할 수 있는 네트워크로, 포트분리와 안정성 그리고 네트워크 관리 측면에서 여러가지 이점을 보입니다. 예를들어 불필요한 포트 간섭이나 트레픽 제어관리, 용이한 네트워크 로그 확인등이 있습니다.
Docker 컨테이너 들어가기
docker exec -it <container_name> /bin/bash: 다음과 같이 컨테이너 내부에 bash를 실행하여 내부를 살펴볼 수 있습니다.
컨테이너 내부를 살펴보는 이유는 pid 1번에 대한 내용을 서술하기 위해서 입니다. 서비스 중 mariadb의 Dockerfile을 보겠습니다.
FROM debian:11
EXPOSE 3306
RUN apt-get update && apt-get install -y mariadb-server tini
COPY conf/50-server.cnf /etc/mysql/mariadb.conf.d/
COPY tools/setup.sh /bin/
RUN chmod +x /bin/setup.sh
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["setup.sh", "mysqld_safe"]
여기서 ENTRYPOINT는 가장 먼저 실행되는 프로그램을 보장하는 명령어이고 CMD는 단순히 명령어를 실행하는 커맨드입니다. mariadb 컨테이너에 접근한 뒤, ps -ef 명령어로 전체 프로세스 목록을 확인해보겠습니다.
PID 1이 tini인 것을 볼 수 있습니다.
PID 1?
가상머신에서 ps -ef 명령어를 실행해봅니다.
(1번 사진)PID 1번은 모든 프로세스의 부모 프로세스이며 PID 2번은 모든 커널 쓰레드의 부모 쓰레드가 되겠습니다. 사실 PID 1번에 대한 처리를 하지 않아도 Docker container로 실행한 서비스에 대해서는 문제가 발생하지 않지만, PID 1번의 존재와 역할을 알게된 이상, 이 부분에 대해서 처리해야겠습니다.
컴퓨터가 동작할 때 1번을 받는 프로세스는 모든 프로세스의 부모 프로세스로서, 모든 자식 프로세스의 초기화, 상태 감지, 리소스 회수 그리고 시그널 처리 등 시스템 전반에 중요한 역할을 담당합니다.
(2번 사진)컨테이너도 가상 머신과 독립적인 공간을 갖고 있으나, 하나의 실행 단위로 가장 먼저 실행하는 프로그램에 pid 1번을 부여합니다. 따라서 이전 세 개의 Dockerfile을 작성한 모든 부분에 tini을 설치하여 ENTRYPOINT를 준 것입니다. 서비스 setup을 위한 스크립트 파일은 시스템 처리의 역할을 하는 프로그램으로는 적합하지 않겠죠.
*nginx 컨테이너에는 이상하게도 ps 명령어가 동작하지 않습니다. 그래서 apt-get install procps를 설치하여 ps 명령어를 사용하여 확인해보세요.
tini을 설치하지 않고 도커 자체의 init을 사용하는 방법
docker-compose.yml의 "init:true"가 바로 tini의 방식을 사용하는 것입니다. Dockerfile의 tini을 사용하지않고 compose를 사용하면 다음과 같이 확인할 수 있습니다.
'42Seoul' 카테고리의 다른 글
Inception - Docker(Wordpress) (1) | 2024.08.27 |
---|---|
Inception - Docker(mariaDB) (0) | 2024.08.27 |
Inception - Docker(Nginx) (0) | 2024.08.27 |
Inception - WordPress, MariaDB (0) | 2024.08.24 |
Inception - Nginx (1) | 2024.07.12 |
댓글