我在连接点时有一些问题。
我设法将旧版应用程序和较新的应用程序进行了docker化,但是现在我需要通过API调用使它们彼此talk
互通。
项目:
project1_appnet
(桥驱动程序)project2_appnet
(桥驱动程序)project3_appnet
(桥驱动程序)在本地,我将这3个项目放在3个单独的文件夹中。每个项目都会有自己的app
,db
和cache
服务。
这是项目之一的docker-compose.yml
。 (他们几乎所有相同的docker-compose.yml都具有不同的图像和卷路径)
version: '3'
services:
app:
build: ./docker/app
image: 'cms/app:latest'
networks:
- appnet
volumes:
- './:/var/www/html:cached'
ports:
- '${APP_PORT}:80'
working_dir: /var/www/html
cache:
image: 'redis:alpine'
networks:
- appnet
volumes:
- 'cachedata:/data'
db:
image: 'mysql:5.7'
environment:
MYSQL_ROOT_PASSWORD: '${DB_ROOT_PASSWORD}'
MYSQL_DATABASE: '${DB_DATABASE}'
MYSQL_USER: '${DB_USER}'
MYSQL_PASSWORD: '${DB_PASSWORD}'
ports:
- '${DB_PORT}:3306'
networks:
- appnet
volumes:
- 'dbdata:/var/lib/mysql'
networks:
appnet:
driver: bridge
volumes:
dbdata:
driver: local
cachedata:
driver: local
问题:
注意:
link
,但显然不推荐使用v3
或不推荐使用curl
从project1容器尝试到project2容器:root@bc3afb31a5f1:/var/www/html# curl localhost:8050/login
curl: (7) Failed to connect to localhost port 8050: Connection refused
答案 0 :(得分:2)
如果最终的设置是每个服务都将在物理上不同的系统上运行,那么实际上没有任何选择。一个系统无法直接访问另一系统上的Docker网络;服务1能够到达服务2的唯一方法是通过其主机的DNS名称(或IP地址)和发布的端口。由于这在不同的环境中会有所不同,因此建议您将该值设置为已配置的环境变量。
environment:
SERVICE_2_URL: 'http://service-2-host.example.com/' # default port 80
一旦您解决了这一问题,大多数情况下就可以对单主机部署使用相同的设置。如果您的开发人员系统使用适用于Mac的Docker或适用于Windows的Docker,则应该可以使用special Docker hostname来访问其他服务
environment:
SERVICE_2_URL: 'http://host.docker.internal:8082/'
(如果您在台式机上使用Linux,则必须知道主机的某些IP地址;不是localhost
,因为它表示“此容器”,而不是docker0
接口地址,因为那样会处于特定网络上,但类似于主机的eth0
地址。)
您的另一个选择是“借用”另一个Docker Compose网络作为外部网络。如果您所有的Docker Compose设置都具有相同的名称,则会有些棘手。从一些实验看来,似乎Docker内部DNS总是会首先解析为您自己的Docker Compose文件,并且您必须了解诸如Compose分配的容器名称(这很难重构且稳定)之类的东西才能到达其他服务。
version: '3'
networks:
app2:
external:
name: app2_appnet
services:
app:
networks:
- appnet
- app2_appnet
environment:
SERVICE_2_URL: 'http://app2_app_1/' # using the service-internal port
MYSQL_HOST: db # in this docker-compose.yml
(我建议使用Docker Compose default
network来声明自己的{{3}};这通常会使您删除文件中的所有networks:
块而不会产生任何不良影响,但是在这种情况下,您需要声明networks: [default, app2_default]
连接到两者。
当您开始考虑此问题时,也可以考虑使用多主机容器解决方案。 Kubernetes是重量级的,但是它将在集群中的任何节点上运行容器(您不必特别担心放置),并且它为您提供名称空间和自动DNS解析。您只需设置SERVICE_2_URL: 'http://app.app2/'
即可指向另一个命名空间,而不必担心这些网络详细信息。
答案 1 :(得分:0)
如果您在本地运行此docker compose;给定的应用程序和数据库位于同一网络上-appnet- app 应该能够使用localhost:$ {DB_PORT}与 db 进行通话。
在生产中,如果app和db位于不同的机器上;应用可能需要使用IP或域名与数据库对话。
答案 2 :(得分:0)
考虑到要针对不同的docker部署使用不同的计算机,最好将它们放置在常规Web服务器(Apache2,Nginx)后面,然后使用简单的虚拟主机将流量从特定域路由到$APP_PORT
。我更喜欢这样做,而不是直接将容器暴露给网络。这样,您还可以在同一台计算机上托管多个应用程序(如果愿意,可以 )。因此,我建议您不要尝试连接docker网络,而应使用“ 常规”网络。
答案 3 :(得分:0)
正在使用inspect和cURL。我想我找到了解决方案。
本地:
NetworkSettings.Network.<network name>.Gateway
的{{1}} 172.25.0.1
8050
内进行了卷曲,以检查curl 172.25.0.1:8050/login
是否可以对app2容器发出http请求。或app1
docker exec -it project1_app_1 curl 172.25.0.1:8050/login
或curl 172.25.0.1:80
做了app2 -> app 1
唯一的问题是,当我们通过docker exec -it project2_app_1 curl 172.25.0.1:80
重新启动时,Gateway
值会发生变化
同样的生产方式:
我在网络和东西方面不是那个专业人士。我的产量估算为:
执行docker-compose up -d
,这是因为Web服务器在自己的计算机上(即使使用负载平衡器)也指向应用程序。