(转)Docker网络回顾

出自:https://juejin.cn/post/7041923410649153543
个人感觉作者这块总结的不错,转载下以便之后个人回顾。

Docker网络基础

  • docker使用Linux桥接网卡,在宿主机虚拟一个docker容器网桥(docker0),docker启动一个容器时会根据docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网络网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
  • docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接Container-IP访问到容器。
  • 如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过-p或-P参数来启用,访问容器的时候就通过宿主机IP:容器端口访问容器。

    Docker网络模式

    Docker网络模式 配置 说明
    host模式 -net=host 容器和宿主机共享Network namespace
    容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
    container模式 -net=container:Name_or_ID 容器和另外一个容器共享Network namespace
    kubernetes中的pod就是多个容器共享一个Network namespace。
    创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围
    none模式 -net=none 容器有独立的Network namespace,并没有对其进行任何网络设置,如分配veth pair和网桥连接,配置IP等。该模式关闭了容器的网络功能
    bridge模式 -net=bridge (默认模式)。此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及Iptable nat表配置与宿主机通信。
    Macvlan network 容器具备Mac地址,使其显示为网络上的物理设备
    Overlay (覆盖网络):利用VXLAN实现的bridge模式

Bridge模式

默认的网络模式。bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是不可见的,但容器通过宿主机的NAT规则后可以访问外网。

Bridge桥接模式的实现步骤

  • Docker Daemon利用veth pair技术,在宿主机上创建两个虚拟网络接口设备,假设为veth0 和veth1。而veth pair技术的特性可以保证无论哪一个veth接收到网络报文,都会将报文传输给另一方。
  • Docker Daemon将veth0附加到Docker Daemon创建的docker0网桥上。保证宿主机的网络报 文可以发往veth0;
  • Docker Daemon 将veth1添加到Docker Container所属的namespace下,并被改名为eth0。 如此一来,保证宿主机的网络报文若发往veth0则立即会被eth0接收,实现宿主机到Docker Container网络的联通性;同时也保证Docker Container单独使用eth0,实现容器网络环境的隔离性。

    Bridge桥接模式的缺陷

    Docker Container不具有一个公有IP,即和宿主机eth0不处于同一个网段。导致的结果是宿主机以外的世界不能直接和容器进行通信。

    注:eth设备是成双成对出现的,一端是容器内部命名为eth0,一端是加入到网桥并命名的veth(通常命名为veth),它们组成了一个数据传输通道,一端进一端出,veth设备连接了两个网络设备并实现了数据通信。

Host网络模式

  • host模式相当于Vmware中的NAT模式,与宿主机在同一个网络中,但没有独立IP地址。

  • 启动容器使用host模式,容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。

  • 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。除此之外容器的其他方面,比如文件系统、进程列表等还是和宿主机隔离。

  • 使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,docker host上已经使用的端口就不能再用了,网络的隔离性不好。

  • host网络模式需要在容器创建时指定–network=host

  • host模式是bridge桥接模式很好的补充。采用host模式的Docker Container,可以直接使用宿主机的IP地址与外界进行通信,若宿主机的eth0是一个公有IP,那么容器也拥有这个公有IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行NAT转换。

  • host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。

    Host网络模式的缺陷

    使用Host模式的容器不再拥有隔离、独立的网络环境。虽然可以让容器内部的服务和传统情况无差别、无改造的使用,但是由于网络隔离性的弱化,该容器会与宿主机共享竞争网络栈的使用; 另外,容器内部将不再拥有所有的端口资源,原因是部分端口资源已经被宿主机本身的服务占用,还有部分端口已经用以bridge网络模式容器的端口映射。

    Container网络模式

    Container网络模式没有改善容器与宿主机以外世界通信的情况(和桥接模式一样,不能连接宿主机以外的其他设备)。
    这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。 同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。

    None模式

    使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
    这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过– network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性

    网络基本用法

    (这部分稍作改动)。

    镜像拉取与容器创建

    1
    2
    3
    4
    5
    # 拉取镜像
    docker pull nginx:1.19.3-alpine

    # 运行镜像
    docker run -itd -name nginx1 nginx:1.19.3-alpine

    其创建流程如下:

  • 创建一对虚拟接口/网卡,也就是veth pair,分别放到本地主机和新容器中;

  • 本地主机一端桥接到默认的 docker0 或指定网桥上,并具有一个唯一的名字,如 vetha596da4;

  • 容器一端放到新容器中,并修改名字作为 eth0,这个网卡/接口只在容器的名字空间可见;

  • 从网桥可用地址段中(也就是与该bridge对应的network)获取一个空闲地址分配给容器的 eth0,并配置默认路由到桥接网卡 vetha596da4。

  • 容器就可以使用 eth0 虚拟网卡来连接其他容器和其他网络。 如果不指定–network,创建的容器默认都会挂到 docker0 上,使用本地主机上 docker0 接口的 IP 作为 所有容器的默认网关。

    多容器之间通讯

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    docker run -itd -name nginx1 nginx:1.19.3-alpine

    docker run -itd -name nginx2 nginx:1.19.3-alpine

    docker network inspect bridge

    # 新建bridge网络, 并将一个运行中的容器连接到该网络
    docker network create -d bridge test-bridge

    docker run -itd -name nginx3 -network test-bridge nginx:1.19.3-alpine

    docker network inspect test-bridge

    docker network connect test-bridge nginx2

    Docker网络命令汇总

    (这部分稍作改动)。
    个人感觉这部分有哪些命令不知道的,直接-h看一下或者查阅官方文档是最好的。
    如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    [root@node1 ~]# docker network -h
    Flag shorthand -h has been deprecated, please use --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.