Docker Container

지난 주에 회사 교육으로 도커 컨테이너에 대한 강의를 들었습니다. 이미 며칠이 지났기 때문에 기억이 조금 흐릿해지긴 했지만 완전히 다 까먹기 전에 기록해 두려고 합니다.

컨테이너 기반 기술

도커(Docker)라는 컨테이너 기술은 어느 날 갑자기 하늘에서 뚝 떨어진 것이 아니며 오래 전부터 리눅스에 포함되어 있던 여러 가지 기술을 잘 조합하여 사용하기 쉽도록 패키징 한 것입니다. 여러 컨테이너 기반 기술 중 주요한 몇 가지를 정리하면 아래와 같습니다.

  1. chroot: 루트 디렉토리 격리
  2. Namespace: 시스템 리소스를 논리적으로 격리
    • PID Namespace: PID 1번을 각 네임스페이스별로 할당
    • MNT Namespace: 파일 시스템의 마운트 포인트를 격리 (개별적으로 mount/umount)
    • UTS Namespace: hostname 격리
    • IPC Namespace: 프로세스간 통신, 데이터 교환 격리
    • USER Namespace: UID와 GID 격리
    • NET Namespace: 네트워크 자원 격리 (네트워크 장치, 주소, 방화벽 규칙)
  3. cgroups (control groups): CPU, Memory, Network, Storage 자원 할당 및 제어
  4. OverayFS: 레이어 방식으로 파일을 저장함
    • Lower Dir (read-only)
    • Upper Dir (read-write)

도커 설치하기

도커를 설치하는 방법은,
(1) Windows 또는 Mac 사용자라면 Docker Desktop을 설치하는 것이 가장 편하고 (라이선스 주의!)
(2) Linux 사용자라면 https://get.docker.com를 저장해서 실행하면 됩니다.

도커 다루기

이 글에서는 상세한 설명은 포함하지 않고 주요 커맨드 위주로 정리하였습니다. 필요할 때 기억을 더듬어서 찾아볼 수 있도록 하는 게 이 글의 목표이니까요.

# 서버와 클라이언트 버전 확인
docker version

# Docker 실행 환경 상세 확인
docker info

# Docker가 사용하고 있는 디스크 확인
docker system df

# 컨테이너 생성 (Start는 하지 않음)
# -it : -i(--interactive) 옵션과 -t(--tty) 옵션의 조합으로,
# 표준 입출력을 할 수 있도록 컨테이너에 pseudo-terminal을 할당함
docker container create -it --name=mytest centos

# 실행 중인 컨테이너 목록 확인
# -a(--all) : Up 상태가 아닌 컨테이너도 출력
docker container ps -a

# 컨테이너 시작
# -a(--attach) : 컨테이너 내 PID 1번 프로세스에 연결
# bash 연결 시 exit를 실행하면 컨테이너가 종료되므로 Ctrl+PQ로 detach
docker container start -ai mytest

# detach 된 컨테이너에 attach (STDIN/STDOUT/STDERR 사용)
docker container attach mytest

# 실행 중인 컨테이너 종료
docker container stop mytest

# 컨테이너를 시작하고 COMMAND(PID 1번 프로세스) 실행
docker container run -it --name=mytest centos
docker container run -it --name=mytest centos /bin/date  # 임의의 COMMAND 실행

# -d(--detach) : COMMAND를 백그라운드 모드로 실행
docker container run -d --name=mytest centos /bin/ping localhost

# shell의 환경 정보를 옵션으로 정의 가능
# -w(--workdir) : 작업 디렉토리 설정
# -e(--env) : 환경 변수 설정
# --env-file=파일명 : 파일을 읽어서 환경 변수 설정
docker container run -it --name=mytest --workdir="/tmpdir" --env "MYNAME=bigboss" centos

# 컨테이너 내부의 프로세스가 종료되었을 때 재시작 옵션에 따라 재구동 동작이 달라짐
# --restart=옵션
# : no (재구동하지 않음, default)
# : on-failure (종료 상태가 0이 아니면 재구동)
# : on-failure:N (종료 상태가 0이 아닌 경우 N회 재구동)
# : always (항상 재구동)
docker container run -it --name=mytest --restart=always centos

