지난 시간에 dockerfile의 volume에 대한 간단한 설명을 끝으로 포스팅을 마무리했다.
이번 포스팅에서는 dockerfile의 volume, wordir, 디스크공간의 개념
그리고 네트워크에 대한 개념을 다뤄보겠다.
Docker volume 학습하기
1. docker container volume과 바운드 마운트 개념
- 도커 컨테이너에 사용자가 생성한 데이터는 컨테이너가 삭제될 때 함께 삭제된다.
- 도커는 컨테이너 안의 파일 변경 사항을 UnionFS을 통해 관리한다.
- UnionFS은 read-only 이미지 layer와 write 컨테이너 layer를 합쳐 컨테이너의 데이터를 관리하고, 컨테이너 삭제 시 write layer도 삭제된다.
- 도커에서 실행하는 애플리케이션이 컨테이너의 생명 주기와 관계없이 데이터를 연속적으로 호스트 서버에 저장할 수 있도록 하기 위해 도커 볼륨과 바인드 마운트를 제공한다.
*docker volume 명령어
docker volume create : 볼륨 생성
docker volume ls : 볼륨 확인
docker volume inspect : 볼륨 상세 정보를 확인
docker volume prune : 컨테이너에서 사용하지 않는 볼륨 모두 삭제하기
docker volume rm : 볼륨 삭제
(1). 볼륨관리
1. 컨테이너의 데이터를 호스트 서버에 저장 유지할 때 사용
2. docker run -v <컨테이너 디렉터리>이 호스트 서버 디렉터리 /var/lib/docker/volumes/에 자동 생성될 경우 이름이 docker에서 자동으로 생성한 hash값을 사용한다. 이름이 어려워 호스트 서버에 자동 생성된 볼륨을 찾기 힘들기 때문에 추천하지 않는다.
3. 명령라인(CLI)에서 docker volume create 명령어를 사용해 이름을 지정하여 관리하기 편하게 한다.
볼륨을 사용하려면 docker run -v <호스트 디렉터리>:<컨테이너의 볼륨 디렉터리>명령어를 사용한다.
실습1 : 바운드 마운트 docker run -v <호스트 디렉터리>:<컨테이너 볼륨디렉터리>
예시 명령문: docker run -it -v /vol1:/lab -name testcon1 ubuntu:14.04 /bin/bash
실습 설명
1. 호스트 서버의 특정 디렉토리와 연결하기 때문에 Volume의 위치를 사용자가 지정하므로 데이터를 관리하기 편하다.
* 특정 디렉토리를 만들지 않으면 호스트 서버 /var/lib/docker/volumes에 hash값을 가지는 디렉토리가 생성되고, _data 디렉토리 안에 컨테이너의 /lab 디렉토리가 자동 마운트 된다.
2. 호스트 서버의 /vol1디렉토리를 컨테이너의 /lab디렉토리로 사용할 수 있도록 연결된다.
3. 호스트 서버에서 /vol1 디렉토리에 파일을 생성하면, 컨테이너에서도 같은 데이터를 사용한다.
4. 양쪽 모두 같은 데이터를 접근하는 것이다.
5. 도커가 관리하지 않는 호스트 서버의 단순 디렉토리 마운트 (바인드마운트)
실습 구성도
실습 (2개의 터미널이 필요하다.)
- 첫번째 터미널에서 작업
[root@cent1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 14.04 13b66b487594 12 months ago 197MB
[root@cent1 ~]# docker run -it -v /vol1:/lab --name testcon1 ubuntu:14.04 /bin/bash
root@96d250243a85:/# cd /lab
root@96d250243a85:/lab# ls
root@96d250243a85:/lab# touch testfile1 testfile2
root@96d250243a85:/lab# ls
testfile1 testfile2
- 두번째 터미널에서 작업
[root@cent1 ~]# ls /vol1 #파일이 확인이 된다!
testfile1 testfile2
[root@cent1 ~]# docker volume ls
DRIVER VOLUME NAME
* 볼륨 리스트를 불러올 수 없다!!! 이유는 호스트 서버에서 docker가 관리하는 볼륨이 아니기 때문이다. 일반 디렉토리 vol1을 마운트하는 바인드 마운트 방식으로 서로 볼륨을 공유하고 있다.
[root@cent1 ~]# docker inspect testcon1 #inspect 컨테이너를 실행하고 중간에 "Mounts"부분을 찾아보자
"Mounts": [
{
"Type": "bind",
"Source": "/vol1",
"Destination": "/lab",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
*실습이 끝났으면 컨테이너를 지우고 호스트서버의 vol1 을 삭제해준다 .
[root@cent1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
96d250243a85 ubuntu:14.04 "/bin/bash" 10 minutes ago Up 10 minutes testcon1
[root@cent1 ~]# docker rm -f testcon1
testcon1
[root@cent1 ~]# ls /vol1
testfile1 testfile2
[root@cent1 ~]# rm -rf /vol1
실습2 : docker volume 사용
실습 설명
1. 도커가 관리하는 볼륨으로 생성 및 관리해보자
2. docker volume 명령어를 사용한다.
실습구성도
실습 (두개의 터미널이 필요하다.)
- 첫번째 터미널에서 작업
[root@cent1 ~]# docker volume create codemonkyu-vol
codemonkyu-vol
[root@cent1 ~]# docker volume ls # 만들어진 볼륨확인
DRIVER VOLUME NAME
local codemonkyu-vol
[root@cent1 ~]# docker volume inspect codemonkyu-vol #볼륨 마운트포인트확인
[
{
"CreatedAt": "2022-04-02T18:32:41+09:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/codemonkyu-vol/_data",
"Name": "codemonkyu-vol",
"Options": {},
"Scope": "local"
}
]
[root@cent1 ~]# ls -l /var/lib/docker/volumes/codemonkyu-vol/_data
합계 0
[root@cent1 ~]# docker run -it -v codemonkyu-vol:/lab --name testcon1 ubuntu:14.04 /bin/bash root@02f3bee6c99c:/# cd /lab
root@02f3bee6c99c:/lab# ls
root@02f3bee6c99c:/lab# touch testfile1
root@02f3bee6c99c:/lab# mkdir -p /lab/firstdir/seconddir
- 2번째 터미널에서 작업
[root@cent1 ~]# docker volume inspect codemonkyu-vol
[
{
"CreatedAt": "2022-04-02T18:41:17+09:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/codemonkyu-vol/_data",
"Name": "codemonkyu-vol",
"Options": {},
"Scope": "local"
}
]
[root@cent1 ~]# cd /var/lib/docker/volumes/codemonkyu-vol/_data
[root@cent1 _data]# ls #첫번째 터미널에서 만든 폴더와 파일 확인가능
firstdir testfile1
[root@cent1 _data]# ls -l
합계 0
drwxr-xr-x 3 root root 23 4월 2 18:41 firstdir
-rw-r--r-- 1 root root 0 4월 2 18:40 testfile1
[root@cent1 _data]# rm testfile1 # 파일을 삭제하고 뭔가 변경사항을 만들어준다.
rm: remove 일반 빈 파일 `testfile1'? y
[root@cent1 _data]# mkdir testdir1 #여러 폴더와 파일을 생성한다.
[root@cent1 _data]# touch codemonkyufile
[root@cent1 _data]# ls
codemonkyufile firstdir testdir1
- 다시 첫번째 터미널로 온다.
root@02f3bee6c99c:/lab# ls # 확인해보면 볼륨이 잘 공유되고 있다는 것을 알 수 있다.
codemonkyufile firstdir testdir1
볼륨 삭제하기
- 컨테이너가 해당 볼륨과 마운트된 상태일 때무는 삭제할 수 없다. 마운트된 컨테이너를 제거하고 볼륨을 제거해야 한다.
[root@cent1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
02f3bee6c99c ubuntu:14.04 "/bin/bash" 13 minutes ago Exited (0) 3 minute s ago testcon1
[root@cent1 ~]# docker rm testcon1 # 컨테이너 삭제
testcon1
[root@cent1 ~]# docker volume ls
DRIVER VOLUME NAME
local codemonkyu-vol
[root@cent1 ~]# docker volume rm codemonkyu-vol # 볼륨삭제
codemonkyu-vol
[root@cent1 ~]# docker volume ls
DRIVER VOLUME NAME
---------------------------------------------------------------------------------------------------------------------------
[root@cent1 ~]# docker volume prune # 컨테이너에서 사용하지 않는 모든 볼륨 삭제
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
결과
1. 컨테이너에서 생성한 파일을 호스트에서 보고 사용 가능하다.
2. 여러 개의 컨테이너가 하나의 볼륨에 접근할 수 있기 때문에 컨테이너 간 데이터 공유가 가능하다.
3. 볼륨에 데이터를 저장해두고, 여러 컨테이너에 마운트만 해주면 해당 데이터를 모든 컨테이너에서 접근할 수 있다.
볼륨과 바인드 마운트의 차이점 정리
1. 도커가 마운트 포인트(디렉토리)를 관리하는지 하지 않는지 차이가 있다.
2. 볼륨을 사용하기 위해 볼륨을 생성(docker volume create) , 삭제(docker volume rm), 관리 (docker volume prune, inspect, ls)가 필요하다.
3. 볼륨은 Docker 상에서 이미지, 컨테이너, 네트워크 관리 방식으로 관리가 되는 장점이 있다.
4. 보통은 볼륨을 사용하지만 특별히 로컬 호스트 서버의 현재 작업 디렉토리에 wget, curl, git등을 이용해 자료를 받아 작업을 할 경우에 바인드 마운트가 더 편할 수 있다.
바인드 마운트를 이용해서 호스트 서버의 해당 디렉토리(작업디렉토리)를 컨테이너의 특정 경로에 마운트 해주면 코드를 변경할 때 마다 변경 사항을 실시간으로 컨테이너의 디렉토리를 통해서도 호스트 서버의 바인드 마운트 디렉토리를 통해서도 확인할 수 있다.
도커 파일 시스템 (컨테이너 마운트 구조)
1. LowerDir: 이미지 레이어
2. UpperDir: 컨테이너 레이어
3. MergedDir: 사용자가 컨테이너 내부에서 마운트된 컨테이너 파일 시스템을 사용할 경우 LowerDir+UpperDir을 통합해 MergedDir로 사용한다.
4. Backing File System: 호스트 서버의 /var/lib/docker을 생성하는 데 사용되는 파일 시스템이 정의되어 스토리지 드라이버를 선택한다. xfs을 지원하는 드라이버는 overlay, overlay2, aufs가 있다. 기본적으로 overlay2를 사용하고 있다.
정보는 #docker info명령어로 확인한다.
WORKDIR
1. WORKDIR <이동할 경로>
2. WORKDIR은 컨테이너 상에서 작업 디렉토리 전환 시 사용한다.
3. WORKDIR 명령문으로 작업 디렉토리를 전환하면 그 이후에 등장하는 모든 RUN, CMD, ENTRYPOINT, COPY, ADD 명령문은 해당 디렉토리를 기준으로 실행한다.
4. WORKDIR은 중간중간 변경도 가능하다.
5. WORKDIR은 상대 경로도 사용할 수 있다. (현재 작업 디렉토리를 중심으로 보고 설정하면 된다.)
예) WORKDIR usr
WORKDIR bin
RUN touch testfile.txt
결과: 컨테이너 접속 시 최초의 디렉토리는 /라서 상대경로를 사용한 경우 /usr로 먼저 이동하고 /bin으로 이동하기 때문에 /usr/bin/testfile.txt로 파일이 생성된다.
USER
1. USER <사용자명>
2. USER는 명령을 실행할 사용자 계정을 설정한다.
3. RUN, CMD, ENTRYPOINT에 적용된다.
4. 사용중인 계정 대신 중간에 다른 사용자를 설정할 수 있다. (중요)
- 실습
[root@cent1 ~]# cd
[root@cent1 ~]# mkdir lab12
[root@cent1 ~]# cd lab12
[root@cent1 lab12]# cat Dockerfile
FROM ubuntu:14.04
USER nobody
RUN touch /tmp/testfile1
USER root # 여기서 사용되는 계정은 컨테이너의 /etc/passwd 파일에 등록된 계정을 사용해야 한다.
RUN mkdir -p /root/mydir1/mydir2
RUN touch /root/mydir1/mydir2/testfile
[root@cent1 lab12]# docker build -t testimage1 .
[root@cent1 lab12]# docker images #이미지 생성 확인
[root@cent1 lab12]# docker run -it --name con1 testimage1 /bin/bash
#각 디렉토리에 생성한 파일들의 소유자 확인하기
root@51a18eee40fc:/# ls -Rl /root
/root:
total 0
drwxr-xr-x 1 root root 20 Jan 25 07:51 mydir1
/root/mydir1:
total 0
drwxr-xr-x 1 root root 22 Jan 25 07:51 mydir2
/root/mydir1/mydir2:
total 0
-rw-r--r-- 1 root root 0 Jan 25 07:51 testfile
root@51a18eee40fc:/# ls -l /tmp
total 0
-rw-r--r-- 1 nobody nogroup 0 Jan 25 07:51 testfile1
ONBUILD
1. ONBUILD <명령> <인자 리스트>
2. ONBUILD 명령을 처음 사용한 Dockerfile에서 이미지를 빌드하면서 실행되지 않는다. ONBUILD명령어로 생성된 이미지를 다른 Dockerfile에서 이미지 생성을 위해 FROM명령어로 그 이미지를 사용해서 새 이미지를 빌드할 때 동작한다.
3. 최초에 ONBUILD를 사용한 상태에서는 아무 명령도 실행하지 않는다. 다음 번에 이미지가 FROM으로 사용될 때 실행할 명령을 예약하는 기능이라 할 수 있다.
4. FROM, MAINTAINER, ONBUILD를 제외한 모든 Dockerfile 명령을 사용할 수 있다.
5. ONBUILD는 이미지를 생성한 뒤 해당 이미지를 기반으로 커스터마이징을 할 때 활용할 수 있다.
6. 사용 예) 웹서버를 위한 이미지를 만들 때 ONBUILD로 미리 정의한 구성파일, 코드, 자료 등을 예약만 하고 그 예약된 이미지를 실제 FROM으로 호출할 때 실행한다.
도커 네트워크
1. 도커 호스트 서버의 네트워크 가상 인터페이스 docker0는 도커의 네트워크 드라이버 중 브리지(Bridge)를 기본 사용한다.
2. 컨테이너를 생성하면 자동으로 docker0 인터페이스를 컨테이너가 통신하기 위해 사용한다.
3. docker0 인터페이스는 172.17.0.0/16 서브넷을 갖기 때문에 컨테이너 생성시 이 대역대로 IP를 자동 할당한다. (예: 172.17.0.2, 172.17.0.3) , 도커 내부 구조로서 자동 할당 된다.
4. 컨테이너는 Linux Namespace 기술을 이용해 각자 격리된 네트워크 공간을 할당 받게 된다. IP는 컨테이너가 재 시작할 때마다 변경된다.
5. 컨테이너는 외부와 통신하기 위해 2개의 네트워크 인터페이스를 함께 생성한다. 컨테이너 내부 Namespace에 할당되는 eth0 이름의 인터페이스와 호스트서버의 네트워크 브리지 docker0에 바인딩 되는 vethXXXXXXX이름 형식의 veth 인터페이스다. (virtual eth)
6. 컨테이너의 eth0 인터페이스와 호스트의 veth 인터페이스는 서로 연결되어 있다.
7. docker0 브리지는 veth가상 인터페이스와 호스트의 eth 인터페이스를 이어주는 중간 다리 역할을 한다. 그리고 컨테이너 안에 eth0인터페이스는 veth가상 인터페이스를 통해 외부와 통신할 수 있고 컨테이너 간에 브리지를 통해 같은 네트워크상에 있기 때문에 서로 통신도 할 수 있다.
8. 컨테이너의 Gateway는 172.17.0.1로서 컨테이너 내부의 모든 패킷이 호스트의 docker0을 통해 외부로 나가게 되는 것을 확인할 수 있다.
9. 도커에서 사용할 수 있는 네트워크 종류는 (bridge), (host), (none) 등이 있다.
- 도커 (기본 bridge) 네트워크 구성도
- 컨테이너가 생성되면 자동으로 etho0이라는 이름의 인터페이스에 할당 되고 vethxxxxx라는 이름으로 docker0브릿지 (게이트웨이)에 바인딩된다.
- docker0브릿지는 각 vethxxxx인터페이스와 바인딩되어 호스트 서버 인터페이스와 컨테이너 eth0 네트워크를 연결해주는 역할을 한다.
- docker network <명령어>
connect: 도커 컨테이너를 도커 네트워크에 연결
disconnect: 연결된 도커 컨테이너 네트워크 연결 해제
create: 도커 네트워크 생성
inspect: 도커 네트워크 상세 정보 확인
ls: 네트워크의 구성 정보를 목록으로 확인
prune: 사용하지 않는 모든 도커 네트워크 제거
rm: 도커 네트워크 제거
도커 네트워크 기본 방식 (bridge)
1. docker의 기본 network 방식은 bridge이다. docker0라는 bridge가 기본 생성된다.
2. 컨테이너 생성하게 되면, 각 컨테이너 마다 고유한 network namespace 영역이 하나씩 생성되며, 이때 docker0 bridge에 container의 인터페이스들이 하나씩 binding 되는 구조이다.
3. #docker network inspect bridge 명령어로 도커 네트워크 상세 정보를 확인할 수 있다.
- 실습 (터미널 2개 필요)
* 첫번째 터미널에서 아래 작업
[root@cent1 ~]# docker network inspect bridge
[root@cent1 ~]# ifconfig docker0
[root@cent1 ~]# docker run -it --name con1 ubuntu:14.04 /bin/bash
root@d3666b813751:/# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever
17: eth0@if18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
root@d3666b813751:/# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 172.17.0.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 * 255.255.0.0 U 0 0 0 eth0
*두번째 터미널에서 아래 작업
[root@cent1 ~]# docker run -it --name con2 ubuntu:14.04 /bin/bash # 컨테이너 2 만들기
root@156018afe8e7:/# ip addr #eth0 ip 주소 확인하기
root@156018afe8e7:/# ping 172.17.0.2 -c5 #컨테이너2에서 컨테이너1의 주소로 ping 테스트
*세번째 터미널에서 작업
[root@cent1 ~]# ip addr
18: veth0538676@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether a2:20:b5:2c:74:5d brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::a020:b5ff:fe2c:745d/64 scope link
valid_lft forever preferred_lft forever
20: veth5efc3cb@if19: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 3a:24:e3:97:2f:f9 brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::3824:e3ff:fe97:2ff9/64 scope link
valid_lft forever preferred_lft forever
[root@cent1 ~]# docker network inspect bridge
"Containers": {
"156018afe8e7fa694a3e48c0b1adb41a0e300ef371e6471a32cc7aaa80218e63": {
"Name": "con2",
"EndpointID": "209e7c1f2fbf9cdfd7a2c7b14fa3b07d420a55cbe706329e49c766d55d3ab840",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"d3666b81375103fcec56dd2b32754631eed3025cd8dd8cd75f83f5cca2bc635f": {
"Name": "con1",
"EndpointID": "1c658392d33556e6da4856eda94720da6b4450fc7f45dff82b759037fca9dabd",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
[root@cent1 ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242dfcfc2ed no veth0538676
veth5efc3cb
host 네트워크 방식
1. 컨테이너가 도커 호스트 서버 네트워크를 동일한 셋팅으로 사용한다.
2. #docker run --net host (docker network create가 따로 필요 없다.)
3. 호스트 모드로 생성된 컨테이너의 경우, 브리지 모드를 사용하지 않으므로, docker0에 바인딩 되지 않는다.
4. hostname, 인터페이스, ip, /etc/hosts도 호스트 서버와 동일한 구성을 사용한다.
5. 호스트 모드로 설정하면 컨테이너 내부의 애플리케이션을 별도의 포트 포워딩 없이 바로 서비스가 가능하다.
- host 네트워크 방식 구성도
- 실습
#첫번째 터미널에서 작업한다. (con1 컨테이너에 접속된 상태 유지)
[root@cent1 ]# docker run -it --net=host --name con1 ubuntu:14.04 /bin/bash
컨테이너의 호스트명 확인 (호스트 서버의 호스트명과 같다.)
root@cent1:/# hostname
cent1.foosys.com
/etc/hosts파일의 내용 확인 (호스트 서버의 파일과 같다.)
root@cent1:/# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.56.200 cent1 cent1.foosys.com
192.168.56.201 cent2 cent2.foosys.com
컨테이너의 네트워크 ip와 인터페이스 확인 (호스트 서버의 구성과 같다.)
root@cent1:/# ip addr
#2번째 터미널을 띄워 작업을 한다.
브리지 상태를 확인하면 사용을 하는 인터페이스가 없다. (이유: 호스트서버의 네트워크를 그대로 사용중임으로)
[root@cent1 ]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242a5cdeeda no
virbr0 8000.525400bb6175 yes virbr0-nic
[root@cent1 ~]# hostname
cent1.foosys.com
[root@cent1 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.56.200 cent1 cent1.foosys.com
192.168.56.201 cent2 cent2.foosys.com
[root@cent1 ~]# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default gateway 0.0.0.0 UG 100 0 0 enp0s3
default gateway 0.0.0.0 UG 101 0 0 enp0s8
10.0.2.0 0.0.0.0 255.255.255.0 U 100 0 0 enp0s3
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.56.0 0.0.0.0 255.255.255.0 U 101 0 0 enp0s8
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
호스트서버의 네트워크 구성
root@cent1:/# ip addr
host 방식의 네트워크 구성 상세 정보를 확인한다.
[root@cent1 ]# docker network inspect host
"Driver": "host",
"Containers": {
"233e00e1d32345454b4b09d484370e0f5e4cfa464f405305344d00e4d5aff06c": {
"Name": "con1",
"EndpointID": "25ddfb3485cbe9bf768e3f2d08694767ec75aeb1c728c59f145bce46c58b1c83",
"MacAddress": "",
"IPv4Address": "",
"IPv6Address": ""
Container 네트워크 방식
1. 기존에 존재하는 다른 컨테이너의 network 환경을 공유하게 된다.
즉 다른 컨테이너의 네트워크 네임스페이스 환경을 공유한다.
2. 공유되는 속성은 내부 IP, 네트워크 인터페이스의 MAC주소등
3. --net container:다른 컨테이너이름
- container 네트워크 구성도
- 실습 (터미널 3개 필요)
#첫번째 터미널에서 작업한다.
#con1의 이름을 가진 컨테이너1을 만들어준다.
[root@cent1 ~]# docker run -it --name con1 ubuntu:14.04 /bin/bash
hostname을 확인한다.
root@bdc2c8cf8b15:/# hostname
#2번째 터미널을 띄우고 작업한다.
#--net=container:con1으로 컨테이너1의 네트워크와 연결해준다.
#con1 컨테이너와 동일한 네트워크를 사용하는 컨테이너2가 만들어진다.
[root@cent1 ~]# docker run -it --name con2 --net=container:con1 ubuntu:14.04 /bin/bash
#3번째 터미널을 띄우고 작업한다 .
컨테이너가 2개이지만 브리지 네트워크 docker0의 인터페이스가 con1의 인터페이스로만 출력되는것을 확인 할 수 있다. con2는 con1의 인터페이스를 공유해서 사용중이다.
[root@cent1 ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242a5cdeeda no veth0eb0b0b
virbr0 8000.525400bb6175 yes virbr0-nic
[root@cent1 ~]# docker network inspect bridge 으로 상세 브릿지(기본)네트워크의 상세정보를 확인해준다.
none 네트워크 방식
1. 격리된 네트워크 영역을 갖긴 하지만, 인터페이스가 없는 상태로 컨테이너를 생성하게 된다.
2. 다른 컨테이너의 네트워크 환경을 공유하면 vethXXXXX의 가상 네트워크 인터페이스를 생성하지 않고 ip도 할당되지 않는다.
3. 수동으로 네트워크를 설정하여 사용하도록 일부러 비워 둔 상태이다.
만약 eth0네트워크 인터페이스 설정을 원한다면 권한 할당 개념을 배우고 실습이 가능하다.
4. cap-add, cap-drop에서 권한 설정을 통해 네트워크 설정 권한을 할당 받고 시스템 관리 이용하기에서 배운다.
- none 네트워크 구성도
- 실습
- 네트워크 설정이 없다는 것만 확인하자
[root@cent1 ~]# docker run -it --name con1 --net=none ubuntu:14.04 /bin/bash
root@e09c79093ca6:/# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
root@e09c79093ca6:/# exit
exit
- 실습 2
수동으로 원하는 IP범위를 가진 네트워크 정의 (docker network create)
1. 사용자가 수동 생성한 네트워크 드라이버 브리지는 자동 설정되는 기본 브리지 네트워크와 Hostname 이름 분석 구조가 다르다.
2. 기본 브리지 네트워크: hostname 분석은 /etc/hosts 파일에 의존적이다.
3. 사용자 정의 브리지 네트워크: hostname 분석은 내장된 DNS 서버에 의해 이름 분석을 하기 때문에 사용이 편리하다.
- 실습2 구성도
- 실습순서
#첫번째 터미널에서 진행
수동으로 컨테이너들이 사용할 네트워크를 구성한다.
[root@cent1 ~]# docker network create --driver bridge --attachable --subnet 10.0.3.0/24 --ip-range 10.0.3.0/24 codemonkyunet
수동으로 구성한 네트워크와 연결할 컨테이너 con1 만들기
[root@cent1 ~]# docker run -it --name con1 --net=codemonkyunet ubuntu:14.04 /bin/bash
#두번째 터미널에서 진행
수동으로 구성한 네트워크와 연결한 컨테이너 con2만들기
[root@cent1 ~]# docker run -it --name con2 --net=codemonkyunet ubuntu:14.04 /bin/bash
#컨테이너 이름으로 ping 테스트를 한다.
이유: 수동 네트워크 연결은 기본 DNS서버에서 이름 분석이 가능하기 때문이다.
root@8c140399a497:/# ping con1
- 실습3
수동 브리지 네트워트2개 구성과 컨테이너 생성 테스트
- 실습 순서
#첫번째 터미널에서 진행
#브리지 타입의 네트워크 2개를 만든다.
[root@cent1 ~]# docker network create --driver bridge --attachable --subnet 10.0.3.0/24 --ip-range 10.0.3.0/24 codemonkyunet1
[root@cent1 ~]# docker network create --driver bridge --attachable --subnet 10.0.3.0/24 --ip-range 10.0.4.0/24 codemonkyunet2
#컨테이너 1,2를 codemonkyunet1 네트워크에 생성한다.
#첫번째 터미널에서 작업 (첫번쨰 터미널 = 첫번쨰 컨테이너에 연결! 헷갈리지말자)
[root@cent1 ~]# docker run -it --name con1 --net=codemonkyunet1 ubuntu:14.04 /bin/bash
#두번째 터미널에서 작업 (두번쨰 터미널 = 두번쨰 컨테이너에 연결! 헷갈리지말자)
[root@cent1 ~]# docker run -it --name con2 --net=codemonkyunet2 ubuntu:14.04 /bin/bash
#세번째 터미널에서 작업
#도커 호스트 서버에서 네트워크 구성을 확인한다.
[root@cent1 ~]# docker network ls
[root@cent1 ~]# brctl show
[root@cent1 ~]# docker network inspect suyenet1
호스트 서버에서 바인딩에 사용하는 네트워크 인터페이스 리스트 확인
[root@cent1 ~]# ip addr
- #컨테이너 네트워크 연결 및 해제 (중요)
1. docker network connect [옵션] 네트워크 컨테이너: 컨테이너를 네트워크에 연결
2. docker network disconnect [옵션] 네트워크 컨테이너: 네트워크에서 연결을 해제
- 실습3-1
컨테이너에 여러개의 네트워크 사용을 설정하기
- 현재 con1(컨테이너1)은 codemonkyunet1 네트워크에 연결된 상태이다 이를 codemonkyunet2 네트워크로 추가시켜 2개의 네트워크에서 con1(컨테이너1)을 사용가능하도록 설정한다.
- 실습3-1 구성도
- 실습 3-1 실습 순서
#con1(컨테이너1) codemonkyunet2에 연결해주기
[root@cent1 ~]# docker network connect codemonkyunet2 con1
#실행중인 con1의 상태 관찰하기
[root@cent1 ~]# docker ps
#브릿지 인터페이스 상태확인
[root@cent1 ~]# brctl show
-> 2개의 컨테이너 con1, con2가 codemonkyunet1 네트워크에 연결된 상태이다.
-> con1컨테이너가 codemonkyunet2네트워크에 연결된상태이다. 즉, con1은 codemonkyunet1과 2에서 모두 사용중이다.
#첫번째 터미널 (con1컨테이너 실행중인 터미널)
root@c3dfecf2d3a0:/# ip addr
-> codemonkyunet1 네트워크에 연결된 eth0 주소 확인 (인터페이스)확인
-> codemonkyunet2 네트워크에 연결된 eth0 주소 확인 (인터페이스)확인
#세번쨰 터미널 (도커 호스트 서버에 연결된 터미널)
[root@cent1 ~]# docker inspect con1
-> 기본 브리짓 네트워크를 위한 게이트웨이 인터페이스와 주소확인 가능
-> codemonkyunet1 네트워크를 위한 게이트웨이 인터페이스 주소 확인
-> codemonkyunet2 네트워크를 위한 게이트웨이 인터페이스 주소 확인
#네번째 터미널( 새 컨테이너 con3를 codemonkyunet2 네트워크에 구성한다.)
[root@cent1 ~]# docker run -it --name con3 --net=codemonkyunet2 ubuntu:14.04 /bin/bash
-> con3는 con1과 ping test가 가능하다 (서로 연결되어 있다.)
- 실습 3-2
기존에 설정된 네트워크를 다른 네트워크로 옮기기
- 실습 3-2 구성도
- 실습 3-2 순서
#두번쨰 터미널에서 진행 (con2가 연결되어있는 터미널)
#컨테이너를 다른 네트워크로 옮기기 위해 컨테이너 stop하기
root@8bc17d41b184:/# exit
[root@cent1 ~]# docker ps #작동중인 컨테이너 확인 con1과 con3만 보여야지 정상
#네트워크에 대한 연결 해제
[root@cent1 ~]# docker network disconnect codemonkyunet1 con2
#네트워크 인터페이스으로 확인
[root@cent1 ~]# brctl show
#codemonkyunet2 네트워크에 컨테이너 2를 연결한다.
[root@cent1 ~]# docker network connect codemonkyunet2 con2
#con2를 다시 start한다.
[root@cent1 ~]# docker start con2
#다시 con2 컨테이너에 접속한다.
[root@cent1 ~]# docker exec -it con2 /bin/bash
#ping con1, con3로 제대로 잘 연결되었는지 ping test를 통해 알아본다.
root@8bc17d41b184:/# ping con1
root@8bc17d41b184:/# ping con3
이상으로 dockerfile에서 설정가능한 대분분의 기능에 대해 간단히 리뷰해 보았다.
특히 docker volume과 docker network에 대해서는 자세히 알아보았다.
docker에서 나름 중요한 개념이라고 생각했기 때문이다.
다음 포스팅에서는 docker network개념과 이어지는 컨테이너의 통신에 대해서 다루어 보겠다.
댓글