Search

Docker: Volume & Network

Created
2021/05/23
Tags
Docker
Container
Image
Volume
Network
Bridge
Host
None

Subjects

1. Docker Volume

Volume이라 함은 일종의 파일이며 주로 디렉토리로써 이용된다. Volume이 정확이 어떤 파일을 의미하며, 어떻게 사용하는지 알아보기 전에 한 가지 예를 통해 Volume이 왜 필요한지 알아보자.
ImageContainer를 생성하게 되면, ImageLayer들은 오로지 Read-Only로 사용된다고 했다. 이 때 Layer들의 변경 사항이나 Container의 작업들은 별도의 Layer에 기록되어 Container의 정보들을 유지하게 된다. 이 때 MySQL 데몬을 Container로 만들어 실행했다고 하면, 이는 MySQL에 대한 내용들은 Image를 통해 생성되어 ImageLayer에 존재하지만 MySQL 데몬이 사용하는 DB와 같은 정보들은 Container가 갖고 있기 때문에 ContainerLayer에 존재하게 된다.
이전 글에서 본 것처럼 Image를 구성하는 Layer를 삭제하기 위해선 이를 참조하고 있는 Container들이 없어야 삭제할 수 있었지만, ContainerLayer는 강제 삭제가 가능하기 때문에 굉장히 쉽게 없앨 수 있었다. 만일 실수로 Container를 삭제하게 되면 Container에 대한 Layer 역시 지워지기 때문에 그 안에 유지 중이던 DB와 같은 정보들도 삭제되고 이는 복구할 수 없다. 사용되고 있는 DB가 서비스에 이용되고 있던 정보들이라면 굉장히 아찔한 상황이 나올 수도 있다. 따라서 이러한 정보들을 지속성 있게 유지하기 위해서 이용하는 것이 Volume이다. 즉, Volume은 정보의 Persistency를 위해서 이용한다고 볼 수 있고, 이는 일종의 공유 공간이라고 볼 수 있다.
Volume을 이용하는 방법은 다양하다. Container를 생성할 때 호스트의 공간을 공유하여 Volume을 생성할 수도 있고, Container를 생성할 때 Container가 사용하고 있는 Volume을 다시 공유받아 Volume을 둘 수도 있고, Docker가 제공하는 Volume을 생성할 수도 있다. 이들을 각각 Host Volume, Volume Container, Docker Volume이라 한다.
이러한 Volume들이 동작하는 원리는 파일을 특정 파일에 올리는 mount에 근거한다. 즉, Volume은 일종의 공유 공간이면서 일종의 파일로써 이용된다고 했는데, Volume으로써 이용하려는 공간이 그 공유 대상에 mount되면서 공유하려는 정보들이 Volume 내에 존재하게 되는 것이다. 따라서 Volume을 두게 되면 Container를 삭제하더라도 Volume은 삭제되지 않기 떄문에 정보들이 Persistency를 갖게 되는 것이다. 그리고 Container 내부에서 반드시 유지되어야 하는 정보들을 분리해냈기 때문에, Stateless하게 Container를 유지할 수 있는 것에 큰 의의가 있다.

1) Host Volume

