[Docker 이해하기] 4. Docker 명령어 실습

Titu·2021년 7월 21일
1

Docker

목록 보기
4/6

이 장에서는 Docker 명령의 기본적인 사용 방법과 주요 옵션을 살펴보기로 한다

4.1 Docker 이미지 조작

Docker Hub

  • Docker Hub는 Docker의 공식 레포지토리다.
    - 공식 Docker 이미지를 다운받을 수 있고, 사용자가 작성한 독자적인 Docker 이미지도 업로드/다운로드할 수 있다.

이미지 다운로드

  • docker image pull [옵션] 이미지명[:태그명]
    • 태그명을 생략하면 최신판(latest)를 취득한다.
    • -a 옵션을 지정하면 모든 태그를 취득할 수 있다.
# CentOS의 버전 7(태그명:7)을 다운로드
$ docker image pull centos:7

# CentOS의 모든 태그 이미지 취득
$ docker image pull -a centos

# Tensorflow 이미지 취득
$ docker image pull tensorflow/tensorflow

이미지 목록 표시

  • docker image ls [옵션] [레포지토리명]
    • -all, -a 옵션을 지정하면 모든 이미지를 표시할 수 있다.
    • --digest 옵션을 지정하면 다이제스트를 표시할 수 있다.
      • digest는 Docker 레지스트리에 업로드한 이미지를 식별하기 위해 부여된 고유번호
    • --no-trunc 옵션을 지정하면 결과를 모두 표시한다.
    • --quiet, -q를 지정하면 Docker 이미지 ID만 표시한다.
# 이미지 목록 표시
$ docker image ls

이미지 상세 정보 확인

  • docker image inspect
    • --format 옵션을 지정하면 특정 정보만을 표시할 수 있다.
# 이미지 상세 정보 표시
$ docker image inspect centos:7

# OS 정보 취득
$ docker image inspect --format="{{.Os}}" centos:7

# image 정보 취득
$ docker image inspect --format="{{.ContainerConfig.Image}}" centos:7

이미지 태그 설정

  • docker image tag <Docker Hub 사용자명>/이미지명:[태그명]
    • 이미지에 표식이 되는 태그를 붙인다.
    • 이미지 태그에는 식별하기 쉬운 버전명을 붙이는 것이 일반적이다.
    • Docker Hub에 작성한 이미지를 등록하려면 이미지에 사용자명을 붙여야 한다.
# nginx라는 이름의 이미지에서 대해 사용자명이 titu고, 컨테이너명이 webserver이며, 태그에 버전 정보가 1.0인 태그를 붙일때
$ docker image tag nginx titu/webserver:1.0

이미지 검색

  • docker search [옵션] <검색 키워드>
    • --no-trunc 옵션을 지정하면 결과를 모두 표시한다.
    • --limit 옵션을 지정하면 n건의 검색 결과를 표시한다.
    • --filter=stars=n 옵션을 통해 즐겨찾기의 수(n 이상)를 지정한다.
  • 검색 결과에서 공식 Docker 이미지는 OFFICIAL이 OK로 표시되어 있다.
  • 검색 결과에서 Dockerfile을 바탕으로 자동 생성된 이미지는 AUTOMATED가 OK로 표시되어 있다
# Docker Hub에 공개되어 있는 이미지 검색
$ docker search nginx

# 인기 있는 이미지 검색
$ docker search --filter=stars=100 nginx

이미지 삭제

  • docker image rm [옵션] 이미지명 [이미지명]
    • --force 옵션을 지정하면 이미지를 강제로 삭제한다.
    • --no-prune 옵션을 지정하면 중간 이미지를 삭제하지 않는다.
    • 이미지명에는 REPOSITORY 또는 IMAGE ID를 지정한다.
# 이미지 삭제
$ docker image rm nginx
  • docker image prune [옵션]
    • 사용하지 않은 Docker 이미지를 삭제하는 명령어다. 사용하지 않은 Docker 이미지는 디스크 용량을 쓸데없이 차지하기 때문에 정기적으로 삭제하는 것이 좋다.
    • --force 옵션을 지정하면 이미지를 강제로 삭제한다.
    • --all, -a 옵션을 지정하면 사용하지 않은 이미지를 모두 삭제한다.
# 사용하지 않은 Docker 이미지 삭제
$ docker image prune

Docker Hub에 로그인

Docker 레포지토리에 업로드를 하려면 도커 로그인을 해야 한다.

  • docker login [옵션] [서버]
    • --password, -p 옵션을 지정하면 비밀번호를 설정할 수 있다.
    • --username, -u 옵션을 지정하면 사용자명을 설정할 수 있다.
    • 옵션을 지정하지 않으면 사용자명과 비밀번호를 물어보므로, Docker Hub에 등록한 계정을 지정하면 된다.
    • Docker Hub가 아닌 Docker 레포지토리에 접속하기 위해서는 서버명을 지정해야 한다.
