Develop!/Docker,Kubernetes

도커 엔진(Docker Engine) - 2

체리필터 2022. 1. 25. 09:11
반응형

2022.01.17 - [Develop!/Docker,Kubernetes] - 도커 엔진 - 1 에 이어 계속 정리 한다.

아래의 책을 읽으면서 알게 된 내용을 정리한다.

http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9791158392291&orderClick=LAG&Kc= 

 

시작하세요! 도커/쿠버네티스 - 교보문고

친절한 설명으로 쉽게 이해하는 컨테이너 관리 | ★ 이 책의 구성 ★◎ 도커의 기본 사용 방법을 익힘으로써 컨테이너의 기본 개념을 학습합니다. (1부 1장, 1부 2장)◎ 도커 스웜 모드를 통해 서

www.kyobobook.co.kr

도커 볼륨

도커 이미지를 컨테이너로 생성하면 이미지는 읽기 전용이 되며, 컨테이너의 변경 사항은 별도로 저장한다. 이 때 컨테이너를 삭제 하게 되면 변경된 저장 사항이 삭제 되게 되므로 컨테이너의 변경 사항을 영속적으로 저장하는 방법이 필요하다.

이 때 사용할 수 있는 가장 쉬운 방법이 볼륨이다. 볼륨을 사용하는 방법은 호스트와 공유하는 방법, 볼륨 컨테이너, 도커가 관리하는 볼륨 이렇게 3가지이다.

호스트 보륨 공유

#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

wordpressdb_hostvolume 이라는 컨테이너를 실행할 때 -v /home/wordpress_db:/var/lib/mysql 이란 옵션을 주었다.

이는 호스트에 있는 "/home/wordpress_db"라는 디렉토리를 컨테이너 안에 있는 "/var/lib/mysql"과 공유 한다는 뜻이다.

즉 "[호스트의 공유 디렉토리]:[컨테이너의 공유 디렉토리]" 형태로 적으면 된다. 이 때 두 디렉토리는 서로 다른 공간에서 데이터를 Sync 하는 것이 아니라 실제로 같은 디렉토리이다.

이렇게 같은 디렉토리가 될 수 있는 것은 호스트의 디렉토리를 컨테이너의 디렉토리에 '마운트' 시키기 때문이다. 따라서 컨테이너에 해당 디렉토리가 있을 경우 컨테이너의 디렉토리가 아니라 호스트의 디렉토리 안에 있는 내용이 사용되어진다.

-v 옵션은 여러번 사용할 수 있으며, 디렉토리 뿐 아니라 파일 단위까지 공유가 가능하다.

볼륨 컨테이너

두 번째 방법은 --volumes-from 옵션을 사용하는 것이다. 첫 번째 방법에서 사용한 호스트 볼륨을 공유한 컨테이너로부터 볼륨을 공유 받는 것이다.

#docker run -i -t \
--name volumes_from_container \
--volumes-from volume_overide \
ubuntu:14.04

위 처럼 하게 된다면 volume_overide라는 컨테이너, 즉 호스트로부터 볼륨을 공유받은 컨테이너로부터 볼륨을 공유 받아 volumes_from_container 라는 컨테이너를 실행 시키는 것이다.

도커 볼륨

도커 자체의 볼륨 기능을 사용하는 방법이다.

#docker volume create --name myvolume
#docker volume ls
DRIVER    VOLUME NAME
local         myvolume

docker volume create라는 명령어를 사용하여 볼륨을 생성할 수 있다. 위의 예제는 local 스토리지에 생성된 경우이다.

생성된 볼륨을 사용하기 위해서는 -v 옵션에 다음과 같이 주면 된다.

[볼륨의 이름]:[컨테이너의 공유 디렉토리]

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

이렇게 만들면 도커에 의해 생성된 myvolume이 컨테이너의 /root 아래 생성되게 된다. 해당 볼륨안에 파일을 작성한 후 다른 컨테이너에서 볼륨을 마운트 시키게 되면 이미 파일이 존재하는 것을 확인해 볼 수 있다.

