목차
Docker Network 실습
Docker0와 Container Network 구조

docker 0는 ip주소 172.17.0.1이 할당되어 있음
# dnf install epel-release –y
# dnf install bridge-utils -y

컨테이너 개수만큼 docker 0의 인터페이스에 보인다(인터페이스가 포트역할을 함)

docker0 interface 특징
- IP 는 자동으로 172.17.0.1 로 설정
- 이 IP 는 DHCP 를 통해 할당 받는 것은 아니며, docker 내부 로직에 의해 자동 할당 받음
- docker0 는 일반적인 interface 가 아니며, virtual ethernet bridge
- docker0 는 container 가 통신하기 위한 가상 linux bridge 이다.
- bridge 는 기본적으로 L2 통신 기반이며, 만약 container 가 하나 생성되면 이 bridge 에 container 의 interface 가 하나씩 binding 되는 형태 이다.
- 따라서 container 가 외부로 통신할 때 docker0 interface 를 지나야 한다.
- 위에서 docker 가 설치 되면 이름이 docker0 라는 bridge 가 생성되며, container 가 running 될 때마다 vethXXXX 라는 이름의 interface 가 attach 되는 형태이다.
- docker0 의 IP 는 자동으로 172.17.0.1 로 설정되며, 네트워크는 172.17.0.0/16 으로 설정된다.
=> 이 subnet 정보는 앞으로 container 가 생성될 때 할당 받게 될 IP 의 range 를 결정한다. 즉, 모든 container 는 172.17.XX.YY 대역에서 IP 를 하나씩 할당받는다.
Docker Network - Bridge
docker 의 기본 network 방식은 bridge 이다. docker daemon 을 실행하면 먼저 docker0 라는 bridge 가 생성된다. 컨테이너가 생성되면, 각 컨테이너 마다 고유한 network namespace 영역이 하나씩 생성되며 이때 docker0 bridge 에 container 의 인터페이스들이 하나씩 binding 되는 구조이다.
docker network create --driver bridge \
> --subnet 172.16.1.0/16 --ip-range 172.16.1.0/24 \
> --gateway=172.16.1.1 vswitch01
bridge 네트워크를 만들어준다.
이름은 vswitch01이고 subnet대역을 172.16.1.0/16으로 만들어준다. 게이트웨이는 172.16.1.1

확인하면 bridge driver에 대해 docker0와 vswitch01이 만들어져있음
이상태에서 컨테이너 2개를 생성한다
# docker run --name centos1 --hostname centos1 \ --network vswitch01 -itd centos
# docker run --name centos2 --hostname centos2 \ --network vswitch01 -itd centos
centos1과 centos2가 생성

centos1의 ip주소를 확인한다

centos1의 ip주소가 0을 사용 -> 원래는 사용하면 안되긴 하는데 상관은 없다
centos2의 ip주소를 확인한다

centos2는 ip주소 2를 사용

브릿지에 interface 할당된것도 확인할 수 있다
참고로 만든 브릿지의 ip주소는 172.16.1.1이다



ping도 서로 잘보내진다.
그런데 어떻게 hostname으로 ping이 잘 보내지는 걸까? 우리는 hostfile과 dns를 건든적이 없다.
추가적으로 centos2에서 /etc/hosts에 보면 centos2만 있고 centos1은 없다

cat /etc/resolv.conf
=> 네임서버 dns에서 잡혀있음 127.0.0.11이 dns로 잡혀있는 것을 확인할 수 있다.

즉, 도커에서 자동으로 dns 세팅을 해준다.
컨테이너 만들 때 hostname을 설정해주었기 때문에 dns에서 인식할 수 있고 ip주소를 찾을 수 있다.
Host 방식
host 방식으로 컨테이너를 생성하면, 컨테이너가 독립적인 네트워크 영역을 갖지 않고 host 와 네트워크를 공유해서 사용한다.
docker run --name centos3 --hostname centos3 \
> --network host -itd centos

centos3 컨테이너가 host 방식으로 생성되었다.
centos3의 ip를 확인해보자

ens33 인터페이스가 뜨는것을 확인할 수 있으며 호스트의 ip와 동일 ip를 사용하는 것을 확인할 수 있다.
또한, 8.8.8.8로 ping이 됨