# Docker Hub에 로그인
$ docker login

이미지 업로드

  • docker image push <Docker Hub 사용자명>/이미지명[:태그명]
# 이미지 업로드
$ docker image push titu/webserver:1.0

Docker Hub에서 로그아웃

  • docker logout [서버명]
    • Docker Hub가 아닌 Docker 레포지토리에 접속하기 위해서는 서버명을 지정해야 한다.
# 이미지 삭제
$ docker image rm nginx

4.2 Docker 컨테이너 생성/시작/정지

이미지가 만들어졌으면 컨테이너를 생성할 수 있다.

Docker 컨테이너의 라이프 사이클

  1. 컨테이너 생성 (docker container create)
    • 이미지로부터 컨테이너 생성. Docker 이미지를 바탕으로 스냅샷을 작성한다. (스냅샷이란 스토리지 안에 존재하는 파일과 디렉토리를 특정 타이밍에 추출한 것을 말한다.)
  2. 컨테이너 생성 및 시작 (docker container run)
    • 이미지로부터 컨테이너를 생성하고, 컨테이너 상에서 임의의 프로세스를 시작한다.
      - Nginx나 Redis와 같은 서버 기능을 프로세스로 작동시킨다.
  3. 컨테이너 시작 (docker container start)
    • 정지중인 컨테이너를 시작할 때 사용한다. 컨테이너에 할당된 컨테이너 식별자를 지정하여 컨테이너를 시작한다.
  4. 컨테이너 정지 (docker container stop)
    • 실행 중인 컨테이너를 정지시킬 때 사용한다. 컨테이너에 할당된 컨테이너 식별자를 지정하여 컨테이너를 정지한다.
  5. 컨테이너 삭제 (docker container rm)
    • 컨테이너를 삭제할 때 사용한다.
      • 컨테이너를 삭제하기 전에는 실행 중인 컨테이너를 정지시켜야 한다.

컨테이너 생성 및 시작

  • docker container run [옵션] 이미지명[:태그명]
    • --attach, -a 옵션을 지정하면 표준 입력(STDIN), 표준 출력(STDOUT), 표준 오류 출력(STDERR)에 어태치한다.
    • --cidfile 옵션을 지정하면 컨테이너 ID를 파일로 출력한다.
    • --detach, -d 옵션을 지정하면 컨테이너를 생성하고 백그라운드에서 실행한다.
    • --interactive, -i 옵션을 지정하면 컨테이너의 표준 입출력을 연다.
    • --tty, -t 옵션을 지정하면 단말기 디바이스를 사용한다.
    • -i 옵션과 -t 옵션을 합친 -it 옵션을 지정하여 콘솔에 결과를 출력한다
    • --name 옵션을 지정하여 컨테이너명을 설정한다.
# centos라는 이름의 이미지를 바탕으로 test1이라는 이름의 컨테이너를 실행하고, 컨테이너 안에서 /bin/cal 명령을 실행
$ docker container run -it --name "test1" centos /bin/cal

# centos라는 이름의 이미지를 바탕으로 test1이라는 이름의 컨테이너를 실행하고, 컨테이너 안에서 /bin/bash 명령을 통해 컨테이너 안에서 쉘을 실행
$ docker container run -it --name "test2" centos /bin/bash
# 쉘 종료
$ exit

컨테이너의 백그라운드 실행

  • docker container run [실행 옵션] 이미지명[:태그명]
    • --detach, -d 옵션을 지정하면 백그라운드에서 실행한다.
    • --user, -u 옵션을 지정하면 사용자명을 설정한다.
    • --restart=[no | on-failure | on-failure:횟수n | always | unless-stopped] 옵션을 지정하여 명령의 실행 결과에 따라 재시작을 한다.
      • no: 재시작하지 않는다
      • on-failure: 종료 status가 0이 아닐 때 재시작한다
      • on-failure:횟수n: 종료 status가 0이 아닐 때 n번 재시작한다
      • always: 항상 재시작한다
      • unless-stopped: 최근 컨테이너가 정지 상태가 아니라면 항상 재시작한다.
    • --rm 옵션을 지정하여 명령 실행 완료 후에 컨테이너를 자동으로 삭제한다.
# centos라는 이름의 이미지를 바탕으로 하여 컨테이너를 생성하고, localhost에 대해 /bin/ping 명령을 실행
$ docker container run -d centos /bin/ping localhost
  • docker container logs [옵션] [컨테이너 ID]
    • 컨테이너가 백그라운드에서 실행되고 있는지 아닌지를 보기 위해 컨테이너의 로그를 확인한다.
    • -t 옵션은 타임스탬프를 표시하는 것