docker run —name <container-name> -v <host-path>:<container-path> <image-name>
Host VolumeHost에 해당하는 공간을 Volume으로써 이용하는 것이다. Host에 해당하는 공간이라 함은 디렉토리 뿐만 아니라 특정 파일만을 대상으로 하는 것도 가능하다. 이는 Container를 생성하는 명령어 (run 혹은 create와 같은 명령어)를 이용할 때 -v 옵션을 이용함으로써 Volume을 둘 수 있고, Host에 해당하는 공간이 Container의 공유 대상에 mount 되면서 정보들을 공유하게 된다. 이런 -v 옵션은 1회만 사용할 수 있는 것이 아니라 여럿 이용할 수 있다. MySQLWordPress 연동에 대한 예제로 살펴보자.
위 그림은 MySQL 데몬을 돌리는 Container를 생성한 것이고, ~/host_volume/var/lib/mysql을 공유하도록 Volume을 설정하였다. Host~/host_volume이라는 공간이 존재하지 않으면 자동으로 생성하면서 Container/var/lib/mysql이라는 공간에 mount된다.
WordPress 데몬을 구동할 Container를 생성할 때 위에서 생성한 MySQL 데몬을 위한 Container와 연동하여 생성한다.
WordPressMySQL이 연동된 서비스가 정상적으로 구동되는 것을 확인할 수 있다.
Host~/host_volume에는 Container/var/lib/mysql에 존재하는 파일들이 그대로 남아 있는 것을 확인할 수 있다. 서비스 중인 MySQLDB들은 기본적으로 /var/lib/mysql에 정보들을 저장하기 때문에, 이러한 정보들이 그대로 ~/host_volume에 저장되는 것 역시 확인할 수 있다.
구동 중인 Container를 지우더라도 Volume으로 두었던 ~/host_volume은 삭제되지 않은 것을 볼 수 있다. 즉, DB에 저장되어 있던 정보들은 그대로 살아 있는 것이다. 이렇게 Persistency가 필요한 공간들을 Volume으로써 이용하면 Container가 삭제되더라도 중요한 정보들은 살아 있으므로 새롭게 Container를 생성할 때 이를 그대로 활용할 수 있게 된다.
Host~/host_volume 디렉토리는 Container/var/lib/mysql 디렉토리에 mount하여 사용되었기 때문에 두 디렉토리는 서로 동일한 디렉토리이고, 따라서 동기화 작업은 요구되지 않는다. 하지만 주의할 점이 있는데, Volume으로 이용할 공간이 mount되면 Container의 공간은 그대로 덮어씌워 지므로 기존에 존재하던 파일이 있으면 이는 사라진다. 예를 통해 살펴보자.
ubuntu 환경을 만들기 위해 해당 ImageContainer를 만들고 최상위 디렉토리에 test_dir이라는 디렉토리를 만들고 내부에 a, b, c, d라는 파일을 두었다. 그리고 이를 새로운 Image로 만들었다.
새롭게 만든 Image를 이용하여 새로운 Container를 만들고, 이에 대한 옵션으로 Host Volume을 주었더니 기존 Image에 두었던 /test_dir에 있던 파일들이 사라진 것을 확인할 수 있다. 이는 Host가 갖고 있는 ~/host_volume이라는 디렉토리를 /test_dir라는 디렉토리에 mount하면서 발생한 것이다. 따라서 Volume을 이용할 때 mount될 위치에 대해서 반드시 신경써야 한다.

2) Volume Container

docker run —name <container-name> —volumes-from <container-name> <image-name>
Volume Container라는 것은 Container가 이용하고 있는 Volume을 다른 Container에게 공유해줄 때를 의미한다. 따라서 공유 받는 ContainerHost의 공간을 직접적으로 공유 받아 Volume으로써 활용하는 것이 아니라 Volume ContainerHost의 공간을 공유 받아 Volume으로써 활용하고 있는 공간을 다시 공유 받아 이용하게 된다. 이는 공유 받을 Container를 생성할 때 —-volumes-from이라는 옵션을 이용하여 설정할 수 있다. Host Volume의 마지막 부분에 했던 container_mount라는 Container를 이용하여 예를 살펴보자.
container_mountHost~/host_volumeContainer/test_dirmount하여 Volume으로 이용했었다. 이를 Volume Container로 이용하여 Volume을 가진 새로운 Container를 만들었더니, ubuntuImage를 이용하여 Container를 생성했음에도 /test_dir이라는 디렉토리를 갖고 있는 것을 확인할 수 있다. 이는 container_mountVolume을 그대로 받았기 때문이다.
우선, Host~/host_volume은 빈 디렉토리인 것을 확인할 수 있다. container_mountVolume을 그대로 받았을 때, 새로 생성된 container_from_container라는 ContainerHost~/host_volume이라는 공간과 정상적으로 공유된 Volume인지 확인하기 위해 /test_dir에 파일 몇 개를 생성해보자.
위와 같이 파일을 5개 생성했을 때, mount 되어 있는 Host~/host_volume 역시 아래 그림처럼 5개의 파일이 새로 생성된 것을 확인할 수 있다.
위 과정을 그림으로 확인해보면 아래와 같은 구조임을 확인할 수 있다.
따라서 특정 ContainerVolume을 활용하고 있을 때 이처럼 —-volumes-from이라는 옵션을 사용하여 Container를 생성하면 여러 ContainerVolume을 공유할 수 있다. 이 점을 잘 활용하면 특정 Container를 말 그대로 Volume Container로써만 기능하도록 만들어 사용할 수 있다.

