docker——网络(bridge简介和案例实践、overlay简介)

docker 网络

docker网络主要解决如下问题

  • 容器与外界通信
  • 容器间通讯,跨主机容器间通讯
  • 网络隔离(容器网络命名空间、子网隔离)
  • 提供网络自定义能力
  • 提供容器间发现功能 (dns解析)
  • 提供负载均衡能力

docker网络命令

#连接一个容器到一个网络
docker network connect Connect a container to a network
#创建一个网络
docker network create Create a network
#将容器从一个网络中断开
docker network disconnect Disconnect a container from a network
#查看网络的详细信息
docker network inspect Display detailed information on one or more networks
#查看网络列表
docker network ls List networks
#移除所有未使用的网络
docker network prune Remove all unused networks
#移除一个或多个网络
docker network rm Remove one or more networks
常见操作
发布端口
# 将容器中tcp端口80映射到主机8080端口
-p 8080:80
# 将容器中tcp端口80映射到地址192.168.239.154:8080
-p 192.168.239.154:8080:80
# 将容器中的udp端口80映射到主机8080端口
-p 8080:80/udp
# 将容器中的udp端口80映射到主机的udp端口8080
# 将容器中的tcp端口80映射到主机的tcp端口8080
-p 8080:80/tcp -p 8080:80/udp

修改hostname
docker run -d --rm --name mynginx1 -p 8081:80 --hostname mynginx1.test.com
nginx:1.23.4
curl http://localhost:8081

iptables简介

docker安装后会自动设置iptables规则来管理网络流量。这是docker网络核心部分之一

iptables结构

iptables由上而下,由Tables,Chains,Rules组成。

tables与链chains

iptables有Filter, NAT, Mangle, Raw四种内建表:

Filter

Filter是iptables的默认表,它有以下三种内建链(chains):

  • INPUT链 – 处理来自外部的数据

  • OUTPUT链 – 处理向外发送的数据。

  • FORWARD链 – 将数据转发到本机的其他网卡设备上。

NAT表

NAT表有三种内建链:

PREROUTING链 – 处理刚到达本机并在路由转发前的数据包。它会转换数据包中的目标IP地址(destination ip address),通常用于DNAT(destination NAT)。

POSTROUTING链 – 处理即将离开本机的数据包。它会转换数据包中的源IP地址(source ip address),通常用于SNAT(source NAT)。

OUTPUT链 – 处理本机产生的数据包。

Mangle表

Mangle表用于指定如何处理数据包。它能改变TCP头中的QoS位。Mangle表具有5个内建链(chains):

  • PREROUTING
  • OUTPUT
  • FORWARD
  • INPUT
  • POSTROUTING
Raw表

Raw表用于处理异常,它具有2个内建链:

PREROUTING chain

OUTPUT chain

rules

规则的关键知识点:

Rules包括一个条件和一个目标(target)

如果满足条件,就执行目标(target)中的规则或者特定值。

如果不满足条件,就判断下一条Rules

Target Values

在target里指定的特殊值:

  • ACCEPT – 允许防火墙接收数据包
  • DROP – 防火墙丢弃包
  • QUEUE – 防火墙将数据包移交到用户空间
  • RETURN – 防火墙停止执行当前链中的后续Rules,并返回到调用链(the calling chain)中
[root@localhost gpt-data]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy DROP)
target     prot opt source               destination
DOCKER-USER  all  --  anywhere             anywhere
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (1 references)
target     prot opt source               destination



ACCEPT     tcp  --  anywhere             172.17.0.2           tcp dpt:http

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

