暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Docker

运维扫盲人 2021-08-29
593

一、Docker网络bridge模型

bridge网络模型:创建容器时会自动创建一对veth,一端在docker0桥上,一端在容器名称空间中,容器借助NAT规则来实现暴露容器服务或者容器访问外网;

host网络模型:容器与host共用网络名称空间,要求容器的IP地址与容器服务的端口号与host不能冲突。

1.1 bridge桥

    bridge name  bridge id          STP   enabled   interfaces
    docker0 8000.02423ff697d4 no veth72f924e
    veth899f774

      ~]$ docker  network ls
      NETWORK ID NAME DRIVER SCOPE
      bf78f07fecab bridge bridge local
      208d9a020e57 host host local
      9cd732fd1232 none null local
        ~]$ docker  network inspect bf78f07fecab
        [
        {
        "Name": "bridge",
        "Id": "bf78f07fecab039033608265bed6e1d53a10e037bb996c58d28d86f491bf5cc2",
        "Created": "2021-04-19T12:40:01.789430412+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
        "Driver": "default",
        "Options": null,
        "Config": [
        {
        "Subnet": "172.18.0.0/16",
        "Gateway": "172.18.0.1"
        }
        ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
        "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
        "55e747767bf618a458533e601ebe11308a1ab2e86ec3450bc880ff671c751d6e": {
        "Name": "repository",
        "EndpointID": "44c5ede5faf9a9eaefb49d3a93eb855f82a8cfc1ebda93dd475612039e430081",
        "MacAddress": "02:42:ac:12:00:02",
        "IPv4Address": "172.18.0.2/16",
        "IPv6Address": ""
        },
        "ff858669f2ae3770ad10c2321da58116418a336ba49656a9a8b04fb3148b0999": {
        "Name": "nigelpoulton",
        "EndpointID": "e5efe22b548acf81c457dadc3754fde4737d64f2495e0c3fab02d4dbd62df33e",
        "MacAddress": "02:42:ac:12:00:03",
        "IPv4Address": "172.18.0.3/16",
        "IPv6Address": ""
        }
        },
        "Options": {
        "com.docker.network.bridge.default_bridge": "true",
        "com.docker.network.bridge.enable_icc": "true",
        "com.docker.network.bridge.enable_ip_masquerade": "true",
        "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
        "com.docker.network.bridge.name": "docker0",
        "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
        }
        ]

        1.2 container veth

          ~]$ ip link show | grep veth
          30: veth72f924e@if29: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
          42: veth899f774@if41: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default

            [root@file_repository-172.17.61.200 ~]$ docker container exec 2a00f5084711  ip a
            1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
            41: eth0@if42: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
            link/ether 02:42:ac:12:00:04 brd ff:ff:ff:ff:ff:ff
            inet 172.18.0.4/16 brd 172.18.255.255 scope global eth0
            valid_lft forever preferred_lft forever
            [root@file_repository-172.17.61.200 ~]$ docker container exec 55e747767bf6 ip a
            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
            29: eth0@if30: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
            link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
            inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
                   valid_lft forever preferred_lft forever
              [root@file_repository-172.17.61.200 ~]$ docker container exec 55e747767bf6 route  -n
              Kernel IP routing table
              Destination Gateway Genmask Flags Metric Ref Use Iface
              0.0.0.0 172.18.0.1 0.0.0.0 UG 0 0 0 eth0
              172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
              [root@file_repository-172.17.61.200 ~]$ docker container exec 2a00f5084711 route -n
              Kernel IP routing table
              Destination Gateway Genmask Flags Metric Ref Use Iface
              0.0.0.0 172.18.0.1 0.0.0.0 UG 0 0 0 eth0
              172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0

              可以看出容器的gateway均指向docker0桥。

              二、同Host中Docker Container之间通信

                ~]$ docker container exec 2a00f5084711  ping 172.18.0.2

                  ~]$ tcpdump  -i docker0 -nn
                  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
                  listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
                  20:02:37.829256 IP 172.18.0.4 > 172.18.0.2: ICMP echo request, id 26880, seq 16, length 64
                  20:02:37.829358 IP 172.18.0.2 > 172.18.0.4: ICMP echo reply, id 26880, seq 16, length 64
                  20:02:38.829514 IP 172.18.0.4 > 172.18.0.2: ICMP echo request, id 26880, seq 17, length 64
                  20:02:38.829586 IP 172.18.0.2 > 172.18.0.4: ICMP echo reply, id 26880, seq 17, length 64

                  通过抓包分析同Host中的不通container通信通过二层的docker0即可实现,且是二层互通。

                    docker container exec 2a00f5084711  arp -a
                    ? (172.18.0.2) at 02:42:ac:12:00:02 [ether] on eth0
                    ? (172.18.0.1) at 02:42:3f:f6:97:d4 [ether] on eth0

                    三、外网与Docker Container之间通信

                    3.1 Docker Container访问外网

                      ~]$ docker container exec 2a00f5084711  ping 114.114.114.114

                        [root@file_repository-172.17.61.200 ~]$ tcpdump  -i eth0 -nn -p icmp
                        tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
                        listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
                        20:06:13.851823 IP 10.1.120.200 > 114.114.114.114: ICMP echo request, id 29696, seq 44, length 64
                        20:06:13.879199 IP 114.114.114.114 > 10.1.120.200: ICMP echo reply, id 29696, seq 44, length 64
                        20:06:14.249643 IP 10.1.120.200 > 114.114.114.114: ICMP echo request, id 30976, seq 38, length 64
                        20:06:14.276981 IP 114.114.114.114 > 10.1.120.200: ICMP echo reply, id 30976, seq 38, length 64
                        20:06:14.852054 IP 10.1.120.200 > 114.114.114.114: ICMP echo request, id 29696, seq 45, length 64
                        20:06:14.879186 IP 114.114.114.114 > 10.1.120.200: ICMP echo reply, id 29696, seq 45, length 64
                        20:06:15.249888 IP 10.1.120.200 > 114.114.114.114: ICMP echo request, id 30976, seq 39, length 64
                        20:06:15.277086 IP 114.114.114.114 > 10.1.120.200: ICMP echo reply, id 30976, seq 39, length 64


                        [root@file_repository-172.17.61.200 ~]$ tcpdump -i docker0 -nn
                        tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
                        listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
                        20:06:45.858726 IP 172.18.0.4 > 114.114.114.114: ICMP echo request, id 29696, seq 76, length 64
                        20:06:45.885721 IP 172.18.0.4 > 172.18.0.2: ICMP echo request, id 26880, seq 264, length 64
                        20:06:45.885771 IP 172.18.0.2 > 172.18.0.4: ICMP echo reply, id 26880, seq 264, length 64
                        20:06:45.885819 IP 114.114.114.114 > 172.18.0.4: ICMP echo reply, id 29696, seq 76, length 64
                        20:06:46.256739 IP 172.18.0.4 > 114.114.114.114: ICMP echo request, id 30976, seq 70, length 64
                        20:06:46.284265 IP 114.114.114.114 > 172.18.0.4: ICMP echo reply, id 30976, seq 70, length 64
                        20:06:46.858940 IP 172.18.0.4 > 114.114.114.114: ICMP echo request, id 29696, seq 77, length 64
                        20:06:46.885944 IP 172.18.0.4 > 172.18.0.2: ICMP echo request, id 26880, seq 265, length 64

                        通过抓包分析,在docker0抓包结果可看出源地址为172.18.0.4的容器地址,而在eth0的抓包结果看出源地址为eth0的地址,原因是container在访问外网时候进行SNAT。而SNAT中关键的一条规则如下,意思是来自任意网口且地址为172.18.0.0/16,流向非docker0的流量都转换为Host主机地址:

                            ~]$ iptables -t nat -vnL POSTROUTING
                          Chain POSTROUTING (policy ACCEPT 319K packets, 26M bytes)
                          pkts bytes target prot opt in out source destination
                            232 14427 MASQUERADE  all  --  *      !docker0  172.18.0.0/16        0.0.0.0/0           

                          3.2 外网访问Docker Container

                          containe的服务默认是不能被外网访问的,除非使用docker run -p暴露了端口,一旦将container端口暴露在Host上,外界流量就可经由DNAT规则到达container,而每一个暴露的端口在Host都有与之对应的docker-proxy进程。

                            ~]$ iptables -t nat -vnL POSTROUTING
                            Chain POSTROUTING (policy ACCEPT 319K packets, 26M bytes)
                             pkts bytes target     prot opt in     out     source               destination         
                            0 0 MASQUERADE tcp -- * * 172.18.0.2 172.18.0.2 tcp dpt:8060
                            0 0 MASQUERADE tcp -- * * 172.18.0.2 172.18.0.2 tcp dpt:1443
                              ~]$ ps -ef | grep proxy | grep -v grep
                              root 896 1683 0 Jul13 ? 00:00:09 usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 80 -container-ip 172.18.0.2 -container-port 8060
                              root 910 1683 0 Jul13 ? 00:00:08 usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 443 -container-ip 172.18.0.2 -container-port 1443
                              root 1322 1 0 Apr19 ? 00:00:00 usr/sbin/gssproxy -D




                              文章转载自运维扫盲人,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                              评论