由于容器的 IP 地址会在容器重启后发生变化,因不能写死 IP 地址,使用容器的名字访问容器服务是最优的,所以就有了下文。

1.使用 --link 参考

docker run --link可以用来链接2个容器,使得源容器(被链接的容器)和接收容器(主动去链接的容器)之间可以互相通信,并且接收容器可以获取源容器的一些数据,如源容器的环境变量。

--link的格式:

--link <name or id>:alias

其中,name和id是源容器的name和id,alias是源容器在link下的别名。

创建并启动名为nginx_test的容器。

[root@ambari01 ~]# docker run -d --name nginx_test nginx

创建并启动名为node的容器,并把该容器和名为nginx的容器链接起来。

[root@ambari01 ~]# docker run -itd --name node --link nginx_test:nginx centos:7 bash

--link nginx_test:nginx

nginx_test是上面启动的源容器的名字,nginx是该容器在link下的别名,可省略。

通俗易懂的讲,站在node容器的角度,nginx_test和nginx都是指向提供nginx服务容器的名字,并且作为容器的hostname,node用这2个名字中的任何一个都可以访问到那个容器并与之通信(docker通过DNS自动解析)。我们可以来看下:

进入node容器:

[root@ambari01 ~]# docker exec -it nginx

[root@2398e6006f7e /]#  ping nginx
PING nginx (172.17.0.5) 56(84) bytes of data.
64 bytes from nginx (172.17.0.5): icmp_seq=1 ttl=64 time=0.064 ms
64 bytes from nginx (172.17.0.5): icmp_seq=2 ttl=64 time=0.045 ms

[root@2398e6006f7e /]#  ping nginx_test
PING nginx (172.17.0.5) 56(84) bytes of data.
64 bytes from nginx (172.17.0.5): icmp_seq=1 ttl=64 time=0.060 ms
64 bytes from nginx (172.17.0.5): icmp_seq=2 ttl=64 time=0.058 ms

[root@2398e6006f7e /]# ping node
ping: node: Name or service not known

当使用--link时,docker会自动在接收容器内创建基于--link参数的环境变量:

docker会在接收容器中设置名为<alias>_NAME的环境变量,我们进入node容器,看下此环境变量:

[root@ambari01 ~]# docker exec -it node /bin/bash
[root@2398e6006f7e /]#  env | grep -i nginx_name
NGINX_NAME=/node/nginx

另外,docker还会在接收容器中创建关于源容器暴露的端口号的环境变量,这些环境变量有一个统一的前缀名称:

<name> PORT <port>_<protocol>

nginx镜像的Dockerfile文件中暴露了4444端口号:

EXPOSE 80

我们进入node容器,看这些此环境变量:

[root@ambari01 ~]# docker exec -it node /bin/bash

[root@2398e6006f7e /]#  env | grep -i NGINX_PORT_80_TCP_
NGINX_PORT_80_TCP_PROTO=tcp
NGINX_PORT_80_TCP_PORT=80
NGINX_PORT_80_TCP_ADDR=172.17.0.5

可见,确实有3个以<name> PORT <port> <protocol> 为前缀的环境变量存在。

另外,docker还在接收容器中创建1个名为<alias>_PORT的环境变量,值为 源容器的URL:源容器暴露的端口号中最小的那个端口号

[root@2398e6006f7e /]# env |grep -i  nginx_port=
NGINX_PORT=tcp://172.17.0.5:80

使用--link参数。只能实现docker的单项连接,及只有node容器能连接访问nginx_test容器中服务和域名,而node容器不能访问自身的容器名字,nginx_test容器不能访问自身及node容器的名字。

[root@ambari01 ~]# docker exec -it nginx_test bash

root@4a22c7ed83a9:/# ping nginx_test
ping: nginx_test: Name or service not known
root@4a22c7ed83a9:/# ping node
ping: node: Name or service not known

2.使用自定义网段

docker 网卡介绍

docker 安装好之后默认会创建三个虚拟网卡,可以使用 docker network ls 命令来查看,三个虚拟网卡和 VMware 的类似。

[root@ambari01 ~]# docker network ls
 NETWORK ID          NAME                DRIVER              SCOPE
 80c5d482237a        bridge              bridge              local
 0d82d44a884a        host                host                local
 61dc3dfc2c93        none                null                local
  • bridge 是默认的网卡,网络驱动是 bridge 模式,类似于 Vmware 的 NAT 模式,如果容器启动时不指定网卡,则会默认连接到这块网卡上。如果需要访问容器内部的端口需要设置端口映射。
  • host 是直接使用主机的网络,网络驱动是 host 模式,类似于 Vmware 的桥接模式,可能会和主机的端口存在冲突,不需要设置端口映射即可连接到容器端口。
  • none 禁止所有联网,没有网络驱动,一般情况下用不到。

由于默认的网卡需要设置端口映射并且 IP 地址会随着容器的启动停止而变动,所以我们这里选择使用自定义网络来实现容器之间互相访问。

创建自定义网络

使用 docker network create my-net 命令来创建一个我们自定义的网络, 网络驱动仍然使用 bridge

