새소식

독서/시작하세요! 도커 & 쿠버네티스

2. 도커 볼륨 & 도커 네트워크

  • -

도커 볼륨

: 도커 이미지는 어떠한 경우로도 변경되지 않으며, 컨테이너 계층에 원래 이미지에서 변경된 파일시스템 등을 저장합니다. 이미지에 mysql을 실행하는 데 필요한 애플리케이션 파일이 들어있다면 컨테이너 계층에는 로그인 정보나 게시글 등과 같이 데이터베이스를 운용하면서 쌓이는 데이터가 저장됩니다.

 

그러나 mysql 컨테이너를 삭제하면 컨테이너 계층에 저장돼 있던 데이터베이스의 정보도 삭제된다는 점인데, 도커의 컨테이너는 생성과 삭제가 매우 쉽습니다. 이를 방지하기 위해 컨테이너의 데이터를 영속적 데이터로 활용할 수 있는 방법이 몇 가지 있는데, 가장 활용하기 쉬운 방법이 바로 볼륨을 활용하는 것입니다. 방법이 여러 가지 있는데 알아서 알아보아요.

 

1. 호스트 볼륨 공유

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.9

# docker run -d -e WORDPRESS_DB_PASSWORD = password --name wordpress_hostvolume --link wordpressdb_hostvolume : mysql -p 80 wordpress

워드프레스 컨테이너에 80 포트를 외부에 노출했으므로 wordpress_hostvolume 컨테이너의 호스트 포트로 워드프레스 컨테이너에 접속할 수 있습니다. 또한 원래 디렉토리 내 파일이 있던 호스트의 볼륨과 다른 컨테이너의 볼륨을 공유할 때 호스트 볼륨이 컨테이너 볼륨으로 마운트된다.

 

2. 볼륨 컨테이너

여러 개의 컨테이너가 동일한 컨테이너에 --volumes -from 옵션을 사용함으로써 볼륨을 공유해 사용할 수도 있다. 데이터를 간접적으로 공유받는 방식이다.

 

3. 도커 볼륨

도커 자체에서 제공하는 볼륨 기능을 활용해 데이터를 보존할 수도 있다. 도커 볼륨도 호스트 볼륨 공유와 마찬가지로 호스트에 저장함으로써 데이터를 보존하지만 파일이 실제로 어디에 저장되는지 사용자는 알 필요가 없습니다.

 

docker inspect 명령어를 사용하면 볼륨이 실제로 어디에 저장되는지 알 수 있다. 컨테이너, 이미지, 볼륨 등 도커의 모든 구성단위의 정보를 확인할 때 사용되며, 정보를 확인할 종류를 명시하기 위해 --type 옵션에 image, volume 등을 입력하는 것이 좋다. 추가로 사용되지 않는 볼륨을 한꺼번에 삭제하려면 docker volume prune 명령어를 사용하면 된다.

 

이처럼 컨테이너가 아닌 외부에 데이터를 저장하고 컨테이너는 그 데이터로 동작하도록 설계하는 것을 stateless 하다고 말합니다. 컨테이너 자체는 상태가 없고 상태를 결정하는 데이터는 외부로부터 제공받습니다. 컨테이너가 삭제돼도 데이터는 보존되므로 스테이트리스한 컨테이너 설계는 도커를 사용할 때 바람직한 설계라고 할 수 있다. 반대로 컨테이너가 데이터를 저장하고 있어 상태가 있는 경우 스테이프풀 하다고 말한다. 이러한 방법은 컨테이너 자체에서 데이터를 보관하므로 지양하는 것이 좋다.

 

 

도커 네트워크

도커는 컨테이너에 내부 IP를 순차적으로 할당하며, 이 IP는 컨테이너를 재시작할 때마다 변경될 수 있다. 이 내부 IP는 도커가 설치된 호스트, 내부 망에서만 쓸 수 있는 IP이므로 외부와 연결될 필요가 있다. 이 과정은 컨테이너를 시작할 때마다 호스트에 veth라는 네트워크 인터페이스를 생성함으로써 이뤄진다. 도커는 각 컨테이너에 외부와의 네트워크를 제공하기 위해 컨테이너마다 가상 네트워크 인터페이스를 호스트에 생성하며 이 인터페이스의 이름은 veth로 시작한다. veth 인터페이스는 사용자가 직접 생성할 필요는 없으며 컨테이너가 생성될 때 도커 엔진이 자동으로 생성한다.

 

eth0은 공인 IP 또는 내부 IP가 할당되어 실제로 외부와 통신할 수 있는 호스트의 네트워크 인터페이스입니다. veth로 시작하는 인터페이스는 컨테이너를 시작할 때 생성됐으며, 각 컨테이너의 eth0과 연결됐습니다. 뿐만 아니라 docker0이라는 브리지도 존재하는데 이는 각 veth 인터페이스와 바인딩돼 호스트의 eth0 인터페이스와 이어주는 역할을 한다.

 

즉 컨테이너의 eth0 인터페이스는 호스트의 veth@@@라는 인터페이스와 연결됐으며 veth 인터페이스는 docker0 브리지와 바인딩 돼 외부와 통신할 수 있다.

 

