# Docker

Tags: docker

WARNING

Podman 의 네트워크 설정 및 compose 기능 미완성으로 인해 당분간 Docker를 사용 (2020년8월24일 기준)

# Installation on CentOS 8

Podman 을 삭제하지 않고 진행

# 안전을 위해 sudo 로 진행
$ sudo dnf makecache
$ sudo dnf install dnf-utils device-mapper-persistent-data lvm2 fuse-overlayfs wget
$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
$ sudo dnf makecache
# CentOS 8은 docker 설치 시 containerd.io 패키지와 podman 패키지 사이의 라이브러리 충돌문제가 있음
# /tmp 디렉토리에서 작업
$ cd /tmp
# containerd.io-1.2.13-3.2.el7.x86_64.rpm 이 현재(20.8.24 기준) 버전
$ wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.13-3.2.el7.x86_64.rpm
$ sudo dnf localinstall ./containerd.io-1.2.13-3.2.el7.x86_64.rpm # localinstall 은 deprecated 됨
$ sudo dnf install docker-ce docker-ce-cli
$ sudo systemctl status docker
$ sudo systemctl start docker
$ sudo systemctl enable docker
$ sudo systemctl status docker
# docker 커맨드를 sudo 없이 사용하기 위해 그룹 조정
$ sudo usermod -aG docker $(whoami)
$ sudo reboot
# test
$ docker version
$ docker run hello-world

# docker-compose install (release 다운로드 위치: https://github.com/docker/compose/releases) 버전 확인해서 해당 버전으로 변경 후 다운로드
# global install
# /tmp 에서 작업
$ curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o docker-compose
$ sudo mv docker-compose /usr/local/bin && sudo chmod +x /usr/local/bin/docker-compose

# per-user installation
$ sudo dnf install python3-pip
$ pip3.6 install docker-compose --user
$ docker-compose -version

# docker-compose 삭제
$ sudo rm /usr/local/bin/docker-compose
# docker-compose 삭제 (pip 로 설치한 경우)
$ pip3.6 uninstall docker-compose

# podman 삭제는 진행하지 않음
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# network 설정 (firewalld 관련)

CentOS 8 상황에서 firewalld 로 인하여 네트워크 rule 추가가 필요함

# open all IPs starts with "172" so that all the containers may communicate each other
$ firewall-cmd --permanent --zone=public --add-rich-rule='rule family=ipv4 source address=172.0.0.0/8 accept'
# make out container able to visit the network outside
$ firewall-cmd --permanent --zone=public --add-masquerade
# apply the change
$ firewall-cmd --reload
$ cat /etc/firewalld/zones/public.xml
1
2
3
4
5
6
7

# nodetest 관련

docker testing (opens new window) 에서 소스 확인

# docker-compose 와 nginx reverse proxy를 이용하여 container load balancing (round-robin)
# 테스트를 위한 port
$ sudo firewall-cmd --zone=public --add-port=4000/tcp --permanent
$ sudo firewall-cmd --zone=public --add-port=27017/tcp --permanent # just for test
$ sudo firewall-cmd --reload

# docker data volume
$ docker volume create --name mongodb_dev
$ docker volume ls

$ docker stop $(docker ps -aq)
$ docker rm $(docker ps -aq)
$ docker system prune -a

$ docker run -d -p 27017:27017 --rm --name mongodb -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=1234 -v mongodb_dev:/data/db mongo

# for test
$ docker run -it -p 3000:3000 --rm --name node -v ~/nodetest:/usr/src/nodetest shockz/nodetest:0.2 # tty output
$ docker run -d -p 3000:3000 --rm --name node -v ~/nodetest:/usr/src/nodetest shockz/nodetest:0.2 # background

# wait-for-it.sh 는 사전에 실행권한 부여
$ chmod +x wait-for-it.sh

# 세부내용은 docker-compose.yaml 참고
$ docker-compose up --build
$ docker-compose up -d # background run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

TIP

현재 docker 컨테이너 중지 및 삭제

$ docker stop $(docker ps -aq)
$ docker rm $(docker ps -aq)
1
2

# docker image export/import/save/load

  1. save / load
  • docker 이미지를 tar 로 저장하고 로드
$ docker save -o nginx.tar nginx:latest
$ docker load -i nginx.tar
1
2
  1. export / import
  • container 를 tar 로 저장하고 로드
$ docker export container_id > temp.tar
$ docker impoort <temp.tar or url> - [image name[:tag name]]
1
2

TIP

  • export / import 는 컨테이너 동작에 필요한 모든 파일을 포함, 루트 파일시스템 전체가 포함됨
  • save / load 는 레이어 구조까지 포함한 형태로 압축

# Reference

# docker stats

$ docker stats
$ docker stats --no-stream
$ docker stats --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"
$ docker stats --format "table {{.Container}}:       {{.CPUPerc}}"
1
2
3
4

TIP

  • 사용 가능한 format string
  • .Container, .Name, .ID, .CPUPerc, .MemUsage, .NetIO, .BlockIO, MemPerc, .PIDs

