Inertia

docker

최근에 docker를 사용해볼 기회가 있어서 몇가지 컨셉 도움이 되는 것들을 정리해 보기로 한다. docker이전엔 virtual machine(VM)이 있었고 이것으로 많이 사용했지만 VM의 문제는 무겁다는 것. 그래서 light하게 에뮬레이션 할 수 있게 docker가 나오기 시작함. 개발환경/서버환경 설정등으로 사용하면 좋은 use case가 됨.

image vs container

처음 헷갈린 것은 image와 container의 관계. image는 read-only이고 container는 image를 기반으로 실행되고 있는 것을 의미함. class와 instance의 관계라고 하면 적당한 비유가 될 것 같다.

name image conatiner
list docker images docker ps

build

docker image 를 빌드하려면 Dockerfile을 작성하면 되는데, 이 파일은 일련의 명령들을 순차적으로 실행해서 내가 원하는 이미지를 만드는 형식이다.

1
2
3
# build using current directory's Dockerfile
docker build .
docker build -t myimage:latest . # set tag as myimage:latest

run

docker run

  • -p host_port:container_port : port forwarding
  • -v host_volume:container_volumen : volume mapping
  • -it : open tty interactive shell
  • –net=host : host network을 그대로 사용하게 함. 즉, expose된 모든 port들은 외부에서 접근가능하게 됨. default는 port forwarding을 해줘야만 접근이 가능함.
  • -e : env va를 다커로 넘겨주는 명령. 환경변수가 많을 경우 --env-file env.list 옵션을 사용할 수 있음.
1
2
3
4
# run nginx docker image with 8000 port
docker run -it -p 8000:80 nginx
docker run -d -e POSTGRES_ENV_POSTGRES_PASSWORD='foo' nginx
docker run --env-file ./env.list ubuntu bash

exec

docker exec -it nginx bash

run과 기본적으로 같지만, 이미 실행되어 있는 container에서 실행하는 명령이다. 즉, 이미 실행되어 있는 웹서버의 bash shell로 들어가서 뭔가 확인해야 할것이 있다면 아래처럼 명령을 실행하면 된다.

delete images

간혹 여러개 이미지를 지워야 할 일이 있는데 아래 커멘드로 한방에 훅. 그러나 다른 것 지우지 않게 조심해야 함.

1
docker images | grep 810001cb03af | awk '{print $3}' | xargs docker rmi

push images

만들어진 docker image를 docker hub에 push하면 나중에 재사용할 수 있기 때문에 빌드 시간을 줄 일 수 있다. 그 전에 중요한 것은 image의 이름이 <dockerhub_id>/<image_name>의 형식으로 되어 있어야 한다.

1
2
3
4
5
6
7
8
9
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
docker-whale latest 7d9495d03763 38 minutes ago 273.7 MB
# change docker tag
docker tag 7d9495d03763 nberserk/docker-whale:latest
#login to docker hub
docker login --username=yourhubusername --email=youremail@company.com
# push image
docker push nberserk/docker-whale

Dockerfile

add

1
2
3
# local 의 dev directory를 container의 /code/dev 로 recursive copy를 하고 싶다면 아래처럼.
# 만약 `add dev /code` 로 주면 dev dir의 파일을 /code로 카피한다. 왜 이렇게 헷갈리게 동작을 정의 했을까..
add dev /code/dev

copy

1
2
COPY dist/. /usr/share/nginx/html/      # copy files under dist folder
COPY dist /usr/share/nginx/html/ # copy dist directory to html folder

위의 예 처럼 폴더안에 든 파일만 카피를 하고 싶다면 <folder>/. 이런식으로 기술해 주면 된다.

CMD vs ENTRYPOINT

ENTRYPOINT는 디폴트로 실행하는 포인트이고 디폴트는 sh -c 이다. CMD는 이 ENTRYPOINT의 parameter가 된다. 자세한 것은 여기를 참고.

ENTRYPOINT를 내가 만든 shell로 대체해서 커스텀화 할 수 있다. docker-entrypoint.sh로 돌리고 CMD로 디폴트로 실행될 파람을 받고 등등..

1
2
3
4
#!/bin/bash -e
/usr/local/bin/uwsgi --ini /django/deploy/uwsgi.ini &
./manage.py migrate
exec "$@"

위는 django server를 띄우고, 또 optional하게 들어오는 커맨드를 실행하는 스크립트이다. 이런식으로 사용하면 된다.

Docker-machine에 insecure registry 영구적으로 추가하기

private docker registry 설정시, Ubuntu의 경우는 /etc/default/docker 에 아래처럼 추가해주면 되고

DOCKER_OPTS=”–insecure-registry <your_registry_ip>:5000”

맥의 경우는, docker-machine ssh 로 들어가서 /var/lib/boot2docker/profile 에 아래처럼 추가하면 된다.

EXTRA_ARGS=”–insecure-registry <your_registry_ip>:5000”

그런데 맥이나 윈도우의 경우는 docker-machine이 reboot될때마다 셋팅이 없어지기 때문에 아래의 커맨드로 vm을 생성하면 영구적인 변경을 줄 수 있다.

docker-machine create –driver virtualbox –engine-insecure-registry 10.240.70.80:5000 registry

vm을 이미 만든 경우라면, ~/.docker/machine/machines/default/config.json의 HostOptions>EngineOptions>InsecureRegistry에 직접 추가해주면 된다. 아래 예 참조. docker 버전은 1.10.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
"HostOptions": {
"Driver": "",
"Memory": 0,
"Disk": 0,
"EngineOptions": {
"ArbitraryFlags": [],
"Dns": null,
"GraphDir": "",
"Env": [],
"Ipv6": false,
"InsecureRegistry": [
"10.240.70.80:5000"
],
"Labels": [],
"LogLevel": "",
"StorageDriver": "",
"SelinuxEnabled": false,
"TlsVerify": true,
"RegistryMirror": [],
"InstallURL": "https://get.docker.com"
},

revision history

  • 2016-3-24 draft
  • 2016-5-20 insecure registry 추가
  • 2016-5-31 –net=host 추가