docker는 containerization(container화 하는 기술)을 할 수 있게 해주는 소프트웨어이다.
docker의 slogan은 Build Once, Run Anywhere로 어디에서나 동일한 실행 결과를 보장한다.
image는 container 실행에 필요한 파일과 설정값등을 포함하고 있는 것으로 immutable하며 image를 실행하면 container가 생성된다.
같은 이미지에서 여러개의 container를 생성할 수 있고 container의 상태가 바뀌거나 container가 삭제되더라도 이미지는 변하지 않고 그대로 남아있다.
container는 virtualization(가상화) 기술의 하나로 격리된 공간에서 프로세스가 동작하는 기술을 의미한다.
cf) virtualization
기존의 virtualization은 host OS위에 guest OS 전체를 가상화하여 사용하는 방식인데 이는 무겁고 느려서 운영환경에선 사용할 수 없었음.
이를 개선하기 위해 프로세스를 격리하는 방식이 등장했다. 리눅스에선 이 방식을 리눅스 컨테이너라고 한다.
docker는 union filesystem을 이용해서 layer들을 하나의 filesystem으로 사용할 수 있게 해준다.
image는 여러개의 read only layer로 구성되고 파일이 추가되거나 수정되면 새로운 layer가 생성된다.
container를 생성할 때도 layer 방식을 사용하는데, 기존의 image layer위에 read-write layer를 추가한다.
image layer를 그대로 사용하면서 container가 실행중에 생성하거나 변경된 것들에 대한 내용은 read-write layer에 저장되므로 여러개의 container를 생성해도 최소한의 용량만 사용한다.
docker 내부적으로는 container를 위한 resource를 분리하고, lifecycle을 제어하는 기능은 linux kernel의 cgroup등이 수행한다.
docker는 추상화 layer를 만들었고 이를 통해 user는 Docker CLI만으로 container를 제어할 수 있다.
var/run/docker.sock
관련 에러가 나온다.$ brew install docker
FROM
FROM <image>[:<tag>] [AS <name>]
# example
From nginx:latest AS ngx
COPY
COPY <src> <dest>
# example
COPY local-file /file
COPY local-dir /dir
ADD
ADD scripts.tar.gz /tmp
ADD http://www.example.com/script.sh /tmp
RUN
RUN <command>
RUN ["executable-command", "parameter1", "parameter2"]
# example
RUN pip install torch
RUN pip install -r requirements.txt
CMD & ENTRYPOINT
CMD <command>
CMD ["executable-command", "parameter1", "parameter2"]
CMD ["parameter1", "parameter2"] # ENTRYPOINT와 함께 사용할 때
# example
CMD python main.py
WORKDIR
WORKDIR /path/to/workdir
# example
WORKDIR /home/demo
RUN pwd # /home/demo 가 출력된다
ENV
ENV <KEY> <VALUE>
ENV <KEY>=<VALUE>
# example
# default 언어 설정
RUN locale-gen ko_KR.UTF-8
ENV LANG ko_KR.UTF-8
ENV LANGUAGE ko_KR.UTF-8
ENV LC_ALL ko_KR.UTF-8
EXPOSE
EXPOSE <port>
EXPOSE <port>/<protocol>
# example
EXPOSE 8080
.
: 현재 경로에 있는 Dockerfile -t
: my-image라는 name과 v1.0.0 tag로 image를 빌드docker build -t my-image:v1.0.0 .
docker run my-image:v1.0.0
TEST
env에 값을 변경docker run -e TEST=bye my-image:v1.0.0
Docker image는 여러 개의 Read-Only layer로 구성되어 있고, 이미지를 빌드할 때 이미 존재하는 layer는 cache되어 재사용되기 때문에, 이를 생각해서 Dockerfile을 구성한다면 시간을 줄일 수 있기
때문에 Dockerfile을 활용하여 docker image를 만들때 layer의 순서가 중요하다.
docker container에는 위 그림과 같은 방식으로 layer가 쌓이며 최상단의 Read/Write layer는 이미지에 영향을 주지 않고 container 내부에서 작업한 내용으로 모두 volatility이다.
image layers에 해당하는 하단의 layer가 변경되면, 그 위의 layer는 모두 새로 빌드되기 때문에 자주 변경되는 부분은 최대한 위쪽 layer로 놓는게 좋다.
또한 합칠 수 있는 Layer는 적절히 합치는 것이 성능향상효과를 이끈다.
.dockerignore
는 .gitignore
와 유사한 역할로 docekr build시에 자동으로 제외한다.
docker image의 tag로 latest는 사용하지 않는 것을 권장한다. 왜냐하면 latest가 default tag name이므로 의도치않게 overwritten 되는 경우가 너무 많이 발생하기 때문이다.
log등의 정보는 container 내부에 저장할 경우 날아갈 수 있으므로 외부에 저장하는 것이 좋으며, secret한 정보들은 Dockerfile에 직접 적는게 아니라 env var 또는 .env config file을 사용한다.
docker는 container 내부에서 작업한 모든 사항이 저장되지 않기 때문에 docker container끼리 격리된 파일 시스템을 사용하고 이 때문에 docker container끼리 데이터를 공유하기 어렵다.
docker cli를 통해서 volume
이라는 리소스를 직접 관리한다.
local에서 docker area(/var/lib/docker
) 아래에 특정 디렉토리를 생성한 다음, 해당 경로를 docker container에 mount한다.
local의 특정 경로를 docker container에 mount
docker run --restart=always ubuntu
docker run -it ubuntu sleep 10
-it
= -i
+ -t
옵션은 container를 실행시킴과 동시에 interactive한 terminal로 접속시켜주는 옵션.
docker run -d ubuntu sleep 10
-d
옵션은 docker container를 background에서 실행시켜서, 컨테이너에서 접속 종료를 하더라도 계속 실행중이 되도록 하는 커맨드
계속해서 log를 지켜볼 필요가 없는 DB의 경우 detached mode로 실행시키고
계속해서 log를 확인해야 하는 Backend API server는 attached mode로 log를 following하면서 실행시키면 효율적이다.