도커 볼륨은 도커 엔진이 관리하며 호스트에 저장 되지만, 호스트 볼륨 공유와 달리 유저가 어디에 저장되는지 알 필요가 없게 된다. 하지만 어디에 저장되는지 알고 싶다면 inspect 명령어를 통해 확인해 볼 수 있다. type 옵션에는 image, volume 등을 사용할 수 있다.

#docker inspect --type volumne myvolume

docker volume create 명령어를 쓰지 않고 -v 옵션을 사용하면 임의의 이름으로 만들어진 볼륨이 자동으로 마운트 되어진다.

#docker run -i -t --name volume_auto \
-v /root \
ubuntu:14.04

위와 같이 하게 되면 컨터이너의 /root 디렉토리 안에 임의의 무작위로 만들어진 디렉토리가 만들어지고 해당 디렉토리에 컨테이너의 볼륨이 마운트 된다. "docker volume ls" 명령 또는 "docker container inspect 컨테이너명" 식으로 명령을 내려보면 해당 볼륨을 볼 수 있다.

volume을 관리하는데 있어서 컨테이너가 가지고 있지 않고 외부에 저장하고 관리하게 되므로 인해 컨테이너가 삭제 되어도 다시 기존 상태를 복구할 수 있게 되는 것은 바람직한 현상이다.

반대로 컨테이너 안에 데이터를 가지고 있게 된다면 해당 컨테이너가 삭제 될 경우 그동안 변경된 값이 같이 삭제 되게 되므로 위험한 구조라 볼 수 있다.

-v 옵션 대신에 --mount 옵션을 쓸 수 있다.

#docker run -i -t --name mount_option_1 \
--mount type=volume, source=myvolume, target=/root \
ubuntu:14.04

volume이 아니라 호스트의 디렉토리를 마운트 할 경우에는 type을 bind로 주면 된다.

#docker run -i -t --name mount_option_2 \
--mount type=bind, source=/home/wordpress_db, target=/home/testdir \
ubuntu:14.04

도커 네트워크

linux에서 ifconfig를 하게 되면 물리적인 네트워크를 담당하는 eth 인터페이스가 보인다. 컨테이너에도 각각 eth가 있으며 이를 호스트와 연결시켜서 외부와 네트워크가 연결 되도록 하는 것이 veth 이다.

컨테이너가 올라간 상태에서 ifconfig를 하게 될 경우 veth가 생성되어 있음을 볼 수 있다. 그리고 docker0라는 브릿지도 존재하는데 veth 인터페이스와 바인딩 되어 호스트의 eth0와 연결시켜 주는 역할을 하게 된다.

다음과 같은 명령어로 docker0에 veth가 연결되어 있는지를 확인할 수 있다.

#brctl show docker0

도커의 네트워크를 다루는 명령어는 docker network 로 시작한다.

$ sudo docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
99cab8ec277c   bridge    bridge    local
4da8af569c59   host      host      local
3a897239748e   none      null      local

bridge 네트워크가 있음을 볼 수 있다. 해당 네트워크의 자세한 내용을 보기 위해서 inpect 명령어를 사용할 수 있다.

$ sudo docker network inspect bridge
[
    {
        "Name": "bridge",
        
        .
        .
        .
        
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        
        .
        .
        .
}
]

Config Subnet에 보면 172.17.0.0/16으로 시작하는 것을 볼 수 있다. bridge network를 사용중인 컨테이너는 Containers 에 있는데 위에는 연결된 컨테이너가 하나도 없음을 보여주고 있다.

브리지 네트워크

docker0가 아닌 사용자 정의 네트워크 브릿지를 생성할 수 있다.

