CheatSheet | Docker


Introduction

  • docker
  • docker compose
  • Glossary
    • swarm : cluster 와 동일한 개념
    • node (manager/worker) : 클러스터에 속한 서버의 단위. 스웜 명령어는 매니저 노드에서만 실행된다
    • service : 각 프로젝트를 구성하고 있는 서비스 단위 정도, 기본적인 배포단위, 하나의 이미지를 기반으로 생성되고 복제 컨테이너를 여러개 실행가능
    • stack : 프로젝트의 단위 정도로 생각하면 될 듯, 하나의 스택으로 묶인 컨테이너들은 기본적으로 같은 overlay 네트워크에 속하게 된다


1. Install docker in centOS

# (1) Set up the repository
$ sudo yum install -y yum-utils
$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

# (2) Install Docker Engine
$ sudo yum install docker-ce docker-ce-cli containerd.io
# (3) Create the docker group.
# $ sudo groupadd docker

# (4)Add your user to the docker group.
# sudo usermod -aG docker irteam
$ sudo /usr/sbin/usermod -aG docker irteam
$ sudo /usr/sbin/usermod -aG docker irteamsu

# (5) change root directory (storage for default docker directory is not enough)
# add {"data-root": "/home1/irteam/docker-data"} in /etc/docker/daemon.json
$ sudo vim /etc/docker/daemon.json

# (6) Run docker
$ sudo systemctl start docker
# if got permission error for /var/run/docker.sock
$ sudo chmod 666 /var/run/docker.sock
# check root directory
$ docker info | grep Root
$ docker run hello-world


2. Docker Commands

# docker 버전확인하기
$ docker --version

# 현재위치의 Dockerfile로 build 하기
$ docker build -t [TAG] .

# 등록된 docker 이미지 확인하기
$ docker images

# 실행중인 도커 머신 정보 보기
$ docker ps -a

# 도커 머신 삭제 하기
$ docker rm -f [container name]

# 도커 이미지 삭제 하기
$ docker rmi [image name]

# 도커 머신 중지하기
$ docker stop [container name]

# 도커 머신 시작하기
$ docker start [container name]

# 도커 머신으로 파일 복사하기
$ docker cp [소스파일] [머신이름:디렉토리]

# 도커 머신으로 부터 파일 가져오기
$ docker cp [머신이름:소스파일] [디렉토리]

# 도커 머신으로 재접속하기
$ docker attach [머신이름]
# 나오기
ctrl p q

# 도커 머신 실행하기
$ docker run --dit -p 22022:22 --name [컨테이너이름] -v $(pwd):[/매핑할경로] --shm-size 4G [이미지이름]
    -d # backgorund
    -it 
    --name # 컨테이너에 이름을 부여
    --rm # 컨테이너가 종료될때 관련 리소스를 제거 

$ docker exec -it [컨테이너이름] /bin/bash
# root로 실행하기 
$ docker exec -u 0 -it [컨테이너이름] bash

# 도커 이미지 커밋/push
$ docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
$ docker push [REPOSITORY[:TAG]]

# 안쓰는 도커 컨테이너 정리
$ docker container prune

# 안쓰는 도커 이미지 정리
$ docker image prune

# building cache까지 모두 정리
$ docker system prune -a

# show logs in container
$ docker logs -f <CONTAINER_NAME> --tail=1000 2>&1 | grep complete


3. Dockerfile Instructions

# base image를 지정
FROM ubuntu:16.04

# build 시에만 사용되는 변수 
ARG PYVERSION

# shell cmd 를 bin/sh -c 로 해당 docker image에 실행시킬때,
# shell이 없는 platform에서 실행하려면 exec
RUN ["apt-get", "install", "-y", "nginx"]

# Docker container 외부에 노출시킬 포트를 지정 할 때, container를 실행할때도 열어줘야함
EXPOSE 8080

# 환경변수를 지정할 때, 지정한 환경변수는 $variable_name으로 사용가능
ENV FOO /bar