# 위 명령어를 실행했을때 표시된 컨테이너 ID를 통해 컨테이너 로그 확인
$ docker container logs -t (컨테이너 ID)

# 컨테이너를 항상 재시작 (명령 안에서 /bin/bash를 exit으로 종료해도 자동으로 컨테이너를 재시작한다)
$ docker container run -it --restart=always centos /bin/bash
[root@623e5f58f5be /]# exit
exit
$ docker container ps
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS              PORTS               NAMES
623e5f58f5be        centos              "/bin/bash"             14 seconds ago      Up 9 seconds                            romantic_boyd

컨테이너의 네트워크 설정

컨테이너를 시작할 때 네트워크에 관한 설정을 할 수 있다.

  • docker container run [네트워크 옵션] 이미지명[:태그명]
    • --add-host=[호스트명:IP 주소] 옵션을 지정하여 컨테이너의 /etc/hosts에 호스트명과 IP 주소를 정의한다.
    • --dns=[IP 주소] 옵션을 지정하여 컨테이너용 DNS 서버의 IP 주소를 지정한다.
    • --expose 옵션을 통해 지정한 범위의 포트번호를 할당한다.
    • --mac-address=[MAC 주소] 옵션을 지정하여 컨테이너용 MAC 주소를 지정한다.
    • --net=[bridge | none | container:<name | id> | host | NETWORK] 옵션을 지정하여 컨테이너의 네트워크를 지정한다. (기본적으로는 호스트 OS와 bridge 연결을 한다)
      • bridge: 브리지 연결을 사용한다.
      • none: 네트워크에 연결하지 않는다.
      • container:<name | id>: 다른 컨테이너의 네트워크를 사용한다.
      • host: 컨테이너가 호스트 OS의 네트워크를 사용한다.
      • NETWORK: 사용자 정의 네트워크를 사용한다.
        • 사용자 정의 네트워크는 docker network create 명령으로 작성한다.
    • --hostname, -h 옵션을 지정하여 컨테이너 자신의 호스트명을 지정한다
    • --publish, -p[호스트의 포트 번호]:[컨테이너의 포트번호] 옵션을 지정하여 호스트와 컨테이너의 포트를 매핑한다.
    • --publish-all, -P 옵션을 지정하여 호스트의 임의의 포트를 컨테이너에 할당한다.
# 컨테이너의 포트 번호와 호스트 OS의 포트 번호 매핑
  # nginx라는 이름의 이미지를 바탕으로 컨테이너를 생성하고, 백그라운드에서 실행한다. 
  # 이때 호스트의 포트 번호 8080과 컨테이너의 포트 번호 80을 매핑시킨다. 
  # 이 명령을 실행하고 호스트의 8080 포트에 액세스하면 컨테이너에서 작동하고 있는 Nginx(80번 포트)의 서비스에 액세스할 수 있다.
$ docker container run -d -p 8080:80 nginx

# 컨테이너의 DNS 서버 지정
$ docker container run -d --dns 192.168.1.1 nginx

# 컨테이너의 MAC 주소 지정
$ docker container run -d --mac-address="92:d0:c6:0a:29:33" centos
9211133409f72e16d3c32b34fc913d3fed54183ac0dc21baf38df62d2709fc40
# 컨테이너 안의 네트워크 구성 확인
$ docker container inspect --format="{{.Config.MacAddress}}" 9211
92:d0:c6:0a:29:33

# 컨테이너의 안의 /etc/hosts에 호스트명과 IP 주소 정의
  # 명령을 실행하고 컨테이너 안의 /etc/hosts를 확인하면 호스트명이 www.test.com과 node1.test.com(192.168.1.1)로 정의되어 있는 것을 알 수 있다.
$ docker container run -it --hostname www.test.com --add-host node1.test.com:192.168.1.1 centos
[root@www /]# cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.1     node1.test.com
172.18.0.6      www.test.com www

# 외부 브리지 네트워크 드라이버를 사용하여 'webap-net'이라는 이름의 네트워크를 작성하고, 작성한 네트워크 상에서 컨테이너를 실행
$ docker network create -d bridge webap-net
$ docker container run --net=webap-net -it centos

자원을 지정하여 컨테이너 생성 및 실행

CPU나 메모리와 같은 자원을 지정하여 컨테이너를 생성 및 실행할 수 있다.

  • docker container run [자원 옵션] 이미지명[:태그명]
    • --cpu-shares, -c 옵션을 지정하여 CPU의 사용 비율을 설정한다. (기본값 1024)
    • --memory, -m 옵션을 지정하여 사용할 메모리를 제한하여 실행한다.
    • --volume=[호스트의 디렉토리]:[컨테이너의 디렉토리], -v 옵션을 지정하여 호스트와 컨테이너의 디렉토리를 공유한다.
