Docker 컨테이너 내에서 systemd 또는 /sbin/init을 사용하는 방법
Docker 컨테이너 내에서 systemd 또는 /sbin/init을 사용하려면 몇 가지 제약 사항과 접근 방법을 고려해야 합니다. 일반적으로 Docker 컨테이너는 경량화된 프로세스로 실행되는데, 이는 기본적으로 Docker의 설계 철학에 따라 "한 개의 프로세스가 하나의 컨테이너에서 실행되어야 한다"는 원칙에 기인합니다.
그럼에도 불구하고, 특정 상황에서 systemd 또는 /sbin/init을 사용해야 할 경우, 아래의 접근 방법을 고려해 볼 수 있습니다.
1. systemd 사용 방법
컨테이너 내에서 systemd를 실행하려면 몇 가지 설정이 필요합니다. 그러나 이는 꽤 복잡한 작업이며, 호스트 시스템의 초기화 프로세스와 컨테이너 환경의 초기화 프로세스 간에 충돌이 발생할 수 있습니다. 일반적으로 권장되는 방법은 아니지만, 실험적으로 사용하고자 한다면 아래의 단계를 따를 수 있습니다.
- Dockerfile 예시
vim Dockerfile
FROM ubuntu:latest
# systemd를 설치하고 환경 설정
RUN apt-get update && apt-get install -y systemd && \
rm -rf /var/lib/apt/lists/* && \
systemctl mask -- \
dev-hugepages.mount \
sys-fs-fuse-connections.mount \
sys-kernel-config.mount \
display-manager.service \
getty@.service \
systemd-logind.service \
systemd-remount-fs.service \
getty.target \
graphical.target
# systemd가 올바르게 실행될 수 있도록 설정
ENV container docker
CMD ["/lib/systemd/systemd"]
이후 컨테이너를 빌드하고 실행할 때 --privileged 옵션과 함께 실행해야 합니다. 하지만 이 방법은 권장되는 방법이 아닙니다.
2. /sbin/init 사용 방법
/sbin/init을 사용하려면 이를 직접 컨테이너 내에서 실행하면 됩니다. 다만, 위와 마찬가지로 호스트 시스템의 초기화 프로세스와 컨테이너 환경의 초기화 프로세스 간의 충돌이 발생할 수 있습니다. 또한, init이 데몬으로 실행되는 경우 컨테이너가 종료되지 않을 수 있습니다.
- Dockerfile 예시
vim Dockerfile
FROM ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Seoul
RUN sed -i 's/kr.archive.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list
# 필요한 패키지 설치
RUN apt-get update \
&& apt-get install -y procps \
&& apt-get install -qq -y build-essential \
&& apt-get install -qq -y tzdata \
&& apt-get install -qq -y vim curl \
&& apt-get clean autoclean \
&& apt-get autoremove -y \
&& rm -rf /var/lib/{apt,dpkg,cache,log}
CMD ["/sbin/init"]
- 도커 빌드
docker build --tag anti1346/ubuntu-init:22.04 .
- 도커 컨테이너 실행
docker run -d --privileged --name ubuntu --hostname ubuntu anti1346/ubuntu-init:22.04 /sbin/init
- 도커 컨테이너 목록 확인
docker ps -a
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
84c406e8dbf8 anti1346/ubuntu-init:22.04 "/sbin/init" 23 seconds ago Up 21 seconds ubuntu
- 도커 컨테이너 진입 및 systemctl 명령 확인
docker exec -it ubuntu bash
systemctl status
$ docker exec -it ubuntu bash
root@ubuntu:/# systemctl status
● ubuntu
State: running
Jobs: 0 queued
Failed: 0 units
Since: Wed 2023-01-18 09:58:34 KST; 1min 3s ago
CGroup: /
├─init.scope
│ ├─ 1 /sbin/init
│ ├─52 bash
│ ├─60 systemctl status
│ └─61 (pager)
└─system.slice
├─networkd-dispatcher.service
│ └─39 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
├─systemd-journald.service
│ └─22 /lib/systemd/systemd-journald
├─systemd-resolved.service
│ └─35 /lib/systemd/systemd-resolved
├─dbus.service
│ └─37 @dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
├─system-getty.slice
│ └─getty@tty1.service
│ └─51 /sbin/agetty -o -p -- \u --noclear tty1 linux
└─systemd-logind.service
└─40 /lib/systemd/systemd-logind
root@ubuntu:/#
위의 접근 방법은 실험적이거나 보안 위험이 있을 수 있으며, 일반적인 상황에서는 권장되지 않습니다. Docker의 기본 사용 패턴을 따르고, 각 컨테이너에 하나의 프로세스만 실행하도록 하는 것이 좋습니다. 만약 특정한 요구 사항이 있을 경우에는 해당 요구 사항을 가능한 다른 방식으로 해결하는 것이 좋습니다.
참고URL
- github : https://github.com/anti1346/ubuntu-init-22.04
- docker hub : https://hub.docker.com/r/anti1346/ubuntu-init
'리눅스' 카테고리의 다른 글
[리눅스] docker centos 8 systemctl 실행(/sbin/init) (0) | 2022.04.28 |
---|---|
우분투에서 APT 패키지 매니저를 사용하여 APM 스택을 설치하는 방법 (0) | 2022.04.28 |
우분투에 OpenSSL을 설치하는 방법(openssl-1.1.1) (0) | 2022.04.28 |
리눅스에서 운영체제 및 버전을 구분하는 스크립트 (0) | 2022.04.25 |
[draft] lsb_release 명령어 (0) | 2022.04.25 |