본문 바로가기

카테고리 없음

도커 볼륨 정의와 도커 네트워크 종류

도커 볼륨 정의와 도커 네트워크 종류

도커 이미지로 컨테이너를 생성하게 되면 이미지는 읽기 전용으로 생성이 됩니다. 컨테이너의 변경 사항만 별도로 저장해서 각각 컨테이너의 정보를 보존하게 됩니다. 이미 생성된 이미지는 어떠한 경우로도 변경이 불가능하며, 컨테이너 계층에 원래 이미지에서 변경된 파일 시스템 등을 저장하게 됩니다. 이미지에 실행을 할 수 있는 필요한 파일이 들어 있다면  컨테이너 계층에는 로그인 정보나 쓴 게시글 등과 같이 데이터베이스에 쌓이는 정보가 저장이 됩니다. 

도커의 치명적인 단점은 컨테이너를 삭제하면 컨테이너 계층에 저장되어 있었던 정보가 모두 삭제가 됩니다. 도커의 컨테이너는 생성과 삭제가 매우 간단하기 때문에, 자칫 잘못하여 컨테이너를 삭제를 하게 된다면 데이터를 복구할 수가 없습니다. 이와 같이 위험을 방지하기 위해 컨테이너의 데이터를 영구적으로 활용할 수 있는 방법이 몇 가지가 있습니다. 그중 가장 대표적인 방법이 볼륨을 이용하는 것입니다. 호스트와 볼륨을 공유할 수도 있고, 볼륨 컨테이너를 활용할 수도 있고, 도커가 관리하는 볼륨도 생성할 수도 있습니다. 

호스트 볼륨 공유

다음 명령어를 입력해서 mysql 데이터 베이스 컨테이너와 워드프레스 웹 서버 컨테이너를 생성합니다.

#docker run -d\

--name wordpressdb_hostvolume \

-e MYSQL_ROOT_PASSWORD=password \

-e MYSQL_DATABASE=wordpress \

-v /home/wordpress_db:/var/lib/mysql \

mysql:5.7

#docker run -d \

-e WORDPRESS_DB_PASSWORD=passwd \

--name wordpress_hostvolume \

--link  wordpressdb_hostvolume:mysql \

-p 80 \

wordpress


워드프레스 컨테이너에 -p 옵션으로 컨테이너의 80포트를 외부에 노출했으므로 wordpress_hostvolume 컨테이너의 호스트 포트로 워드프레스 컨테이너에 접속할 수 있습니다. mysql을 구동하는데 필요한 각종 파일이 공유가 됐고, mysql, performance_schema, sys, wordpress 디렉터리는 mysql에 존재하는 실제 데이터베이스에 대응됩니다.

볼륨 컨테이너

볼륨을 사용하는 두번째 방법은 -v옵션으로 볼륨을 사용하는 컨테이너를 다른 컨테이너와 공유하는 것입니다. 컨테이너를 생성할 때 --volume-from 옵션을 설정하게 되면 -v 또는 --volume 옵션을 적용한 컨테이너의 볼륨 디렉터리를 공유할 수 있습니다. 

도커 볼륨

볼륨을 활용하는 세번째 방법은 도커 볼륨 명령어를 사용하는 것입니다. 지금까지 한방 법과 같이 호스트와 볼륨을 공유해 컨테이너의 데이터를 보존하거나 --volume-from 옵션을 활용하는 것도 나쁘지 않지만 도커 자체에서 제공하는 볼륨 기능을 활용해 데이터를 보전할 수도 있습니다. 볼륨을 다루는 명령어는 docker volume으로 시작해서 docker volume create로 생성합니다. 

#docker volume create --name myvolume 명령어를 입력해서 생성된 볼륨을 확인합니다.

#docker volume ls

볼륨을 생성할 때 플러그인 드라이버를 설정해 여러 종류의 스토리지 백엔드를 쓸 수 있습니다. 하지만 기본적으로 제공되는 local 드라이버를 사용하며, 이 볼륨은 로컬 호스트에 저장이 되며 도커 엔진에 의해 생성되고 삭제가 됩니다. 다음 명령어를 입력해 myvolume이라는 볼륨을 사용하는 컨테이너를 생성합니다. 호스트와 볼륨을 공유할 때 사용한 -v옵션의 입력과 달리 다음과 같은 형식을 입력해야 됩니다.

[볼륨의 이름]:[컨테이너의 공유 디렉터리] 아래의 예시에서 생성되는 컨테이너는 볼륨을 컨테이너의 /root/ 디렉터리에 파일을 쓰면 해당 파일이 볼륨에 저장됩니다.

# docker run -i -t --name myvolume_1 \ -v myvolume:/root/ \

