Docker的网络管理

文章目录

一、Docker容器之间的通信

1、直接互联(默认Bridge网络)

1.1、Docker安装后默认的网络配置

Docker服务安装完成之后,默认在每个宿主机会生成一个名称为docker0的网卡其IP地址都是 172.17.0.1/16。

bash 复制代码
ip a | grep docker0

1.2、创建容器后的网络配置

1.2.1、首先创建一个容器
bash 复制代码
[root@localhost ~]# docker run -itd --name nginx_v1 -p 8081:80 nginx
1.2.2、ip a 列出网卡变化信息
bash 复制代码
[root@localhost ~]# ip a
...
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:77:03:57:c7 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:77ff:fe03:57c7/64 scope link
       valid_lft forever preferred_lft forever
5: veth6ce240e@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether aa:8b:8e:1b:35:93 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::a88b:8eff:fe1b:3593/64 scope link
       valid_lft forever preferred_lft forever
  • 创建了容器后

    • 宿主机就会多了一个虚拟网卡,和容器的网卡组合成一个网卡,比如:5: veth6ce240e@if4,而在容器内的网卡名为4,可以看出和宿主机的网卡之间的关联

    • 容器会自动获取一个172.17.0.0/16网段的随机地址,默认从172.17.0.2开始,第二个容器为 172.17.0.3,以此类推

    • 容器获取的地址并不固定。每次容器重启,可能会发生地址变化

