본 글은 Open vSwitch로 여러 호스트에 존재하는 Docker Container들을 연결 할 수 있는 방법에 대해서 작성 하였으며,

테스트 환경은 Ubuntu 14.04 LTS, Docker v1.5, Open vSwitch 2.0.2 버전에서 진행 되었으며, 기타 자세한 설정에 대해서는 생략 하였습니다.

그리고, 공통된 부분에는 root@ruo91:~# 이라는 것으로 표기 될것이며, 개별 설정인 경우에는 다르게 표기 될것 이므로 이점 유의 하시길 바랍니다.

 

Open vSwitch는 무엇인가?


네트워크 표준 관리 인터페이스 및 프로토콜(NetFlow, sFlow, IPFIX, RSPAN, CLI, LACP, 802.1ag)를 지원하면서,

프로그램의 확장을 통해 대규모의 네트워크 자동화를 가능하게 해주는 소프트웨어 입니다.

간단하게 말하자면, 하드웨어가 할일을 소프트웨어를 통해 제어 할 수 있다는 것입니다.

 

Architecture diagram


쉽게 설명 드리고자 간단하게 만들어 본 구성도이며, 각각의 Server-1, Server-2 안에 Docker의 Container들이 존재하게 됩니다.

Server-1에서 Server-2의 Container-1에게 Ping을 날려 볼 수 있도록 설정 해볼 것입니다.

Open vSwitch - Architecture diagram

Open vSwitch 및 Docker 설정


1. Open vSwitch 설치

Ubuntu 14.04 기준으로 Open vSwitch를 아래 명령어로 쉽게 설치가 가능 합니다.

이 작업을 server-1, server-2에서 동일하게 설치를 진행 하도록 합니다.

root@ruo91:~# apt-get install -y openvswitch-switch bridge-utils

 

2. Docker bridge CIDR 설정

기존의 docker0 브릿지는 172.17.42.1/16 으로 CIDR이 설정 되어 있기 때문에, 10.0.0.1/24로 설정하겠습니다.

우선, docker 데몬을 중지 하고, docker0 브릿지를 삭제 합니다.

root@ruo91:~# service docker stop
root@ruo91:~# ip link set dev docker0 down
root@ruo91:~# brctl delbr docker0
root@ruo91:~# iptables -t nat -F POSTROUTING

 

이후 docker0 브릿지를 추가시 CIDR을 10.0.0.1/24로 변경 합니다.

– server-1

root@server-1:~# brctl addbr docker0
root@server-1:~# ip addr add 10.0.0.1/24 dev docker0
root@server-1:~# ip link set dev docker0 up

 

– server-2

root@server-2:~# brctl addbr docker0
root@server-2:~# ip addr add 10.0.0.2/24 dev docker0
root@server-2:~# ip link set dev docker0 up

 

3. Open vSwitch 설정

br0 브릿지를 새로 추가 합니다.

root@ruo91:~# ovs-vsctl add-br br0

 

GRE 터널링을 통해 서로 다른 호스트에서 Container끼리 통신이 가능 하도록 설정 합니다.

뒤에 오는 remote_ip는 server-1, server-2의 public ip를 뜻합니다.

– server-1

root@server-1:~# ovs-vsctl add-port br0 gre0 -- set interface gre0 type=gre options:remote_ip=192.168.0.2

 

– server-2

root@server-2:~# ovs-vsctl add-port br0 gre0 -- set interface gre0 type=gre options:remote_ip=192.168.0.3

 

docker0 브릿지를 브릿지할 br0을 추가 합니다.

root@ruo91:~# brctl addif docker0 br0

 

4. IPTABLE 설정

해당 대역에서 NAT을 사용 할 수 있도록 설정 합니다.

root@ruo91:~# iptables -t nat -A POSTROUTING -s 10.0.0.1/24 ! -d 10.0.0.1/24 -j MASQUERADE

 

들어오는 트래픽을 허용 하도록 합니다.

root@ruo91:~# iptables -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

 

이외의 내부 컨테이너에서 나가는 트래픽을 허용 하도록 합니다.

root@ruo91:~# iptables -A FORWARD -i docker0 ! -o docker0 -j ACCEPT

 

나가는 트래픽을 모두 허용 하도록 합니다.

root@ruo91:~# iptables -A FORWARD -i docker0 -o docker0 -j ACCEPT

 

5. Docker 시작

중지 하였던 Docker 데몬을 실행 합니다.

root@ruo91:~#service docker restart

 

6. 설정 확인

– ip addr show

root@server-1:~# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
    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
35: ovs-system: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default
    link/ether ae:2c:ac:67:e2:37 brd ff:ff:ff:ff:ff:ff
73: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether d6:36:8b:18:dc:4f brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.1/24 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::5077:70ff:fec4:835d/64 scope link
       valid_lft forever preferred_lft forever
74: br0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UNKNOWN group default
    link/ether d6:36:8b:18:dc:4f brd ff:ff:ff:ff:ff:ff
    inet6 fe80::f00a:3fff:fe52:d3f9/64 scope link
       valid_lft forever preferred_lft forever
1676: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:01:5d brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.2/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:15d/64 scope link
       valid_lft forever preferred_lft forever

 

– ip route show
root@server-1:~# ip r s
default via 192.168.0.2 dev eth0
10.0.0.0/24 dev docker0  proto kernel  scope link  src 10.0.0.1
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.1

 

– brctl show

root@server-1:~# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.d6368b18dc4f       no              br0

 

– ovs-vsctl show

root@server-1:~# ovs-vsctl show
e6ad6b8f-5116-4f46-84bc-e109e2bfc9c6

    Bridge "br0"
        Port "br0"
            Interface "br0"
                type: internal
        Port "gre0"
            Interface "gre0"
                type: gre
                options: {remote_ip="192.168.0.3"}
    ovs_version: "2.0.2"

 

Ping Test


아래 핑 테스트를 통해 설정이 잘 되었는지 확인 하면 됩니다.
– server-1
root@server-1:~# ping -c 5 10.0.0.12
PING 10.0.0.12 (10.0.0.12) 56(84) bytes of data.
64 bytes from 10.0.0.12: icmp_seq=1 ttl=64 time=0.627 ms
64 bytes from 10.0.0.12: icmp_seq=2 ttl=64 time=0.135 ms
64 bytes from 10.0.0.12: icmp_seq=3 ttl=64 time=0.139 ms
64 bytes from 10.0.0.12: icmp_seq=4 ttl=64 time=0.140 ms
64 bytes from 10.0.0.12: icmp_seq=5 ttl=64 time=0.088 ms

--- 10.0.0.12 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4000ms
rtt min/avg/max/mdev = 0.088/0.225/0.627/0.202 ms

 

– server-2
root@server-2:~# ping -c 5 10.0.0.3
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
64 bytes from 10.0.0.3: icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from 10.0.0.3: icmp_seq=2 ttl=64 time=0.056 ms
64 bytes from 10.0.0.3: icmp_seq=3 ttl=64 time=0.054 ms
64 bytes from 10.0.0.3: icmp_seq=4 ttl=64 time=0.052 ms
64 bytes from 10.0.0.3: icmp_seq=5 ttl=64 time=0.038 ms

--- 10.0.0.3 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 3996ms
rtt min/avg/max/mdev = 0.038/0.054/0.072/0.012 ms

 

감사합니다. 🙂

참고


https://docs.docker.com/articles/networking/

http://openvswitch.org/support/config-cookbooks/port-tunneling/

https://goldmann.pl/blog/2014/01/21/connecting-docker-containers-on-multiple-hosts/