添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

由于容器的 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 `服务依然能正常运行? 服务器重...