# 구동 중인 컨테이너에서 새 프로세스 실행
docker container exec -it mytest /bin/bash

# 컨테이너 내 PID 1번 프로세스의 STDOUT/STDERR 출력
# -ft : -f(--follow) 옵션과 -t(--timestamp) 옵션의 조합
docker container logs -ft mytest

# 컨테이너 가동 상태와 사용 중인 자원 확인
docker container stats

# 컨테이너 상세 정보 조회
docker container inspect mytest

# 컨테이너에서 실행되고 있는 프로세스 확인
# 이 때 PID와 PPID는 컨테이너 내부 격리 환경이 아닌 호스트의 프로세스 ID가 출력됨
docker container top mytest

# 컨테이너 일시정지
docker container pause mytest
docker container unpause mytest

# 컨테이너 삭제
# -f(--force) : 실행 중인 컨테이너를 강제 종료 후 삭제함
docker container rm -f mytest

# 종료 상태의 컨테이너를 일괄적으로 삭제
# -f(--force) : 확인 메시지 출력 없이 삭제
docker container prune

# 컨테이너 이름 변경
docker container rename mytest yourtest

# 컨테이너와 호스트 간 파일 복사
docker container cp testfile mytest:/containerfile  # 호스트->컨테이너
docker container cp mytest:/containerfile containerfile  # 컨테이너->호스트

# 컨테이너 내에서 변경된 파일 정보 확인
# C (변경), A (추가), D (삭제)
docker container diff mytest

도커 볼륨

컨테이너 내에서 생성/변경된 모든 파일은 Container Layer (Upper Layer)에 Copy-on-Write 방식으로 저장되며, 컨테이너가 삭제될 때 함께 삭제됩니다. 따라서 데이터의 영속성을 유지하기 위하여 볼륨을 활용할 수 있습니다.

# bind mount
# -v : 호스트 경로와 컨테이너 마운트 경로를 연결
docker container run -it -v /tmp/hostdir:/container_dir \
-v /tmp/readonly:/read_dir:ro centos

# 볼륨 생성
docker volume create myvol

# 볼륨 목록 조회
docker volume ls

# 볼륨 상세 정보 조회
docker volume inspect myvol

# 볼륨 사용하기
docker container run -it --name=mytest -v myvol:/container centos

# 다른 컨테이너과 동일한 볼륨 사용하기
docker container run -it --volumes-from mytest --name=newtest centos

# tmpfs (호스트의 메모리에 마운트)
docker container run -it --tmpfs /updir centos

도커 네트워크

도커는 컨테이너에 Private IP를 순차적으로 할당하며, 이 IP는 컨테이너가 재시작될 때마다 변경될 수 있습니다. (172.17.0.0/16)
이 Private IP는 도커가 설치된 호스트 안에서만 사용할 수 있기 때문에 컨테이너를 서비스 용도로 사용하려면 외부 네트워크와 연결하여야 합니다. 이 때 내부적으로 NAPT (Network Address Port Translation)라는 기술이 사용됩니다.

# Bridged Network
docker container run -d -p 8080:80 nginx

# Host Network (호스트의 네트워크 환경을 그대로 사용)
docker container run -it --net host centos

# None Network (네트워크 사용하지 않음)
docker container run -it --net none centos

# 동일 호스트 내 컨테이너 간 통신
docker run -itd --name db00 centos
docker run -itd --name web00 --link db00 centos

마무리

도커 컨테이너에 대해 정리하다보니 내용은 별로 없는데 작성 시간이 꽤 많이 걸리네요. 이번 글은 도커 컨테이너의 사용법 위주로 대충 마무리 하고 도커 이미지와 컴포즈에 대해서는 따로 정리하도록 하겠습니다. 제 기억을 보조하기 위해 작성하였기 때문에 상당히 불친절한 글이지만 누군가에게 참고가 되면 좋겠습니다.

1 Reply to “Docker Container”

Leave a Reply

Your email address will not be published. Required fields are marked *