-> 컨테이너 생성할때 host라고 지정하면 host의 ip를 사용
=> host가 서버a임 => 서버a의 ip를 이용하여 외부하고 통신을 한다
but 좋은 방식은 아니다.
container
이 방식으로 생성된 컨테이너는 기존에 존재하는 다른 컨테이너의 network 환경을 공유하며 생성시 옵션으로 --net=container:CONTAINER_ID 를 사용한다.
docker run --name centos4 --net=container:b529a87387e4 \
> -dit centos
기존에 사용하는 컨테이너의 네트워크를 공유하여 사용

centos1의 ip를 똑같이 사용하고 있다
실무에서는 사용x
brctl을 할때는 centos4와 centos1이 똑같은 걸로 인식하기 때문에 interface에는 안뜬다. centos3은 호스트이기 때문에 안뜸
none
자기자신외에는 통신 못함 => 외부 통신 불가
overlay는 swarm에서 다룬다
Container Port 외부로 노출(expose) 하기
docker-proxy가 port fowarding을 해준다.

모든 ip에 8080으로 들어오는 것을 80으로 바꿔라
docker-proxy 프로세스는 container 의 port 를 노출하도록 설정한 수만큼 추가로 생성된다 (run process per port).
NAT

iptables 내역에서 먼저 Docker host 에 들어온 패킷이 PREROUTING chain 을 통해 DOCKER Chain 으로 전달하고, Docker Chain 에서는 DNAT 로 5000 포트로 들어온 요청을 172.17.0.2 IP 를 가진 container 의 443 포트로 포워딩 되는 것을 알 수 있다. 반대로, Container 에서 외부로 나갈 때는 POSTROUTING 을 거쳐 MASQUERADE 되어 외부로 나간다. 여기서 볼 수 있는 container 관련 iptables rule 관리는 docker daemon 이 자동으로 제어한다. 또한, NAT 를 위한 ip_forward 설정도 docker daemon 에서 제어한다.
link
web 서버 역할의 컨테이너와 DB 서버 역할의 컨테이너가 있다고 가정할 때 이 두 container 사이를 연동할 경우 container 사이 연동에 필요한 link 옵션을 사용할 수 있다.
container 연동시 link를 사용해야 하는 이유
Container IP는 언제든 변할 수 있는 유동적인 성격을 가지고 있다.
Container 는 일종의 Process 이므로, 언제든 생성/소멸될 수 있고 이때, Container 에게 부여되는 Private IP 는 언제든 변할 수 있다.
따라서, Container 사이 연동을 하려면, IP 기반의 설정은 권고되지 않으며 그 해결 방법으로 권고되고 있는 방법이 바로 link 옵션이다
link를 이용한 연동
# docker run --name centos3 --hostname centos3 \
> --link centos1 -itd centos
link 연동 구조
container 가 구동되면, container 환경 중 일부는 docker daemon 에 의해 자동으로 제어된다. 이 중 한가지가 container 내부의 domain name 을 관리하는 hosts 파일이다. link 연동이 걸린 centos3 container 의 hosts 파일을 살펴보자

host 파일을 보니 centos1이 들어가있다.
link 를 걸지 않으면, 이 정보가 없다.
만약, link 가 걸린 상태에서 centos1 container 가 재기동되어 IP 가 변경되어도 이 컨테이너와 link 가 걸린 centos3 컨테이너의 hosts 파일 정보가 자동으로 갱신됨을 볼 수 있다.
docker daemon 은 이렇게 container 의 hosts 파일을 자동으로 갱신할 수 있다.
docker host 에서 실제 이 file 을 열어보면 위와 같이 container 의 hosts 파일과 동일하다.
링크를 사용하는 가장 중요한 목적
=>link 가 걸린 상태에서 centos1 container 가 재기동되어 IP 가 변경되어도 이 컨테이너와 link 가 걸린 centos3 컨테이너의 hosts 파일 정보가 자동으로 갱신됨을 볼 수 있다.
=> 링크라는 기능은 호스트 파일에 등록된 다른 컨테이너의 ip를 자동으로 변경해줌
=> 그래서 ip가 바뀌어도 수동으로 변경할 필요는 없음!
이전에서 레포지토리 만들때 hosts 파일에 서버의 ip주소 등록해 줬다. 이 hosts파일은 자동으로 갱신이 안됨
but 도커의 링크같은 경우는 자동으로 변경이 된다.
but 문제점은 host에 존재하는 container 사이에서만 유효하다 => 다른 호스트에서는 사용하지 못한다 only 동일 호스트 사이에서만 연결을 해야 한다
목차
Docker Network 실습
Docker0와 Container Network 구조

