• Docker 的网络模式


    简述

    网络模式决定了容器之间互联方式,地址资源的分配空间。处于统一网络的容器可以互通并且可以使用 hostname 访问。
    使用的过程中需要根据 容器之间聚合的关系,是否需要隔离网络地址和转发的效率等方面来选择适合的网络模型。

    dockerd 在启动的时候,会初始化以下三个不同 driver 模式的网络

    NETWORK ID          NAME                        DRIVER              SCOPE
    24e6af25485a        bridge                      bridge              local
    3ad8ec491277        host                        host                local
    9608b5edcc32        none                        null                local
    

    因为第四种 joined-container 模式需要依托于一个运行时容器,所以并没有对应的初始网络。

    同时由于 bridge 桥接模式需要一个 "网关", 所以还会有一个 docker0 虚拟网卡在 "宿主机" 上面。

    3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
        link/ether 02:42:7b:1d:8f:e4 brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
           valid_lft forever preferred_lft forever
        inet6 fe80::42:7bff:fe1d:8fe4/64 scope link 
           valid_lft forever preferred_lft forever
    

    之前使用的容器网络互连方式(Deprecated)

    在容器启动时加上 --link <container_id|container_name[:alias]> 参数,可以使得新创建的容器在启动的时候自动添加环境变量和 hosts 参数(由于容器无论是哪一种网络模式,在宿主机上都是可以使用IP寻址的),从而实现互通。
    这种方式适用于临时容器的连接,例如使用一个工具容器来 link 到现有的容器中进行网络测试。
    早期的 k8s 容器互联中的容器名解析也试用了这种方式。
    在 docker-compose 里面参数为 links: container_name[:alias],但是既然使用了 docker compose 就不建议使用这种方式了。

    作为资源统一管理的 Docker 互联网络

    可以使用 docker network 管理网络对象。建议为服务创建自己的网络。
    在创建容器时,可以指定其属于的网络,或者说通过选择一个默认网络驱动来指定网络类型。

    --network <bridge|host|none|container_name|custom>
    

    其中,bridge|host|none 是网络资源里面默认的三种网络,container_name是joined-container类型,custom是预先创建的网络。

    如果是 docker-compose 里面声明的网络,会自动创建。

    bridge 桥接模式

    bridge 模式是自动挡,创建的容器有自己的 Network Namespace,并且还会在目标网络中分配一个 IP。
    桥接网络的网络地址是递增的,从默认初始的 docker0 的 172.17.0.1/16 开始,创建的桥接网络会以如下命名。

    br-<NETWORK_ID> 172.18.0.1/16
    br-<NETWORK_ID> 172.19.0.1/16
    br-<NETWORK_ID> 172.20.0.1/16
    

    如果创建的容器没有指定 network 类型,默认就是 docker0 为网关的桥接模式。

    bridge 网络模式中,容器的网络初始化过程:

    1. 在主机上创建一对虚拟网卡 veth pair 设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
    2. Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在主机中,以veth65f9这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看。
    3. 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。
      veth pair 生成的一对网卡,一端是 容器的 eth0,一端是 docker0 网络段的地址。
      为了实现容器与外部通信,宿主机上添加的 Iptable 规则
    -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
    -A DOCKER ! -i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.5:80
    

    第一条规则会将源地址为 172.17.0.0/16 的包(也就是从 Docker 容器产生的包),并且不是从docker0网卡发出的,进行源地址转换,转换成主机网卡的地址。这么说可能不太好理解,举一个例子说明一下。假设主机有一块网卡为 eth0,IP地址为 10.10.101.105/24,网关为 10.10.101.254。从主机上一个IP为 172.17.0.2/16 的容器中ping百度(180.76.3.151)。IP 包首先从容器发往自己的默认网关 docker0,包到达 docker0 后,也就到达了主机上。然后会查询主机的路由表,发现包应该从主机的 eth0 发往主机的网关10.10.105.254/24。接着包会转发给eth0,并从 eth0 发出去(主机的ip_forward转发应该已经打开)。这条规则对包做 SNAT 转换,将源地址换为 eth0 的地址。这样,在外界看来,这个包就是从10.10.101.105上发出来的,Docker容器对外是不可见的。
    第二条规则就是对主机 eth0 收到的目的端口为外部映射端口的 tcp 流量进行DNAT转换,将流量发往172.17.0.5:80,也就是我们创建的Docker容器的地址。所以,外界只需访问 10.10.101.105:80 就可以访问到容器中得服务。

    host 主机模式

    使用 --net 设定为 host 的容器,使用 ip addr 等会看到和宿主机一样的网卡情况。不会创建 Network Namespace 而是和宿主机公用同一个。
    容器并没有向 bridge 模式那样有一个私有 IP 地址,而且端口都是和宿主机共用一个地址空间。所以 -p 等端口映射的操作不仅是无效的,还会得到运行失败和一句警告
    WARNING: Published ports are discarded when using host network mode
    因为 dockerfile 里面尝试使用的端口例如 80 如果在宿主机上已经 bind,例如 nginx 在 host 模式下面是无法启动的。
    如果容器内的服务需要对本机其他服务进行操作,例如 Consul 或者 kubernates 等的本地服务之间的监听和通信,或者对性能有要求,就需要改为 host 模式。

    none

    none 模式是手动档。没有网络配置的网络模式,需要手动配置。有独立的 Network Namespace。

    joined-container 联合容器

    类似 host 模式,这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。
    kubernetes 的 pod 里面,如果有多个容器,就是使用的这一模式。

    参考:
    https://juejin.cn/post/6868086876751085581

  • 相关阅读:
    android数据恢复
    UVA 690 Pipeline Scheduling
    2017 国庆湖南 Day4
    2017 国庆湖南 Day5
    2017 国庆湖南 Day6
    2017国庆 清北学堂 北京综合强化班 Day1
    2017 国庆湖南Day2
    bzoj 2962 序列操作
    UVA 818 Cutting Chains
    UVA 211 The Domino Effect
  • 原文地址:https://www.cnblogs.com/yumingle/p/14120310.html
Copyright © 2020-2023  润新知