본문 바로가기
Openstack

DVR packet flow(FIP:North-south)

 

이번 문서는  packet flow는 kolla 7.0 으로 배포한 구성에서 DVR을 활성화 하였을 경우 Floating ip를 추가 하여 packet이 어떻게 흘러가는지 확인 한 것이다.

1. "North-south" traffic(vm → internet)

배포 서버 혹은 openstack client 가 설치된 노드에서 openstack 명령어를 이용 하여 아래와 같이 
"test"이름의 인스턴스가 "demo-net" 이름으로 172.12.10.4 아이피가 할당 되어 있으며,floating ip 로 192.168.10.106 가 설정 되어 있는 것을 확인 한다.
[root@cy2-deploy ~]# openstack server show test
+-------------------------------------+----------------------------------------------------------+
| Field                               | Value                                                    |
+-------------------------------------+----------------------------------------------------------+
| OS-DCF:diskConfig                   | AUTO                                                     |
| OS-EXT-AZ:availability_zone         | nova                                                     |
| OS-EXT-SRV-ATTR:host                | cy2-compute02                                            |
| OS-EXT-SRV-ATTR:hypervisor_hostname | cy2-compute02                                            |
| OS-EXT-SRV-ATTR:instance_name       | instance-00000003                                        |
| OS-EXT-STS:power_state              | Running                                                  |
| OS-EXT-STS:task_state               | None                                                     |
| OS-EXT-STS:vm_state                 | active                                                   |
| OS-SRV-USG:launched_at              | 2018-11-25T08:30:49.000000                               |
| OS-SRV-USG:terminated_at            | None                                                     |
| accessIPv4                          |                                                          |
| accessIPv6                          |                                                          |
| addresses                           | selfservice2=172.12.10.4, 192.168.10.106                 |
| config_drive                        |                                                          |
| created                             | 2018-11-25T08:30:10Z                                     |
| flavor                              | m1.medium (3)                                            |
| hostId                              | 525330417c94af77f6cddd5850764a01445dfeb6d10620f35910d25f |
| id                                  | aac0a6c0-4235-4543-b80d-bf7dcd349f77                     |
| image                               |                                                          |
| key_name                            | mykey                                                    |
| name                                | test                                                     |
| progress                            | 0                                                        |
| project_id                          | cceb34e1bc91413cb0137011e8734425                         |
| properties                          |                                                          |
| security_groups                     | name='default'                                           |
| status                              | ACTIVE                                                   |
| updated                             | 2018-11-26T03:54:51Z                                     |
| user_id                             | e5b3cb7ad1f94ad5950bac42bf0aacf3                         |
| volumes_attached                    | id='a8a24f42-ee15-4c33-9500-db289d307bc2'                |
+-------------------------------------+----------------------------------------------------------+

