docker - Docker Compose:暴露不起作用
问题描述
码头工人-ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83b1503d2e7c app_nginx "nginx -g 'daemon ..." 2 hours ago Up 2 hours 0.0.0.0:80->80/tcp app_nginx_1
c9dd2231e554 app_web "/home/start.sh" 2 hours ago Up 2 hours 8000/tcp app_web_1
baad0fb1fabf app_gremlin "/start.sh" 2 hours ago Up 2 hours 8182/tcp app_gremlin_1
b663a5f026bc postgres:9.5.1 "docker-entrypoint..." 25 hours ago Up 2 hours 5432/tcp app_db_1
他们都工作正常:
- app_nginx 与 app_web 连接良好
- app_web 与 postgres 连接良好
没有工作文件:
- app_web 无法与 app_gremlin 连接
docker-compose.yaml
version: '3'
services:
db:
image: postgres:9.5.12
web:
build: .
expose:
- "8000"
depends_on:
- gremlin
command: /home/start.sh
nginx:
build: ./nginx
links:
- web
ports:
- "80:80"
command: nginx -g 'daemon off;'
gremlin:
build: ./gremlin
expose:
- "8182"
command: /start.sh
错误:
基本上我无法gremlin
从我的容器连接到app_web
容器。
以下所有内容均已在web_app
容器内执行
卷曲:
root@49a8f08a7b82:/# curl 0.0.0.0:8182
curl: (7) Failed to connect to 0.0.0.0 port 8182: Connection refused
网络统计
root@49a8f08a7b82:/# netstat -l
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.11:42681 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN
udp 0 0 127.0.0.11:54232 0.0.0.0:*
Active UNIX domain sockets (only servers)
Proto RefCnt Flags Type State I-Node Path
地图
root@49a8f08a7b82:/# nmap -p 8182 0.0.0.0
Starting Nmap 7.60 ( https://nmap.org ) at 2018-06-22 09:28 UTC
Nmap scan report for 0.0.0.0
Host is up.
PORT STATE SERVICE
8182/tcp filtered vmware-fdm
Nmap done: 1 IP address (1 host up) scanned in 2.19 seconds
nslookup
root@88626de0c056:/# nslookup app_gremlin_1 服务器:127.0.0.11 地址:127.0.0.11#53
非权威回答:名称:app_gremlin_1 地址:172.19.0.3
实验:
对于我做的 Gremlin 容器,
ports:
- "8182:8182"
然后从Host
我可以连接到gremlin
容器但web
与gremlin
容器之间仍然没有连接
我正在创建一个重新创建示例 Docker 文件(重新创建问题的最少内容),同时任何人都知道问题可能是什么?
解决方案
curl 0.0.0.0:8182
0.0.0.0 地址是一个通配符,它告诉应用程序侦听所有网络接口,您不要作为客户端连接到该接口。对于容器到容器的通信,您需要:
- 同一用户生成网络上的容器(compose 默认为您执行此操作)
- 连接到服务的名称(或容器名称)
- 连接到另一个容器内的端口,而不是发布的端口。
在您的情况下,命令应该是:
curl http://gremlin:8182
网络是在容器内运行的应用程序中命名的,因此每个容器都可以在桥接网络上获得它的开放环回接口和 IP 地址。因此,将应用程序移入容器意味着您需要监听 0.0.0.0 并使用 DNS 连接到网桥 ip。
您还应该从 Dockerfile 中删除链接和依赖项,它们不适用于版本 3。链接早已被弃用以支持共享网络。而且depends_on 在swarm 模式下不起作用,并且可能没有做你想做的事情,因为它从未检查过目标应用程序是否正在运行,只是该容器的启动被启动了。
最后一点,expose 不会影响在公共网络上的容器之间进行通信或在主机上发布端口的能力。Expose 只是在图像上设置元数据,即创建图像的人和运行图像的人之间的文档。应用程序不需要使用该值,但为了下游用户的利益,让您的应用程序默认使用该值是一个好习惯。由于它的作用,除非您有另一个应用程序检查公开的端口列表,例如自我更新的反向代理,否则无需在 compose 文件中公开端口,除非您将 compose 文件提供给另一个人并且他们需要文档。
推荐阅读
- windows - 通过 docker-compose 将 build-args 传递给 Dockerfile 的奇怪行为
- python - 时间序列数据合并最近右数据集具有多个相同的值
- c++ - 编写输出文件 Cuda C++
- ruby-on-rails - Rails 应用程序支持不同的时区
- node.js - Firebase 部署在控制台中有效,但在 bitbucket 管道中无效
- python - Pandas,为什么字符串匹配在第一个字母处停止
- css - 如何删除 Wordpress 中标题和滑块之间的空白?
- ios - 我无法在 Xcode 12 的 xib 中创建自定义 UIView
- c# - 如何从 WPF DataGrid 获取单元格内容
- angular - 在primeng中,我们如何获取表格列的默认下拉值过滤器