3) Docker Volume

docker run —name <container-name> -v <volume-name>:<container-path> <image-name>
Host Volume을 이용했던 것처럼 Host에 존재하는 특정 공간을 직접 지정하여 Volume을 이용하려 하면 그 공간이 어디에 있는지 늘 신경 써야한다는 단점이 있다. 물론 직접적으로 관리해야 할 만큼 중요한 공간이라면 괜찮겠지만, 그렇지 않은 많은 공간들을 관리하는 것은 쉬운 것이 아니다. 따라서 Volume을 활용할 때 반드시 Host내의 특정 공간을 지정하여 mount할 필요없이, Docker Engine의 도움을 받아 Host의 특정 공간에 임의의 디렉토리를 만들어 이를 Volume으로 활용수 있다. 이는 docker volume create와 같은 명령어로 수행할 수 있다. 생성된 Volume을 이용하여 Container를 만들면, 해당 ContainerVolume Container로 이용하는 것도 가능하므로 굉장히 유용하다. Docker Volume을 예제로 간단히 살펴보자.
Docker Volume을 이용하는 명령어는 글 아래 부분에서 더 자세히 다룬다.
위와 같은 명령어로 Docker Volume을 생성할 수 있고, 그 목록을 확인할 수 있다. 이렇게 생성된 Docker Volume은 로컬 상에 저장되고, Docker Engine에 의해 생성되고 삭제되는 식으로 관리된다.
새롭게 생성된 new_volume이라는 것을 이용하여 주어진 명령어를 통해 Docker Volume을 사용하여 2개의 Container를 생성하고 new_volume이 정상적으로 동작하는지 확인해보았다.
이와 같은 구조를 그림으로 나타내면 아래와 같다.
Host Volume에서 직접 지정하여 이용한 공간과 달리 Docker VolumeDocker EngineHost의 특정 공간에 임의의 이름으로 디렉토리를 만든다고 했는데, 이는 docker volume inspect라는 명령어를 통해 Host의 어느 공간에 Docker Volume이 생성되었는지 확인할 수 있다.
docker run -i -t --rm --privileged --pid=host justincormack/nsenter1
이를 실제로 확인하려 했을 때 현재 사용자의 경로에는 /var/lib/docker/volumes가 존재하지 않는 것을 볼 수 있는데, 그 이유는 DockerLinux 상에서 동작하는 것이 아니라 Linuxkit이라는 가상화된 Kernel 위에서 동작하기 때문이다. (Docker Toolbox를 이용한다면 Linuxkit이 아니라 별도로 설치한 Linux 상에서 확인할 수 있다.) 따라서 위와 같은 경로를 확인하기 위해선 Linuxkit 내부로 들어가는 것이 우선이다. Linuxkit 내부로 들어가는 방법은 여럿 있지만 간단하게 위에 주어진 명령어로 Container를 만들어 구동함으로써 Linuxkit에 대한 쉘을 실행할 수 있다. 주어진 경로를 타고 들어가보면 Docker Volume이 존재하는 것을 확인할 수 있다.

2. Docker Network