docker 0는 ip주소 172.17.0.1이 할당되어 있음
# dnf install epel-release –y # dnf install bridge-utils -y

컨테이너 개수만큼 docker 0의 인터페이스에 보인다(인터페이스가 포트역할을 함)

docker0 interface 특징
- IP 는 자동으로 172.17.0.1 로 설정
- 이 IP 는 DHCP 를 통해 할당 받는 것은 아니며, docker 내부 로직에 의해 자동 할당 받음
- docker0 는 일반적인 interface 가 아니며, virtual ethernet bridge
- docker0 는 container 가 통신하기 위한 가상 linux bridge 이다.
- bridge 는 기본적으로 L2 통신 기반이며, 만약 container 가 하나 생성되면 이 bridge 에 container 의 interface 가 하나씩 binding 되는 형태 이다.
- 따라서 container 가 외부로 통신할 때 docker0 interface 를 지나야 한다.
- 위에서 docker 가 설치 되면 이름이 docker0 라는 bridge 가 생성되며, container 가 running 될 때마다 vethXXXX 라는 이름의 interface 가 attach 되는 형태이다.
- docker0 의 IP 는 자동으로 172.17.0.1 로 설정되며, 네트워크는 172.17.0.0/16 으로 설정된다.
=> 이 subnet 정보는 앞으로 container 가 생성될 때 할당 받게 될 IP 의 range 를 결정한다. 즉, 모든 container 는 172.17.XX.YY 대역에서 IP 를 하나씩 할당받는다.
Docker Network - Bridge
docker 의 기본 network 방식은 bridge 이다. docker daemon 을 실행하면 먼저 docker0 라는 bridge 가 생성된다. 컨테이너가 생성되면, 각 컨테이너 마다 고유한 network namespace 영역이 하나씩 생성되며 이때 docker0 bridge 에 container 의 인터페이스들이 하나씩 binding 되는 구조이다.
docker network create --driver bridge \ > --subnet 172.16.1.0/16 --ip-range 172.16.1.0/24 \ > --gateway=172.16.1.1 vswitch01
bridge 네트워크를 만들어준다.
이름은 vswitch01이고 subnet대역을 172.16.1.0/16으로 만들어준다. 게이트웨이는 172.16.1.1

확인하면 bridge driver에 대해 docker0와 vswitch01이 만들어져있음
이상태에서 컨테이너 2개를 생성한다
# docker run --name centos1 --hostname centos1 \ --network vswitch01 -itd centos # docker run --name centos2 --hostname centos2 \ --network vswitch01 -itd centos
centos1과 centos2가 생성

centos1의 ip주소를 확인한다

centos1의 ip주소가 0을 사용 -> 원래는 사용하면 안되긴 하는데 상관은 없다
centos2의 ip주소를 확인한다

centos2는 ip주소 2를 사용

브릿지에 interface 할당된것도 확인할 수 있다
참고로 만든 브릿지의 ip주소는 172.16.1.1이다



ping도 서로 잘보내진다.
그런데 어떻게 hostname으로 ping이 잘 보내지는 걸까? 우리는 hostfile과 dns를 건든적이 없다.
추가적으로 centos2에서 /etc/hosts에 보면 centos2만 있고 centos1은 없다

cat /etc/resolv.conf
=> 네임서버 dns에서 잡혀있음 127.0.0.11이 dns로 잡혀있는 것을 확인할 수 있다.

즉, 도커에서 자동으로 dns 세팅을 해준다.
컨테이너 만들 때 hostname을 설정해주었기 때문에 dns에서 인식할 수 있고 ip주소를 찾을 수 있다.
Host 방식
host 방식으로 컨테이너를 생성하면, 컨테이너가 독립적인 네트워크 영역을 갖지 않고 host 와 네트워크를 공유해서 사용한다.
docker run --name centos3 --hostname centos3 \ > --network host -itd centos

centos3 컨테이너가 host 방식으로 생성되었다.
centos3의 ip를 확인해보자

ens33 인터페이스가 뜨는것을 확인할 수 있으며 호스트의 ip와 동일 ip를 사용하는 것을 확인할 수 있다.
또한, 8.8.8.8로 ping이 됨