[irteamsu@bkoh001-tl-spd1-jp2v-dev ~]$ sudo docker network create --driver bridge mybridge
86f568996a7d43cfadc79b174758716594319256174bd2badcd076abb46982ba
[irteamsu@bkoh001-tl-spd1-jp2v-dev ~]$ 
[irteamsu@bkoh001-tl-spd1-jp2v-dev ~]$ sudo docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
99cab8ec277c   bridge     bridge    local
4da8af569c59   host       host      local
86f568996a7d   mybridge   bridge    local
3a897239748e   none       null      local

create 명령어를 사용해서 생성했더니 mybridge란 네트워크가 생성 되었다. 컨테이너 실행 시 --net 명령어를 사용해 브릿지 이름을 주게 되면 해당 네트워크 브릿지를 사용하게 된다.

#docker run -i -t --name mynetwork_container \
--net mybridge \
ubuntu:14.04

생성된 사용자 정의 네트워크는 network connect, disconnect 명령어를 사용해서 연결을 맺거나 끊을 수 있다.

#docker network disconnect mybridge mynetwork_container
#docker network connect mybridge mynetwork_container

네트워크의 서브넷, 게이트웨이, ip 할당 범위 등을 설정 하려면 아래와 같이 하면 된다.

#docker network create --driver=bridge \
--subnet=172.72.0.0/16 \
--ip-range=172.72.0.0/24 \
--gateway=172.72.0.1 \
my_custom_network

호스트 네트워크

네트워크를 호스트로 설정하면 호스트의 네트워크 환경을 그대로 쓸 수 있다.

#docker run -i -t --name network_host \
--net host \
ubuntu:14.04

논 네트워크

none network는 네트워크를 사용하지 않는다는 의미이다.

#docker run -i -t --name network_none \
--net none \
ubuntu:14.04

이렇게 되면 컨테이너 안에서 ifconfig를 실행하게 되면 로컬 호스트를 나타내는 lo 외에는 네트워크 인터페이스가 없는 것을 볼 수 있다.

컨테이너 네트워크

--net 옵션에 container를 입력하면 다른 컨테이너의 속성을 이용할 수 있다.

사용은 --net container:[containerID] 와 같이 쓰면 된다.

#docker run -i -t --name network_container_1 ubuntu:14.04
#docker run -i -t --name network_container_2 \
--net container:network_container_1 \
ubuntu:14.04

위와 같이 하게 되면 network_container_2는 network_container_1의 네트워크를 그대로 사용하게 된다.

브리지 네트워크와 --net-alias

브리지 네트워크와 run 명령의의 --net-alias 명령어를 같이 쓰면 특정 호스트 이름으로 컨테이너 여러개에 접근할 수 있다.

#docker run -i -t -d --name network_alias_container1 \
--net mybridge \
--net-alias alicek106 ubuntu:14.04

#docker run -i -t -d --name network_alias_container2 \
--net mybridge \
--net-alias alicek106 ubuntu:14.04

#docker run -i -t -d --name network_alias_container3 \
--net mybridge \
--net-alias alicek106 ubuntu:14.04

위와 같이 mybridge라는 브리지 네트워크에 alicek106 이라는 alias를 걸어 주게 되면 세개의 컨테이너가 alicek106 이란 이름으로 사용되게 된다. (물론 각각의 아이피는 다르다)

이 상태에서 특정 컨테이너를 만들어 들어간 다음, alicek106으로 ping을 날려 보면 3개의 ip가 돌아가면서 ping이 되는 것을 볼 수 있다.

이것은 round-robin 방식으로 호출하게 되기 때문이다. (도커 엔진에 내장된 DNS를 사용)

사용 된 도커의 내장 DNS의 아이피는 127.0.0.11 이다.

 

 

반응형

'Develop! > Docker,Kubernetes' 카테고리의 다른 글

도커 엔진(Docker Engine) - 2  (0) 2022.01.25
도커 엔진(Docker Engine) - 1  (0) 2022.01.17