[Docker] 2. 볼륨, 네트워크

Jk Lim·2023년 7월 3일
0

MLOps 부트캠프

목록 보기
32/34
post-thumbnail

1. 볼륨

  • 컨테이너 서비스가 종료되면 컨테이너에 저장된 데이터는 다 사라진다.
  • 도커에서는 호스트 PC에서 데이터 저장소를 관리하고 연결하는 방법을 사용할 수 있다.
  • 도커에서는 bind mount와 volume, 두가지 방식이 있다.

    참고

    • 컨테이너 서비스의 환경설정 파일은 보통 호스트에서 일괄 관리한다.
      • 관리 방법은 볼륨을 만들어서 연결 하는 방식
      • 볼륨이 없는 상태에서 컨테이너 run 및 -v 옵션 적용 시, 볼륨이 새로 생성됨
      • 컨테이너에서 설정 변경이 필요한 디렉토리를 볼륨으로 지정하고 생성하는 것이 일반적임
      • 볼륨이 생성되면 호스트와 컨테이너 어디서 수정하던 그 내용이 반영됨
      • 컨테이너를 삭제해도 볼륨은 그대로 남아있음. (-v 옵션으로 같이 삭제 가능.)
      • 만약 컨테이너 생성하면서 볼륨을 지정할 때, 호스트 디렉토리에 파일이 있으면(기존 볼륨을 사용하거나) 그 파일은 연결된 컨테이너 디렉토리로 복사된다.
      • 여러 서비스를 동일한 환경에서 사용할 때는 하나의 볼륨을 사용해서 설정파일을 공유할 수 있다.

(1) bind mount

  • 호스트의 디렉토리와 컨테이너의 디렉토리를 동기화 (어디서 작업하던 동기화됨)
  • -v 옵션으로 마운팅 포인트 설정
  • 컨테이너를 실행할 때, bind mount 연결 설정
  • 이미 실행중인 컨테이너에는 bind mount 연결을 할 수 없다.
  • bind mount는 도커에 의해서 관리되지 않지만 inspect로 디렉토리 확인은 가능하다.
  • 컨테이너를 지워도 동기화 된 디렉토리와 파일은 지워지지 않음.