Container로 서비스를 배포하게 되면 외부 네트워크에서도 Container로 접근하여 서비스를 이용할수 있게 된다. Container는 가상화된 환경에서 구동되기 때문에 Private IP 주소를 사용하고 있음에도 외부에서 접근이 가능한데, 이는 Container를 생성할 때 별도의 포트 포워딩 설정을 했기 때문이다. 그렇다면 Container들은 IP 주소를 어떻게 유지하고 있으며, 해당 IP 주소들이 외부와 통신할 수 있도록 Docker가 어떤 네트워크 구조를 유지하고 있는지 알아보자.
우선 container_network_1이라는 Container를 하나 생성하여 ifconfig를 실행해보면 Container의 인터페이스 구조를 확인할 수 있다. 위 그림을 보면 container_network_1은 자기 자신을 의미하는 Loopback 인터페이스와 외부와의 통신을 위한 eth0라는 인터페이스를 갖고 있는 것을 확인할 수 있다. eth0 인터페이스에 할당된 IP 주소를 확인해보면 가장 처음에 할당된 2개의 Octet172.17인 것을 알 수 있고, 이는 B 클래스에 해당하는 Private IP 주소이다. 이와 같이 할당된 IP 주소는 현재 속한 네트워크의 내부에서만 사용할 수 있기 때문에 eth0 인터페이스를 이용하여 외부와 통신하기 위해선 다른 장치의 도움을 받아야 한다.
DockerLinuxkit이라는 가상화된 Kernel 위에서 동작하기 때문에 Linuxkit의 네트워크 설정을 통해서 여러 Containereth0 인터페이스들은 외부와 통신할 수 있게 된다. 일단 Container가 실행 상태에 들어서면, LinuxkitKernelveth (Virtual Ethernet)라는 네트워크 인터페이스를 생성 받아 Containereth0 인터페이스와 연결하게 된다. veth 인터페이스의 생성은 Docker Engine에 의해서 이뤄진다.
docker run -i -t --rm --privileged --pid=host justincormack/nsenter1
Container 실행과 동시에 생성된 veth 인터페이스를 확인하기 위해 Linuxkit 내부로 들어가서 확인할 필요가 있다. 위 명령어를 사용하면 Linuxkit 내부 상태를 확인할 수 있도록 별도의 Container를 만들고 쉘을 실행하게 된다. 이후 쉘에서 ifconfig 명령어를 입력하면 아래 그림과 같이 veth 인터페이스가 존재하는 것을 확인할 수 있다. veth 인터페이스가 2개인 이유는 container_network_1라는 Container와 현재 Linuxkit을 이용하기 위한 Container, 총 2개의 Container가 실행 중이기 때문이다. 즉, veth 인터페이스는 실행 중인 Container의 수만큼 존재하는 것이다.
Linuxkit의 쉘에서 ifconfig 명령어를 실행 했을 때, veth 인터페이스만 찾아내는 것이 아니라 모든 출력결과를 살펴보면 docker0라는 것을 찾을 수 있다. docker0Docker 데몬 실행 시에 자동으로 생성되는 가상화된 Bridge로써, 모든 veth 인터페이스들이 docker0에 바인드 되어있기 때문에 모든 veth 인터페이스들을 관리할 뿐만 아니라 외부 네트워크와 통신할 수 있는 Hosteth0와 연결해주는 역할을 한다. 즉, Container를 생성했을 때 별도의 네트워크 설정이 없다면, veth 인터페이스들은 모두 docker0라는 Bridge에 속하게 되므로 외부 네트워크와 통신을 하게 되면 무조건 docker0라는 Bridge를 거친다. 따라서 현재 Container들과 Host의 네트워크 구조는 아래 그림과 같다.
brctl show docker0
docker0는 실행 중인 Container들의 수만큼 veth 인터페이스를 유지하고 있다고 했는데, 실제로 veth 인터페이스가 docker0에 잘 바인드 되어 있는지 확인할 때는 위 명령어를 Linuxkit의 쉘에 입력하면 된다. 아래 그림을 살펴보면 실행 중인 2개의 Container에 대한 2개의 veth 인터페이스가 바인드 되어 있는 것을 확인할 수 있다.
이에 대해서 조금 더 자세히 확인해보기 위해 몇 개의 Container를 더 생성해보자. 재밌는 점은 생성된 Container들의 IP 주소를 확인해보면, 가장 처음에 할당된 3개의 Octet을 제하고는 모두 오름차순의 형태로 순서대로 할당된다는 것이다. 실제로 이는 BridgeIP 주소 대역 설정 값을 만족하도록 자동으로 할당된 값이며, IP 주소 대역 설정 값Docker 데몬의 옵션을 조정함으로써 설정할 수 있다.
그렇다면 Container를 생성했을 때 docker0 외의 선택지도 있을까? Docker Engine은 기본적으로 Container가 사용할 수 있는 Network DriverBridge, Host, None, Container라는 선택지를 제공하며, 외부 솔루션으로 사용할 수 있는 Network Driver도 다수 존재한다. docker0Bridge이므로 Container 생성 시의 기본 설정은 docker0라는 Bridge를 이용하도록 Bridge라는 Network Driver를 이용한다고 보면 된다. 이러한 설정은 Container 생성 시 사용자가 별도의 옵션을 주면 다른 Network Driver를 이용할 수도 있다. 혹은 동일한 종류의 Network Driver를 이용하더라도 다른 이름으로 네트워크를 생성하여 이용하면 Container들의 네트워크를 구조를 격리시키는 것도 가능하다. Container들이 이용하는 네트워크를 별도로 생성하지 않은 초기 상태에는 아래 그림과 같이 네트워크를 유지하고 있다.