# apt 패키지 설치시 사용자 상호 작용 방지




 




FROM ubuntu:latest

FROM ubuntu
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
    apt-get install -y  bash git openssh-server rsync augeas-tools libdbd-mysql-perl python3
...
1
2
3
4
5
6
7

# ENV vs ARG

  • ENV
    • 환경변수 지정
    • $변수 혹은 ${변수} 형태로 표현 가능
    • 또한, ${변수:-값}으로 값을 기본값으로 표현 가능
    • ${변수:+값}의 경우는 반대에 경우인데 사용할 일이 있을까 싶다.
    • docker run 시에 --e 옵션을 활용하여 오버라이딩 할 수 있다.
  • ARG
    • build 시점에만 사용되는 변수
    • ARG 변수 혹은 ARG 변수=값 형태로 표현 가능
    • ENV처럼 ${변수:+값}, ${변수:-값}으로도 표현 가능
    • docker build 시에 --build-arg 옵션을 활용하여 오버라이딩 할 수 있다.

# CMD vs ENTRYPOINT

  • CMD
    • 컨테이너가 시작될 때 실행
    • Dockerfile에서 한번만 사용 가능
    • 마지막 CMD만 사용
    • CMD ["실행 파일", "매개 변수", "매개 변수 ..."]
    • docker run [IMAGE] [COMMAND]에서 COMMAND를 넣으면 CMD가 무시
  • ENTRYPOINT
    • CMD와 동일하게 컨테이너가 시작될 때 실행
    • CMD와 같이 있으면 ENTRYPOINT는 실행 파일, CMD는 매개변수 역할을 함
    • docker run --entrypoint="[COMMAND] [IMAGE]"를 사용하여 무시 가능

# ADD vs COPY

  • ADD
    • 파일 복사
    • 압축 파일인 경우, 압축을 품
    • 단, URL로 가져온 파일은 압축만 해제하고 풀지는 않음
    • OS에 따라서 압축 해제 여부가 있음
    • 파일은 소유 root:root과 기존 권한을 가짐
    • URL은 소유 root:root과 600 권한을 가짐
  • COPY
    • 파일 복사
    • ADD와 달리 파일 그대로 가져옴
    • 권한 그대로 설정
    • 공통적으로 .dockerignore에 명시된 영역은 제외

# docker 재설치

  • container 중지 및 삭제
$ docker stop $(docker ps -q)
$ docker rm $(docker ps -q)
$ docker rmi $(docker images -q)
$ sudo systemctl stop docker
$ sudo systemctl stop containerd
1
2
3
4
5
  • docker 패키지 확인
$ yum list installed | grep docker
1
  • 이전 버전 제거
$ sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

$ sudo yum erase containerd.io.x86_64
$ sudo yum erase docker-ce.x86_64
$ sudo yum erase docker-ce-cli.x86_64
1
2
3
4
5
6
7
8
9
10
11
12
  • 관련 파일 삭제
$ cd /var/lib/docker
# 주의!
$ rm -rf *

$ cd /var/run
# 서비스가 중지됐다면 docker.pid 는 없음
$ rm docker.sock docker.pid
# 주의!
$ rm -rf docker
1
2
3
4
5
6
7
8
9
  • 설치 시 종속성 관련 에러가 발생되는 경우가 있음
  • 기본 저장소에는 containerd 의 버전이 늦는 경우가 있음
# 확인
$ sudo yum list installed | grep docker

# 저장소 추가
$ sudo yum install -y yum-utils
$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 특정 버전 설치시
$ sudo yum list docker-ce --showduplicates | sort -r

# docker-ce 설치
$ sudo yum install docker-ce
1
2
3
4
5
6
7
8
9
10
11
12
  • 서비스 시작 및 자동 시작 등록
$ sudo systemctl enable docker
$ sudo systemctl enable containerd
$ sudo systemctl start docker
$ sudo systemctl start containerd
$ sudo systemctl status docker
$ sudo systemctl status containerd
1
2
3
4
5
6

# docker tag

$ docker tag 0186e4019f7a ghcr.io/shockzinfinity/name:latest
1

# docker shared volume permission denied

  • docker run 사용 시 --privileged 옵션 혹은 docker-compose.yml 상에 privileged: true 사용




 

services:
  service_temp:
    container_name: service_temp
    image: service_temp:latest
    privileged: true
1
2
3
4
5

# docker command ref

$ docker run -d --hostname swn-rabbit --name swn-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3-management
$ docker build -t aspnetapp .
$ docker run -d -p 8080:80 --name myapp aspnetapp
$ docker-compose -f docker-compose.yml -f docker-compose.override.yml up --build

# List all containers (only IDs)
$ docker ps -aq
# Stop all running containers
$ docker stop $(docker ps -aq)
# Remove all containers
$ docker rm $(docker ps -aq)
# Remove all images
$ docker rmi $(docker images -q)
# Remove all none images
$ docker system prune
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15