[Docker] 도커 컨테이너에서 호스트에 있는 명령어를 실행하는 방법
포스트
취소

[Docker] 도커 컨테이너에서 호스트에 있는 명령어를 실행하는 방법

도커 컨테이너에서 호스트에 있는 명령어를 실행하는 방법

출처의 내용을 한글로 번역하였습니다.

출처 : https://stackoverflow.com/questions/32163955/how-to-run-shell-script-on-host-from-docker-container


도커 컨테이너에서 호스트에 있는 명령어를 호스트가 직접 실행하게 하고 싶다.

네임드 파이프(Named Pipe, 명명된 파이프)를 이용하여 컨테이너와 호스트 간 통신을 하여 구현할 것이다.

파이프란 프로세스간 통신을 할 때 사용하는 방법 중 하나이다.

방법

1. 호스트에서 파이프 생성해보기

호스트에서, named pipe를 원하는 위치에 아래 명령어로 생성한다.

1
mkfifo /path/to/pipe/mypipe

Type이 p인 파일이 생성된다.

1
2
ls -l /path/to/pipe/mypipe
prw-r--r-- 1 root root 0  5월 18 15:08 /path/to/pipe/mypipe

터미널을 2개 열어서, 파이프로 메시지를 수신/송신 해보자.

터미널 1에서 파이프에서 메시지를 수신하도록 한다.

1
2
# 터미널 1
tail -f /path/to/pipe/mypipe

터미널 2에서 파이프로 메시지를 송신한다.

1
2
# 터미널 2
echo "hello world!" > /path/to/pipe/mypipe

터미널 1에서 “hello world!” 가 정상적으로 출력되는지 확인한다.

Ctrl + C를 입력하여 빠져나올 수 있다.

2. 생성한 파이프를 통해 명령어 수행해보기

터미널 1에서 tail -f 대신 아래 명령어로 파이프에서 읽은 메시지를 수행하도록 한다.

1
2
# 터미널 1
eval "$(cat /path/to/pipe/mypipe)"

터미널 2에서 ls -l 명령어를 파이프로 송신한다.

1
2
# 터미널 2
echo "ls -l" > /path/to/pipe/mypipe

터미널 1에서 ls -l 명령어의 수행 결과가 출력되는지 확인한다.

3. 호스트에서 파이프를 계속 읽도록 하기

2번 방법에선 하나의 명령어를 수신한 뒤 멈추기 때문에, 아래 명령어로 계속 수신하게 한다.

1
2
# 터미널 1
while true; do eval "$(cat /path/to/pipe/mypipe)"; done

이제 터미널 2에서 파이프로 여러 번 명령어를 송신해도 처음 수신 후 멈추지 않고 계속해서 명령어를 수신받는 것을 확인한다.

Ctrl + C를 입력하여 빠져나올 수 있다.

4. reboot 시에도 스크립트가 실행되도록 하기

아래 내용을 스크립트로 작성한다.

1
2
#!/bin/bash
while true; do eval "$(cat /path/to/pipe/mypipe)"; done

만약 파이프로 전송된 메시지 수행한 기록을 파일로 남기고 싶다면 아래 내용으로 스크립트를 작성한다.

1
2
3
4
#!/bin/bash
while true; do eval "$(cat /path/to/pipe/mypipe)" &> /somepath/output.txt; done
# /somepath/output.txt 파일에 기록이 남는다.
# &>> 로 변경하면 덮어쓰지 않고 뒤에 붙여쓴다.

작성한 스크립트를 chmod +x 로 실행권한을 준다.

그리고 crontab에 reboot 시 스크립트가 실행되도록 추가한다.

1
crontab -e
1
2
# 아래 내용을 추가
@reboot /path/to/pipe/exec_pipe.sh

5. 컨테이너에서 호스트의 파이프 마운트하기(VOLUME)

dockerfile 또는 컨테이너를 실행할 때, 생성한 파이프 파일을 마운트하도록 volumn을 설정한다.

호스트의 /path/to/pipe 디렉토리를 컨테이너의 /hostpipe 디렉토리에 마운트한다.

1
2
3
# dockerfile 에서 설정
volumes:
   - /path/to/pipe:/hostpipe
1
2
# 컨테이너 실행 시 설정
docker run test -d --name <container> -v /path/to/pipe:/hostpipe ubuntu:20.04 bash

6. 컨테이너에서 파이프를 통해 호스트에서 명령어 실행하게 하기

컨테이너에 접속해서 파이프에 명령어를 송신해보자.

컨테이너에 접속한다.

1
docker exec -it <container> bash

컨테이너에 호스트의 파이프가 마운트 된 것을 확인할 수 있다.

1
cd /hostpipe && ls -l

컨테이너에서 파이프로 명령어를 송신한다.

1
echo "touch this_file_was_created_on_main_host_from_a_container.txt" > /hostpipe/mypipe

파이프를 통해 this_file_was_created_on_main_host_from_a_container.txt 파일이 호스트에 생성되었음을 확인해보자.

주의사항

리눅스 host, 리눅스 container에서 정상 작동한다.

macOS 또는 Windows 기반의 시스템에서는 정상 작동하지 않을 수 있다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

[VSCode] 내가 사용하는 VSCode Extension

[HTML] video tag