기본적으로 같은 네트워크가 아닌 외부 인터넷 네트워크에 대하여 Default gateway인 172.12.10.1 로 보내며, 해당 gateway의 mac address인
fa:16:3e:78:d6:60 으로 포워딩 하게 설정 되어 있다.
[centos@test ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc pfifo_fast state UP qlen 1000
    link/ether fa:16:3e:ae:b3:e7 brd ff:ff:ff:ff:ff:ff
    inet 172.12.10.4/24 brd 172.12.10.255 scope global dynamic eth0
       valid_lft 80160sec preferred_lft 80160sec
    inet6 fe80::f816:3eff:feae:b3e7/64 scope link
       valid_lft forever preferred_lft forever


[centos@test ~]$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.12.10.1     0.0.0.0         UG    0      0        0 eth0
172.12.10.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0

[centos@test ~]$ arp -a
gateway (172.12.10.1) at fa:16:3e:78:d6:60 [ether] on eth0
openstack por list 를 이용 하여 172.12.10.4  아이피를 사용 하는 포트의 정보를 확인 하면 MAC 주소,해당 포트의 아이디 등을 알 수 있다.
이중 8aa5e3b4-6c0b-4d77-8c45-146cacf576ec 라는 포트 아이디에서 앞의 10개의 문자를 기반으로 인터페이스 및 브릿지 등의 해당 포트의 관련된 아이디로 사용 된다.
즉  8aa5e3b4-6c0b-4d77-8c45-146cacf576ec 아이디에서  8aa5e3b4-6c 으로 실제 연결된 가상 인터페이스의 이름 등을 확인 할 수 있다.
[root@cy2-deploy ~]#  openstack port  list  -f yaml | grep 172.12.10.4 -A 2
- {Fixed IP Addresses: 'ip_address=''172.12.10.4'', subnet_id=''39f6cf8d-0dc7-45c1-b63b-8cd83623b68d''',
  ID: 8aa5e3b4-6c0b-4d77-8c45-146cacf576ec, MAC Address: 'fa:16:3e:ae:b3:e7', Name: '',
  Status: ACTIVE}
논리적으로 아래 그림과 같이 인스턴스에 해당 포트의 아이디의 아이피가 연결 된것으로 볼 수 있다.
 해당 인스턴스가 실행 되고 있는 compute node에서 "brctl show"를 이용 하여 앞에서 확인한 포트의 아이디  8aa5e3b4-6c 가 있는 브릿지를 확인 해본다.
인스턴스는 tap8aa5e3b4-6c 이름의 가상 인터페이스와 연결 되어 있으며, 해당 tap가상 인터페이스는  qbr8aa5e3b4-6c  이름의  linuxbridge로 연결 되어 있다.
해당 브릿지에 있는  iptables security group을 거친뒤 linuxbridge에는 qvb8aa5e3b4-6c 인터페이스로 패킷으로 보내거나 받는다.
[root@cy2-compute02 ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.0242b0a568b3       no
qbr8aa5e3b4-6c          8000.fa596f2d2f32       no              qvb8aa5e3b4-6c
                                                                            tap8aa5e3b4-6c
compute node의 iptables정책에서 8aa5e3b4-6c  아이디 중 앞의4자리인 8aa5으로 검색하면 아래와 같이  security group의 정책이 iptables의 정책으로 설정 되어 있는 것을 확인 할 수 있다.
[root@cy2-compute02 ~]#  iptables -S | grep 8aa5
-N neutron-openvswi-i8aa5e3b4-6
-N neutron-openvswi-o8aa5e3b4-6
-N neutron-openvswi-s8aa5e3b4-6
-A neutron-openvswi-FORWARD -m physdev --physdev-out tap8aa5e3b4-6c --physdev-is-bridged -m comment --comment "Direct traffic from the VM interface to the security group chain." -j neutron-openvswi-sg-chain
-A neutron-openvswi-FORWARD -m physdev --physdev-in tap8aa5e3b4-6c --physdev-is-bridged -m comment --comment "Direct traffic from the VM interface to the security group chain." -j neutron-openvswi-sg-chain
-A neutron-openvswi-INPUT -m physdev --physdev-in tap8aa5e3b4-6c --physdev-is-bridged -m comment --comment "Direct incoming traffic from VM to the security group chain." -j neutron-openvswi-o8aa5e3b4-6
-A neutron-openvswi-i8aa5e3b4-6 -m state --state RELATED,ESTABLISHED -m comment --comment "Direct packets associated with a known session to the RETURN chain." -j RETURN
-A neutron-openvswi-i8aa5e3b4-6 -d 172.12.10.4/32 -p udp -m udp --sport 67 --dport 68 -j RETURN
-A neutron-openvswi-i8aa5e3b4-6 -d 255.255.255.255/32 -p udp -m udp --sport 67 --dport 68 -j RETURN
-A neutron-openvswi-i8aa5e3b4-6 -p icmp -j RETURN
-A neutron-openvswi-i8aa5e3b4-6 -m set --match-set NIPv415ca6cb4-09b4-418e-aee4- src -j RETURN
-A neutron-openvswi-i8aa5e3b4-6 -p tcp -m tcp -m multiport --dports 1:65535 -j RETURN
-A neutron-openvswi-i8aa5e3b4-6 -m state --state INVALID -m comment --comment "Drop packets that appear related to an existing connection (e.g. TCP ACK/FIN) but do not have an entry in conntrack." -j DROP
-A neutron-openvswi-i8aa5e3b4-6 -m comment --comment "Send unmatched traffic to the fallback chain." -j neutron-openvswi-sg-fallback
-A neutron-openvswi-o8aa5e3b4-6 -s 0.0.0.0/32 -d 255.255.255.255/32 -p udp -m udp --sport 68 --dport 67 -m comment --comment "Allow DHCP client traffic." -j RETURN
-A neutron-openvswi-o8aa5e3b4-6 -j neutron-openvswi-s8aa5e3b4-6
-A neutron-openvswi-o8aa5e3b4-6 -p udp -m udp --sport 68 --dport 67 -m comment --comment "Allow DHCP client traffic." -j RETURN
-A neutron-openvswi-o8aa5e3b4-6 -p udp -m udp --sport 67 --dport 68 -m comment --comment "Prevent DHCP Spoofing by VM." -j DROP
-A neutron-openvswi-o8aa5e3b4-6 -m state --state RELATED,ESTABLISHED -m comment --comment "Direct packets associated with a known session to the RETURN chain." -j RETURN
-A neutron-openvswi-o8aa5e3b4-6 -j RETURN
-A neutron-openvswi-o8aa5e3b4-6 -m state --state INVALID -m comment --comment "Drop packets that appear related to an existing connection (e.g. TCP ACK/FIN) but do not have an entry in conntrack." -j DROP
-A neutron-openvswi-o8aa5e3b4-6 -m comment --comment "Send unmatched traffic to the fallback chain." -j neutron-openvswi-sg-fallback
-A neutron-openvswi-s8aa5e3b4-6 -s 172.12.10.4/32 -m mac --mac-source FA:16:3E:AE:B3:E7 -m comment --comment "Allow traffic from defined IP/MAC pairs." -j RETURN
-A neutron-openvswi-s8aa5e3b4-6 -m comment --comment "Drop traffic without an IP/MAC allow rule." -j DROP
-A neutron-openvswi-sg-chain -m physdev --physdev-out tap8aa5e3b4-6c --physdev-is-bridged -m comment --comment "Jump to the VM specific chain." -j neutron-openvswi-i8aa5e3b4-6
-A neutron-openvswi-sg-chain -m physdev --physdev-in tap8aa5e3b4-6c --physdev-is-bridged -m comment --comment "Jump to the VM specific chain." -j neutron-openvswi-o8aa5e3b4-6
[root@cy2-compute02 ~]#
위 linux bridge 과정을 추가한 구성도를 보면 아래와 같은 구성인 것을 확인 할 수 있다.
ovs-vsctl show 명령어를 통하여 openvswitch 를 통하여 관리 되는 브릿지 들의 정보를 확인 한다.
이중 qvb8aa5e3b4-6c 와 연결되어 있는  br-int를 확인 해봐야 한다. br-int에는 qvo8aa5e3b4-6c 이름의 인터페이스가 qvb와 연결 되어 있다.
[root@cy2-compute02 ~]# docker exec -uroot -it neutron_openvswitch_agent ovs-vsctl show
27dd7152-b796-4d59-b1a7-afc5ee8d9889
    Manager "ptcp:6640:127.0.0.1"
        is_connected: true
    Bridge br-tun
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port patch-int
            Interface patch-int
                type: patch
                options: {peer=patch-tun}
        Port br-tun
            Interface br-tun
                type: internal
        Port "vxlan-0a0a140d"
            Interface "vxlan-0a0a140d"
                type: vxlan
                options: {df_default="true", in_key=flow, local_ip="10.10.20.22", out_key=flow, remote_ip="10.10.20.13"}
        Port "vxlan-0a0a140b"
            Interface "vxlan-0a0a140b"
                type: vxlan
                options: {df_default="true", in_key=flow, local_ip="10.10.20.22", out_key=flow, remote_ip="10.10.20.11"}
        Port "vxlan-0a0a140c"
            Interface "vxlan-0a0a140c"
                type: vxlan
                options: {df_default="true", in_key=flow, local_ip="10.10.20.22", out_key=flow, remote_ip="10.10.20.12"}
    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port patch-tun
            Interface patch-tun
                type: patch
                options: {peer=patch-int}
        Port "qr-56718ce4-c6"
            tag: 1
            Interface "qr-56718ce4-c6"
                type: internal
        Port "fg-38f32d91-3d"
            tag: 2
            Interface "fg-38f32d91-3d"
                type: internal
        Port br-int
            Interface br-int
                type: internal
        Port "qvo8aa5e3b4-6c"
            tag: 1
            Interface "qvo8aa5e3b4-6c"
        Port int-br-ex
            Interface int-br-ex
                type: patch
                options: {peer=phy-br-ex}
    Bridge br-ex
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port br-ex
            Interface br-ex
                type: internal
        Port phy-br-ex
            Interface phy-br-ex
                type: patch
                options: {peer=int-br-ex}
        Port "eth4"
            Interface "eth4"
 
ovs-appctl 를 사용하여 mac address table을 확인 하기 위해서는 해당 openvswitch의 pid나, ctl파일을 지정 해야 한다.
kolla로 배포 할 경우 이름 특정 번호로 생성 되기 때문에 ls 를 사용 하여 파일 이름을 확인 한다.
[root@cy-compute01 ~]#   docker exec -it openvswitch_vswitchd  ls -a /var/run/openvswitch/ovs-vswitchd.*.ctl
/var/run/openvswitch/ovs-vswitchd.14.ctl
이제 ovs-appctl  명령어에 fdb/show 옵션을 추가(FDB→forward data base) 하고 위에서 확인한 ctl파일을 지정 하여 br-int의 mac address table을 확인 하여 본다.
일반적인 L2 스위치의 FDB와 동일한 형태로 vlan 과 포워딩될 포트의 이름 aging time이 표현 된다.
앞에서 확인한  Default gateway(172.12.10.1) 의 mac address가 fa:16:3e:78:d6:60 라는 것을 확인 했었다. 해당 테이블에서 fa:16:3e:78:d6:60  주소는 vlan 1으로 설정 4번 포트로 포워딩 되도록 설정 되어 있다.
[root@cy-compute01 ~]# docker exec -it openvswitch_vswitchd  ovs-appctl -t /var/run/openvswitch/ovs-vswitchd.14.ctl  fdb/show br-int
port  VLAN  MAC                Age
    1     2  a0:c5:89:0e:a6:c8  297
    1     2  52:54:00:0d:10:e8  264
    1     2  00:14:5e:0a:80:66  240
    1     2  00:0c:29:93:61:b3  187
    1     2  7e:a1:17:1c:0d:ca  168
    1     2  c4:85:08:cf:12:8c  166
    1     2  00:1a:4a:16:01:ae  141
    1     2  40:9c:28:5b:2a:80  126
    1     2  28:d2:44:a0:a2:9b  122
...
    4     1  fa:16:3e:78:d6:60    0

포워딩 될 포트를 알았으니, 해당 포트가 어떤 인터페이스인지 확인 해본다. ovs-ofctl show 명령어는 해당 브릿지의 포트의 정보를 확인 할 수 있는 명령어다.
4번포트에는  qr-56718ce4-c6 이름의 인터페이스로 되어 있으며 172.12.10.1 은 해당 이름의 포트로 포워딩 된다.
[root@cy2-compute02 ~]#  docker exec -it openvswitch_vswitchd  ovs-ofctl show br-int
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000de935f730140
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
1(int-br-ex): addr:fa:08:89:2f:91:b9
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
2(patch-tun): addr:c6:3b:47:ae:1a:54
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
4(qr-56718ce4-c6): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
6(fg-38f32d91-3d): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
8(qvo8aa5e3b4-6c): addr:ce:a3:0f:17:54:f8
     config:     0
     state:      0
     current:    10GB-FD COPPER
     speed: 10000 Mbps now, 0 Mbps max
LOCAL(br-int): addr:de:93:5f:73:01:40
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
  qr-56718ce4-c6 인터페이스는 이름에서 유추 할 수 있는 것 처럼 라우터 네임스페이스 연결 되는 가상인터페이스이다.
해당 노드의 namespace를 확인하면 qrouter-65710e96-0467-4281-9ada-63d3bdd4cd5e 라우터 네임스페이스를 확인 할 수 있다.
[root@cy2-compute02 ~]# ip netns
fip-eddc07d8-7544-4f3a-b9f4-27f005fb114f
qrouter-d3218b9c-73bb-4788-87e4-5828625fe586
해당 네임스페이스의 인터페이스를 확인해보자.
  qr-56718ce4-c6  인터페이스가 해당 네임스페이스에 있는 것을 볼 수 있다.   qr-56718ce4-c6  인터페이스는 172.12.10.0/24 대역의 게이트웨이인 172.12.10.1 이 할당 되어 있다.
vm은 해당 gateway 가 있는 네임스페이스 까지 패킷이 포워딩 된다.
[root@cy2-compute02 ~]# ip netns exec qrouter-d3218b9c-73bb-4788-87e4-5828625fe586 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    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
2: rfp-d3218b9c-7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 96:80:29:54:59:f6 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 169.254.106.114/31 scope global rfp-d3218b9c-7
       valid_lft forever preferred_lft forever
    inet6 fe80::9480:29ff:fe54:59f6/64 scope link
       valid_lft forever preferred_lft forever
15: qr-56718ce4-c6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN qlen 1000
    link/ether fa:16:3e:78:d6:60 brd ff:ff:ff:ff:ff:ff
    inet 172.12.10.1/24 brd 172.12.10.255 scope global qr-56718ce4-c6
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fe78:d660/64 scope link
       valid_lft forever preferred_lft forever
qrouter 의 namespace까지의 구성을 보면 아래와 같은 그림으로 구성 된것을 확인 한다.
qrouter namespace에서는 fip  사용 유무에 따라서 s/dnat 를 수행 한다. 현 과정은 instance에서 외부 인터넷으로 나가기 때문에 내부  아이피172.12.10.4 아이피가 fip 192.168.10.106으로 snat 되야 한다. qrouter namespace 에서 nat 테이블에 neutron-l3-agent-float-snat 체인에서 출발지 아이피 172.12.10.4 아이피가 192.168.10.106 으로 snat되는 부분을 iptables에서 확인 할 수 있다.  (-A neutron-l3-agent-float-snat -s 172.12.10.4/32 -j SNAT --to-source 192.168.10.106)
[root@cy2-compute02 ~]# ip netns exec qrouter-d3218b9c-73bb-4788-87e4-5828625fe586 iptables -S -t nat
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N neutron-l3-agent-OUTPUT
-N neutron-l3-agent-POSTROUTING
-N neutron-l3-agent-PREROUTING
-N neutron-l3-agent-float-snat
-N neutron-l3-agent-snat
-N neutron-postrouting-bottom
-A PREROUTING -j neutron-l3-agent-PREROUTING
-A OUTPUT -j neutron-l3-agent-OUTPUT
-A POSTROUTING -j neutron-l3-agent-POSTROUTING
-A POSTROUTING -j neutron-postrouting-bottom
-A neutron-l3-agent-POSTROUTING ! -i rfp-d3218b9c-7 ! -o rfp-d3218b9c-7 -m conntrack ! --ctstate DNAT -j ACCEPT
-A neutron-l3-agent-PREROUTING -d 192.168.10.106/32 -i rfp-d3218b9c-7 -j DNAT --to-destination 172.12.10.4
-A neutron-l3-agent-PREROUTING -d 169.254.169.254/32 -i qr-+ -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 9697
-A neutron-l3-agent-float-snat -s 172.12.10.4/32 -j SNAT --to-source 192.168.10.106
-A neutron-l3-agent-snat -j neutron-l3-agent-float-snat
-A neutron-postrouting-bottom -m comment --comment "Perform source NAT on outgoing traffic." -j neutron-l3-agent-snat
해당 nat 과정을 거친 패킷은 외부로 어떻게 나갈까? 단순하게 qrouter namespace에서 route명령어로 확인 하면 어떤 인터페이스로 가야 할지 모른다.
[root@cy2-compute02 ~]# ip netns exec qrouter-d3218b9c-73bb-4788-87e4-5828625fe586 route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
169.254.106.114 0.0.0.0         255.255.255.254 U     0      0        0 rfp-d3218b9c-7
172.12.10.0     0.0.0.0         255.255.255.0   U     0      0        0 qr-56718ce4-c6
ip 명령어로 라우팅 테이블의 rule 을 확인 하면 기본적으로 있는 main,local,default외에 추가적인 rule을 볼 수 있다.
[root@cy2-compute02 ~]# ip netns exec qrouter-d3218b9c-73bb-4788-87e4-5828625fe586 ip rule ls
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default
57481:  from 172.12.10.4 lookup 16
2886470145:     from 172.12.10.1/24 lookup 2886470145
main,local,default 에서 처리 되지 못한 패킷이 16 이라는 라우팅 테이블에서 default 라우팅 되어 있는것을 볼 수 있다.(숫자가 main,default,local 보다 숫자가 높기 때문에)
즉, 16 라우팅 테이블에서 아래와 같이 169.254.106.115 아이피를 목적으로  rfp-d3218b9c-7 인터페이스를 통하여 snat 되어 패킷이 간다는 것을 알 수 있다.
[root@cy2-compute02 ~]# ip netns exec qrouter-d3218b9c-73bb-4788-87e4-5828625fe586 ip route ls table 16
default via 169.254.106.115 dev rfp-d3218b9c-7
다시 qrouter namspace에서   rfp-d3218b9c-7 인터페이스를 확인 하면 169.254.106.114 로 할당 되어 있다.
[root@cy2-compute02 ~]# ip netns exec qrouter-d3218b9c-73bb-4788-87e4-5828625fe586 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    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
2: rfp-d3218b9c-7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 96:80:29:54:59:f6 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 169.254.106.114/31 scope global rfp-d3218b9c-7
       valid_lft forever preferred_lft forever
    inet6 fe80::9480:29ff:fe54:59f6/64 scope link
       valid_lft forever preferred_lft forever
15: qr-56718ce4-c6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN qlen 1000
    link/ether fa:16:3e:78:d6:60 brd ff:ff:ff:ff:ff:ff
    inet 172.12.10.1/24 brd 172.12.10.255 scope global qr-56718ce4-c6
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fe78:d660/64 scope link
       valid_lft forever preferred_lft forever
rfp-d3218b9c-7  인터페이스는 fip-eddc07d8-75 namespace에  fpr-d3218b9c-7 인터페이스와 peer to peer로 연결 되어 있어 해당 qrouter에서 처리된 패킷이 fip 으로 포워딩 된다.
또한  같은 namespace안에 있는 fg-38f32d91-3d 는  fip와 같은 대역을 같은 아이피로 floating ip의 gateway역할을 한다. (외부->내부)
[root@cy2-compute02 ~]# ip netns
fip-eddc07d8-7544-4f3a-b9f4-27f005fb114f
qrouter-d3218b9c-73bb-4788-87e4-5828625fe586
[root@cy2-compute02 ~]# ip netns exec fip-eddc07d8-7544-4f3a-b9f4-27f005fb114f ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    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
2: fpr-d3218b9c-7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether f2:d4:ad:59:11:7d brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 169.254.106.115/31 scope global fpr-d3218b9c-7
       valid_lft forever preferred_lft forever
    inet6 fe80::f0d4:adff:fe59:117d/64 scope link
       valid_lft forever preferred_lft forever
16: fg-38f32d91-3d: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN qlen 1000
    link/ether fa:16:3e:30:c9:5b brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.103/16 brd 192.168.255.255 scope global fg-38f32d91-3d
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fe30:c95b/64 scope link
       valid_lft forever preferred_lft forever
[root@cy2-compute02 ~]#
fip namespace 도 동일하게 route table 중 가장 마지막 table에서  fip의 실제 gateway인 192.168.0.1.아이피를 목적으로  fg인터페이스로 연결 보내도록 설정 되어 있어서
인스턴스에서 보낸 패킷이 fg패킷을 통하여 포워딩 된다.
[root@cy2-compute02 ~]# ip netns exec fip-eddc07d8-7544-4f3a-b9f4-27f005fb114f ip rule
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default
2852022899:     from all iif fpr-d3218b9c-7 lookup 2852022899
[root@cy2-compute02 ~]# ip netns exec fip-eddc07d8-7544-4f3a-b9f4-27f005fb114f ip route ls table 2852022899
default via 192.168.0.1 dev fg-38f32d91-3d
fg-38f32d91-3d 인터페이스는 다시 br-int 브릿지로 연결 된다. 아래와 같이 fg-38f32d91-3d 이름으로 연결 되어 있는것을 확인 할 수 있다
[root@cy2-compute02 ~]# docker exec -uroot -it neutron_openvswitch_agent ovs-vsctl show
...
    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port patch-tun
            Interface patch-tun
                type: patch
                options: {peer=patch-int}
        Port "qr-56718ce4-c6"
            tag: 1
            Interface "qr-56718ce4-c6"
                type: internal
        Port "fg-38f32d91-3d"
            tag: 2
            Interface "fg-38f32d91-3d"
                type: internal
        Port br-int
            Interface br-int
                type: internal
        Port "qvo8aa5e3b4-6c"
            tag: 1
            Interface "qvo8aa5e3b4-6c"
        Port int-br-ex
            Interface int-br-ex
                type: patch
                options: {peer=phy-br-ex}
...

지금까지 따라온 구조를 보면 아래와 같이 인스턴스에서  qbr 리눅스 브릿지를 통하여 security group 을 거쳤으며, 그뒤 br-int라는 openVswitch 브릿지를 통하여 qrouter namspace로 들어 온뒤
snat되어 fip namespace로 전달 되고, 다시 br-int까지 내려오는 구조라는 것을 확인 하였다.
이제 br-int에서 외부 gateway인 192.168.0.1이 어떻게 나가는지 확인 해야 한다.
arp -a 를 통하여 192.168.0.1의  mac주소를 90:9f:33:65:47:02 라는 것을  확인 한다.
[root@cy2-deploy ~]# arp -a | grep 192.168.0.1
gateway (192.168.0.1) at 90:9f:33:65:47:02 [ether] on eth1
br-int의 mac address table 에서 해당 mac이 1번 포트로 포워딩 되는 것을 확인 할 수 있으며,
1번 포트에는 int-br-ex 라는 인터페이스가 연결 되어 있는 것을 확인 할 수 있다.
[root@cy2-compute02 ~]# docker exec -it openvswitch_vswitchd  ovs-appctl -t /var/run/openvswitch/ovs-vswitchd.14.ctl  fdb/show br-int | grep 90:9f:33:65:47:02
port  VLAN  MAC                Age
    1     2  f8:63:3f:26:27:0d  209
    1     2  e4:2b:34:25:3f:08  194
    1     2  da:4e:e4:94:06:71  180
    1     2  52:54:00:8c:91:81  178
    1     2  82:58:13:e7:2c:9b  158
....
    1     2  90:9f:33:65:47:02    2
[root@cy2-compute02 ~]# docker exec -it openvswitch_vswitchd  ovs-ofctl show br-int
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000de935f730140
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
1(int-br-ex): addr:fa:08:89:2f:91:b9
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
2(patch-tun): addr:c6:3b:47:ae:1a:54
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
4(qr-56718ce4-c6): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
6(fg-38f32d91-3d): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
8(qvo8aa5e3b4-6c): addr:ce:a3:0f:17:54:f8
     config:     0
     state:      0
     current:    10GB-FD COPPER
     speed: 10000 Mbps now, 0 Mbps max
LOCAL(br-int): addr:de:93:5f:73:01:40
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
다시 ovs-vsctl 을 통하여 브릿지들의 정보를 보면 int-br-ex 포트가 phy-br-ex 포트워 patch 타입으로 연결 되어 있으며 phy-br-ex는 br-ex 라는 브릿지에 속하여 있다.
br-ex에서는 최종적으로 포트 eth4을 통하여 나가며,해당 포트는 실제 인터 페이스 eth4를 통하여 포워딩 된다.
[root@cy2-compute02 ~]# docker exec -it openvswitch_vswitchd  ovs-vsctl show
...
    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
...
        Port int-br-ex
            Interface int-br-ex
                type: patch
                options: {peer=phy-br-ex}
    Bridge br-ex
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port br-ex
            Interface br-ex
                type: internal
        Port phy-br-ex
            Interface phy-br-ex
                type: patch
                options: {peer=int-br-ex}
        Port "eth4"
            Interface "eth4"
최종적으로는 아래와 같은 형태로 실제 물리 인터페이스 eth4를 통하여 패킷이 gateway까지 포워딩 된다.

2. North-south traffic(internet → vm)

vm의 fip 인 192.168.10.106의 arp를 확인 하고, 해당 arp와 동일한  mac 주소를 확인 하면 192.168.10.103이라는 아이피를 확인 할 수 있다.
[root@cy2-deploy ~]# arp -a | grep 192.168.10.106
? (192.168.10.106) at fa:16:3e:30:c9:5b [ether] on eth1
[root@cy2-deploy ~]# arp -a | grep  fa:16:3e:30:c9:5b
? (192.168.10.106) at fa:16:3e:30:c9:5b [ether] on eth1
? (192.168.10.103) at fa:16:3e:30:c9:5b [ether] on eth1
192.168.10.103은 해당 vm이 있는 노드의  fip가 포워딩 되는 fip namespace에서 fg 인터페이스에 할당 된 아이피로, 해당 인터페이스에서 
Proxy Arp( 자신이 알고 있는 network 의 정보에 대하여 대신해서  arp응답을 해주는 기능)를 통하여 vm이 있는 네트워크 까지 올 수 있도록 해준다.
[root@cy2-compute02 ~]# ip netns exec fip-eddc07d8-7544-4f3a-b9f4-27f005fb114f ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    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
2: fpr-d3218b9c-7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether f2:d4:ad:59:11:7d brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 169.254.106.115/31 scope global fpr-d3218b9c-7
       valid_lft forever preferred_lft forever
    inet6 fe80::f0d4:adff:fe59:117d/64 scope link
       valid_lft forever preferred_lft forever
16: fg-38f32d91-3d: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN qlen 1000
    link/ether fa:16:3e:30:c9:5b brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.103/16 brd 192.168.255.255 scope global fg-38f32d91-3d
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fe30:c95b/64 scope link
       valid_lft forever preferred_lft forever
아래 그림과 같이 (1) 이 있는 부분으로 외부 게이트웨이를 통하여 들어온 패킷이 fg까지 가기 위해서(2)br-ex의 port eth4와 pyh-br-ex 를 거쳐서 br-int로 가게 된다.
(3)에서 br-int의  fg 포트를 통하여 fip namespace의 fg 인터페이스 192.168.10.103까지 전달 된다.
mac을 통하여 fip namespace에 왔지만 실제 fip 192.168.10.106을 찾아 가야 한다.  fip라우팅 테이블을 확인 하면 fpr-d3218b9c-7 인터페이스를 통하여 qrouter로 포워딩 되게 설정 되어 있다.
[root@cy2-compute02 ~]# ip netns exec fip-eddc07d8-7544-4f3a-b9f4-27f005fb114f route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
169.254.106.114 0.0.0.0         255.255.255.254 U     0      0        0 fpr-d3218b9c-7
192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 fg-38f32d91-3d
192.168.10.106  169.254.106.114 255.255.255.255 UGH   0      0        0 fpr-d3218b9c-7
qrouter로 들어온 패킷은  iptables 의 nat테이블에서 DNAT되어 도착지 아이피가  fip가 아닌 실제 할당된 내부 아이피로 변환 된다.
(-A neutron-l3-agent-PREROUTING -d 192.168.10.106/32 -i rfp-d3218b9c-7 -j DNAT --to-destination 172.12.10.4)
[root@cy2-compute02 ~]# ip netns exec qrouter-d3218b9c-73bb-4788-87e4-5828625fe586 iptables -S -t nat
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N neutron-l3-agent-OUTPUT
-N neutron-l3-agent-POSTROUTING
-N neutron-l3-agent-PREROUTING
-N neutron-l3-agent-float-snat
-N neutron-l3-agent-snat
-N neutron-postrouting-bottom
-A PREROUTING -j neutron-l3-agent-PREROUTING
-A OUTPUT -j neutron-l3-agent-OUTPUT
-A POSTROUTING -j neutron-l3-agent-POSTROUTING
-A POSTROUTING -j neutron-postrouting-bottom
-A neutron-l3-agent-POSTROUTING ! -i rfp-d3218b9c-7 ! -o rfp-d3218b9c-7 -m conntrack ! --ctstate DNAT -j ACCEPT
-A neutron-l3-agent-PREROUTING -d 192.168.10.106/32 -i rfp-d3218b9c-7 -j DNAT --to-destination 172.12.10.4
-A neutron-l3-agent-PREROUTING -d 169.254.169.254/32 -i qr-+ -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 9697
-A neutron-l3-agent-float-snat -s 172.12.10.4/32 -j SNAT --to-source 192.168.10.106
-A neutron-l3-agent-snat -j neutron-l3-agent-float-snat
-A neutron-postrouting-bottom -m comment --comment "Perform source NAT on outgoing traffic." -j neutron-l3-agent-snat
172.12.10.4의 내부 아이피로 nat된 도착지 아이피는  qrouter namespace의 라우팅 테이블에 의하여  qr-56718ce4-c6 인터페이스로 포워딩 된다.
[root@cy2-compute02 ~]# ip netns exec qrouter-d3218b9c-73bb-4788-87e4-5828625fe586 route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
169.254.106.114 0.0.0.0         255.255.255.254 U     0      0        0 rfp-d3218b9c-7
172.12.10.0     0.0.0.0         255.255.255.0   U     0      0        0 qr-56718ce4-c6
qr-56718ce4-c6는 위에서 확인 한 것 처럼  br-int에 연결 되어 있는데, br-int의 mac address table을 확인 하면 8번 포트의  
qvo8aa5e3b4-6c 로 qbr8aa5e3b4-6c 의 리눅스 브릿지를 통하여 까지 패킷이 포워딩 된다.
[root@cy2-compute02 ~]# ip netns exec qrouter-d3218b9c-73bb-4788-87e4-5828625fe586 arp -a  | grep 172.12.10.4
? (172.12.10.4) at fa:16:3e:ae:b3:e7 [ether] PERM on qr-56718ce4-c6


[root@cy2-compute02 ~]# docker exec -it openvswitch_vswitchd  ovs-appctl -t /var/run/openvswitch/ovs-vswitchd.14.ctl  fdb/show br-int| grep fa:16:3e:ae:b3:e7
port  VLAN  MAC                Age
....
    8     1  fa:16:3e:ae:b3:e7    0


[root@cy2-compute02 ~]# docker exec -it openvswitch_vswitchd  ovs-ofctl show br-int

....
8(qvo8aa5e3b4-6c): addr:ce:a3:0f:17:54:f8
     config:     0
     state:      0
     current:    10GB-FD COPPER
     speed: 10000 Mbps now, 0 Mbps max
....
아래 그림과 같이 (6)을 통하여 br-int로 전달 되고,  br-int에서 qbr을 거쳐서 vm으로 전달 되는 과정이다.

 

반응형