본 글은 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 및 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
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
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
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/