# CPU 시간의 상대 비율과 메모리 사용량을 지정
$ docker container run --cpu-shares=512 --memory=lg centos

# 호스트 OS와 컨테이너 안의 디렉토리를 공유하고 싶을 때
  # 호스트 OS의 /Users/asa/webap 폴더를 컨테이너의 /usr/share/nginx/html 디렉토리와 공유함
$ docker container run -v /Users/asa/webap:/usr/share/nginx/html nginx

컨테이너를 생성 및 시작하는 환경을 지정

컨테이너의 환경변수나 컨테이너 안의 작업 디렉토리 등을 지정하여 컨테이너를 생성/실행할 수 있다.

  • docker container run [환경설정 옵션] 이미지명[:태그명]
    • --env=[환경변수], -e 옵션을 지정하여 환경변수를 실행한다.
    • --env-file=[파일명] 옵션을 지정하여 환경변수를 파일로부터 설정한다.
    • --read-only=[true | false] 옵션을 지정하여 컨테이너의 파일 시스템을 읽기 전용으로 만든다.
    • --workdir=[패스], -w 옵션을 지정하여 컨테이너의 작업 디렉토리를 지정한다.
    • -u, --user=[사용자명] 옵션을 지정하여 사용자명 또는 UID를 설정한다.
# 환경변수 설정
$ docker container run -it -e foo=bar centos /bin/bash
[root@0e838eb3ade6 /]# set

# 작업 디렉토리 설정
  # 컨테이너의 /tensorflow를 작업 디렉토리로 설정함
$ docker container run -it -w=/tensorflow centos /bin/bash
[root@222a1fe7d233 tensorflow]# pwd
/tensorflow

가동 컨테이너 목록 표시

Docker 상에서 작동하는 컨테이너의 가동 상태를 확인할 때는 docker container ls 명령을 사용한다.

  • docker container ls [옵션]
    • --all, -a 옵션을 지정하여 모든 컨테이너를 표시한다.
    • --filter, -f 옵션을 지정하여 표시할 컨테이너를 필터링한다.
    • --format 옵션을 지정하여 표시 포맷을 설정한다.
      • .ID : 컨테이너 ID
      • .Image: 이미지 ID
      • .Command: 실행 명령
      • .CreatedAt: 컨테이너가 작성된 시간
      • .RunningFor: 컨테이너의 가동 시간
      • .Ports: 공개 포트
      • .Status: 컨테이너 상태
      • .Size: 컨테이너 디스크 크기
      • .Names: 컨테이너명
      • .Mounts: 볼륨 마운트
      • .Networks: 네트워크명
    • --last, -n 옵션을 지정하여 마지막으로 실행된 n건의 컨테이너만 표시한다.
    • --latest, -l 옵션을 지정하여 마지막으로 실행된 컨테이너만 표시한다.
    • --no-trunc 옵션을 지정하여 정보를 생략하지 않고 표시한다.
    • --quiet, -q 옵션을 지정하여 컨테이너 ID만 표시한다.
    • --size, -s 옵션을 지정하여 파일 크기를 표시한다.
# 컨테이너 목록 표시
$ docker container ls

# 컨테이너 목록의 필터링
  # 이름에 test1이 포함된 컨테이너를 표시
$ docker container ls -a -f name=test1

# 컨테이너 목록의 필터링
  # status에 종료 코드가 0인 컨테이너를 표시
$ docker container ls -a -f exited=0

# 컨테이너 목록의 출력 형식 지정
  # 컨테이너 ID와 Status 출력
$ docker container ls -a --format "{{.Names}}:{{.Status}}"

# 컨테이너 목록을 표 형식으로 출력
$ docker container ls -a --format "table {{.Names}}\t{{.Status}}\t{{.Mounts}}"

컨테이너 가동 확인

도커 상에서 작동하는 컨테이너 가동 상태를 확인할 때

  • docker container stats [컨테이너 식별자]

컨테이너에서 실행 중인 프로세스를 확인할 때

  • docker container top [컨테이너 식별자]
# 컨테이너 가동 확인
$ docker container stats webserver
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
5beeb2af6e2b        webserver           0.00%               1.961MiB / 992.1MiB   0.20%               828B / 0B           0B / 8.19kB         3

# 컨테이너에서 실행 중인 프로세스 확인
$ docker container top webserver
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                1534                1520                0                   08:14               ?                   00:00:00            nginx: master process nginx -g daemon off;
systemd+            1593                1534                0                   08:14               ?                   00:00:00            nginx: worker process

