10 Docker0网络详解

Docker 网络

理解Docker0网络

  • 测试

    三个网络: lo,eth0, docker0/podman0

    Docker是如何处理容器网络访问的?

    [root@localhost ~]# 
    [root@localhost ~]# ip ad sh
    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
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
        link/ether 00:e0:70:2b:4e:1a brd ff:ff:ff:ff:ff:ff
        inet 192.168.73.10/24 brd 192.168.73.255 scope global noprefixroute eth0
           valid_lft forever preferred_lft forever
    3: cni-podman0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
        link/ether 0e:b7:b0:23:cb:d9 brd ff:ff:ff:ff:ff:ff
        inet 10.88.0.1/16 brd 10.88.255.255 scope global cni-podman0
           valid_lft forever preferred_lft forever
    
    # 启动刚才上传到阿里云的tomcat9:
    
    [root@localhost ~]# podman run -p 9080:8080 --name "tomcat9" -d c379423344cf
    ec72ee25696946790ede78dbcf98148601a63f399f05dd91cfaf5c05f9fc10db
    [root@localhost ~]#
    [root@localhost ~]# podman ps
    CONTAINER ID  IMAGE                                                       COMMAND               CREATED        STATUS            PORTS                   NAMES
    ec72ee256969  registry.cn-chengdu.aliyuncs.com/diablofmb/diablofmb:1.0    /bin/sh -c /usr/l...  9 seconds ago  Up 7 seconds ago  0.0.0.0:9080->8080/tcp  tomcat9
    
    
    # 查看网络信息
    [root@localhost ~]# podman exec ec72ee256969 ip ad sh
    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
    3: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
        link/ether 3a:3d:af:4a:e5:7e brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet 10.88.0.11/16 brd 10.88.255.255 scope global eth0
           valid_lft forever preferred_lft forever
    
    # 容器启动时,podman会给容器分配网络网卡eth0@if13,以及配置网络地址
    
    # 思考. linux 内部能否ping通容器地址。
    [root@localhost ~]# ping 10.88.0.11
    PING 10.88.0.11 (10.88.0.11) 56(84) bytes of data.
    64 bytes from 10.88.0.11: icmp_seq=1 ttl=64 time=0.140 ms
    ^C
    --- 10.88.0.11 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.140/0.140/0.140/0.000 ms
    [root@localhost ~]# 
    

    原理是怎样?

    1. 我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个docker0/podman0 网卡,桥接模式,使用的evth-apir技术!!
    # 我们发现,容器新增的网卡,都是成对出现。
    # evth-pair 就是一对的虚拟设备接口,它们都是成对出现的。一端连接着协议,另一端彼此相连。
    # 正因为有这样的特性,evth-pair就可以充当一个桥梁,链接各种虚拟网络设备。
    # OpenStack,Docker容器之间的链接,OVS(OpenVSwitch) 的链接,都是使用evth-pair技术。
    
    
    # 可以看到,docker0上链接着两个另外的虚拟网卡,而这个网卡另一端,就是容器内的地址
    [root@Simon_Phicomm-N1:~]# brctl show
    bridge name     bridge id               STP enabled     interfaces
    docker0         8000.0242ec32f694       no              veth0991058
                                                            vethb6b413f
    br-faf39c0b6e58         8000.02426946e4cc       no
    [root@Simon_Phicomm-N1:~]#
    
    # 查看一下防火墙规则,在POSTROUTING可以看到一条规则
    [root@Simon_Phicomm-N1:~]# iptables -t nat -xvnL
    ......
    Chain POSTROUTING (policy ACCEPT 1 packets, 76 bytes)
    pkts   bytes target     prot opt in     out     source               destination
    35     1481 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0
    ......
    [root@Simon_Phicomm-N1:~]#
    
    # 35     1481 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0
    # 从任何接口进来,只要不是从docker0网络接口出去的数据包,源地址是172.17.0.0/16,不管到什么地址
    # 0.0.0.0/0,自动做MASQUERADE(地址伪装),而且是自动SNAT,就是自动在本机上物理网卡中,选择一个
    # 最合适的源地址做伪装。
    
    # ## 所以说docker0桥,是NAT桥,就是这个原因
    
    

    结论

    容器和容器之间是可以互相ping通的。

    容器和容器之间共用一个网桥路由,Docker0/Podman0

    所有容器在不指定网络的情况下,都是docker0路由,docker会给容器分配一个默认可用的IP。

    docker中所有的网络接口都是虚拟的,因为虚拟的转发效率高!

    自定义网络

    • 查看所有的docker网络
    [root@Simon_Phicomm-N1:~]# docker network --help
    
    Usage:  docker network COMMAND
    
    Manage networks
    
    Commands:
      connect     Connect a container to a network
      create      Create a network
      disconnect  Disconnect a container from a network
      inspect     Display detailed information on one or more networks
      ls          List networks
      prune       Remove all unused networks
      rm          Remove one or more networks
    
    Run 'docker network COMMAND --help' for more information on a command.
      
      
      
    [root@Simon_Phicomm-N1:~]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    8e2a5c39c11b        bridge              bridge              local
    706910adfed0        host                host                local
    f6da1cad8b8f        macnet              macvlan             local
    eb985bc0f88e        none                null                local
    

    网络模式

    • bridge:桥接,docker (默认,自己创建网络,也用bridge模式)
    • none: 不配置网络
    • host:和宿主机共享网络
    • container:容器网络连通!(用的少,局限性大,了解就行)

    创建自定义网络:

    [root@Simon_Phicomm-N1:~]# docker network create --help
    
    Usage:  docker network create [OPTIONS] NETWORK
    
    Create a network
    
    Options:
          --attachable           Enable manual container attachment
          --aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
          --config-from string   The network from which copying the configuration
          --config-only          Create a configuration only network
      -d, --driver string        Driver to manage the Network (default "bridge")
          --gateway strings      IPv4 or IPv6 Gateway for the master subnet
          --ingress              Create swarm routing-mesh network
          --internal             Restrict external access to the network
          --ip-range strings     Allocate container ip from a sub-range
          --ipam-driver string   IP Address Management Driver (default "default")
          --ipam-opt map         Set IPAM driver specific options (default map[])
          --ipv6                 Enable IPv6 networking
          --label list           Set metadata on a network
      -o, --opt map              Set driver specific options (default map[])
          --scope string         Control the network's scope
          --subnet strings       Subnet in CIDR format that represents a network segment
    
    
    # 需要用到的参数:
    # 指定网络模式,默认为bridge
    -d, --driver string        Driver to manage the Network (default "bridge")
    # 掩码
    	--subnet strings       Subnet in CIDR format that represents a network segment
    # 网关
    	--gateway strings      IPv4 or IPv6 Gateway for the master subnet
    
    
    [root@Simon_Phicomm-N1:~]# docker network create --driver bridge --subnet 192.168.78.0/24 --gateway 192.168.78.1 net_test
    faf39c0b6e584c56e46964beeb0c6752225a98128d9e08afc133761198dbeae2
    [root@Simon_Phicomm-N1:~]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    8e2a5c39c11b        bridge              bridge              local
    706910adfed0        host                host                local
    f6da1cad8b8f        macnet              macvlan             local
    faf39c0b6e58        net_test            bridge              local
    eb985bc0f88e        none                null                local
    [root@Simon_Phicomm-N1:~]# docker network inspect net_test
    [
        {
            "Name": "net_test",
            "Id": "faf39c0b6e584c56e46964beeb0c6752225a98128d9e08afc133761198dbeae2",
            "Created": "2020-09-20T13:34:54.442270485+08:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": {},
                "Config": [
                    {
                        "Subnet": "192.168.78.0/24",
                        "Gateway": "192.168.78.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {},
            "Options": {},
            "Labels": {}
        }
    ]
    [root@Simon_Phicomm-N1:~]#
    
    
    # 启动容器两个容器,测试网络
    [root@Simon_Phicomm-N1:~]# docker run -d -P --name "tomcat-net-01“ --net net_test tomcat
    [root@Simon_Phicomm-N1:~]# docker run -d -P --name "tomcat-net-02” --net net_test tomcat
    [root@Simon_Phicomm-N1:~]# docker exec -it tomcat-net-01 ping tomcat-net-02
    [root@Simon_Phicomm-N1:~]# docker exec -it tomcat-net-02 ping tomcat-net-01
    
    # 自定义网络,docker已经维护好对应关系,可以通过主机名直接ping通链接。
    # 好处:
    # 不同集群,使用不同的网络,保证集群是安全和健康的
    
    

    网络连通的操作

    [root@Simon_Phicomm-N1:~]# docker network connect --help
    
    Usage:  docker network connect [OPTIONS] NETWORK CONTAINER
    
    Connect a container to a network
    
    Options:
          --alias strings           Add network-scoped alias for the container
          --ip string               IPv4 address (e.g., 172.30.100.104)
          --ip6 string              IPv6 address (e.g., 2001:db8::33)
          --link list               Add link to another container
          --link-local-ip strings   Add a link-local address for the container
    
    

    开启docker的远程连接:

    docker服务是可以被远程连接的,默认docker服务只显示本机资源,也就是sock接口

    [root@Simon_Phicomm-N1:~]# ll /var/run/docker.sock
    srw-rw----    1 root     root           0 Aug 24 20:40 /var/run/docker.sock
    
    # 修改docker的daemon.json,添加tcp服务监听端口2375,不要忘记保留原docker.sock方式
    # bip 参数是为 docker0 网桥指定地址
    [root@Simon_Phicomm-N1:~]# cat /etc/docker/daemon.json
    {
      "storage-driver": "overlay2",
      "registry-mirrors": ["https://hvs1rb9d.mirror.aliyuncs.com", "https://quay.io" ],
      "bip":  "10.0.0.1/16" ,
      "hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock" ]
    }
    [root@Simon_Phicomm-N1:~]#systemctl reload docker
    
    
posted @ 2022-11-24 20:45  oldSimon  阅读(202)  评论(0编辑  收藏  举报