1.2.3、查看新建容器后的桥接状态
bash 复制代码
[root@localhost ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.0242770357c7       no              veth6ce240e
  • bridge name : 显示网桥的名称,在这个例子中是docker0docker0是Docker在宿主机上自动创建的默认网桥,用于连接Docker容器到宿主机的网络。

  • bridge id : 每个网桥都有一个唯一的标识符,通常格式为8000.<MAC地址>。在这个例子中,8000.0242770357c7docker0网桥的ID,其中02:42:77:03:57:c7是该网桥的MAC地址的一部分

  • STP enabled : 显示是否启用了Spanning Tree Protocol(STP,生成树协议)。STP用于防止局域网中的桥接循环(bridge loops)和广播风暴。输出中的no表示在docker0网桥上STP是禁用的,这是Docker默认的行为,因为通常在容器环境中不需要STP。

  • interfaces : 列出了连接到该网桥的网络接口。在这个例子中,只有veth6ce240e这个接口连接到了docker0网桥。veth接口是一对虚拟以太网设备,通常一个在容器的网络命名空间内(容器的eth0),另一个在宿主机的网络命名空间内,它们通过这种方式桥接容器网络到宿主机网络,使得容器可以与宿主机及其他容器通信。

  • 创建容器后容器会自动获取ip地址

    bash 复制代码
    [root@localhost ~]# docker exec -it nginx_v1 ip a

1.3、容器内安装常见的工具

pingnslookupifconfigipcurl

监视系统状态和管理进程的工具集合

bash 复制代码
apt install inetutils-ping -y
apt install dnsutils -y
apt install net-tools -y
apt install iproute2 -y
apt install curl -y
apt install procps -y

1.4、容器间通信

默认情况下,同一个宿主机的不同容器之间可以相互通信。

不同宿主机之间的容器IP地址重复,默认不能相互通信。

在docker.service配置文件中的fd://后面添加--icc=false 选项可以禁止同一个宿主机的不同容器间通信。

  • 再创建一个容器进行互相通信
bash 复制代码
[root@localhost ~]# docker run -itd --name nginx_v2 -p 8082:80 nginx
5e088a915221aef79d369bba6d76961598ea341222ae1c20d0cb1b8a0e1147f0
  • 分别获取两个容器对应的ip地址

    bash 复制代码
    [root@localhost ~]# docker exec -it nginx_v1 hostname -i
    172.17.0.2
    [root@localhost ~]# docker exec -it nginx_v2 hostname -i
    172.17.0.3
  • 直接测试网络连通性

    bash 复制代码
    [root@localhost ~]# docker exec -it nginx_v1 bash
    root@da9b2e5ecf77:/# ping 127.0.0.3 -c 3
    PING 127.0.0.3 (127.0.0.3): 56 data bytes
    64 bytes from 127.0.0.3: icmp_seq=0 ttl=64 time=0.068 ms
    64 bytes from 127.0.0.3: icmp_seq=1 ttl=64 time=0.096 ms
    64 bytes from 127.0.0.3: icmp_seq=2 ttl=64 time=0.087 ms
    --- 127.0.0.3 ping statistics ---
    3 packets transmitted, 3 packets received, 0% packet loss
    round-trip min/avg/max/stddev = 0.068/0.084/0.096/0.000 ms

2、容器名称互联

2.1、原理

  • docker run 创建容器,可使用--link选项实现容器名称的引用

  • 其本质就是在容器内的/etc/hosts中添加--link后指定的容器的IP和主机名的对应关系,从而实现名称解析。

2.2、指令格式

bash 复制代码
docker run --name	#先创建指定名称的容器
docker run --link	#再创建容器时引用上面容器的名称

2.3、创建新的容器并引用已创建的容器

bash 复制代码
[root@localhost ~]# docker run -itd --name nginx_test1 --link nginx_v1 -p 8083:80 nginx
eb9b74839c4c5e493df5fbfa5b0482cbc984e70a7ac7addcd9b01cce792d9449

2.4、进入容器查看/etc/hosts文件

bash 复制代码
[root@localhost ~]# docker exec -it nginx_test1 /bin/bash
root@eb9b74839c4c:/# cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      nginx_v1 cf9fc9d97972
172.17.0.4      eb9b74839c4c

2.5、使用容器名称互相通信

bash 复制代码
root@eb9b74839c4c:/# ping nginx_v1 -c 2
PING nginx_v1 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.064 ms
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.077 ms
--- nginx_v1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.064/0.071/0.077/0.000 ms

3、自定义容器别名互联

自定义的容器名称可能后期会发生变化,那么一旦发生变化也会带来一些影响,这个时候如果每次都更改名称又比较麻烦

这个时候可以使用定义别名的方式解决,即容器名称可以随意更改,只要不更改别名即可。

3.1、指令格式

bash 复制代码
#先创建指定名称的容器
docker run --name <容器名称> 
docker run --name <容器名称> --link <目标容器名称>:"<容器别名1> <容器别名2> ..."

3.2、起别名的形式创建一个新的容器

bash 复制代码
[root@localhost ~]# docker run -itd --name nginx_test2 -p 8084:80 --link nginx_v2:nginx_v2_alias nginx
3382790d21e3224c50799e907b229185fb5ab37140b51cc6ab4536e19c00dabd
  • --link nginx_v2:nginx_v2_alias: 设置容器间的链接。
  • 这里表示当前新创建的容器将与名为 nginx_v2 的容器建立链接,并且在新容器内部,这个链接将以 nginx_v2_alias 的别名存在。
  • 链接允许容器之间相互通信,并且可以使用别名通过环境变量等方式访问被链接容器的信息。

3.3、使用别名互相通信

bash 复制代码
docker exec -it nginx_test2 ping -c 2 nginx_v2_alias

4、自定义网络

4.1、创建自定义网络

bash 复制代码
[root@localhost ~]# docker network create my_network
0c93f493d62d5791febeb088048f85874e9ae2bc9266bb84f88f4864ad379d46
[root@localhost ~]# docker network ls
NETWORK ID     NAME         DRIVER    SCOPE
4d478ce25a22   bridge       bridge    local
738397fc865f   host         host      local
0c93f493d62d   my_network   bridge    local
75326f81366f   none         null      local

当我们创建了一个自定义网络(my_network)Docker 会创建一个新的桥接网络(bridge driver)。

其底层技术仍然是基于桥接网络实现的,即每个连接到此自定义网络的容器都会获得一个虚拟网卡,并通过Docker管理的一个虚拟网桥(类似于默认的bridge网络所使用的网桥)与其他容器以及宿主机进行通信。

4.2、启动两个容器并连接到自定义网络

[root@localhost ~]# docker run -itd --name nginx_network3 --network my_network nginx
c98ca358f48e945a9d6b9f4d0c54e562cbbf1aef58e2a265bf2f40296cecb923
[root@localhost ~]# docker run -itd --name nginx_network4 --network my_network nginx
c0e09ba99d47652eb4755b7d4e5c1c676fd1f7e4a52a93a55865475c001ae0ea

4.3、自定义网络进行容器间通信

bash 复制代码
[root@localhost ~]# docker exec nginx_network3 ping -c 2 nginx_network4

5、Host网络模式

5.1、启动使用Host网络模式的容器

使用Host网络模式,容器直接使用宿主机的网络栈

host 网络模式下,容器直接使用宿主机的网络栈,没有独立的网络命名空间,因此容器内部的服务就直接监听在宿主机的网络接口上,不再需要端口映射。

bash 复制代码
[root@localhost ~]# docker run -itd --name nginx_host -p 8086:80 --network host nginx

可以看到Docker是会忽略--network host模式启动容器时指定的端口映射的

5.2、使用Host网络模式进行通信

此时其他容器就可以通过宿主机的ip和端口进行访问

bash 复制代码
docker exec -it nginx_v1 ping -c 2 192.168.112.60

6、端口映射

6.1、启动带有端口映射的容器

这里的镜像mycentos_nginx:v1用的是之前Docker制作镜像中的使用DockerFile制作的nginx镜像

[root@localhost ~]# docker run -itd --name nginx_port -p 8090:80 mycentos_nginx:v1

6.2、其他容器访问

bash 复制代码
[root@localhost ~]# docker exec -it nginx_v3 curl -s 192.168.112.60:8090
#发现可以获取到之前定义的index.html文件内容

二、Docker的网络模式

1、查看默认的网络模式

bash 复制代码
[root@localhost ~]# docker network ls

默认会生成三种不同的网络

bridgehostnull

2、常见的五种网络模式

Docker网络模式 配置 说明
bridge模式 --net=bridge(默认) 为每个容器分配独立的网络命名空间和IP地址,通过Docker虚拟网桥(docker0)与宿主机及其它容器通信。
host模式 --net=host 容器直接使用宿主机的网络命名空间,无独立IP,容器和服务直接通过宿主机的网络接口和端口暴露。
none模式 --net=none 容器仅有lo(回环)接口,无网络配置,适用于不需要网络的场景。
container模式 --net=container:NAME_or_ID 新容器共享指定容器的网络命名空间,包括IP地址和端口范围,适用于紧密网络耦合的场景。
User-defined(用户自定义) docker network create <网络名> --net=<网络名> 创建自定义网络,可以配置网络驱动、子网、IP范围等,提供更灵活的网络控制,适用于微服务架构等复杂网络需求。

3、Bridge网络模式

3.1、Bridge网络模式的架构

3.2、工作原理

1、创建虚拟网桥
  • Docker启动时自动创建名为docker0的虚拟网桥,作为容器间及容器与宿主机通信的基础。
  • 所有在同一宿主机上启动的Docker容器默认连接到这个虚拟网桥,模拟物理交换机行为,形成二层网络。
2、IP地址分配与默认网关设置
  • 从docker0网桥关联的子网中动态分配IP地址给新创建的容器使用。
  • 设置docker0的IP地址作为容器的默认网关,确保容器对外通信的路由正确。
3、veth Pair设备与网络接入
  • 在宿主机和容器间创建一对虚拟以太网设备(veth pair),实现容器网络栈与宿主机网络栈的连接。
  • veth pair的一端(eth0)置于容器内作为其网络接口,另一端(vethxxx)留在宿主机并加入docker0网桥,完成容器网络接入。
4、网络命名空间隔离
  • 每个Docker容器都运行在自己的网络命名空间中,这意味着它们有自己独立的网络配置,包括网卡、IP地址、路由表等,彼此之间互不影响,增强了容器之间的隔离性。
5、与外部网络之间的通信(SNAT)
  • 当Docker容器尝试访问外部网络(如访问互联网)时,由于容器的IP地址是私有的(属于docker0网桥的子网),直接访问外部网络会遇到路由问题。此时,宿主机上的网络栈会介入,通过**源地址转换(Source Network Address Translation, SNAT)**技术,将容器发出的数据包的源IP地址替换为宿主机的公网IP地址,从而使得数据包能够顺利通过路由器并到达目标服务器。这一过程使得容器能够透明地访问外部网络资源。
6、被外部主机访问(DNAT)
  • 要使外部主机能够访问容器内的服务,Docker通过**目的地址转换(Destination Network Address Translation, DNAT)**实现。当你使用docker run -p命令将容器端口映射到宿主机端口时,Docker会在宿主机的iptables规则中设置DNAT条目,将指向宿主机特定端口的流量重定向到容器内的相应端口。这意味着外部客户端可以使用宿主机的IP地址和映射的端口号来访问容器内的服务。
7、ip_forward功能
  • 为了使上述SNAT和DNAT能够正常工作,宿主机需要启用IP转发功能。IP转发允许宿主机作为网络中间节点,将接收到的数据包转发到其他网络接口或设备,这对于容器通过宿主机路由进出流量至关重要。通常,可以通过编辑/etc/sysctl.conf文件(增加或修改net.ipv4.ip_forward=1)并执行sysctl -p命令来启用这一功能。

bash 复制代码
[root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward
1

安装Docker后会默认启用ip_forward

3.3、Bridge网络模式的特点

  • **网络资源隔离:**不同宿主机的容器无法直接通信,各自使用独立网络
  • **无需手动配置:**容器默认自动获取172.17.0.0/16的IP地址,此地址可以修改
  • **可访问外网:**利用宿主机的物理网卡,SNAT连接外网
  • **外部主机无法直接访问容器:**可以通过配置DNAT接受外网的访问
  • **性能较低:**因为可通过NAT,网络转换带来更的损耗
  • **端口管理繁琐:**每个容器必须手动指定唯一的端口,容器产生端口冲突

3.4、修改bridge网络的默认网段

有两种方式可以修改bridge网络的默认网段,但是两种只能选择一种,否则docker服务无法启动

3.4.1、修改docker.service文件

修改配置文件前记得备份,前面跟着做的就不需要重复备份了

bash 复制代码
[root@localhost ~]# vim /usr/lib/systemd/system/docker.service
...
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --bip=172.10.0.1/16
...
#修改为172.10网段

[root@localhost ~]# systemctl daemon-reload && systemctl restart docker
bash 复制代码
[root@localhost ~]# docker run -itd --name nginx_v4 -p 8091:80 mycentos_nginx:v1
[root@localhost ~]# docker run -itd --name nginx_v5 -p 8092:80 mycentos_nginx:v1
#创建两个容器来验证网段是否修改

[root@localhost ~]# docker inspect nginx_v4 --format='{{json .NetworkSettings.IPAddress}}'
"172.10.0.2"
[root@localhost ~]# docker inspect nginx_v5 --format='{{json .NetworkSettings.IPAddress}}'
"172.10.0.3"
#可以看到再创建的容器分配到的ip地址就是172.10网段的ip,且从172.10.0.2往后顺延
3.4.2、修改daemon.json文件

没有这个文件的是没有开启镜像加速功能

阿里云镜像加速 -> 容器镜像服务 -> 镜像工具 -> 镜像加速器 依据操作文档添加

bash 复制代码
[root@localhost docker]# cat /etc/docker/daemon.json
{
  "registry-mirrors": ["https://jzjzrggd.mirror.aliyuncs.com"],
  "bip": "172.72.0.1/16",
  "dns": ["8.8.8.8"]
}
#这里我将默认网段修改为172.72

[root@localhost docker]# systemctl daemon-reload && systemctl restart docker
bash 复制代码
[root@localhost ~]# docker run -itd --name nginx_v6 -p 8093:80 mycentos_nginx:v1
0dba43ccae42824f0c3bbd80617de2c2685dc8c9a6120c416047b43fe4f90cdd
[root@localhost ~]# docker run -itd --name nginx_v7 -p 8094:80 mycentos_nginx:v1
2fa22556636d2d223bfe0ca8a0d961dd8f88671fb018b4095f1a86d02c9babe7
#创建两个容器来验证网段是否修改

[root@localhost ~]# docker exec -it nginx_v6 hostname -i
172.72.0.2
[root@localhost ~]# docker exec -it nginx_v7 hostname -i
172.72.0.3
#可以看到再创建的容器分配到的ip地址就是172.72网段的ip,且从172.72.0.2往后顺延

注意:由于之前示例的容器均没有固定ip以及设置随docker自启所以以上操作会导致用于示例的容器都是Exited (0)状态,并且重启容器后ip地址也会从新设置的网段开始分配

4、Host网络模式

4.1、Host网络模式的架构

4.2、工作原理

  • 网络命名空间共享:容器不再拥有独立的网络接口、IP地址、路由表等,而是直接使用宿主机的网络配置,包括网络接口卡(NIC)、IP地址、端口等。
  • 端口和网络服务:容器内的服务可以直接通过宿主机的IP地址和端口访问,无需进行端口映射,因为容器与宿主机网络完全一致。
  • 性能:由于没有网络栈的额外开销,Host模式下的容器网络性能通常优于其他网络模式。
  • 安全性与隔离性:这是Host模式的最大劣势,容器失去了网络层面的隔离保护,容器内的服务与宿主机服务在同一个网络环境中,存在潜在的安全风险,且容器间也无网络隔离。

4.3、Host 网络模式的特点

  • 共享宿主机网络
  • 网络性能无损耗
  • 网络故障排除相对简单
  • 各容器网络无隔离
  • 网络资源无法分别统计
  • 端口管理困难,容易产生端口冲突
  • 不支持端口映射
  • 适用于运行容器端口比较固定的业务

4.4、示例

4.4.1、创建一个host网络模式的nginx容器
bash 复制代码
[root@localhost ~]# docker run -itd --name nginx_v8 --network host mycentos_nginx:v1
0d61e812c6c82d86b87fe89649c3c99768c9a2b794c81ecf902fdace092cc331

[root@localhost ~]# ss -tnl | grep 80
#可以看到宿主机的80端口打开
4.4.2、再创建一个host网络模式的nginx容器
bash 复制代码
[root@localhost ~]# docker run -itd --name nginx_v9 --network host -p 8095:80 mycentos_nginx:v1

可以看到再创建nginx容器就会出现端口冲突的情况

也无法使用端口映射,因为是公用宿主机的80端口

5、none网络模式

5.1、none网络模式架构

5.2、工作原理

1. 网络命名空间隔离解除

在None模式下,虽然容器仍然有自己的网络命名空间,但这个命名空间内几乎为空,Docker不会为容器配置任何网络接口、IP地址或路由规则。这意味着容器没有网络连接能力,既不能访问宿主机网络,也不能与其他容器通信。

2. 仅有的网络接口:loopback

在None模式下启动的容器,内部通常只包含回环接口(lo),即localhost,用于容器内部的进程间通信。这意味着容器内的服务只能通过localhost地址互相访问,但无法与宿主机或外部网络通信。

3. 手动网络配置

虽然None模式下的容器没有默认的网络配置,但用户可以根据需要手动配置网络。这意味着可以使用ip命令或相关脚本为容器内的网络接口添加IP地址、配置路由规则等,使其能够连接到特定网络。这通常涉及创建虚拟以太网对(veth pairs)并将其中一端放入容器,然后手动配置网络参数。

5.3、none网络模式的特点

  • 安全隔离:对于不需要网络连接的容器,使用None模式可以增强安全性,减少攻击面。
  • 定制化网络:当需要构建非常特定的网络配置,如点对点通信、直接与宿主机的特定网络接口相连等,可以在None模式基础上手动配置网络。
  • 调试与测试:在排除网络问题或进行网络相关的单元测试时,可以使用None模式创建一个干净、无网络干扰的环境。

5.4、示例

5.4.1、创建一个none网络模式的容器
bash 复制代码
[root@localhost ~]# docker run -itd --name nginx_v10 -p 8096:80 --network none mycentos_nginx:v1
5.4.2、进入容器,查看网络接口信息并测试通信能力
bash 复制代码
[root@localhost ~]# docker exec -it nginx_v10 bash
[root@49d500bcbc3a /]# 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
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
[root@49d500bcbc3a /]# ping www.baidu.com
ping: www.baidu.com: Name or service not known
[root@49d500bcbc3a /]# ping 172.17.0.1
connect: Network is unreachable
#可以看到网络接口信息只有lo接口,无法与外部通信

6、Container网络模式

6.1、Container网络模式架构

6.2、工作原理

1. 共享网络命名空间
  • 当使用 --net=container:NAME_or_ID 参数启动一个容器时,Docker 不会为新容器创建新的网络命名空间,而是让它与指定容器共享同一个网络命名空间。
  • 这意味着两个容器看网络的角度是完全一样的,就像它们是在同一台机器上运行一样,共享相同的网络配置和网络资源。
2. 网络接口和IP地址
  • 新容器不会获得自己的网络接口和IP地址,它直接使用被共享容器的网络接口和IP地址。
  • 两个容器可以访问相同的网络服务,如同一局域网内的两台电脑,无需额外的端口映射或网络配置。
3. 端口冲突
  • 由于共享网络命名空间,两个容器不能绑定到同一个端口上运行服务,否则会出现端口冲突。
  • 如果需要在多个容器中运行相同服务,应考虑使用其他网络模式,如Bridge模式,并通过端口映射解决冲突。
4. 通信方式
  • 容器间通信非常直接,因为它们共享相同的网络环境,通过localhost或容器内的IP即可互相访问。
  • 对于外部访问,由于它们共享宿主机的网络栈,所以外部访问也遵循与共享容器相同的规则,例如,如果共享容器有端口映射到宿主机,则新容器的服务也可通过这些映射端口访问。

6.3、Container网络模式的特点

  • 与宿主机网络空间隔离
  • 容器间共享网络空间
  • 适合频繁的容器间的网络通信
  • 直接使用对方的网络,较少使用
  • 主要用于需要紧密网络耦合的场景,如微服务架构中某些服务间的直接通信。

6.4、示例

6.4.1、创建一个nginx容器
bash 复制代码
[root@localhost ~]# docker run -itd --name nginx_v11 -p 8098:80 mycentos_nginx:v1        06810ca19da88562cd539f7bd9dff8b8030bc64628760e28f8f4204ced5135b3
6.4.2、创建一个新的container容器共享nginx的网络环境
bash 复制代码
[root@localhost ~]# docker run -itd --name container_v1 --network container:nginx_v11 centos:7
6.4.3、查看两个容器的ip地址
bash 复制代码
[root@localhost ~]# docker exec -it nginx_v11 hostname -i                                
172.72.0.10
[root@localhost ~]# docker exec -it container_v1 hostname -i
172.72.0.10

7、自定义网络模式

7.1、工作原理

  1. 网络命名空间:每个连接到自定义网络的容器都会有自己的网络命名空间,确保网络资源(如网络接口、路由表等)的隔离。
  2. 网络桥接:Docker使用网络驱动(通常是Bridge驱动)创建一个或多个虚拟网桥,容器的网络接口通过虚拟网桥与宿主机的网络接口相连,实现容器间以及容器与宿主机的通信。
  3. IP地址管理:Docker会根据指定的子网为每个容器分配一个静态或动态IP地址,并管理网络配置,如网关、DNS服务器等。
  4. 服务发现:Docker通过内置的DNS服务或外部服务发现机制,使得容器可以通过名称查找其他容器的IP地址,简化配置。

7.2、自定义网络的特点

  • 灵活性:用户可以自定义网络的配置,包括子网、IP地址、DNS设置等,满足复杂应用的网络需求。
  • 可扩展性:随着应用规模扩大,可以通过Overlay网络驱动实现跨主机容器通信,扩展网络覆盖范围。
  • 隔离性:每个自定义网络都是独立的,提供容器间以及与宿主机的网络隔离,增加安全性。
  • 易管理性:通过Docker CLI轻松创建、删除、连接或断开容器与网络的关联,便于网络运维。

7.3、语法

7.3.1、语法格式
bash 复制代码
docker network COMMAND
docker network create -d <mode> --subnet <CIDR> --gateway <网关> <自定义网络名称>

mode不支持host和none,默认是bridge模式

7.3.2、命令
bash 复制代码
Commands:
• connect 将容器连接到网络
• create  创建网络
• disconnect断开容器与网络的连接
• inspect 显示一个或多个网络的详细信息
• ls 列出网络列表
• prune 删除所有未使用的网络
• rm 删除一个或多个网络
7.3.3、选项参数
bash 复制代码
[options]
--driver 或 -d: 指定网络的驱动类型。默认是 bridge,但也可以是 overlay、macvlan、ipvlan 等。例如,创建一个 overlay 网络:--driver overlay。

--subnet: 指定网络的子网。可以多次指定以创建多个子网。例如,--subnet=172.16.23.0/24。

--gateway: 设置网络的默认网关地址。例如,--gateway=172.16.23.1。

--ip-range: 限制Docker从指定的子网范围内分配IP地址给容器。这对于大型网络很有用。

--opt: 传递特定于驱动程序的选项。例如,对于 overlay 驱动,可以设置 --opt encrypted 来加密网络通信。

--internal: 将网络配置为内部网络,意味着外部流量不能到达此网络上的容器。

--attachable: 允许后续的容器即使在创建网络时没有指定也能连接到这个网络。

--label: 添加元数据标签到网络,用于过滤和识别。格式为 key=value。

--scope: 设置网络的作用域,通常是 local(单个Docker主机)或 global(Swarm模式下)。默认为 local。

--ingress: (Swarm模式特有)创建一个特殊的Ingress网络,用于Swarm服务的外部流量路由。

7.4、示例

7.4.1、创建自定义网络

bash 复制代码
[root@localhost ~]# docker network create -d bridge --subnet 172.172.0.0/16 --gateway 172.172.0.1 net-test

[root@localhost ~]# docker network ls
NETWORK ID     NAME         DRIVER    SCOPE
3593c2126bf2   bridge       bridge    local
738397fc865f   host         host      local
0c93f493d62d   my_network   bridge    local
8f95cd5b3ac0   net-test     bridge    local
75326f81366f   none         null      local

此时会新添加一个虚拟网卡和网桥

brctl show查看新的虚拟网卡对应的interfaces显示为空。

7.4.2、使用自定义网络创建容器
bash 复制代码
[root@localhost ~]# docker run -itd --name nginx_v13 --network net-test -p 8099:80  mycentos_nginx:v1
a9e35a0b3d86caeef38501c5c45c62d753ac31e650f231e2bd41d4c34b03ed4c
7.4.3、查看容器的ip地址及对应的index.html文件内容
bash 复制代码
[root@localhost ~]# docker exec -it nginx_v13 hostname -i
172.172.0.2
[root@localhost ~]# curl 172.172.0.2
test nginx !
[root@localhost ~]# docker exec -it nginx_v13 cat /usr/local/nginx/html/index.html
test nginx !
7.4.4、查看网络
bash 复制代码
[root@a9e35a0b3d86 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.172.0.2  netmask 255.255.0.0  broadcast 172.172.255.255
        ether 02:42:ac:ac:00:02  txqueuelen 0  (Ethernet)
        RX packets 17  bytes 1285 (1.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7  bytes 670 (670.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
7.4.5、自定义网络中容器的通信
bash 复制代码
[root@a9e35a0b3d86 /]# ping -c 2 www.baidu.com
PING www.a.shifen.com (180.101.50.188) 56(84) bytes of data.
64 bytes from 180.101.50.188 (180.101.50.188): icmp_seq=1 ttl=127 time=8.85 ms
64 bytes from 180.101.50.188 (180.101.50.188): icmp_seq=2 ttl=127 time=8.53 ms

--- www.a.shifen.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 8.535/8.694/8.854/0.184 ms
7.4.6、查看iptables相应的规则
bash 复制代码
[root@localhost ~]# iptables -t nat -nvL

PREROUTING 和 OUTPUT 链中的DOCKER规则

  • 规则允许所有目的地址为本地(dst-type LOCAL)的数据包进入,并将其标记为DOCKER流量,这是为了确保发往本地并且最终目标是Docker容器的流量能够被正确处理。
  • 在OUTPUT链中,有规则指明所有出站流量如果不是发往127.0.0.0/8(即本地回环),且目标是本地的,也会被标记为DOCKER流量。

POSTROUTING 链中的MASQUERADE规则

  • 多个MASQUERADE规则用于将来自不同子网(如172.172.0.0/16172.18.0.0/16)的流量伪装成主机的IP地址,以便容器可以透明地访问外部网络。这表明容器对外通信时,它们的源IP会被替换为主机的外网IP。

DOCKER链中的规则

  • RETURN规则指示当数据包来自于特定的Docker网络接口(如br-8f95cd5b3ac0, docker0, br-0c93f493d62d)时直接返回,这通常意味着这些网络内部的流量不需要进一步处理。
  • DNAT(Destination NAT,目标地址转换)规则将到达主机的特定端口(例如8094至8099)的数据包转发到对应的容器内端口80上。这展示了端口映射配置,允许外部访问容器的服务。
相关推荐
翻滚吧键盘35 分钟前
记录一个连不上docker中的mysql的问题
mysql·docker·容器
计算机毕设定制辅导-无忧学长1 小时前
Nginx 性能优化技巧与实践(二)
运维·nginx·性能优化
元气满满的热码式2 小时前
K8S中数据存储之配置存储
云原生·容器·kubernetes
龙胖不下锅2 小时前
k8s服务StatefulSet部署模板
云原生·容器·kubernetes
忘忧人生2 小时前
docker 部署 java 项目详解
java·docker·容器
律二萌萌哒3 小时前
K8S极简教程(4小时快速学会)
云原生·容器·kubernetes
烛.照1034 小时前
Nginx部署的前端项目刷新404问题
运维·前端·nginx
安静的做,安静的学4 小时前
网络仿真工具Core环境搭建
linux·网络·网络协议
m0_742155435 小时前
linux ——waitpid介绍及示例
linux·c++·学习方法
华纳云IDC服务商5 小时前
超融合服务器怎么优化数据管理?
运维·服务器