컨테이너 시작

  • docker container start [옵션] [컨테이너 식별자]
    • --attach, -a 옵션을 지정하면 표준 입력(STDIN), 표준 출력(STDOUT), 표준 오류 출력(STDERR)에 어태치한다.
    • --interactive, -i 옵션을 지정하면 컨테이너의 표준 입출력을 연다.
# Docker container 시작
$ docker container start 

컨테이너 정지

  • docker container stop [옵션] [컨테이너 식별자]
    • --time, -t 옵션을 통해 컨테이너의 정지 시간을 정지한다. (기본값 10초)
# 컨테이너 Id가 5be~~인 컨테이너를 2초 후에 정지
$ docker container stop -t 2 5be

컨테이너 재시작

  • docker container restart [옵션] [컨테이너 식별자]
    • --time, -t 옵션을 통해 컨테이너의 재시작 시간을 정지한다. (기본값 10초)
# 컨테이너명이 webserver인 컨테이너를 2초 후에 재시작
$ docker container restart -t 2 webserver

컨테이너 삭제

  • docker container rm [옵션] [컨테이너 식별자]
    • --force, -f 옵션을 지정하면 실행 중인 컨테이너를 강제로 삭제한다.
    • --volumes, -v 옵션을 지정하면 할당한 볼륨을 삭제한다.
# webserver라는 이름의 컨테이너를 삭제
$ docker container rm webserver
  • docker container prune
    • 정지 중인 모든 컨테이너를 삭제
$ docker container ls -a

# 정지 중인 컨테이너 삭제
$ docker container prune

$ docker container ls -a

컨테이너 중단/재개

  • docker container pause [컨테이너 식별자]
    • 실행중인 컨테이너에서 작동 중인 프로세스를 모두 중단시킬 때
  • docker container repause [컨테이너 식별자]
    • 컨테이너를 재개할때
# 컨테이너 중단 
$ docker container pause webserver

$ docker container ls

# 중단 컨테이너의 재개
$ docker container unpause webserver

4.3 Docker 컨테이너 네트워크

Docker 컨테이너끼리 통신을 할 때는 Docker 네트워크를 통해 수행한다.

네트워크 목록 표시

Docker 네트워크 목록을 확인하기 위한 명령이다. Docker는 기본값으로 bridge, host, none, 이 세 개의 네트워크를 만든다.

  • docker network ls [옵션]
    • -f, --filter=[] 옵션을 지정하여 출력을 필터링한다.
      • driver: 드라이버 지정
      • id: 네트워크 ID
      • label: 네트워크에 설정된 라벨
      • name: 네트워크명
      • scope: 네트워크 스코프(swarm/global/local)
      • type: 네트워크의 타입
    • --no-trunc 옵션을 지정하여 상세 정보를 출력한다.
    • --q, --quiet 옵션을 지정하여 네트워크 ID만 표시한다.
# 네트워크 목록 표시
$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
d06e9acfb760        bridge              bridge              local
a97b671cfa14        host                host                local
6cecdcf0fab7        none                null                local

# 브리지 네트워크의 네트워크 ID만을 목록으로 표시하고 싶을때
$ docker network ls -q --filter driver=bridge
d06e9acfb760

# 네트워크를 명시적으로 지정하지 않고 Docker 컨테이너를 시작하면 기본값인 'bridge' 네트워크로 Docker 컨테이너를 시작한다.
$ docker container run -itd --name=sample ubuntu:latest

$ docker inspect --format='{{range .NetworkSettings.Networks}}{{.NetworkID}}{{end}}' sample
d06e9acfb76094078126e49bc3980ecf6a5ab4b3d57663e1a92812c842b6f343

네트워크 작성

새로운 네트워크를 작성하기 위한 명령이다.

  • docker network create [옵션] 네트워크
    • --driver, -d 옵션을 지정하여 네트워크 드라이버(브리지 또는 오버레이)를 설정한다. (기본값은 bridge)
    • --ip-range 옵션을 지정하여 컨테이너에 할당하는 IP 주소의 범위를 설정한다.
    • --subnet 옵션을 지정하여 서브넷을 CIDR 형식으로 설정한다.
    • --ipv6 옵션을 지정하여 IPv6 네트워크를 유효화할지 말지 설정한다.
    • -label 옵션을 지정하여 네트워크에 설정하는 라벨을 설정한다.
# 'web-network'라는 이름의 브리지 네트워크 작성
$ docker network create --driver=bridge web-network
413bddc36b6cb8ac1e72b4453e11ced7a8a4daa3cb7f8f7c9f9f8dda31d2ab7b

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
d06e9acfb760        bridge              bridge              local
a97b671cfa14        host                host                local
6cecdcf0fab7        none                null                local
413bddc36b6c        web-network         bridge              local

네트워크 연결