# docker container가 시작할 때 실행할 커맨드를 지정
CMD ["python", "main.py"]

#해당 도커 이미지를 실행할 user를 지정
USER nginx  

#호스트의 dir를 docker 컨테이너에 연결시킬 수 있다
VOLUME ["opt/project"]

# 파일과 디렉토리를 호스트에서 docker image로 copy 한다
ADD file /some/dir/file

# ADD와 기본적으로 동일하나 압축파일을 자동으로 풀어주지 않고, URL을 파일소스로 사용할 수 없다
COPY file /some/dir/file


4. Docker Compose

$ docker-compose up -d # Docker Compose에 정의되어있는 모든 서비스 컨테이너를 한번에 생성하고 실행하기 위해

$ docker-compose down

$ docker-compose stop [컨테이너]

$ docker-compose ps
version: '3.7'
services:

  my_service1:
    build: # if wanna build a image
      context: ./
      dockerfile: ./Dockerfile
    image: # image name
    hostname: # host name
    tty: true # docker run -t
    container_name: <my_cont1> # container_name
    volumes: # mout volumes
      - ./src:/naver/shoppinglive/src
    networks:
      # 같은 networks 안의 다른 컨테이너에서는 my_cont1:3003으로 접속가능
      # my_service1:3003 도 가능, service, container name 둘다 가능한듯
      - shoppinglive
      # network를 추가하면 and 로 추가됨, 여기저기 다 가능해짐
    ports:
      - 2003:3003
    user: celery
    command: python -m black /naver/shoppinglive/src -t py39
    depends_on:
      - black

volumes:
  rabbitmq:
    driver: local
  redis:
    driver: local
networks:
  shoppinglive:


5. Docker swarm

  • Server Orchestration
    • Scheduling : 컨테이너 여러개를 각 서버에 나누어 배포하고, 서버가 죽으면 실행중이던 서버를 다른 서버로 배포하여 서비스에 차질이 없도록 한다
    • Clustering : 여러개의 서버를 하나의 서버처럼 사용할 수 있게 해준다. 클러스터에 새로운 서버를 추가/제거 하여 여기 저기 흩어져 있는 컨테이너도 가상 네트워크를 이용, 같은 서버에 있는 것 처럼 쉽게 통신할 수 있게 해준다.
    • Service Discovery :
    • Logging, Monitoring
  • Why Docker Swarm?
    • API 서버를 구축하고 서버의 트래픽이 증가하여 서버 한대로 감당할 수 없을 때,
    • 컨테이너를 구성하는 이미지가 업데이트 된다면 ? 현재 구동중인 모든 컨테이너를 지우고 docker-compose로 다시 새로운 컨테이너를 만들어야 할까 => 도커 스웜의 롤링 업데이트 기능
    • 스웜은 도커와 별도로 개발되어오다 1.12 버전부터 스웜모드라는 이름으로 합쳐졌다
# (1) init docker swarm
$ docker swarm init # run on manager node
# This will return the following command. To add a worker to this swarm, just run that command on the worker node
> docker swarm join --token .............

# (2) deploy
$ docker stack deploy --compose-file <docker-compose.yml> <STACK_NAME> # deploy using docker-compse.yml

# manage the swarm node
$ docker node ls # show all nodes joined to current node
$ docker stack ls # show all stacks in current node (manager) 
$ docker service ls # show all services (including worker nodes) managed by current node 

$ docker service ps <SERVICE_NAME>

6. File sharing in docker container

  • Bind-mount : are files mounted from your host machine (the one that runs your docker daemon) onto your container.

  • Volume : are like storage spaces totally managed by docker. In fact, volumes are managed in the hidden(?) path of host machine such as ‘/var/lib/docker/volumes/VOLUME_NAME’

    • named volumes : you provide the name of it

    • anonymous volumes : usual UUID names from docker, like you can find them on container or untagged images

docker volume ls
docker volume rm
docker volume inspect VOLUME_NAME