도커 볼륨과 네트워크

날짜
Aug 27, 2024
태그
docker
설명
도커 볼륨과 네트워크
 

도커 볼륨

도커 이미지로 컨테이너를 생성하면 이미지는 읽기 전용이 되고 컨테이너의 변경 사항만 별도로 저장해서 각 컨테이너의 정보를 보존한다.
 
도커 이미지로 mysql 컨테이너를 생성, 워드프레스 블로그를 위한 데이터베이스 정보는 컨테이너가 가지고 있다.
도커 이미지로 mysql 컨테이너를 생성, 워드프레스 블로그를 위한 데이터베이스 정보는 컨테이너가 가지고 있다.
이미지에는 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 옵션을 통한 호스트 볼륨 공유는 호스트의 디렉터리를 컨테이너의 디렉터리에 마운트한다.
 
복사 규칙
  1. host 디렉터리를 입력하지 않으면, 디렉터리를 host에 생성하고, host 디렉터리는 컨테이너의 디렉터리 파일을 복사하여 가져간다.
  1. 호스트와 컨테이너 내부에 모두 디렉터리가 존재할 때는 컨테이너 디렉터리가 호스트의 디렉터리로 덮어씌워진다. 호스트 >> 컨테이너
 

볼륨 컨테이너

-v 옵션으로 볼륨을 사용하는 컨테이너를 다른 컨테이너와 공유할 수 있다.
 
docker run -i -t \ # 사용자가 입력받을 수 있도록 설정 --name volumes_from_container \ # 컨테이너 이름 지정 --volumes-from volumes_overide \ # 다른 컨테이너의 볼륨을 공유하기 위한 옵션, volumes_overide라는 이름의 컨테이너에서 정의된 모든 볼륨을 현재 컨테이너에서 사용할 수 있게 한다. 데이터가 저장된 볼륨을 여러 컨테이너에서 공유할 수 있어 데이터 일관성을 유지할 수 있다. ubuntu:14:04 # 사용할 이미지
직접 볼륨을 공유하지 않고 -v 옵션을 적용한 컨테이너를 통해 공유한다. 호스트와 다른 컨테이너는 볼륨 옵션이 적용된 컨테이너인 volume_overide 컨테이너에서 볼륨을 공유받는다.
root@:/ ls /home/testdir2 ... wordpress
공유가 잘 이뤄지는지 확인
 
—volumes-from 옵션을 적용한 컨테이너와 볼륨 컨테이너 사이의 관계
—volumes-from 옵션을 적용한 컨테이너와 볼륨 컨테이너 사이의 관계
 
👨‍🔬
위 그림과 같은 구조를 활용해 볼륨만 공유하는 ‘볼륨 컨테이너’로 활용이 가능하다. 볼륨을 사용하려는 컨테이너에 —volumes-from 옵션을 사용해 볼륨 컨테이너에 연결하고 데이터를 간접적으로 공유받을 수 있다.
 

도커 볼륨

도커 자체에서 제공하는 볼륨 기능을 활용해 데이터를 보존할 수 있다.
 
docker volume create --name myvolume
도커 볼륨 생성
docker volume ls
생성된 볼륨 확인
 
docker run -i -t \ # 사용자가 입력받을 수 있도록 설정 --name myvolume_1 \ # 컨테이너 이름 지정 -v myvolume:/root/ \ # 볼륨 마운트 ubuntu:14.04 # 사용할 이미지
/root 디렉터리에 volume 이라는 파일을 생성.
root@:/ echo hello, volume! >> /root/volume
root에 volume 파일을 생성한다.
 
docker run -i -t \ --name myvolume_2 \ ubuntu:14.04
다른 컨테이너도 myvolume 볼륨을 사용하면 볼륨을 활용한 디렉터리에 volume 파일이 존재할 것이다.
root@/ cat /root/volume hello, volume!
같은 파일인 volume 이 존재한다.
 
 
도커 볼륨 사용 구조
도커 볼륨 사용 구조
 
👨‍🔬
도커 볼륨도 여러 개의 컨테이너에 공유되어 활용될 수 있다.
 
볼륨은 디렉터리 하나에 상응하는 단위로서 도커 엔진에서 관리합니다. 도커 볼륨도 호스트 볼륨 공유와 마찬가지로 호스트에 저장함으로써 데이터를 보존하지만 파일이 실제 어디에 저장되는지 사용자는 알 수 없다.
 
docker inspect --type volume myvolume
inspect 명령어로 myvolume 볼륨이 실제 어디에 저장되는지 알 수 있다.
[ { "driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/myvolum/_data", "Name": "myvolume", "Options": {}, "Scope": "local" } ]
inspect 명령어에 대한 결과값
  • Driver: 볼륨이 쓰는 드라이버
  • Labels: 볼륨을 구분하는 라벨
  • Mountpoint: 볼륨이 실제 호스트의 저장되는 경로
 
 
docker run -i -t \ # 사용자가 입력받을 수 있도록 설정 --name volume_auto \ # 컨테이너 이름 지정 -v /root \ # 호스트의 /root 디렉토리를 컨테이너 내부의 /root에 마운트 ubuntu:14.04
컨테이너에 공유할 디렉터리 위치를 -v 옵션에 입력하면 해당 디렉터리에 볼륨을 자동으로 생성한다.
docker volume ls DRIVER VOLUME NAME local dae... local myvolume
볼륨을 확인해보면 무작위의 16진수의 볼륨이 자동으로 생성된다.
 
이렇게 도커 볼륨을 생성, 삭제하다 보면 불필요한 볼륨이 남는다. 볼륨을 사용하는 컨테이너를 삭제해도 볼륨은 삭제되지 않기 때문이다.
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
docker로 생성한 ubuntu 웹서버 내부에서 ifconfig 명령어를 입력했다.
 
eth0: 공인 IP 또는 내부 IP가 할당되어 실제로 외부와 통신할 수 있는 호스트의 네크워크 인터페이스이다.
veth로 시작하는 인터페이스는 컨테이너를 시작할 때 생겼으며, 각 컨테이너의 eth0와 연결됐다.
 
도커는 컨테이너 내부 IP를 순차적으로 할당하며, 이 IP는 컨테이너를 재시작할 때마다 변경될 수 있다. 이 내부 IP는 도커가 설치된 호스트, 즉 내부 망에서만 쓸수 있는 IP이므로 외부와 연결될 필요가 있다. 도커는 각 컨테이너에 외부와의 네트워크를 제공하기 위해 컨테이너마다 가상 네트워크 인터페이스를 호스트에 생성하며 이 인터페이스의 이름은 veth로 시작한다. veth의 인터페이스는 컨테이너가 생성될 때 도커 엔진이 자동 생성 한다.
 

댓글

guest