# 호스트 PC
mkdir bm1
touch bm1/filea.txt
docker run -itd --name os3 -v ~/bm1:/tmp/mount centos:latest # 컨테이너 생성, bind 연결
docker attach os3
# os3 컨테이너
ls -l tmp/mount/filea.txt 
-rw-r--r-- 1 root root 0 Jun 27 02:53 tmp/mount/filea.txt
# 호스트 PC
docker inspect os3
...
"HostConfig": {
            "Binds": [
                "/root/bm1:/tmp/mount"
            ],

(2) volume

  • 도커에서 volume이라는 오브젝트를 생성하고 컨테이너의 디렉토리와 연결하는 방식
  • /var/lib/docker/volume/<볼륨명> 디렉토리에 생성된다.
  • -v 옵션으로 볼륨을 생성할 수 있으며, 기존에 없는 볼륨을 지정시 자동으로 생성해 준다.
docker volume create vol1
vol1

docker volume ls
DRIVER    VOLUME NAME
local     22b20f0808547df6c3d4bf1f741eb5a3644961ac2554de0f1d0785ea3e868b24
local     1487a532cbc3dea5fdbdb151985d9023b00f8996f2a235bb2ef8bd6940a0b5be
local     vol1

docker inspect vol1
[
    {
        "CreatedAt": "2023-06-27T12:08:33+09:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/vol1/_data", # 볼륨 디렉토리
        "Name": "vol1",
        "Options": null,
        "Scope": "local"
    }
]

# 만든 볼륨과 컨테이너를 연결
docker run -itd --name os4 -v vol1:/tmp/volume centos:latest
833a2d22773d8b4f4cb0d4411a78a1a893951ec203389e7f26abab9b055501c3
# 아직 없는 볼륨도 컨테이너를 생성하면서 만들고 연결할 수 있다.
docker run -itd --name os5 -v vol2:/tmp/volume centos:latest
f58aa7aae43ef69b5b3e6414cbbcd11c7f255b181a1c89bde6851e35e634a74c

# 컨테이너에 연결된 볼륨에 대한 정보 확인
docker inspect os4
...
"Mounts": [
            {
                "Type": "volume",
                "Name": "vol1",
                "Source": "/var/lib/docker/volumes/vol1/_data",
                "Destination": "/tmp/volume",
                "Driver": "local",
                "Mode": "z",
                "RW": true,
                "Propagation": ""
            }
        ],
...

# 볼륨 지우기
docker stop os5
docker rm os5
docker volume rm vol2 # 볼륨을 사용중인 컨테이너를 종료해야 함.

(3) 볼륨 삭제

  • docker volume rm <볼륨이름> : 볼륨 삭제
  • docker rm -v <컨테이너이름> : 컨테이너 + 볼륨 함께 삭제
  • docker volume prune : 컨테이너가 사용중인 볼륨 말고 모든 볼륨 지우기
  • docker rm -f $(docker ps -qa) : 모든 컨테이너 삭제

2. 네트워크

  • 도커에서는 기본적으로 3개의 다른기능을 하는 네트워크 드라이버가 있다.
docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
99fb034daf6a   bridge    bridge    local
ca0527e4ee2b   host      host      local
4b26268f658d   none      null      local

(1) bridge

  • 컨테이너가 사용하는 프라이빗 네트워크.
  • 컨테이너 환경에서 기본적으로 사용하는 네트워크 방식.
  • 포트포워딩을 사용해야 외부에서 접근이 가능하다.
# 해당 네트워크 object의 설정을 확인 할 수 있다.
docker inspect bridge
...
"Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",  # ip 대역
                    "Gateway": "172.17.0.1"
                }
            ]
        },
