공식문서나 유튜브를 통해서 도커 기초 공부는 끝마쳤지만, 참고서를 기반으로 간략하게 정리하고자 한다. 지난 포스팅에서 도커가 무엇인지 간단하게 정리했다. 이번 포스팅부터는 도서의 순서대로 TIL
형식으로 기록하고자 한다.
도커 엔진에서 사용하는 기본 단위는 이미지와 컨테이너이다. 이번 포스팅은 통해서 컨테이너가 무엇인지, 어떤 방식으로 사용하는지 이해하는 것을 목표로 한다.
[저장소이름]/[이미지이름]:[태그이름]
으로 구성된다 (기억해두자)위에서 도커 엔진을 이용해서 컨테이너와 이미지의 기본적인 개념을 이해했고, 아래는 도커 엔진의 기초적인 사용법을 설명하고자 한다.
# docker -v
# docker run -i -t ubuntu:14.04
- 위에서 설명한바와 같이
[저장소이름]/[이미지이름]:[태그이름]
으로 구성되어 있으나, 저장소이름이 생략되어있다는 것은 docker hub에서 설치하겠다는 의미이다.- 위 명령어를 사용하면 자동으로 생성된 컨테이너 터미널로 접속된다.
root@f4cfasfds:/# exit
# docker images
# docker create -i -t --name mycentos centos:7
# docker start mycentos
docker attach mycentos
run
: pull + create + start + attach
create
: pull + create
pull 은 저장소에서 이미지를 설치하는 거라고 이해하면 된다.
# docker ps
# docker ps -a
CONTAINER ID
: 자동 부여된 아이디
IMAGE
: 이미지 이름
COMMAND
: 컨테이너 시작될 때 명령어
CREATED
: 생성된 이후 흐른 시간
STATUS
: Up | Exited | Pause
PORTS
: 호스트와 연결된 포트
NAMES
: 컨테이너 고유 이름(사용자가 작성한 별칭)
# docker rm mycentos
# docker ps //확인하는 명령어
현재 실행중인 컨테이너는 삭제할 수 없기 때문에, 중지하고 삭제해야 한다.
# docker stop mycentos [다른 컨테이너] .. 여러개 동시에 적용할 수 있음
# docker rm mycentos
강제로 삭제하려면 아래와 같은 명령어를 사용한다.
# docker rm -f mycentos
# docker container prune
// 위 아래 분리
# docker stop $(docker ps -a -q)
# docker rm $(docker ps -a -q)
# docker run -i -t --name mycentos -p 80:80 ubuntu:14.04
// 위와 아래 명령어 분리
# docker run -i -t -p 3306:3306 -p 192.168.0.100:7777:80 ubuntu:14.04
포트는 한개만 연결하는게 아니고, 여러개를 연결 할 수도 있음
상황은 워드 애플리케이션 1개와 mysql 서버 애플리케이션을 구축한다고 가정해보자. 도커 컨테이너는 1개당 1나의 어플리케이션을 준수하는 것이 기본이다.
# docker run -d \
--name wordpressdb \
-e MYSQL_ROOT_PASSWORD=password \
-e MYSQL_DATABASE=wordpress \
mysql:5.7
# docker run -d \
-e WORDPRESSDB=mysql
-e ...
--name wordpress \
--link wordpressdb:mysql \
-p 80 \
wordpress
- -p 80은 컨테이너의 포트를 의미한다. 즉 호스트의 랜덤한 포트와 80포트가 연결된다.
- 만일 호스트의 포트를 확인하고 싶다면 아래와 같은 명령어를 사용한다.
- -link [컨테이너이름]:[내가 정하고 싶은 별명]
# docker port wordpress
만일 데이터베이스로 활용중이던 컨테이너가 누군가에 의해 강제로 삭제되면 어떻게 될까? 정답은 큰일난다!! 이다. 이를 위해 어떻게 안전하게 보관 할 수 있을까? 두가지 방법이 있다.
(1) 호스트에 저장
(2) 저장장소 컨테이너를 추가한다.
(3) 도커 자체에서 제공해주는 볼륨기능
이 것에 대해서 설명하고자 한다.
# docker run -d \
-e ...
-v /home/wordpress_db:/var/lib/mysql \
mysql:5.7
- 위와 같이 -v 옵션을 통해 [호스트 저장장소]:[컨테이너 저장장소] 로 연결할 수 있다.
- /var/lib/mysql 은 mysql의 데이터 저장장소임.
# docker run -i -t \
--name volumes_from_container
--volumes-from volume_overide \
ubuntu:14.04
# docker volume create --name myVolume
# docker volume ls
# docker run -i -t --name myvolume_1 \
-v myVolume:/root/ \
ubuntu:14.04
# docker inspect --type volume myVolume
도커는 컨테이너에 내부 IP(사설)을 순차적으로 할당하고, 이 주소는 컨테이너를 재시작할 때마다 리셋된다. 즉 내부 망에서만 쓸 수 있는 IP주소이다.
도커는 각 컨테이너에 외부와의 소통을 네트워크로 제공하기 위해 컨테이너마다 가상 네트워크 인터페이스를 호스트에 생성하며 이 인터페이스의 이름은 veth이다.
# docker network inspect bridge
- bridge는 도커 네트워크 종류이다.(디폴트)
- 컨테이너마다 생성된 veth는 docker0와 연결되어 외부와 통신할 수 있다.
docker0이 아닌 사용자 정의 브리지를 새로 생성해서 각 컨테이너에 연결하는 네트워크 구조로 사용자 정의 브리지를 새로 생성해서 각 컨테이너에 연결하는 네트워크 구조이다.
# docker network create --driver bridge myBridge
# docker run -i -t --name mynetwork_container \
--net myBridge
ubuntu:14.04
docker network create --driver=bridge \
--subnet=172.72.0.0/16 \
--ip-range=172.72.0.0/24
--gateway=172.72.0.1 \
my_custom_network
호스트 네트워크 환경을 그대로 활용하는 네트워크이다.
# docker run -i -t --name network_host \
--net host \
ubuntu:14.04
아무런 네트워크를 쓰지 않는 것을 의미한다. ifconfig로 컨테이너 내부에서 확인하면 loopback 네트워크를 제외하고는 존재하지 않는 것을 확인 할 수 있다.
# docker run -i -t --name network_none \
--net none \
ubuntu:14.04
--net 옵션으로 container를 입력하면 다른 컨테이너의 네트워크 네임스페이스 환경을 공유할 수 있다. 공유되는 속성은 내부 IP, MAC주소 등이 있다. 즉 맥주소와 eth0에 표시되어있는 ip가 동일하고, veth를 통해서 docker0, 호스트 etho0와 연결된다.
# docker run -i -t --name network_continer_1 \
ubuntu:14.04
# docker run -i -t --name network_container_2 \
--net container:network_container_1 \
ubuntu:14.04
브리지 타입의 네트워크와 --net-alias를 함께 사용하면 특정 호스트 이름으로 컨테이너 여러개 접근할 수 있다.
# docker run -i -t -d --name network network_alias_1 \
--net mybridge \
--net-alias test \
ubuntu:14.04
# docker run -i -t -d --name network network_alias_2 \
--net mybridge \
--net-alias test \
ubuntu:14.04
# docker run -i -t -d --name network network_alias_3 \
--net mybridge \
--net-alias test \
ubuntu:14.04
# ping -c 1 test
- 위 테스트를 하면 각 컨테이너에 ping이 찍힌다.
- --net-alias 별칭을 통해 dns 형태로 ip를 유동적으로 가지게 된다.
- 확인하려면 dig를 통해 test를 호스트에서 찍어보면 3개의 유동 ip를 얻을 수 있다.
호스트의 네트워크 인터페이스 카드를 가상화해서 물리 네트워크 환경을 컨테이너에 동일하게 제공한다. 이를 통해서 가상의 MAC주소를 가지게 되고, 다른 호스트에 있는 컨테이너와 통신이 가능해진다. 즉 동일한 IP 대역을 사용하는 서버(호스트) 및 컨테이너들은 서로 통신이 가능해진다.
# docker network create -d macvlan --subnet=192.168.0.0/24 \
--ip-range=192.168.0.64/28 \
--gateway=192.168.0.1 \
-o macvlan_mode=bridge -o parent=eth0 my_macvlan
- 조심해야할 점은 호스트간 ip-range 주소를 다르게 설정해줘야 한다는 점이다.