Docker 网络基本概念

news2024/9/29 20:39:53

在之前讲 Redis 集群搭建的时候,我们用过一个选项 --net host​,现在就来讲讲该选项,以及 Docker 的网络。

docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381

网络情况

我们先停止 Docker:systemctl stop docker

在不启动 Docker 的情况下,网络情况是这样的:

$ ifconfig
enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.2.242  netmask 255.255.255.0  broadcast 192.168.2.255
        inet6 fe80::3c89:876e:2930:5286  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:74:1d:cd  txqueuelen 1000  (Ethernet)
        RX packets 90493  bytes 13330101 (12.7 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 38633  bytes 3330369 (3.1 MiB)
        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 6230364  bytes 7704637318 (7.1 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6230364  bytes 7704637318 (7.1 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

virbr0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255
        ether 52:54:00:06:12:45  txqueuelen 1000  (Ethernet)
        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

第一个 enp0s8,有一个 ip 地址 192.168.2.242,就是我们宿主机的地址

第二个 lo,就是 localhost 的简写,指本地回环链路;

第三个:virbr0,用的较少,了解即可。在虚拟机里,安装一个 Centos 的过程中,如果有选择相关虚拟化的的服务安装系统后,启动网卡时会发现有一个以网桥连接的私网地址的 virbr0 网卡(virbr0 网卡还有一个固定的默认 IP 地址 192.168.122.1),是做虚拟机网桥的使用的,其作用是为连接其上的虚机网卡提供 NAT 访问外网的功能。

之前学习 Linux 安装,勾选安装系统的时候附带了 libvirt 服务才会生成的一个东西,如果不需要可以直接将 libvirtd 服务卸载:yum remove libvirt-libs.x86_64

docker 启动后,多了一个 docker0 的虚拟网桥:

$ ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:c0ff:fe81:167e  prefixlen 64  scopeid 0x20<link>
        ether 02:42:c0:81:16:7e  txqueuelen 0  (Ethernet)
        RX packets 57719  bytes 2948857 (2.8 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 60032  bytes 75842649 (72.3 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

容器与容器之间、容器和宿主机之间,就是通过该虚拟网桥来通信的。

查看 docker 网络模式,这是安装 Docker 后,默认创建的:

$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
5bd056a8204a   bridge    bridge    local
553d2c47bcaa   host      host      local
1ddfe19eb462   none      null      local

我们主要掌握前 2 个,第 3 个 none 很少用到。

我们看看文档:

$ 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.

可以创建一个网络:

$ docker network create aa_network
9eeb4fd0bf15a59d77bdba7e40594eb30ddd2c2c2ad66df706608a939cd2d193


$ docker network ls
NETWORK ID     NAME         DRIVER    SCOPE
9eeb4fd0bf15   aa_network   bridge    local
5bd056a8204a   bridge       bridge    local
553d2c47bcaa   host         host      local
1ddfe19eb462   none         null      local

NAME 为 bridge 的网络,是桥接模式;NAME 为 host 的是主机模式

查看网络源数据:docker network inspect XXX网络名字

$ docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "5bd056a8204a81086acd846de2d0791373671f14a5f6880ebcbf7f4ddceb92cb",
        "Created": "2023-09-10T12:10:26.138357898+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": {},
        "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": {}
    }
]

Docker 的网络能解决什么问题:

  • 容器间的互联和通信以及端口映射
  • 容器 IP 变动时,可以通过服务名直接网络通信而不受到影响

访问一个容器,比较关键的一点是在不在同一网段。目前我们是在单机运行 Docker,所以这个问题不明显;

在工作中,则设计到多个 Docker,他们之间的网络管理和容器调用的规划,就得用到 Docker 网络的问题了

网络模式

网络模式简介
bridge为每一个容器分配、设置 IP 等,并将容器连接到一个 docker0。虚拟网桥,默认是该模式
host容器将不会虚拟出自己的网课,配置自己的 IP 等,而是使用宿主机的 IP 和端口
none容器有独立的 Network namespace,但并没有对其进行任何网络设置,
如分配 veth pair 和网桥连接,IP 等
container新创建的容器不会创建自己的网卡和配置自己的 IP,
而是和一个指定的容器共享 IP、端口范围等

  • bridge 模式:使用–network bridge 指定,默认使用 docker0。默认模式,最常见的模式
  • host 模式:使用–network host 指定
  • none 模式:使用–network none 指定,几乎不用
  • container 模式:使用–network container:NAME 或者容器 ID 指定

接下来我们通过一个实例,来理解为什么我们要学习这个 Docker 的网络知识

容器实例内默认网络 IP 生产规则

先启动两个 ubuntu 容器实例:

$ docker run -it --name u1 ubuntu 

$ docker run -it --name u2 ubuntu 

$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS          PORTS     NAMES
3e1c46b6b32e   ubuntu    "bash"    8 seconds ago    Up 7 seconds              u2
64fecffbfaca   ubuntu    "bash"    26 seconds ago   Up 25 seconds             u1

接下来查看下容器内的信息:docker inspect u1​,最后面有网络的信息:

"Networks": {
    "bridge": {
        "IPAMConfig": null,
        "Links": null,
        "Aliases": null,
        "NetworkID": "5bd056a8204a81086acd846de2d0791373671f14a5f6880ebcbf7f4ddceb92cb",
        "EndpointID": "9b0b1229700e53ea0651dd347d599d3873fa6f00ad92e255c72c2c17fabc87e8",
        "Gateway": "172.17.0.1",
        "IPAddress": "172.17.0.2",
        "IPPrefixLen": 16,
        "IPv6Gateway": "",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "MacAddress": "02:42:ac:11:00:02",
        "DriverOpts": null
    }
}

可以看到目前是桥接模式,网关是 172.17.0.1,容器本身的 IP 是 172.17.0.2

u2 的信息:

"Networks": {
    "bridge": {
        "IPAMConfig": null,
        "Links": null,
        "Aliases": null,
        "NetworkID": "5bd056a8204a81086acd846de2d0791373671f14a5f6880ebcbf7f4ddceb92cb",
        "EndpointID": "3acf96d0214c8bb088e615e5e0544f19527e7da4fe8dd2cf57dee9f4f72c8ef0",
        "Gateway": "172.17.0.1",
        "IPAddress": "172.17.0.3",
        "IPPrefixLen": 16,
        "IPv6Gateway": "",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "MacAddress": "02:42:ac:11:00:03",
        "DriverOpts": null
    }
}

如果我们删除 u2 实例,再启动一个新的 u3,并查看其休息:

$ docker rm -f u2


$ docker run -it --name u3 ubuntu 


$ docker inspect u3
 "Networks": {
    "bridge": {
        "IPAMConfig": null,
        "Links": null,
        "Aliases": null,
        "NetworkID": "5bd056a8204a81086acd846de2d0791373671f14a5f6880ebcbf7f4ddceb92cb",
        "EndpointID": "371217a338a6787dd444ebd315fe5fee14b6346d2dd90601bcc49a29b7ecdfda",
        "Gateway": "172.17.0.1",
        "IPAddress": "172.17.0.3",
        "IPPrefixLen": 16,
        "IPv6Gateway": "",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "MacAddress": "02:42:ac:11:00:03",
        "DriverOpts": null
    }
}

可以看到 u3 的 IP,和之前 u2 的一样。如果我们想要 u2 的服务,结果 u2 被删除了,请求发到 u3 了,那么可能就会出错。

结论:docker 容器内部的 ip 是有可能会发生改变的。

为此,有必要自己做一些网络设计,例如创建一个新的网络模式,让部分容器在该网络模式下运行。

bridge

Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),该桥接网络的名称为 docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信。示意图:

说明:

  • Docker 使用 Linux 桥接,在宿主机虚拟一个 Docker 容器网桥(docker0),Docker 启动一个容器时会根据 Docker 网桥的网段分配给容器一个 IP 地址,称为 Container-IP,同时 Docker 网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信。
  • docker run 的时候,没有指定 network 的话默认使用的网桥模式就是 bridge,使用的就是 docker0。在宿主机 ifconfig,就可以看到 docker0 和自己 create 的 network(后面讲)eth0,eth1,eth2……代表网卡一,网卡二,网卡三……,lo 代表 127.0.0.1,即 localhost,inet addr 用来表示网卡的 IP 地址
  • 网桥 docker0 创建一对对等虚拟设备接口一个叫 veth,另一个叫 eth0,成对匹配。
    • 整个宿主机的网桥模式都是 docker0,类似一个交换机有一堆接口,每个接口叫 veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫 veth pair);
    • 每个容器实例内部也有一块网卡,每个接口叫 eth0;
    • docker0 上面的每个 veth 匹配某个容器实例内部的 eth0,两两配对,一一匹配。

通过上述,将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一个网络下,会从这个网关下各自拿到分配的 ip,此时两个容器的网络是互通的。

接下来我们两两匹配验证,启动两个 Tomcat:

docker run -d -p 8081:8080 --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --name tomcat82 billygoo/tomcat8-jdk8

然后我们可以用 ip addr 命令查看,在下方多了两个 veth 的:

61: veth6ddaa35@if60: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether e6:d2:ee:03:d7:7e brd ff:ff:ff:ff:ff:ff link-netnsid 2
    inet6 fe80::e4d2:eeff:fe03:d77e/64 scope link 
       valid_lft forever preferred_lft forever


63: veth6b10f89@if62: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether fa:f7:44:71:39:65 brd ff:ff:ff:ff:ff:ff link-netnsid 3
    inet6 fe80::f8f7:44ff:fe71:3965/64 scope link 
       valid_lft forever preferred_lft forever

进入到容器内部,可以看到有 eth0 的:

$ docker exec -it tomcat81 bash


$ ip addr
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

60: eth0@if61: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

可以看到 eho0 和 veth 是一一配对的,

接下来介绍下 host 模式。

host

host,主机模式,直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行 NAT 转换。

容器将不会获得一个独立的 Network Namespace, 而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡而是使用宿主机的 IP 和端口。示意图:

再启动一个 Tomcat:可以看到有一个警告,不太推荐该种模式

$ docker run -d -p 8083:8080 --network host --name tomcat83 billygoo/tomcat8-jdk8
WARNING: Published ports are discarded when using host network mode
09a334d59bc97365d886911be278ebcd9e4dff637dcda97a6687fe3e9b1d2335

为什么有警告?docker 启动时指定–network=host 或-net=host,如果还指定了-p 映射端口,那这个时候就会有此警告,并且通过-p 设置的参数将不会起到任何作用,端口号会以主机端口号为主,重复时则递增。

解决的办法就是使用 docker 的其他网络模式,例如–network=bridge;或者不用-p 选项,或忽略警告

此时我们用 docker inspect tomcat83 ​查看信息:没有网关和 IP 地址。

"Networks": {
    "host": {
        "IPAMConfig": null,
        "Links": null,
        "Aliases": null,
        "NetworkID": "553d2c47bcaad9d82904e56225e6afae3d5a23379822c9d96ac74170041aad79",
        "EndpointID": "1946b0286e008731cb65b6a30f074d6995dc08936126029bb76ea4665dd3d446",
        "Gateway": "",
        "IPAddress": "",
        "IPPrefixLen": 0,
        "IPv6Gateway": "",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "MacAddress": "",
        "DriverOpts": null
    }
}

进入容器内部看:几乎和宿主机的一样

$ docker exec -it tomcat83 bash

$ ip addr
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: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:a4:2c:88 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic enp0s3
       valid_lft 84224sec preferred_lft 84224sec
    inet6 fe80::d81a:24b:f174:82f/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever


3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:74:1d:cd brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.242/24 brd 192.168.2.255 scope global noprefixroute dynamic enp0s8
       valid_lft 602624sec preferred_lft 602624sec
    inet6 fe80::3c89:876e:2930:5286/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever


4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:06:12:45 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever


5: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
    link/ether 52:54:00:06:12:45 brd ff:ff:ff:ff:ff:ff



6: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:94:6e:78:c1 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

没有设置-p 的端口映射了,如何访问启动的 tomcat83 ?直接访问宿主机即可!http://宿主机 IP:8080/

在 CentOS 里面用默认的火狐浏览器访问容器内的 tomcat83 看到访问成功,因为此时容器的 IP 借用主机的,所以容器共享宿主机网络 IP,这样的好处是外部主机与容器可以直接通信。

none

在 none 模式下,并不为 Docker 容器进行任何网络配置,禁用了网络功能,只有 lo 标识(就是 127.0.0.1,本地回环)

也就是说,这个 Docker 容器没有网卡、IP、路由等信息,只有一个 lo,需要我们自己为 Docker 容器添加网卡、配置 IP 等。

启动一个来分析:

docker run -d -p 8084:8080 --network none --name tomcat84 billygoo/tomcat8-jdk8

通过 inspect 查看:没有网关和 IP

$ docker inspect tomcat84 | tail -n 20
"Networks": {
    "none": {
        "IPAMConfig": null,
        "Links": null,
        "Aliases": null,
        "NetworkID": "1ddfe19eb462f6485c00ec56945ce5d1835d4aac20b6229e73a0018176c05ff5",
        "EndpointID": "9b92af07ef5c8c85a0c1218167304a72ac01047af69be44e489d199e1879d260",
        "Gateway": "",
        "IPAddress": "",
        "IPPrefixLen": 0,
        "IPv6Gateway": "",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "MacAddress": "",
        "DriverOpts": null
    }
}

进入容器内看:

$ docker exec -it tomcat84 bash


$ ip addr
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

了解即可,不过多展开

container

新建的容器和已经存在的一个容器共享一个网络 IP 配置而不是和宿主机共享。

新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同

样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。

示意图:

接下来实践下,先创建一个容器:

docker run -d -p 8085:8080 --name tomcat85 billygoo/tomcat8-jdk8

然后创建第二个,并使用第一个容器的网卡,但是报错了:

$ docker run -d -p 8086:8080 --network container:tomcat85 --name tomcat86 billygoo/tomcat8-jdk8
$ docker: Error response from daemon: conflicting options: port publishing and the container type network mode.
See 'docker run --help'.

相当于 tomcat86 和 tomcat85 公用同一个 ip 同一个端口,导致端口冲突

这里我们换个镜像:Alpine 操作系统。Alpine Linux 是一款面向安全的、轻型、独立的、非商业的通用 Linux 发行版,专为追求安全性、简单性和资源效率的用户而设计。 可能很多人没听说过这个 Linux 发行版本,但是经常用 Docker 的朋友可能都用过,因为他小,简单,安全而著称,所以作为、基础镜像是非常好的一个选择,可谓是麻雀虽小但五脏俱全,镜像非常小巧,不到 6M 的大小,所以特别适合容器打包

启动 2 个容器:

docker run -it                             --name alpine1  alpine /bin/sh

新开一个终端,运行第二个:

docker run -it --network container:alpine1 --name alpine2  alpine /bin/sh

接下来验证是否共用搭桥,在两个终端内执行 ip addr​:

$ docker exec -it alpine1 /bin/sh
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
21: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

$ docker exec -it alpine2 /bin/sh
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
21: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

可以看到两个 IP 都是一样的,172.17.0.2。如果 alpine1 被关闭了呢?docker stop alpine1

那么 alpine2 也没有 IP 了:

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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

自定义网络

接下来介绍第 5 种:自定义网络

Docker 默认的网络有 3 种:

$ docker network ls
NETWORK ID     NAME         DRIVER    SCOPE
5bd056a8204a   bridge       bridge    local
553d2c47bcaa   host         host      local
1ddfe19eb462   none         null      local

但是我们也可以创建一个网络:

$ docker network create aa_network
9eeb4fd0bf15a59d77bdba7e40594eb30ddd2c2c2ad66df706608a939cd2d193


$ docker network ls
NETWORK ID     NAME         DRIVER    SCOPE
9eeb4fd0bf15   aa_network   bridge    local
5bd056a8204a   bridge       bridge    local
553d2c47bcaa   host         host      local
1ddfe19eb462   none         null      local

为什么需要自定义网络?可以将容器分门别类,在各自的网络中通信。之前我们演示过,Docker 内容器的 IP 是有可能发生变化的

在介绍自定义网络之前,我们再次演示下,不使用自定义网络有什么问题。

为避免干扰,先删除其他容器,再启动两个 Tomcat:

docker run -d -p 8081:8080   --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080   --name tomcat82 billygoo/tomcat8-jdk8

然后我们打开两个终端,分别进入容器:

docker exec -it tomcat81 bash
docker exec -it tomcat82 bash

81 的 IP 信息:172.17.0.2

$ ip addr
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
23: eth0@if24: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

82 的 IP 信息:172.17.0.3

$ ip addr
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
25: eth0@if26: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

此外,在两个容器内,互相是能 ping 通的,例如 81 能 ping 通 82:

$ ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.030 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.024 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.024 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.026 ms

既然 IP 地址是可能变化的,那么根据 IP 地址来通信是可能会被干扰的,能否通过服务名来 ping 呢?当然是不行的,例如在 81:

$ ping tomcat2
ping: tomcat2: Name or service not known

接下来我们演示,使用自定义网络的话,能不能解决上述问题。

首先自定义桥接网络,自定义网络默认使用的是桥接网络 bridge:

$ docker network create zzyy_network

$ docker network ls
NETWORK ID     NAME           DRIVER    SCOPE
f1c9ebe5d961   bridge         bridge    local
553d2c47bcaa   host           host      local
1ddfe19eb462   none           null      local
daf309d234de   zzyy_network   bridge    local

删除之前的容器,新建容器,加入上一步新建的网络:

docker run -d -p 8081:8080 --network zzyy_network  --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --network zzyy_network  --name tomcat82 billygoo/tomcat8-jdk8

再次打开两个终端,分别进入容器,,并且试试能否 ping 通:

$ docker exec -it tomcat81 bash

$ ping tomcat82
PING tomcat82 (172.18.0.3) 56(84) bytes of data.
64 bytes from tomcat82.zzyy_network (172.18.0.3): icmp_seq=1 ttl=64 time=0.046 ms
64 bytes from tomcat82.zzyy_network (172.18.0.3): icmp_seq=2 ttl=64 time=0.038 ms
64 bytes from tomcat82.zzyy_network (172.18.0.3): icmp_seq=3 ttl=64 time=0.039 ms

可以看到完全能 ping 通。

结论:自定义网络本身就维护好了主机名和 IP 的对应关系( IP 和域名都能通)

link 技术

在过去,Docker 还有一种通信的功能(类似网络),叫做 link,不过已经过时了,不用再去学习,官网文档如下:Legacy container links

The --link​ flag is a legacy feature of Docker. It may eventually be removed. Unless you absolutely need to continue using it, we recommend that you use user-defined networks to facilitate communication between two containers instead of using --link​.

(完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2136812.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【python】OpenCV—Mask RCNN for Object Detection and Instance Segmentation

文章目录 1、任务描述2、MASR RCNN 网络结构3、方法实现4、结果展示5、涉及到的库getPerfProfile 6、参考 1、任务描述 利用 mask rcnn 网络&#xff0c;进行图片和视频的目标检测和实例分割 2、MASR RCNN 网络结构 3、方法实现 # Copyright (C) 2018-2019, BigVision LLC (L…

YOLOv5改进 | 模块缝合 | C3 融合Self-Calibrated Convolutions丰富特征图【CVPR2020】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv5入门 改…

pgrouting实战应用

1&#xff09;下载地区地区数据&#xff08;下载数据是XYZM 四位数据&#xff09; 2&#xff09;下载裁剪行政区数据 3&#xff09;使用arcgis pro添加路网数据和行政区数据 4&#xff09;裁剪数据&#xff0c;仅历下行政区路网 5&#xff09;arcgis pro要素转线&#xff0…

基础GAN生成式对抗网络(pytorch实验)

&#xff08;Generative Adversarial Network&#xff09; 一、理论 https://zhuanlan.zhihu.com/p/307527293?utm_campaignshareopn&utm_mediumsocial&utm_psn1815884330188283904&utm_sourcewechat_session 大佬的文章中的“GEN的本质”部分 二、实验 1、数…

SIP ACK method

SIP ACK同样在RFC3261中定义。 ACK仅仅用于对INVITE request的response的回复&#xff0c;例如在通话结束时&#xff0c;MO要断开连接&#xff0c;此时就会生成一条BYE 消息。BYE不会经过代理&#xff0c;而是直接路由到MT。MT通过200 (OK) 响应确认收到 BYE&#xff0c;然后就…

vagrant+virtualbox+ubuntu22.04无法上网问题

一、过程 vagrantfile配置私有网络 config.vm.network "private_network", ip: "192.168.56.10"启动虚拟机&#xff0c;可以ping通百度的实际IP&#xff0c;ping不通域名修改/etc/netplan/50-vagrant.yaml&#xff0c;配置DNS network:renderer: Networ…

计算机毕业设计Python知识图谱美团美食推荐系统 美团餐厅推荐系统 美团推荐系统 美食价格预测 美团爬虫 美食数据分析 美食可视化大屏

《Python知识图谱美团美食推荐系统》开题报告 一、研究背景与意义 随着信息技术的飞速发展和互联网应用的普及&#xff0c;人们的消费习惯逐渐从线下转移到线上&#xff0c;外卖行业迎来了前所未有的发展机遇。美团作为国内领先的生活服务电子商务平台&#xff0c;拥有庞大的…

基于SpringBoot+Vue的考务报名平台(带1w+文档)

基于SpringBootVue的考务报名平台(带1w文档) 基于SpringBootVue的考务报名平台(带1w文档) 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进…

026.(娱乐)魔改浏览器-任务栏图标右上角加提示徽章

一、目标&#xff1a; windows中&#xff0c;打开chromium&#xff0c;任务栏中会出现一个chromium的图标。我们的目标是给这个图标的右上角&#xff0c;加上"有1条新消息"的小提示图标&#xff0c;也叫徽章(badge)注意&#xff1a;本章节纯属娱乐&#xff0c;有需要…

【DS】AVL树

目录 AVL树的介绍AVL树节点的定义认识AVL树的抽象图AVL树的插入BSTree规则插入更新平衡因子平衡因子的判断 AVL树的旋转左单旋右单旋左右双旋右左双旋 AVL树的验证AVL树的查找AVL树的性能 在上篇搜索二叉树末尾提到过&#xff0c;得益于搜索二叉树的性质&#xff1a;大于根往右…

计算机毕业设计Python深度学习垃圾邮件分类检测系统 朴素贝叶斯算法 机器学习 人工智能 数据可视化 大数据毕业设计 Python爬虫 知识图谱 文本分类

基于朴素贝叶斯的邮件分类系统设计 摘要&#xff1a;为了解决垃圾邮件导致邮件通信质量被污染、占用邮箱存储空间、伪装正常邮件进行钓鱼或诈骗以及邮件分类问题。应用Python、Sklearn、Echarts技术和Flask、Lay-UI框架&#xff0c;使用MySQL作为系统数据库&#xff0c;设计并实…

java: 程序包org.junit.jupiter.api不存在

明明idea没有报错&#xff0c;引用包也没问题&#xff0c;为啥提示java: 程序包org.junit.jupiter.api不存在&#xff1f; 配置&#xff01;还TMD是配置&#xff01; 如果是引用包的版本不对或者其他&#xff0c;直接就是引用报错或者pom里面飘红了。 这个应该是把generat…

微服务-- Sentinel的使用

目录 Sentinel&#xff1a;微服务的哨兵 生态系统景观 sentinel与spring cloud Hystrix 对比 Sentinel 主要分为两部分 Sentinel安装与使用 Sentinel的控制规则 流控规则 流控规则的属性说明 新增流控规则 关联流控模式 SentinelResource注解的使用 SentinelResou…

如何将自己的项目发布到Maven中央仓库

1.背景 本教程为2024年9月最新版 我有一个java项目想发布到maven中央仓库&#xff0c;然后任何人都可以在pom文件中引用我写的代码 引用格式如下&#xff1a; <!-- 这是引用rocketmq的坐标 --> <dependency><groupId>org.apache.rocketmq</groupId>&l…

炫酷HTML蜘蛛侠登录页面

全篇使用HTML、CSS、JavaScript&#xff0c;建议有过基础的进行阅读。 一、预览图 二、HTML代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-w…

ESP8266做httpServer提示Header fields are too long for server to interpret

CONFIG_HTTP_BUF_SIZE512 CONFIG_HTTPD_MAX_REQ_HDR_LEN1024 CONFIG_HTTPD_MAX_URI_LEN512CONFIG_HTTPD_MAX_REQ_HDR_LEN由512改为1024

C++ | Leetcode C++题解之第404题左叶子之和

题目&#xff1a; 题解&#xff1a; class Solution { public:bool isLeafNode(TreeNode* node) {return !node->left && !node->right;}int sumOfLeftLeaves(TreeNode* root) {if (!root) {return 0;}queue<TreeNode*> q;q.push(root);int ans 0;while …

氢能源多旋翼无人机技术详解

1. 技术背景与优势 随着全球对低碳、环保和高效能源解决方案的需求日益增长&#xff0c;氢能源作为一种清洁、高效的能源形式&#xff0c;在多个领域展现出巨大的应用潜力。在无人机领域&#xff0c;氢能源多旋翼无人机因其独特的优势逐渐受到关注。相比传统锂电池无人机&…

Linux sh命令

目录 一. 基本语法二. 选项2.1 -c 字符串中读取内容&#xff0c;并执行2.1.1 基本用法2.1.2 获取当前目录下失效的超链接 2.2 -x 每个命令执行之前&#xff0c;将其打印出来2.3 结合Here文档使用 一. 基本语法 ⏹Linux 和 Unix 系统中用于执行 shell 脚本 或 运行命令 的命令。…

【我的 PWN 学习手札】Fastbin Double Free

前言 Fastbin的Double Free实际上还是利用其特性产生UAF的效果&#xff0c;使得可以进行Fastbin Attack 一、Double Free double free&#xff0c;顾名思义&#xff0c;free两次。对于fastbin这种单链表的组织结构&#xff0c;会形成这样一个效果&#xff1a; 如果我们mallo…