/root 디렉터리에 volume이라는 파일을 생성했고, 다른 컨테이너도 myvolume 볼륨을 쓰면 볼륨을 활용한 디렉터리에 vulme 파일이 존재할 것입니다. 볼륨은 디렉터리 하나에 상응하는 단위로써 도커 엔진에서 관리합니다. 도커 볼륨도 볼륨 공유와 마찬가지로 호스트에 저장함으로써 데이터를 보존하지만 파일이 실제로 어디에 저장되는지 사용자는 알 필요가 없습니다. docker instpect 명령어를 사용하면 myvolume 볼륨이 실제로 어디에 저장이 되는지 알 수가 있습니다. docker inspect 명령어는 컨테이너, 이미지, 볼륨 등 도커의 모든 구성단위의 정보를 확인할 때 사용이 됩니다. 

도커 네트워크

도커 네트워크 구조

컨테이너 내부에서 ifconfig를 입력해 컨테이너의 네트워크 인터페이스를 확인했습니다. 도커는 컨테이너에 내부 IP를 순차적으로 할당받아서 컨테이너를 재시작할 때마다 변경이 될 수 있습니다. 내부 IP 도커가 설치된 호스트는 외부망 IP와 연결이 돼야 됩니다. 도커는 각각 컨테이너에 외부와의 네트워크를 제공하기 위해서 컨테이너마다 가상 네트워크 인터페이스를 호스트에 생성하여 사용합니다. 외부와 연결되기 위한 인터페이스 이름은 veth로 시작이 되며 사용자들은 veth를 직접 생성할 필요가 없으며 컨테이너가 생성이 될 때 도커 엔진이 자동으로 만듭니다.

도커 네트워크 기능

컨테이너를 생성하게 되면 기본적으로 docker0 브리지를 통해 외부와 통신 할 수 있는 환경을 사용할 수 있지만 사용자의 선택에 따라 여러 네트워크 드라이버를 쓸 수도 있습니다. 도커가 자체적으로 제공하는 대표적인 네트워크 드라이버는 브리지, 호스트, 논, 컨테이너, 오버레이가 있습니다. 도커 자체만으로 쉽게 사용할 수 있는 브리지, 호스트, 논, 컨테이너에 대해 설명을 해보겠습니다.  

브리지 네트워크

브리지 네트워크는 사용자 정의 브리지를 새로 생성해 컨테이너에 연결하는 네트워크 구조입니다. 컨테이느너는 연결된 브리지를 통해 외부와 통신할 수 있습니다. 기본적으로 존재하는 docker0을 사용하는 브리지 네트워크가 아닌 새로운 브리지 타입을 생성할 수 있고, 다음 명령어를 통해서 브리지 네트워크를 생성합니다.

# docker network create --driver bridge mybridge

브리지 타입이 mybridge라는 네트워크가 생성됐습니다. docker run 또는 create 명령어에 --net 옵션의 값을 설정하면 컨테이너가 이 네트워크를 사용하도록 설정할 수 있습니다. 명령어를 통해 mybridge 네트워크를 사용하는 컨테이너를 생성합니다.

#docker run -i -t --name mynetwork_container \

--net mybridge \

이렇게 사용자 정의 네트워크는 docker network connect 명령어를 통해 쉽게 유동적으로 붙일 수 있습니다. 아래 명령어로 mynetwork_container 컨테이너에 mybridge라는 이름의 브리지 네트워크를 끊은 뒤 다시 연결합니다.

#docker network disconnect mybridge mynetwork_container

#docker network connect mybridge mynetwork_container

논 네트워크, 호스트 네트워크에서는 위의 명령어가 먹히지 않고, 특정 IP 대역을 갖는 네트워크 모드에서만 명령어를 쓸 수 가 있습니다.

호스트 네트워크

네트워크를 호스트로 설정하면 호스트의 네트워크 환경을 그대로  쓸 수 있습니다. 브리지 드라이버와 달리 호스트 드라이버의 네트워크는 별도로 생성할 필요가 없이 기존 host라는 이름의 네트워크를 사용할 수 있습니다. --net 옵션을 입력해 호스트를 설정한 컨테이너 내부에서 네트워크 환경을 확인하면 호스트와 같은 것을 확인할 수 있습니다. 호스트 머신에서 설정한 호스트 이름도 컨테이너가 물려받기 때문에 컨테이너의 호스트 이름도 도커 엔진이 설치된 호스트 머신의 호스트 이름으로 설정이 됩니다. 컨테이너 네트워크를 호스트 모드로 설정하면 컨테이너 내부의 애플리케이션을 별도의 포트 포워딩 없이 서비스할 수 있습니다. 

논 네트워크

none이라는 해석은 말 그대로 네트워크를 쓰지 않는다라는 말입니다. 아래와 같이 컨테이너를 생성하게 되면 외부와 단절을 차단할 수 있습니다.

# docker run -i -t --name network_none \

--net none\

--net 옵션으로 none을 설정한 컨테이너 내부에서 네트워크 인터페이스를 확인하면 로컬 호스트를 나타내는 lo 외에는 존재하지 않는 것을 확인할 수 있습니다.