1) Bridge

docker run —name <container-name> —net <network-name> <image-name>
Bridge라는 Network DriverDocker에서 가장 흔하게 이용되는 Network Driver이며, Container 생성 시 기본적으로 설정되는 네트워크 환경 역시 docker0라는 Bridge이다. 만약 사용자가 docker0라는 Bridge를 이용하지 않고 격리된 네트워크 환경을 사용하고 싶다면 새로운 Bridge를 만들어 이용할 수 있다. 운영에 필요한 만큼의 Bridge를 생성할 수 있으며, Bridge 내에 유지하고 있는 Container를 분리할 수도 있고 새로운 Container를 연결할 수도 있어서 운영 측면에서 유용하게 활용할 수 있다. 간단한 예를 살펴보자.
Docker Network를 이용하는 명령어는 글 아래 부분에서 더 자세히 다룬다.
위와 같은 명령어로 Docker Network를 생성할 수 있고, 그 목록을 확인할 수 있다. —-driver 옵션으로 생성하려는 Network Driver를 설정할 수 있는데, Bridge를 생성하고 싶다면 bridge라고 기입하면 된다. 결과적으로 초기 상태의 네트워크 구성에서 new_bridge가 추가된 것을 확인할 수 있다.
Container 생성 시 docker0라는 Bridge가 아닌, 새로 생성한 new_bridge를 이용하도록 제시된 명령어를 이용해보면 IP 주소docker0를 이용했을 때와 사뭇 다른 것을 확인할 수 있다. 이는 new_bridgeIP 주소 대역 설정 값을 따르기 때문이다. Bridge 생성 시에 별도로 BridgeIP 주소 대역 설정 값을 주지 않았다면 Docker Engine은 순서대로 IP 주소 대역 설정 값을 매기기 때문에 docker0172.17.x.x 대역 다음인 172.18.x.x 대역을 받게 되고, container_network는 해당 대역을 따르는 것을 확인할 수 있다.
Network Driver의 환경을 설정할 수 있는 옵션들은 다양한데, 대표적으로 쓰이는 옵션들은 위 그림에서 확인할 수 있다. Subnet, Gateway, IP 주소 대역 설정 값 등에 대해 기입할 수 있으며, Subnet에 기입한 값과 IP 주소 대역 설정 값에 기입한 값은 같은 범위에 있어야 네트워크가 성공적으로 생성된다.
이렇게 생성된 네트워크에는 Container를 분리해내거나 새롭게 연결할 수 있다고 했는데, 새로운 container_connection을 생성하여 알아보자. 별도의 Network Driver를 설정하지 않았기 때문에 container_connectiondocker0를 이용한다.
docker network disconnect <network-name> <container-name>
우선 new_bridge_with_setting에 연결되어 있는 container_network를 위 명령어를 통해 분리해보자. 주어진 명령어를 수행하고 난 뒤에 container_network에서 ifconfig 명령어를 이용해보면, eth0 인터페이스가 사라지고 Loopback 인터페이스만 남은 것을 확인할 수 있다.
docker network connect <network-name> <container-name>
이번에는 위 명령어를 이용하여 container_connectionnew_bridge_with_setting에 연결해보자. 주어진 명령어를 수행하고 난 뒤에 container_connection에서 ifconfig 명령어를 이용해보면, 이전에 유지하고 있던 인터페이스들에 new_bridge_with_setting에 해당하는 인터페이스가 추가된 것을 볼 수 있다.
네트워크에 대한 connectdisconnect 명령어를 이용할 때 주의할 점이 있는데, Network DriverHost 혹은 None으로 설정한 Container에 대해서는 명령어가 수행되지 않는다. 이에 대한 확인을 위해 간단히 container_test라는 Network DriverNone으로 이용하는 Container를 만들어보자.
Container가 성공적으로 생성되었다면, 네트워크에 대한 connect 명령어를 수행해보면 위 그림처럼 오류를 뱉으며 요청이 거절되는 것을 확인할 수 있다. 결과적으로 네트워크에 대한 connectdisconnect 명령어는 특정 IP 주소 대역을 가진 네트워크 환경을 이용하는 Container에 대해서만 수행할 수 있다. 이러한 네트워크 환경에는 Bridge 혹은 Overlay 같은 것이 있다.
Overlay 네트워크에 대해서는 소개하지 않으므로 아래 링크를 참고하자.
Bridge는 가장 기본적인 형태로도 운용되는 만큼 굉장히 다양한 것들을 시도해볼 수 있다.
Container를 생성할 때 네트워크에 대한 설정 중 하나로 —-net-alias라는 옵션을 사용할 수 있는데, 이를 통해 Container가 이용하는 네트워크에서 분별을 위한 별칭을 부여할 수 있다. 이는 일반 URIIP 주소Resolve하는 것과 비슷하게 Docker 내부적으로 유지 중인 DNS Resolver에 의해서 별칭에 대한 IP 주소를 풀어내게 된다. 이 때, 여러 Container를 하나의 Bridge에 두고 —-net-alias를 이용하여 해당 Container들을 모두 동일한 별칭으로 부여하게 되면 ping 명령어의 결과로 흥미로운 것을 확인할 수 있다.
혹은 MacVLAN이라고 하여 사용자가 이용 중인 네트워크 인터페이스 카드를 가상화하여 Container들에게 할당할 수 있다. 기존 Bridge는 가상 네트워크 상이었지만 MacVLAN을 이용하면 물리 네트워크 상에서 동작하게 되며, 물리 네트워크 상에서 Container들은 가상의 MAC 주소를 가지면서 동일 네트워크 상의 Container들과 통신할 수 있게 된다. 즉, 물리 네트워크 상에서 동작하는지 가상 네트워크 상에서 동작하는지만 다를 뿐 MacVLANBridge와 비슷한 역할을 한다. MacVLAN을 적용하기 위해선 적어도 네트워크 장비 1개가 필요하므로 간단한 실험을 하고 싶다면 공유기와 VM으로 진행할 수 있다. 주의할 점으로는 IP 주소 대역 설정 값이 다른 네트워크와 겹치지 않아야 한다는 것이고, 이 글에서는 진행하지 않기 때문에 직접 찾아보는 것을 권장한다.