-> 컨테이너 생성할때 host라고 지정하면 host의 ip를 사용
=> host가 서버a임 => 서버a의 ip를 이용하여 외부하고 통신을 한다
but 좋은 방식은 아니다.
container
이 방식으로 생성된 컨테이너는 기존에 존재하는 다른 컨테이너의 network 환경을 공유하며 생성시 옵션으로 --net=container:CONTAINER_ID 를 사용한다.
docker run --name centos4 --net=container:b529a87387e4 \ > -dit centos
기존에 사용하는 컨테이너의 네트워크를 공유하여 사용

centos1의 ip를 똑같이 사용하고 있다
실무에서는 사용x
brctl을 할때는 centos4와 centos1이 똑같은 걸로 인식하기 때문에 interface에는 안뜬다. centos3은 호스트이기 때문에 안뜸
none
자기자신외에는 통신 못함 => 외부 통신 불가
overlay는 swarm에서 다룬다
Container Port 외부로 노출(expose) 하기
docker-proxy가 port fowarding을 해준다.

모든 ip에 8080으로 들어오는 것을 80으로 바꿔라
docker-proxy 프로세스는 container 의 port 를 노출하도록 설정한 수만큼 추가로 생성된다 (run process per port).
NAT

iptables 내역에서 먼저 Docker host 에 들어온 패킷이 PREROUTING chain 을 통해 DOCKER Chain 으로 전달하고, Docker Chain 에서는 DNAT 로 5000 포트로 들어온 요청을 172.17.0.2 IP 를 가진 container 의 443 포트로 포워딩 되는 것을 알 수 있다. 반대로, Container 에서 외부로 나갈 때는 POSTROUTING 을 거쳐 MASQUERADE 되어 외부로 나간다. 여기서 볼 수 있는 container 관련 iptables rule 관리는 docker daemon 이 자동으로 제어한다. 또한, NAT 를 위한 ip_forward 설정도 docker daemon 에서 제어한다.
link
web 서버 역할의 컨테이너와 DB 서버 역할의 컨테이너가 있다고 가정할 때 이 두 container 사이를 연동할 경우 container 사이 연동에 필요한 link 옵션을 사용할 수 있다.
container 연동시 link를 사용해야 하는 이유
Container IP는 언제든 변할 수 있는 유동적인 성격을 가지고 있다.
Container 는 일종의 Process 이므로, 언제든 생성/소멸될 수 있고 이때, Container 에게 부여되는 Private IP 는 언제든 변할 수 있다.
따라서, Container 사이 연동을 하려면, IP 기반의 설정은 권고되지 않으며 그 해결 방법으로 권고되고 있는 방법이 바로 link 옵션이다
link를 이용한 연동
# docker run --name centos3 --hostname centos3 \ > --link centos1 -itd centos
link 연동 구조
container 가 구동되면, container 환경 중 일부는 docker daemon 에 의해 자동으로 제어된다. 이 중 한가지가 container 내부의 domain name 을 관리하는 hosts 파일이다. link 연동이 걸린 centos3 container 의 hosts 파일을 살펴보자

host 파일을 보니 centos1이 들어가있다.
link 를 걸지 않으면, 이 정보가 없다.
만약, link 가 걸린 상태에서 centos1 container 가 재기동되어 IP 가 변경되어도 이 컨테이너와 link 가 걸린 centos3 컨테이너의 hosts 파일 정보가 자동으로 갱신됨을 볼 수 있다.
docker daemon 은 이렇게 container 의 hosts 파일을 자동으로 갱신할 수 있다.
docker host 에서 실제 이 file 을 열어보면 위와 같이 container 의 hosts 파일과 동일하다.
링크를 사용하는 가장 중요한 목적
=>link 가 걸린 상태에서 centos1 container 가 재기동되어 IP 가 변경되어도 이 컨테이너와 link 가 걸린 centos3 컨테이너의 hosts 파일 정보가 자동으로 갱신됨을 볼 수 있다.
=> 링크라는 기능은 호스트 파일에 등록된 다른 컨테이너의 ip를 자동으로 변경해줌
=> 그래서 ip가 바뀌어도 수동으로 변경할 필요는 없음!
이전에서 레포지토리 만들때 hosts 파일에 서버의 ip주소 등록해 줬다. 이 hosts파일은 자동으로 갱신이 안됨
but 도커의 링크같은 경우는 자동으로 변경이 된다.
but 문제점은 host에 존재하는 container 사이에서만 유효하다 => 다른 호스트에서는 사용하지 못한다 only 동일 호스트 사이에서만 연결을 해야 한다