도커 볼륨
도커 이미지로 컨테이너를 생성하면 이미지는 읽기 전용이 되고 컨테이너의 변경 사항만 별도로 저장해서 각 컨테이너의 정보를 보존한다.
이미지에는 mysql을 실행하는 애플리케이션 파일이, 컨테이너 계층에는 워드프레스에서 만든 정보를 데이터가 저장된다.
치명적인 단점은 mysql 컨테이너가 삭제되면 컨테이너 계층에 저장되어 있던 데이터도 함께 삭제된다.
이를 방지하고자, 도커 볼륨을 활용한다.
도커 볼륨 활용 방법 3가지
- 호스트 볼륨 공유
- 볼륨 컨테이너
- 도커 볼륨
호스트 볼륨 공유
docker run -d \ # 백그라운드에서 실행 --name wordpressdb_hostvolume \ # 컨테이너 이름 지정 -e MYSQL_ROOT_PASSWORD=password \ # 환경변수 설정 -e MYSQL_DATABASE=wordpress \ # 환경변수 설정 -v /home/wordpress_db:/var/lib/mysql # 볼륨 마운트 옵션. 컨테이너의 MySQL 데이터가 호스트의 지정된 디렉토리에 저장되며, 컨테이너가 삭제되더라도 데이터는 보존된다. mysql 8:0 # 사용할 이미지와 버전
docker run -d \ # 백그라운드에서 실행 -e WORDPRESS_DB_PASSWORD=password \ # 환경변수 설정 --name wordpress_hostvolume \ # 컨테이너 이름 지정 --link wordpressdb_hostvolume:mysql \ # 컨테이너와의 연결 -p 80:80 \ # 호스트 머신의 80 포트와 컨테이너의 80 포트 바인딩 wordpress # 사용할 이미지
데이터베이스 컨테이너 생성시
-v
옵션을 사용했고, 값을 특정해 설정했다. 이는 호스트의 /home/wordpress_db
디렉터리와 컨테이너의 /var/lib/mysql
디렉터리를 공유하겠다는 의미이다.호스트의
/home/wordpress_db
경로에 미리 추가해주지 않아도 자동으로 생성된다.-v
[호스트의 공유 디렉터리]:[컨테이너의 공유 디렉터리]컨테이너의
/var/lib/mysql
디렉터리는 MySQL이 데이터를 저장하는 기본 디렉터리이다.mysql을 구동하는 데 필요한 파일이 공유됐다. 이제 컨테이너를 삭제하고도 데이터베이스의 데이터가 보존되는지 확인해보자.
docker stop wordpress_hostvolume wordpressdb_hostvolume docker rm wordpress_hostvolume wordpressdb_hostvolume
ls /home/wordpress_db
- 컨테이너의
/var/lib/mysql/
디렉터리와 호스트의/home/wordpress_db
디렉터리는 동기화가 아닌 완전히 같은 디렉터리이다.
- 컨테이너의 파일이 호스트로 복사되는 구조이다.
- 디렉터리뿐아니라 단일 파일의 공유도 가능하다.
-v
을 동시에 여러개 사용하는 것도 가능하다.
만약 호스트의 머신에 공유하려는 디렉터리가 이미 존재한다면 어떻게 될까?
이미지에 존재하던 디렉터리에 호스트의 볼륨을 공유하면 컨테이너 자체의 디렉터리가 덮어씌워진다. 정확히 말하면, -v 옵션을 통한 호스트 볼륨 공유는 호스트의 디렉터리를 컨테이너의 디렉터리에 마운트한다.
복사 규칙
- host 디렉터리를 입력하지 않으면, 디렉터리를 host에 생성하고, host 디렉터리는 컨테이너의 디렉터리 파일을 복사하여 가져간다.
- 호스트와 컨테이너 내부에 모두 디렉터리가 존재할 때는 컨테이너 디렉터리가 호스트의 디렉터리로 덮어씌워진다. 호스트 >> 컨테이너
볼륨 컨테이너
-v
옵션으로 볼륨을 사용하는 컨테이너를 다른 컨테이너와 공유할 수 있다.docker run -i -t \ # 사용자가 입력받을 수 있도록 설정 --name volumes_from_container \ # 컨테이너 이름 지정 --volumes-from volumes_overide \ # 다른 컨테이너의 볼륨을 공유하기 위한 옵션, volumes_overide라는 이름의 컨테이너에서 정의된 모든 볼륨을 현재 컨테이너에서 사용할 수 있게 한다. 데이터가 저장된 볼륨을 여러 컨테이너에서 공유할 수 있어 데이터 일관성을 유지할 수 있다. ubuntu:14:04 # 사용할 이미지
root@:/ ls /home/testdir2 ... wordpress
위 그림과 같은 구조를 활용해 볼륨만 공유하는 ‘볼륨 컨테이너’로 활용이 가능하다.
볼륨을 사용하려는 컨테이너에
—volumes-from
옵션을 사용해 볼륨 컨테이너에 연결하고 데이터를 간접적으로 공유받을 수 있다.도커 볼륨
도커 자체에서 제공하는 볼륨 기능을 활용해 데이터를 보존할 수 있다.
docker volume create --name myvolume
docker volume ls
docker run -i -t \ # 사용자가 입력받을 수 있도록 설정 --name myvolume_1 \ # 컨테이너 이름 지정 -v myvolume:/root/ \ # 볼륨 마운트 ubuntu:14.04 # 사용할 이미지
root@:/ echo hello, volume! >> /root/volume
docker run -i -t \ --name myvolume_2 \ ubuntu:14.04
root@/ cat /root/volume hello, volume!
도커 볼륨도 여러 개의 컨테이너에 공유되어 활용될 수 있다.
볼륨은 디렉터리 하나에 상응하는 단위로서 도커 엔진에서 관리합니다. 도커 볼륨도 호스트 볼륨 공유와 마찬가지로 호스트에 저장함으로써 데이터를 보존하지만 파일이 실제 어디에 저장되는지 사용자는 알 수 없다.
docker inspect --type volume myvolume
[ { "driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/myvolum/_data", "Name": "myvolume", "Options": {}, "Scope": "local" } ]
Driver
: 볼륨이 쓰는 드라이버
Labels
: 볼륨을 구분하는 라벨
Mountpoint
: 볼륨이 실제 호스트의 저장되는 경로
docker run -i -t \ # 사용자가 입력받을 수 있도록 설정 --name volume_auto \ # 컨테이너 이름 지정 -v /root \ # 호스트의 /root 디렉토리를 컨테이너 내부의 /root에 마운트 ubuntu:14.04
docker volume ls DRIVER VOLUME NAME local dae... local myvolume
이렇게 도커 볼륨을 생성, 삭제하다 보면 불필요한 볼륨이 남는다. 볼륨을 사용하는 컨테이너를 삭제해도 볼륨은 삭제되지 않기 때문이다.
docker volume prune
- 스테이트리스: 컨테이너 자체는 상태가 없고 상태를 결정하는 데이터는 외부로부터 제공 받는다.
- 스테이트풀: 컨테이너가 데이터를 저장하고 있어 상태가 있다.
컨테이너가 삭제돼도 데이터는 보존되므로 스테이트리스한 컨테이너 설계는 도커를 사용할때 매우 바람직한 설계입니다.
도커 네트워크
도커 네트워크 구조
root@eec07d6873f3:/# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 65535 inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet) RX packets 2052 bytes 24664848 (24.6 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1567 bytes 109167 (109.1 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0
: 공인 IP 또는 내부 IP가 할당되어 실제로 외부와 통신할 수 있는 호스트의 네크워크 인터페이스이다. veth로 시작하는 인터페이스는 컨테이너를 시작할 때 생겼으며, 각 컨테이너의 eth0와 연결됐다.
도커는 컨테이너 내부 IP를 순차적으로 할당하며, 이 IP는 컨테이너를 재시작할 때마다 변경될 수 있다. 이 내부 IP는 도커가 설치된 호스트, 즉 내부 망에서만 쓸수 있는 IP이므로 외부와 연결될 필요가 있다. 도커는 각 컨테이너에 외부와의 네트워크를 제공하기 위해 컨테이너마다 가상 네트워크 인터페이스를 호스트에 생성하며 이 인터페이스의 이름은 veth로 시작한다. veth의 인터페이스는 컨테이너가 생성될 때 도커 엔진이 자동 생성 한다.
댓글