Docker群服务到服务调用

时间:2019-01-18 17:01:00

标签: python docker flask 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群中运行时,我无法使应用程序与应用程序建立连接。 我仍然可以从集群外部调用每个应用程序服务:

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吗?

2 个答案:

答案 0 :(得分:2)

我还没有足够的声誉来发表评论。

Ram Idavalapati的答案是错误的,因为只有当服务的容器都在同一节点上时,这才起作用。无法使用服务名称访问位于不同节点上的另一个服务的端口。

我已经在SOgithub上为此创建了问题。我在这里写这是为了让任何来找的人都知道他/她并不孤单!

答案 1 :(得分:1)

Service name用作host将有助于在同一覆盖网络上的docker swarm中运行的两个docker服务/容器之间进行通信。

参考:https://docs.docker.com/v17.12/docker-cloud/apps/service-links/#discovering-containers-on-the-same-service-or-stack

示例堆栈文件: test.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。 此呼叫将转到主服务,而主服务将呼叫分片服务。

Master(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)

碎片(app.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)

主文件和分片的Dockerfile:

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