...
"Containers": {   # 해당 네트워크 드라이버를 사용하는 컨테이너를 확인 할 수 있다.
            "385610a0c9740b66c2a4a700fae45fc02281ee1554638e94e4a134fac53cf37a": {
                "Name": "os3",
                "EndpointID": "5c2bc76d44e6694b421af1703ffdaa6f79871337f55d9a363d0e7fe3fa0cbc35",
                "MacAddress": "02:42:ac:11:00:05",
                "IPv4Address": "172.17.0.5/16",
                "IPv6Address": ""
            },
            "65fef2c34aaf88b9e2cbbf25abc742dcbff5edf438e29af9f28c94e13b52379c": {
                "Name": "db2",
                "EndpointID": "144a0c2ce0a245aa7c694ee65ef8827f3bdfa6a8cf97809512b33ab1ae946b12",
                "MacAddress": "02:42:ac:11:00:04",
                "IPv4Address": "172.17.0.4/16",
                "IPv6Address": ""
            },
  • bridge 네트워크 드라이버 만들기
docker network create --subnet 192.168.100.0/24 --gateway 192.168.100.254 net1
ae8332dceb7074751d937912aef10428287dde40c17f085520ed29f747c74b28

docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
99fb034daf6a   bridge    bridge    local
ca0527e4ee2b   host      host      local
ae8332dceb70   net1      bridge    local  # 새로 생성된 브릿지 네트워크
4b26268f658d   none      null      local

# 컨테이너 생성 시, 네트워크 드라이버 지정
docker run -itd --name os5 --network net1 centos:latest

(2) host

  • 호스트의 네트워크 정보를 그대로 따르는 네트워크 인터페이스
# 호스트 환경
# localhost에서 80포트로 실행되는 서비스가 없는 상태
curl localhost
curl: (7) Failed connect to localhost:80; 연결이 거부됨

# host네트워크 정보를 따르는 httpd 컨테이너 생성
docker run -d --name web4 --network host httpd:latest
3ea122526ef4e627518cbc0060d2939551a9bf17bb2458866548d5dcd3c54174

# localhost를 호출해서 웹페이지 출력되는 것 확인
curl localhost
<html><body><h1>It works!</h1></body></html>

(3) macvlan

  • 컨테이너가 호스트 처럼 MAC주소와 IP 대역을 할당 받는 기능
  • promiscuous 모드 : 모든 패킷을 받아들이는 설정 (기본적으로 네트워크 인터페이스는 자신에게 전송된 패킷만 받아들임)
  • -d : 네트워크의 드라이버 형태를 지정하는 옵션. 미입력 시 bridge로 자동 생성
ip link set enp0s8 promisc on # promiscuous 모드를 활성화
# 네트워크 드라이브 생성
docker network create -d macvlan --subnet=192.168.56.0/24 --gateway=192.168.56.1 --ip-range=192.168.56.64/26 -o parent=enp0s8 macvlan1
# macvlan1 드라이브로 컨테이너 생성
docker run -itd --name os6 --network macvlan1 centos:latest
docker run -itd --name os7 --network macvlan1 centos:latest
# 각각의 컨테이너 ip 주소 확인
docker inspect os6 | grep IPA
            "SecondaryIPAddresses": null,
            "IPAddress": "",
                    "IPAMConfig": null,
                    "IPAddress": "192.168.56.64",
docker inspect os7 | grep IPA
            "SecondaryIPAddresses": null,
            "IPAddress": "",
                    "IPAMConfig": null,
                    "IPAddress": "192.168.56.65",
# 퀴즈1
# www1 컨테이너 생성
# curl ip -> "docker cp test" 메시지가 출력되게
# docker cp를 이용할 것

# 퀴즈2
# www2 컨테이너 생성
# curl ip -> "docker bind mount test" 메시지가 출력되게
# docker bind mount를 이용할 것

# 퀴즈3
# www3 컨테이너 생성
# curl ip -> "docker volume test" 메시지가 출력되게
# docker volume을 이용할 것

(4) 포트포워딩

  • 호스트의 포트와 도커 컨테이너의 포트를 연결시켜 애플리케이션을 실행하는 기능
  • 외부에서 컨테이너 애플리케이션에 접속하는 방법
  • -p <호스트포트>:<컨테이너포트>
  • 포트포워딩을 하면 도커가 알아서 방화벽을 열어준다.
# 포트포워딩 컨테이너 생성
docker run -d --name web5 -p 8080:80 httpd:lastest
docker inspect web5 | grep IPA
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.10",
                    "IPAMConfig": null,
                    "IPAddress": "172.17.0.10",

curl 172.17.0.10:80
<html><body><h1>It works!</h1></body></html>
curl localhost:8080
<html><body><h1>It works!</h1></body></html>

# PORTS 값 확인
docker ps
CONTAINER ID   IMAGE           COMMAND                   CREATED             STATUS             PORTS                                   NAMES
9e28bdd4da69   httpd:latest    "httpd-foreground"        54 seconds ago      Up 53 seconds      0.0.0.0:8080->80/tcp, :::8080->80/tcp   web5
  • 컨테이너 간에 별칭으로 통신할 수 있는 기능
  • link 옵션을 사용하면 컨테이너 운영체제의 /etc/hosts 에 자동으로 기입되는 원리
docker run -itd --name os6 --link web3 centos:centos7 # [호스트] 컨테이너 생성(+링크옵션)
cat /etc/hosts # [컨테이너] hosts에 자동으로 기입됨.
127.0.0.1	localhost
...
172.17.0.2	web3 eca10aa21c32
172.17.0.3	3b887340c5d0
docker run -itd --name os7 --link web3:apache centos:centos7 # [호스트] 여러개를 입력
ping web3 # [컨테이너]
ping apache # web3과 똑같은 컨테이너로 신호가 보내짐

0개의 댓글