Docker 컨테이너를 Docker 네트워크에 연결하고, 연결을 해제하기 위한 명령이다.

  • docker network connect [옵션] 네트워크 컨테이너
    • --ip 옵션을 지정하여 IPv4 주소를 설정한다.
    • --ip6 옵션을 지정하여 IPv6 주소를 설정한다.
    • --alias 옵션을 지정하여 별명을 설정한다.
    • --link 옵션을 지정하여 다른 컨테이너에 대한 링크를 설정한다.
# 'sample'라는 이름의 컨테이너를 'web-network'라는 이름의 네트워크와 연결
$ docker network connect web-network sample

# 컨테이너에 속한 네트워크를 확인한다
$ docker container inspect sample

# 네트워크를 지정한 컨테이너 시작
  # 베이스 이미지가 'nginx'이고 'webap'이라는 이름의 Docker 컨테이너를 'web-network' 네트워크에 만든다. 
$ docker container run -itd --name=webap --net=web-network nginx

# 컨테이너에 속한 네트워크를 확인한다
$ docker container inspect webap

# 네트워크에 대한 연결 해제
$ docker network disconnect web-network webap

# 컨테이너에 속한 네트워크를 확인한다
$ docker container inspect webap

네트워크 상세 정보 확인

이름, ID, 드라이버, 서브넷, 게이트웨이, 컨테이너 등과 같은 네트워크 상세 정보를 확인하는 명령이다.

  • docker network inspect [옵션] 네트워크
# 네트워크 상세 정보 표시
$ docker network inspect web-network

네트워크 삭제

네트워크를 삭제하려면 그 전에 연결 중인 모든 컨테이너와의 연결을 해제해야 한다.

  • docker network rm [옵션] 네트워크
# 네트워크 삭제
$ docker network rm web-network

4.4 가동 중인 Docker 컨테이너 조작

가동 컨테이너 연결

가동 중인 컨테이너에 연결하는 명령이다.

  • docker container attach [컨테이너명]
    • 연결한 컨테이너를 종료하려면 CTRL+C를, 종료하지 않고 분리하려면 CTRL+P 또는 CTRL+Q를 입력한다.
# /bin/bash가 실행되고 있는 sample이라는 이름의 컨테이너에 연결
$ docker container attach sample
[root@5f193522a67e /]# 

가동 컨테이너 프로세스 실행

가동 중인 컨테이너에 새로운 프로세스를 실행하는 명령이다. 웹 서버와 같이 백그라운드에서 실행되고 있는 컨테이너에 액세스하고 싶을 때, docker container attach 명령으로 연결해도 쉘이 작동하지 않는 경우는 명령을 접수할 수 없다. 이 때, docker container exec 명령을 사용하여 임의의 명령을 실행한다. docker container exec 명령은 실행 중인 컨테이너에서만 실행할 수 있다.

  • docker container exec [옵션] <컨테이너 식별자> <실행할 명령>
    • --detach, -d 옵션을 지정하여 명령을 백그라운드에서 실행한다.
    • --interactive, -i 옵션을 지정하여 컨테이너의 표준 입력을 연다.
    • --tty, -t 옵션을 지정하여 단말 디바이스를 사용한다.
    • --user, -u 옵션을 지정하여 사용자명을 설정한다.
$ docker container run -d --name=webserver -p 8080:80 nginx

$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
53a9687ef00e        nginx               "/docker-entrypoint.…"   42 seconds ago      Up 42 seconds       0.0.0.0:8080->80/tcp   webserver

# 컨테이너에서 bash 실행
$ docker container exec -it webserver /bin/bash
root@53a9687ef00e:/# 

# 컨테이너에서 echo 실행
$ docker container exec -it webserver /bin/echo "Hello world"
Hello world

가동 컨테이너의 프로세스 확인

  • docker container top <컨테이너 식별자>
    • 실행 중인 프로세스의 PID, USER, 실행 중인 명령이 표시된다.
      • PID는 리눅스의 프로세스 식별자로, 프로세스를 고유하게 식별하기 위한 ID이다.
# 프로세스 확인
$ docker container top

가동 컨테이너의 포트 전송 확인

  • docker container port <컨테이너 식별자>
    • 가동 중인 컨테이너에서 실행되고 있는 프로세스가 전송되고 있는 포트를 확인
# 컨테이너의 포트 전송
  # 'webserver' 컨테이너의 80번 포트가 호스트의 8080번 포트로 전송되는 것을 확인
$ docker container port webserver
80/tcp -> 0.0.0.0:8080

컨테이너의 이름 변경

  • docker container rename [컨테이너 이름] [새이름]
    • 가동 중인 컨테이너에서 실행되고 있는 프로세스가 전송되고 있는 포트를 확인
$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
53a9687ef00e        nginx               "/docker-entrypoint.…"   16 minutes ago      Up 16 minutes       0.0.0.0:8080->80/tcp   webserver