2) Host

docker run —name <container-name> —net host <image-name>
ContainerNetwork DriverHost로 설정하게 되면, Host의 네트워크 환경을 그대로 이용할 수 있게 된다. 기존 Host의 네트워크 환경을 그대로 이용하기 때문에 Bridge처럼 별도의 네트워크 생성을 할 필요가 없다. Host라는 Network Driverhost라는 이름으로 유지되고 있기 때문에, Container 생성 시 —-net이라는 옵션을 이용하여 host라는 이름의 네트워크를 지정하 곧바로 Host의 네트워크 환경으로 설정된다. 따라서 기존의 ContainerPrivate IP 주소를 이용하고 있어서 외부와의 통신을 위해 포트 포워딩을 했던 것과 달리, 별도의 포트 포워딩이 없어도 외부에서 Container 내부의 서비스에 바로 접근할 수 있다.
현재 docker0라는 BridgeIP 주소 대역 설정 값172.17.x.x를 따르도록 되어 있는데, 위 그림처럼 Network DriverHost롤 이용했을 때는 Bridge 대역을 따르지 않고 eth0 인터페이스의 IP 주소192.168.65.6인 것을 볼 수 있다.
실제로 Host의 네트워크 환경을 그대로 이용한다면, HostIP 주소Container가 사용하는 IP 주소와 동일할텐데 Host 환경에서 ifconfig 명령어를 이용해보면 어디에서도 Container가 사용하고 있는 192.168.65.6이라는 주소를 찾아볼 수 없다.
docker run -i -t —rm —privileged —pid=host justincormack/nsenter1
이미 너무나도 익숙하겠지만, 위 명령어를 이용하여 Linuxkit 내부에서 쉘을 실행시키는 Container를 만들어 ifconfig 명령어를 이용해보면 아래 그림처럼 container_network가 이용하고 있던 192.168.65.6이라는 주소를 찾을 수 있다. 즉, Host의 네트워크 환경을 그대로 이용할 수 있다는 말은 Linuxkit의 네트워크 환경을 그대로 이용할 수 있다는 말이 된다. 이는 DockerLinux 환경에서 구동되기 때문인데, Host OSLinux로 두고 Docker를 이용한다면 별도의 가상화 환경을 구축할 필요가 없으므로 Host의 네트워크 환경과 Container의 네트워크 환경이 바로 일치하게 되지만 Windows 혹은 Mac OS X를 이용한다면 Docker 구동을 위해 가상의 Linux 환경을 구축하므로 ContainerLinuxkit의 네트워크 환경을 따르게 되는 것이다.