기능

컨테이너를 생성하면 기본적으로 docker0 브리지를 통해 외부와 통신할 수 있는 환경을 사용할 수 있지만 사용자의 선택에 따라 여러 네트워크 드라이버를 쓸 수도 있다. 대표적 유형으로는 Bridge, host, none, container, overlay가 있습니다. 서드파티 플러그인 설루션으로는 weave, flannel, openvswitch 등이 있으며, 더 확장된 네트워크 구성을 위해 활용할 수 있다.

 

# docker network ls 명령어를 사용하면 이미 브리지, 호스트, 논 네트워크가 있다. 브리지 네트워크는 컨테이너를 생성할 때 자동으로 연결되는 docker0 브리지를 활용하도록 설정돼 있다. 이 네트워크는 172.17.0.x IP 대역을 컨테이너에 순차적으로 할당합니다.

 

Config의 항목 서브넷과 게이트웨이가 설정돼 있는 것을 확인할 수 있다. 

 

1. 브리지 네트워크

브리지 네트워크는 docker0이 아닌 사용자 정의 브리지를 새로 생성해 각 컨테이너에 연결하는 네트워크 구조입니다. 컨테이너는 연결된 브리지를 통해 외부와 통신할 수 있습니다. 예시로 확인해 봅시다.

위와 같이 사용자 정의 네트워크는 disconnect, connect로 컨테이너에 유동적으로 붙이고 뗄 수 있다. 네트워크의 서브넷, 게이트웨이, IP 할당 범위 등을 임의로 설정하려면 --subnet, --ip-range, --gateway 옵션을 추가하면 된다. 단 --subnet과 --ip-range는 같은 대역이어야 한다.

 

브리지 네트워크와 --net-alias 옵션을 함께 사용하면 특정 호스트 이름으로 컨테이너 여러 개에 접근할 수 있다. 위에서 생성한 mybridge 네트워크를 이용해 컨테이너 3개를 생성하고, alicek106이라는 호스트 이름으로 생성한 3개의 컨테이너에 접근할 수 있다. 컨테이너의 IP 주소는 172.18.0.3, 4, 5 일 것이고, 핑을 보내게 되면 3개의 IP로 각각 ping 전송을 확인할 수 있다. 매번 달라지는 IP를 결정하는 것은 라운드 로빈 방식입니다. 이것이 가능한 이유는 도커 엔진에 내장된 DNS가 alicek106이라는 호스트 이름을 --net-alias 옵션으로 alicek106 설정한 컨테이너로 변환하기 때문입니다.

 

특정 호스트 ping alicek106 -> 도커 내장된 DNS에게 alicek106 호스트 이름 변환 요청 후 -> 다시 IP 목록을 반환하고 -> ping을 쏘아줌.

도커의 DNS는 호스트 이름으로 유동적인 컨테이너를 찾을 때 주로 사용됩니다. ex로 --link 옵션인데 이는 컨테이너의 IP가 변경돼도 별명으로 컨테이너를 찾을 수 있게 DNS에 의해 자동으로 관리됩니다.

 

 

2. 호스트 네트워크

네트워크를 호스트로 설정하면 호스트의 네트워크 환경을 그대로 쓸 수 있습니다. 위의 브리지 드라이버 네트워크와 달리 호스트 드라이버의 네트워크는 별도로 생성할 필요 없이 기존의 host라는 이름의 네트워크를 사용한다. 컨테이너의 네트워크를 호스트 모드로 설정하면 컨테이너 내부의 애플리케이션을 별도의 포트 포워딩 없이 바로 서비스할 수 있다. 이는 실제 호스트에서 애플리케이션을 외부에 노출하는 것과 같고, 호스트 모드를 쓰는 컨테이너에서 아파치 웹 서버를 구동한다면 호스트의 IP와 컨테이너의 아파치 웹 서버 포트인 80으로 바로 접근할 수 있다.

 

 

3. 논 네트워크

말 그대로 아무런 네트워크를 쓰지 않는 것을 뜻합니다. 로컬호스트를 나타내는 Lo 외에는 존재하지 않음.

 

 

4. 컨테이너 네트워크

--net 옵션으로 container를 입력하면 다른 컨테이너의 네트워크 네임스페이스 환경을 공유할 수 있다. 공유되는 속성은 내부 IP, 네트워크 인터페이스의 맥 주소 등이다. 다른 컨테이너의 네트워크 환경을 공유하면 내부 IP를 새로 할당받지 않고, 호스트에 veth로 시작하는 가상 네트워크 인터페이스도 생성되지 않습니다. 새로 만든 network_container2 컨테이너의 네트워크와 관련된 사항은 network_container1과 같게 설정됩니다.

'독서 > 시작하세요! 도커 & 쿠버네티스' 카테고리의 다른 글

6. 도커 데몬  (2) 2023.12.07
5. Dockerfile 명령어  (3) 2023.12.02
4. Dockerfile 빌드  (0) 2023.11.30
3. 도커 이미지  (0) 2023.11.29
1. 도커  (4) 2023.11.24
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.