# 컨테이너의 이름 변경
$ docker container rename webserver new-webserver

$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
53a9687ef00e        nginx               "/docker-entrypoint.…"   16 minutes ago      Up 16 minutes       0.0.0.0:8080->80/tcp   new-webserver

컨테이너 안의 파일을 복사

  • docker container cp <컨테이너 식별자>:<컨테이너 안의 파일 경로> <호스트의 디렉토리 경로>
    • 컨테이너 안의 파일을 호스트에 복사할 때
# webserver라는 이름의 컨테이너 안에 있는 /etc/nginx/nginx.conf 파일을 호스트의 /tmp/etc에 복사할 때
$ docker container cp webserver:/etc/nginx/nginx.conf /tmp/nginx.conf
$ ls -la /tmp/nginx.cong
  • docker container cp <호스트의 파일> <컨테이너 식별자>:<컨테이너 안의 파일 경로>
    • 호스트 안의 파일을 컨테이너에 복사할 때
# 호스트의 현재 디렉토리에 있는 local.txt라는 이름의 파일을 webserver라는 이름의 컨테이너 안의 /tmp/local.txt로 복사할 때
$ docker container cp ./local.txt webserver:/tmp/local.txt

컨테이너 조작의 차분(달라진 점) 확인

컨테이너 안에서 어떤 조작을 한 후, 컨테이너가 이미지로부터 생성되었을 때와 달라진 점(차분)을 확인하기 위한 명령이다.

  • docker container diff <컨테이너 식별자>
    • 변경의 구분
      • A: 파일 추가
      • B: 파일 삭제
      • C: 파일 수정
$ docker container run -itd --name=sample ubuntu

# 컨테이너에서 신규 사용자 작성
$ docker container exec -it sample /bin/bash
root@5d55fed79b08:/# useradd newuser
root@5d55fed79b08:/# exit
exit

# 컨테이너의 변경 부분 확인
  # 명령의 결과를 통해 /etc/passwd나 /etc/group 등에 변경이 일어났다는 것을 알 수 있다.
$ docker container diff sample
C /var
C /var/log
C /var/log/faillog
C /var/log/lastlog
C /etc
C /etc/group
A /etc/group-
C /etc/subgid
C /etc/subuid
C /etc/passwd
A /etc/subuid-
C /etc/gshadow
A /etc/passwd-
C /etc/shadow
A /etc/gshadow-
A /etc/shadow-
A /etc/subgid-
C /root
A /root/.bash_history

4.5 Docker 이미지 생성

Docker 컨테이너는 Docker 이미지를 바탕으로 작성하지만, 반대로 Docker 컨테이너를 바탕으로 Docker 이미지를 작성할 수도 있다.

컨테이너로부터 이미지 작성

  • docker container commit [옵션] <컨테이너 식별자> [이미지명[:태그명]]
    • --author, -a 옵션을 지정하여 작성자를 지정한다.
    • --message, -m 옵션을 지정하여 메시지를 지정한다.
    • --change, -c 옵션을 지정하여 커밋 시 Dockerfile 명령을 지정한다.
    • --pause, -p 옵션을 지정하여 컨테이너를 일시 정지하고 커밋한다.
# 컨테이너로부터 이미지 작성
$ docker container commit -a "Titu" sample tituvely/webserver:1.0
sha256:f5b5ce23d6472c67e79145d38d7662de9be2936470c88444abc8d5c62aae90c5

$ docker image ls
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
tituvely/webserver   1.0                 f5b5ce23d647        19 seconds ago      73.1MB

# 이미지 상세 정보 확인
  # 설정한 작성자 정보를 확인할 수 있다.
$ docker image inspect tituvely/webserver:1.0
~ 생략
        "DockerVersion": "17.12.0-ce",
        "Author": "Titu",
~ 생략

컨테이너를 tar 파일로 출력

  • docker container export <컨테이너 식별자>
    • Docker에서는 가동 중인 컨테이너의 디렉토리/파일들을 모아서 tar 파일을 만들 수 있다. 이 tar 파일을 바탕으로 하여 다른 서버에서 컨테이너를 가동시킬 수 있다.
$ docker container export sample > latest.tar

$ ls -la
total 73716
drwx------  4 root root     4096 Jul 21 09:09 .
drwxr-xr-x 22 root root     4096 Feb 24  2018 ..
-rw-r--r--  1 root root     3122 Feb 24  2018 .bashrc
drwx------  2 root root     4096 Jul 21 08:56 .cache
-rw-r--r--  1 root root        0 Feb 24  2018 .hushlogin
-rw-r--r--  1 root root 75457024 Jul 21 09:09 latest.tar
-rw-r--r--  1 root root      148 Aug 17  2015 .profile
drwxr-xr-x  2 root root     4096 Feb 24  2018 .ssh