Chain DOCKER-USER (1 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere

网络驱动

bridge 网桥网络
  • bridge是docker默认的网络驱动程序。如果没有指定驱动程序,这就是正在创建的网络类型。当应 用程序在需要与同一主机上的其他容器通信的容器中运行时,通常会使用桥接网络。
  • 就联网而言,桥接网络是在网段之间转发流量的链路层设备,链路层设备Mac地址进行通信。桥接 器可以是在主机内核运行的硬件设备或者软件设备。
  • 就docker而言,网桥网络为软件网桥。允许连接到同一网桥的容器进行通讯,同时提供与未连接到 该网桥的容器的隔离。不同网桥上的容器无法直接通讯。
  • 启动docker是,会自动创建一个名为docker0的网桥网络,并且新启动的容器会默认连接到该网络
[root@localhost gpt-data]# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.0242832fe5ed       no              veth861b463
                                                        vetha32efdf
默认网桥&&自定义网桥
  • 自定义网桥提供容器之间的自动DNS解析,可通过容器名称或别名互相访问,默认网桥网络上的容 器只能通过IP地址互相访问。
  • 自定义网桥提供更好的网络隔离,因为所有未指定网络的容器都将连接到默认网桥,而自定义网桥 则必须显示指定容器网络后,方可加入该网络。
  • 每个自定义网络都会创建一个可配置的网桥。如果使用默认网桥,对其配置将使得所有容器都使用 相同的设置,此外配置默认网桥发生在docker本身之外,需要重新启动docker。使用docker网络 创建和配置自定义网桥网络,可以在创建是分别对不同的网桥做不同的配置。

使用网桥驱动创建网络options

选项 默认值 描述
com.docker.network.bridge.name 创建Linux网桥时要使用的接口名称
com.docker.network.bridge.enable_ip_masquerade true 是否启用IP伪装,即将容器的IP地址转换成宿主机的ip地址进行网络访问,从而实现容器访问外部网络的功能,即容器对外部网络访问的权限等同宿主机
com.docker.network.bridge.enable_icc true 启用或禁用容器间连接(不是DNS解析)
com.docker.network.bridge.host_binding_ipv4 0.0.0.0 绑定容器端口时的默认IP
com.docker.network.driver.mtu 0(不限制) 设置容器最大传输单元
com.docker.network.container_iface_prefix eth 容器接口自定义前缀
查看默认网络
docker network ls
查看路由表
route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.74.18.1      0.0.0.0         UG    104    0        0 eth0
10.74.18.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0

所有以172.17开头并且子网掩码为255.255.0.0的IP地址的数据包都会被发送到docker0网桥

查看iptables规则

docker安装后悔自动设置iptables规则来管理网络流量。查看filter表

[root@localhost gpt-data]# iptables -t filter --line-numbers -L  -n -v | column -t

Chain INPUT (policy ACCEPT 10M packets, 2480M bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy DROP 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1     2309 8646K DOCKER-USER  all  --  any    any     anywhere             anywhere
2     2309 8646K DOCKER-ISOLATION-STAGE-1  all  --  any    any     anywhere             anywhere
3     1194 8580K ACCEPT     all  --  any    docker0  anywhere             anywhere             ctstate RELATED,ESTABLISHED
4        0     0 DOCKER     all  --  any    docker0  anywhere             anywhere
5     1115 66538 ACCEPT     all  --  docker0 !docker0  anywhere             anywhere
6        0     0 ACCEPT     all  --  docker0 docker0  anywhere             anywhere

Chain OUTPUT (policy ACCEPT 16M packets, 2444M bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain DOCKER (1 references)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 ACCEPT     tcp  --  !docker0 docker0  anywhere             172.17.0.2           tcp dpt:http

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
num   pkts bytes target     prot opt in     out     source               destination
1     1115 66538 DOCKER-ISOLATION-STAGE-2  all  --  docker0 !docker0  anywhere             anywhere
2     2309 8646K RETURN     all  --  any    any     anywhere             anywhere

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 DROP       all  --  any    docker0  anywhere             anywhere
2     1115 66538 RETURN     all  --  any    any     anywhere             anywhere

Chain DOCKER-USER (1 references)
num   pkts bytes target     prot opt in     out     source               destination
1     2309 8646K RETURN     all  --  any    any     anywhere             anywhere


  1. Chain INPUT (policy ACCEPT) :Chain INPUT 是一个默认的过滤链,它决定了进入本地系统的数
    据包如何处理。policy ACCEPT 表示该链的默认策略是接受(allow)所有进入的数据包。
  2. Chain OUTPUT (policy ACCEPT):OUTPUT链用于处理从本地系统发出的数据包。它决定了本地系统发往外部网络的流量如何进行过滤和处理。默认情况下,OUTPUT链的策略是ACCEPT,意味着所有从本地系统发出的数据包都会被允许通过。
  3. Chain FORWARD (policy DROP):FORWARD链用于处理转发(Forwarding)数据包,即通过本地系统进行转发的数据包。它决定了经过本地系统的数据包如何进行过滤和处理。默认情况下,FORWARD链的策略是DROP,意味着所有经过本地系统的转发数据包都会被丢弃。这样可以确保只有经过明确允许的规则才能进行转发
  4. Chain DOCKER:DOCKER链用于处理与Docker容器相关的网络流量。它是由Docker自动创建的一个用户定义链(user-defined chain),用于进行NAT(Network Address Translation)和过滤规则。
  5. Chain DOCKER-USER:DOCKER-USER链是Docker自动创建的另一个用户定义链(user-defined chain),用于处理与Docker容器相关的用户定义规则。
  6. Chain DOCKER-ISOLATION-STAGE:DOCKER-ISOLATION-STAGE链是Docker自动创建的用户定义链(user-defined chain),用于实现容器网络隔离。

查看iptables nat表规则列表


[root@localhost docker]# iptables -t nat -L -n -v --line-numbers | column -t
Chain  PREROUTING   (policy  ACCEPT       29    packets,  3391      bytes)
num    pkts         bytes    target       prot  opt       in        out       source         destination
1      962          54116    DOCKER       all   --        *         *         0.0.0.0/0      0.0.0.0/0     ADDRTYPE  match     dst-type          LOCAL
Chain  INPUT        (policy  ACCEPT       21    packets,  1767      bytes)
num    pkts         bytes    target       prot  opt       in        out       source         destination
Chain  OUTPUT       (policy  ACCEPT       1     packets,  60        bytes)
num    pkts         bytes    target       prot  opt       in        out       source         destination
1      3            180      DOCKER       all   --        *         *         0.0.0.0/0      !127.0.0.0/8  ADDRTYPE  match     dst-type          LOCAL
Chain  POSTROUTING  (policy  ACCEPT       3     packets,  180       bytes)
num    pkts         bytes    target       prot  opt       in        out       source         destination
1      49           3160     MASQUERADE   all   --        *         !docker0  172.17.0.0/16  0.0.0.0/0
2      0            0        MASQUERADE   tcp   --        *         *         172.17.0.2     172.17.0.2    tcp       dpt:80
3      0            0        MASQUERADE   tcp   --        *         *         172.17.0.6     172.17.0.6    tcp       dpt:80
Chain  DOCKER       (2       references)
num    pkts         bytes    target       prot  opt       in        out       source         destination
1      0            0        RETURN       all   --        docker0   *         0.0.0.0/0      0.0.0.0/0
2      27           1620     DNAT         tcp   --        !docker0  *         0.0.0.0/0      0.0.0.0/0     tcp       dpt:8081  to:172.17.0.2:80
3      74           4440     DNAT         tcp   --        !docker0  *         0.0.0.0/0      0.0.0.0/0     tcp       dpt:82    to:172.17.0.6:80


  1. -t nat: 指定使用nat表,即网络地址转换表
  2. -v: 显示详细信息,包括数据包和字节计数
  3. n: 不进行域名解析,直接显示IP地址
  4. -L: 列出规则列表
  5. Chain PREROUTING:(预路由链)是iptables中的一个网络地址转换表(nat表)的链。它用于在数据包到达主机之前进行处理和转发
  6. Chain POSTROUTING:(后路由链)是iptables中的一个网络地址转换表(nat表)的链。它用于在数据包离开主机之前进行处理和转发。
  7. 规则解读
Chain POSTROUTING (policy ACCEPT 7697 packets, 516K bytes)
 pkts bytes target     prot opt in     out     source               destination
   49  3160 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0
    0     0 MASQUERADE  tcp  --  *      *       172.17.0.2           172.17.0.2           tcp dpt:80

表示对于从不在docker0接口上的网络流量(即输出流量),如果源IP地址属于172.17.0.0/16网段,则进行伪装(MASQUERADE),将源IP地址替换为本机的外部IP地址,以实现网络地址转换(NAT)功能。这样可以确保来自172.17.0.0/16网段的数据包能够正确地回应到发起请求的主机

bridge驱动使用案例

启容器

docker run -dit --rm --name alpine1 myalpine ash
docker run -dit --rm --name alpine2 myalpine ash

查看bridge网络

docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "52c18e3316468f9f14736d495029aa15b63473dbca0818b8ceab3f1d526dbac5",
        "Created": "2023-12-26T11:26:27.150249598+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "5c35cf3a8315d1477da3cd7693f83444af91d5a846007572cfc0c663c03c12a8": {
                "Name": "alpine1",
                "EndpointID": "46340efda036eda601504b5ca6928db7a098d3776bc77ff819921485156df026",
                "MacAddress": "02:42:ac:11:00:04",
                "IPv4Address": "172.17.0.4/16",
                "IPv6Address": ""
            },
            "d9bd1dac57b716ad763d2cedc57ccb9de63e77074c6a16ba6b672cdec1c0cd1c": {
                "Name": "alpine2",
                "EndpointID": "fc082c335bb511f9518fa0c15fe717432b8c1b3b81d71e1bd3f6fc79620df7ee",
                "MacAddress": "02:42:ac:11:00:05",
                "IPv4Address": "172.17.0.5/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": {}
    }
]

查看系统网络接口,会多出两张veth

ip ad
[root@localhost docker]# ip ad
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
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether fa:16:3e:30:2c:c0 brd ff:ff:ff:ff:ff:ff
    inet 10.74.18.61/24 brd 10.74.18.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fe30:2cc0/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:83:2f:e5:ed brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:83ff:fe2f:e5ed/64 scope link
       valid_lft forever preferred_lft forever
309: vethf7628d0@if308: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether 8a:ab:91:3a:0c:a7 brd ff:ff:ff:ff:ff:ff link-netnsid 2
    inet6 fe80::88ab:91ff:fe3a:ca7/64 scope link
       valid_lft forever preferred_lft forever
169: veth861b463@if168: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether c2:d4:57:7a:85:51 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::c0d4:57ff:fe7a:8551/64 scope link
       valid_lft forever preferred_lft forever
185: vetha32efdf@if184: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether e6:4d:1a:49:65:15 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::e44d:1aff:fe49:6515/64 scope link
       valid_lft forever preferred_lft forever

docker0网桥工作原理

docker——网络(bridge简介和案例实践、overlay简介)_第1张图片

默认桥接网络不提供dns解析,容器之间可以通过ip地址相互访问,但不能通过容器名称相互访问。可以使用自定义网络,将容器添加进网络,这样容器间就可以相互使用名字访问了

自定义bridge网络
docker network create --driver bridge nginx-net

运行两个容器

docker run -d -p 8088:80 --network nginx-net --name nginx1 nginx
docker run -d -p 8089:80 --network nginx-net --name nginx2 nginx
# 查看nginx-net
[root@localhost docker]# docker inspect nginx-net
[
    {
        "Name": "nginx-net",
        "Id": "b9bc42bfe03ffe38df86dd3b388d8d1ff58c1f8d5614ffe606191427fc6c5288",
        "Created": "2024-01-03T14:47:57.506257705+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "3d22cf84216493e7fbb3a5ad773b8e77fc750a5aab356a06af083bff59944b5a": {
                "Name": "nginx2",
                "EndpointID": "3b47ad3fafebebee7acdc0243f0e0f3fac46b3039411fb46c6d62f8e292de6f4",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "e9c736a4ca090945fcee290614f491fe1fca5048b2d2b34fd78d878b96e88eba": {
                "Name": "nginx1",
                "EndpointID": "c2ecc9cecf7e8a1ae8c76fc2027feef1c169c9508a77ca382db63c2efd0362e3",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

两个容器之间可以使用容器名访问。容器网络,直接访问80端口

[root@localhost docker]# docker exec -it nginx1 bash
root@e9c736a4ca09:/# curl http://nginx2:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

将已有容器加入到新的网络
# 将容器 nginx3 加入网络 nginx-net
docker network connect nginx-net nginx3
# 将容器 nginx4 加入网络 nginx-net
docker network connect nginx-net nginx4
# 查看网络详情
docker network inspect nginx-net
从自定义网络中移除所有容器

加入默认网络中的容器无法再不停服的情况下与docker0网桥断开

docker network disconnect nginx-net nginx1
docker network disconnect nginx-net nginx2
docker network disconnect nginx-net nginx3
docker network disconnect nginx-net nginx4
移除网络
docker network rm alpine-net
带option创建自定义网络
docker network create \
--driver=bridge \
--subnet=172.28.0.0/16 \
--ip-range=172.28.5.0/24 \
--gateway=172.28.5.254 \
--opt com.docker.network.bridge.name=nginx-net1 \
--opt com.docker.network.bridge.enable_ip_masquerade=false \  #禁用IP伪装,无法访问外网
--opt com.docker.network.bridge.enable_icc=false \            #禁用容器间通讯
--opt com.docker.network.container_iface_prefix=ethtest \     # 网络接口前缀
nginx-net1
一点问题记录

启动nginx后,外部机器无法访问首页(之前一直没啥问题)。查了下原因是因为ip转发未开启 net.ipv4.ip_forward=0

修改为1即可

sysctl -w net.ipv4.ip_forward=1
Overlay 覆盖网络与vxlan

https://blog.51cto.com/u_14928887/3084685

https://zhuanlan.zhihu.com/p/629065642

你可能感兴趣的:(docker,网络,容器)