3) None

docker run —name <container-name> —net none <image-name>
Network DriverNone으로 쓴다는 말은 네트워크 통신을 하지 않겠다는 것을 의미한다. 따라서 이를 이용한 Container는 아래 그림과 같이 eth0 인터페이스가 없고 오로지 Loopback 인터페이스만 존재하는 것을 확인할 수 있다.

4) Container

docker run —name <container-name> —name container:<container-name> <image-name>
Network DriverContainer로 이용한다는 말은 네트워크의 환경 중 일부를 특정 Container가 이용하고 있는 설정 값으로 이용하겠다는 말이다. 위 명령어를 통해 Container를 생성하게 되면 <container-name>에 해당하는 IP 주소, MAC 주소 등을 그대로 이용하게 된다. 따라서 Container 실행 시 Docker Engine에 의한 docker0IP 주소 대역 설정 값에 해당하는 새로운 IP 주소 할당이 이뤄지지 않을 뿐 아니라 추가적인 veth 인터페이스 역시 생성되지 않는다.
위와 같이 설정된 네트워크 구조는 아래 그림과 같이 나타난다.

3. Volume Commands

1) Docker Volume 생성

docker volume create —name <volume-name>
Docker Engine이 지원하는 Docker Volume을 생성할 수 있다. —-name 옵션으로 <volume-name>을 지정하지 않으면 Container를 생성할 때처럼 임의로 16자리 이상의 HashingDigest 값을 <volume-name>으로 이용한다.

2) Docker Volume 목록 확인

docker volume ls
생성된 Docker Volume들의 목록을 확인할 수 있다.

3) Docker Volume 정보 확인

docker volume inspect <volume-name>
Docker Volume의 상세한 정보들을 확인할 수 있다.

4) Docker Volume 삭제

docker volume rm <volume-name>
현재 사용 중이지 않은 Docker Volume을 삭제할 수 있다.
위 그림처럼 현재 사용 중인 Docker Volume에 대해 명령어를 이용하면 하면 오류를 뱉으며 요청이 거절되는 것을 확인할 수 있다. 이는 강제 삭제 옵션인 -f를 이용해도 아래 그림처럼 현재 사용 중인 Docker Volume에 대해선 요청이 거절 된다.

5) 사용 중이지 않은 Docker Volume 삭제

docker volume prune
현재 사용하고 있지 않은 모든 Docker Volume을 한 번에 삭제하는 명령어이다.

4. Network Commands

1) Network 생성

docker network create —driver <driver-name> <network-name>
새로운 네트워크를 생성할 수 있다. —-driver 옵션을 생략하면 네트워크를 Bridge로 생성하게 된다.

2) Network 목록 확인

docker network ls
기본적으로 지원하는 네트워크 및 사용자에 의해 생성된 네트워크들의 목록을 확인할 수 있다.

3) Network 연결

docker network connect <network-name> <container-name>
Container를 네트워크에 연결한다. 특정 IP 주소 대역을 가진 네트워크 환경을 이용하는 Container에 대해서만 수행할 수 있다.

4) Network 연결 해제

docker network disconnect <network-name> <container-name>
Container를 네트워크에서 연결 해제한다. 특정 IP 주소 대역을 가진 네트워크 환경을 이용하는 Container에 대해서만 수행할 수 있다.

5) Network 정보 확인

docker network inspect <network-name>
네트워크에 대한 상세한 정보들을 확인할 수 있다.

6) Network 삭제

docker network rm <network-name>
현재 사용하고 있지 않은 네트워크를 삭제할 수 있다.
위 그림처럼 현재 사용 중인 네트워크에 대해 명령어를 이용하면 오류를 뱉으며 요청이 거절되는 것을 확인할 수 있다. 네트워크의 삭제 명령어에는 강제 삭제 옵션인 -f가 없기 때문에, 네트워크를 정상적으로 삭제하려면 이를 이용하는 Container가 없어야 한다.

7) 사용 중이지 않은 Docker Network 삭제

docker network prune
현재 사용하고 있지 않은 모든 Docker Network를 한 번에 삭제하는 명령어이다.

5. Reference