# 생성된 tar 파일의 상세 정보 확인
$ tar -tf latest.tar

$ tar tf latest.tar |more

tar 파일부터 이미지 작성

  • docker image import <파일 또는 URL> | - [이미지명[:태그명]]
    • Linux OS 이미지의 디렉토리/파일로부터 Docker 이미지를 만들 수 있으며, 압축된 디렉토리나 파일도 취급할 수 있다.
      • 간혹, root 권한으로 실행하지 않으면 액세스 권한이 없는 파일이 포함되지 않는 경우가 발생한다.
# latest.tar로 모아놓은 디렉토리나 파일을 바탕으로 tituvely/webserver라는 이름의 태그명이 1.1인 이미지를 작성한다.
$ cat latest.tar | docker image import - tituvely/webserver:1.1
sha256:6f310930b06a9f9cd2d9993abacf9e2d30a8c8746b089d664bbd19a0538529ac

$ docker image ls
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
tituvely/webserver   1.1                 6f310930b06a        7 seconds ago       73.1MB
tituvely/webserver   1.0                 f5b5ce23d647        21 minutes ago      73.1MB

이미지 저장

Docker 이미지를 tar 파일로 저장할 수 있다.

  • docker image save [옵션] <저장 파일명> [이미지명]
    • -o 옵션을 지정하여 저장할 파일명을 설정한다.
# tensorflow/tensorflow라는 이름의 이미지를 export.tar에 저장한다
$ docker image save -o export.tar tensorflow/tensorflow

$ ls -l
total 1367524
-rw------- 1 root root 1324875776 Jul 21 09:34 export.tar

이미지 읽어 들이기

tar 이미지로부터 이미지를 읽어 들이는 명령이다.

  • docker image load [옵션]
    • -i 옵션을 지정하여 읽어 들일 파일명을 설정한다.
# export.tar라는 이름의 이미지를 읽어들인다
$ docker image load -i export.tar

불필요한 이미지/컨테이너를 일괄 삭제

사용하지 않는 이미지, 컨테이너, 볼륨, 네트워크를 일괄적으로 삭제하는 명령이다.

  • docker system prune [옵션]
    • --all, -a 옵션을 지정하여 사용하지 않는 리소스를 모두 삭제한다.
    • --force, -f 옵션을 지정하여 강제적으로 삭제한다.
# 불필요한 리소스 삭제
$ docker system prune -a

export/import와 save/load의 차이

export/import

  • 컨테이너를 export하면 컨테이너를 작동시키는 데 필요한 파일을 모두 압축 아카이브로 모을 수 있다. 그래서 이 tar 파일을 풀면 컨테이너의 루트 파일 시스템을 그대로 추출할 수 있다.
$ docker container run -itd --name="sample" nginx

$ docker container export sample > export.tar

$ tar xvf export.tar

$ ls
bin  boot  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  export.tar  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

save/load

  • 한편, 이미지를 save하면 이미지의 레이어 구조도 포함된 형태로 압축 아카이브에 모을 수 있다.
$ docker image pull nginx

$ docker image save -o save.tar nginx

$ tar xvf save.tar

$ ls
3c3a333cdf8c89b9396046da92a7bf6a19b43a504c27ed45ca4b7103c5fff4a2       7a2bb957c3e5ab2cbb17641fb45d84c4db95409b257f3d3a3344884e0267fe78  repositories
4cdc5dd7eaadff5080649e8d0014f2f8d36d4ddf2eff2fdf577dd13da85c5d2f.json  99822641346ab3f492352d3e866bee8d4f7a555fceb6f7dc216f7ec24fa6f19d  save.tar
60bf9b686621b4f7c2fe99054209c446b1c94522e61c2fbcd0025544e2b5b50d       f4cb2c3fcbf290613eb42a3882b2cb60155ceb72532114422c040021d93bbc80
6ad1e4ec9a1cdc46ae489465c50471ed690e526d212c3b9f944c5949823b8e82       manifest.json

=> 바탕이 되는 이미지는 똑같아도 docker container export 명령과 docker image save 명령은 내부적인 디렉토리와 파일 구조가 다르므로, docker container export 명령으로 작성한 것을 읽어 들일 때는 docker image import 명령을, docker image save 명령으로 생성한 것을 읽어 들일 때는 docker image load 명령을 사용해야 한다.

docker container export <-> docker image import
docker image save <-> docker image load


본문은 'Asa Shijo, <완벽한 IT 인프라 구축을 위한 Docker>, 정보문화사(2020)' 를 참고하여 정리한 글입니다.

[참고: 완벽한 IT 인프라 구축을 위한 Docker]

profile
This is titu

0개의 댓글