[root@ambari01 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
80c5d482237a        bridge                  bridge                 local
0d82d44a884a        host                     host                    local
4745257203be        my-net                 bridge                 local
61dc3dfc2c93          none                    null                     local
[root@ambari01 ~]#

现在这个创建好的自定义网络就和默认的 bridge 网络隔离开了,互相之间不能访问,而且它们也不在同一个网段上。

使用 docker network inspect my-net 命令查看默认网卡的详细信息。

[root@ambari01 ~]# docker network inspect my-net
[
{
"Name": "my-net",
"Id": "4745257203be38ff4b886acb4d9c1e1bbb3e5a87c62d08ca396831ae2775c839",
"Created": "2021-10-18T14:50:27.269076493+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
......省略
"Options": {},
"Labels": {}
}
]

创建两个 python 容器,使用 docker run -it --name test1 --network my-net centos:7 bash 命令来创建第一个名字为 test1 的容器, --name 参数指定容器的名字, --network 参数指定使用自定义的网络。

新开启一个终端,使用 docker run -it --name test2 --network my-net centos:7 bash 命令创建第二个名字为 test2 的容器,尝试使用ping通过别名 test1 来访问第一个容器。

使用 ping 命令测试是可以正常 ping 的通的。

[root@ambari01 ~]# docker run -it --name test2 --network my-net centos:7 bash
[root@b2461a7e6fe6 /]# ping test1
PING test1 (172.18.0.2) 56(84) bytes of data.
64 bytes from test1.my-net (172.18.0.2): icmp_seq=1 ttl=64 time=0.066 ms
64 bytes from test1.my-net (172.18.0.2): icmp_seq=2 ttl=64 time=0.057 ms

[root@b2461a7e6fe6 /]# ping test2
PING test2 (172.18.0.3) 56(84) bytes of data.
64 bytes from b2461a7e6fe6 (172.18.0.3): icmp_seq=1 ttl=64 time=0.021 ms
64 bytes from b2461a7e6fe6 (172.18.0.3): icmp_seq=2 ttl=64 time=0.032 ms

由于在创建容器时并没有使用 -p 参数设置端口映射,所以外部不能访问到容器内部的内容,但是容器之间全端口都是可以正常访问的。

再次使用 docker network inspect my-net 命令来验证两个容器连接到了同一个自定义网络下。

[root@ambari01 ~]# docker network inspect my-net
[
{
"Name": "my-net",
"Id": "4745257203be38ff4b886acb4d9c1e1bbb3e5a87c62d08ca396831ae2775c839",
"Created": "2021-10-18T14:50:27.269076493+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": {
"06c8f14df63e6595a6b1cb8443568680e07e11b37f5089e21f87f02c6bf8224a": {
"Name": "test1",
"EndpointID": "2cef43667b03ce1270f76e7f8a933f51f799af1d177cc782714d829dd8390c0e",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"b2461a7e6fe66cac4c62e5b4aa4c285663f1ef13b59d35407b21c1fbefb8bc22": {
"Name": "test2",
"EndpointID": "a2e75b42dc87e7b2eb5f16e309d77ea29af2ba28ca1b75527a5ab4c052bdb7cb",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]

在 Containers 字段中可以看到两个容器连接到了同一个网段下,并且自动分配了同网段的 IP 地址。

默认网络和自定义网络区别

说到这里可能有人会问了,那默认的网卡的网卡驱动也是 bridge 模式的,用户自定义的网络也是 bridge 模式,不就是换了一个名字吗,为什么默认的网卡不可以使用别名进行 IP 地址解析呢?

这个问题问得好,官方特意解释了这两个网卡的 区别

User-defined bridges provide automatic DNS resolution between containers .
Containers on the default bridge network can only access each other by IP addresses, unless you use the --link option, which is considered legacy. On a user-defined bridge network, containers can resolve each other by name or alias.

翻译过来大意: 就是用户自定义的网卡可以在容器之间提供自动的 DNS 解析 ,缺省的桥接网络上的容器只能通过 IP 地址互相访问,除非使用 --link 参数。在用户自定义的网卡上,容器直接可以通过名称或者别名相互解析。

文档中提到了 --link 参数,官方文档中已经 不推荐 使用 --link 参数,并且最终可能会被删除,所以最好不要使用 --link 参数来连接两个容器,并且它有多个缺点。

如果使用 --link 参数,需要在容器之间手动创建链接,这些链接需要双向创建,如果容器多于两个的话,将会很困难。或者也可以通过编辑 hosts 文件的方式来指定解析结果,但是这样将会非常难以调试。

默认网卡测试

默认网卡 Name 为bridge ,使用该网段,容器间可以互相通过容器ip访问,但是无法通过容器名字互相访问或者进行自身访问。

以上就是通过自定义网卡来使两个容器互相连接的方法,这种方法便于部署和调试,而且还提供了网络隔离功能,两个容器之间不会互相干扰,可以随时断开或者连接,并且可以使用 --subnet 参数指定自定义网络的 IP 段,这里就不详细展开了。

在使用 Docker 的时候我们会常常碰到这么一种应用,就是我需要 两个 多个 容器 ,其中某些 容器 需要使用另外一些 容器 提供的服务。比如这么一种情况:我们需要一个 容器 来提供mysql的数据库服务,而另外 两个 容器 作为客户端来连接使用mysql数据库服务。下面我们就来看看 Docker 是怎样通过Link来实现这种功能的。 1. 这里我们首先创建 两个 容器 image,一个用来模拟mysql数据库,另外一个使用mysql的client来模拟一些使用mysql服务的应用,这种应用可以是任何php,python,java等的应用。 1.1 先创建一个mysql_server目录并在其下创建一个 Docker file文件, 您想在 多个 版本的PostgreSQL上运行sql / plpgsql代码,以查看其在所有版本上的性能。 使用此软件,您可以使用具有不同PostgreSQL版本的 Docker 容器 创建构建场。 将使用上游的PostgreSQL源进行构建。 这可以用作测试环境,以在 多个 不同的主要和次要PostgreSQL版本上测试PostgreSQL功能/查询/ sql / plpgsql。 首先,它创建了预先提供了PostgreSQL源代码的 docker 容器 。 然后,在每个服务器内部构建适当的Pg版本,然后在每个服务器内部启动Pg服务器。 然后,您可以在 多个 Pg版本上运行测试套件,然后基于Pg日志构建报告,以查看您的测试用例在不同版本上的行为。 如果您试图找出问题,重现问题,然后创建一个 (如果可以的话,或者创建 ),这样可以有所帮助,以便您以简化的形式与他人共享。 在这些 容器 上, / va 本文主要给大家介绍了关于.net 4.5部署到 docker 容器 的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 .net4.5部署到 docker 容器 部署到windows 容器 部署到 linux 容器 部署到windows 容器 由于.net本身就是运行在windows平台的,所以它与windows 容器 也是更加适合,你可以以iis镜像为基础,去编写你的 Docker file文件,从而去构建你的.net项目镜像。 1. 两个 现成的例子 .net console程序 docker run --rm mcr.microsoft.com/dotnet/frame 因为 容器 中的ip地址 和 宿主机的ip地址 是不同的,所以当 nacos 用 localhost 时,其实对应的是 nacos 容器 的ip地址,所以调用 localhost 时,并不能通过 宿主机的ip地址调用3306端口映射到 容器 中3306端口调用mysql 容器 ,也不能通过 nacos 容器 ip地址调用3306端口调用mysql 容器 ,因为 docker 中 nacos 容器 和 mysql 容器 分配的地址是不同的。这种模式下, docker 不为 容器 进行任何网络配置,需要我们自己为 容器 添加网卡,配置IP。 参考https://www.cnblogs.com/CloudMan6/p/7400580.html 在上一节中, 两个 host上四个 容器 的网络信息如下,然后进行网络连通性测试,可见通vlan的 容器 即使分布在不同的host上也是可以通信的,不同vlan的 容器 不管在不在同一个host上都不能通信 root@host1:~# docker exec bbox_10_1 ip r 文章目录 Docker 网络详解一、理解 Docker 0二、evth-pair技术三、- - link四、自定义网络五、网络连通 学习视频链接,以示尊重:https://www.bilibili.com/video/BV1og4y1q7M4?p=37 Docker 网络详解 一、理解 Docker 0 Docker 使用的是 Linux 的桥接,在宿主机中是一个 Docker 容器 的网桥 docker 0。 每启动一个 docker 容器 docker 就会给 docker 容器 分配一个ip,只要安装了 docker ,就会有一个网卡do 用于 容器 和主机的 Docker DNS Docker DNS创建一个 容器 ,该 容器 充当计算机中 Docker 容器 的DNS。 例如,每个正在运行的 容器 都可以通过$container_name. docker 访问 。 如果愿意,您可以通知自己的域名。 您的域可在 docker 内部和外部使用,但仅适用于您的机器。 例如,您可以从浏览器窗口或从 容器 内部 访问 。 创建它是为了让您可以在 容器 中工作,就像是“真实的”服务器设置一样。 您将可以 访问 容器 内的所有端口/服务,而无需暴露所有端口。 您也可以像以前一样发布端口来 访问 它。 例如:127.0.0.1:8080-> container_ip:80 它已经在 linux 和macOS Catalina上进行了测试。 macOS环境有一个缺点,那就是每次引导主机时始终会运行./bin/ docker -dns tunnel 。 将在每次引导时安装并加载服务以处理这种必要 文章目录服务器重启后 Docker 服务 访问 失败一、 检查服务 容器 是否启动如果有 容器 未启动就启动 容器 二、检查是否被防火墙屏蔽如果端口未开放,有两种情况:1. 不需要防火墙,直接关掉防火墙服务2. 需要防火墙,添加需要开放的端口三、检查路由IP转发是否开启发现IP转发未开启,解决方案:开启IP转发,在配置文件添加策略问题解析:为什么之前没有手动开启IP转发时` DOCKER `服务依然能正常运行? 服务器重...