Skip to main content
 首页 » 编程设计

python之Docker群服务到服务调用

2024年09月03日31cmt

我是 docker swarm 菜鸟。我有两个正在迁移以作为 docker 服务运行的 python Flask 应用程序,一个需要调用另一个。 我正在使用 nginx 反向代理来管理与服务的外部连接。

nginx 位置设置是:

location /alpha/ { 
  proxy_pass https://alpha-app:5000/; 
} 
 
location /beta/ { 
  proxy_pass https://beta-app:5001/; 
} 

在 docker swarm 中运行时,其中“demo”是堆栈名称:

$ sudo docker service ls: 
NAME        PORTS 
demo_alpha  *:3002->5000/tcp 
demo_beta   *:3001->5001/tcp 
demo_nginx  *:443->443/tcp 

我可以在外部访问服务:

https://my-host/alpha/some_endpoint 
https://my-host/beta/some_endpoint 

现在我需要让 alpha 调用 beta 中的服务。 如果我在常规 docker 容器中运行应用程序,则以下从 alpha 到 beta 的调用有效:

url = https://my-host/beta/some_endpoint 
requests.get(url, cert, verify) 

请注意,当在 docker swarm 中运行时,应用程序在不同的主机上运行,​​但使用相同的网络。 当应用程序作为服务在 docker swarm 中运行时,我无法让应用程序到应用程序连接正常工作。 我仍然可以从 swarm 外部调用每个应用程序服务:

https://my-host/alpha/some_endpoint -> works 
https://my-host/beta/some_endpoint  -> works 

我无法让 alpha 使用来自 beta 的服务。 我试过只使用服务名称:

url = https://beta-app/some_endpoint -> connection refused 
url = https://beta-app:5001/some_endpoint -> hostname doesn't match 
url = https://my-host/beta/some_endpoint > name or service not known 

requests.get() 总是失败

一个 docker swarm 服务调用另一个的正确 url 是什么? 我需要查找服务的内部 IP 吗?

请您参考如下方法:

使用服务名称作为主机将有助于在同一覆盖网络上的docker swarm中运行的两个docker服务/容器之间进行通信。

更新 引用:https://docs.docker.com/network/overlay/#container-discovery

示例堆栈文件: 测试.yml

version: "3.4" 
services: 
    # This is the service name which is used in master as host. 
    # ex: http://shard:<port> 
    shard: 
        image: ramidavalapati/shard:0.1 
        deploy: 
            restart_policy: 
                condition: on-failure 
        networks: 
            - abc 
    master: 
        image: ramidavalapati/master:0.1 
        deploy: 
            restart_policy: 
                condition: on-failure 
        ports: 
            - 5000:80 
        networks: 
            - abc 
networks: 
    abc: 
        driver: overlay 

部署:sudo docker stack deploy -c test.yml test

API 调用:curl http://localhost:5000。 此调用将转到主服务,主服务将调用分片服务。

大师(app.py):

import urllib 
 
from flask import Flask 
app = Flask(__name__) 
 
@app.route("/") 
def hello(): 
    r = urllib.urlopen("http://shard:80") 
    return r.read() 
 
if __name__ == '__main__': 
    app.run(host='0.0.0.0', port=80) 

分片(应用程序.py):

from flask import Flask 
 
app = Flask(__name__) 
 
@app.route("/") 
def hello(): 
    return "Hello World" 
 
if __name__ == "__main__": 
    app.run(host='0.0.0.0', port=80) 

master 和 shard 的 Dockerfile:

FROM python:2.7-slim 
RUN pip install Flask 
ADD . . 
CMD ["python", "app.py"]