Docker Compose:模拟外部服务

6
我有以下情况:
我的应用程序由一个单独的Web服务组成,该服务调用外部API(例如一些SaaS服务、ElasticSearch等)。为了非单元测试目的,我们想要控制外部服务,并在后续注入故障。应用程序和“模拟”的API都已经docker化,现在我想使用docker-compose来启动所有容器。
由于应用程序中有几个硬编码的地址(例如外部服务的主机名),我无法更改它们并需要绕过此问题。 service容器向http://external-service.com/getsomestuff发出调用。
我的想法是利用Docker提供的某些功能,将所有外向流量重定向到外部的http://external-service.com/getsomestuff,并将其指向模拟容器,而不更改URL。
我的docker-compose.yaml如下:
version: '2'
services:
  service:
    build: ./service
    container_name: my-service1
    ports:
      - "5000:5000"
    command: /bin/sh -c "python3 app.py"

  api:
    build: ./api-mock
    container_name: my-api-mock
    ports:
      - "5001:5000"
    command: /bin/sh -c "python3 app.py"

最后,我有了一个只执行以下操作的驱动程序:
curl -XGET localhost:5000/
curl -XPUT localhost:5001/configure?delay=10
curl -XGET localhost:5000/

第二个 curl 设置模拟延迟为 10 秒。

我考虑了几种选项:

  • 使用 iptables-fu(需要修改 Dockerfile 安装它)
  • 使用 Docker 网络(这对我来说非常不清楚)

有没有简单的方法可以实现我想要的效果?

编辑:

为了清晰起见,以下是 service 代码的相关部分:

import requests

@app.route('/')
def do_stuff():
    r = requests.get('http://external-service.com/getsomestuff')
    return process_api_response(r.text())
3个回答

3

Docker会为用户定义的网络运行一个内部DNS服务器。任何未知的主机查找都将被转发到您正常的DNS服务器。

2+版本的组合文件将自动创建一个网络供组合使用,因此有多种方法来控制它解析的主机名。

最简单的方法是使用主机名命名容器:

version: "2"
services:
  external-service.com:
    image: busybox
    command: sleep 100
  ping:
    image: busybox
    command: ping external-service.com
    depends_on:
      - external-service.com

如果您想保留容器名称,可以使用 链接
version: "2"
services:
  api:
    image: busybox
    command: sleep 100
  ping:
    image: busybox
    links:
      - api:external-service.com
    command: ping external-service.com
    depends_on:
      - api

或者网络别名

version: "2"
services:
  api:
    image: busybox
    command: sleep 100
    networks:
      pingnet:
        aliases:
        - external-service.com
  ping:
    image: busybox
    command: ping external-service.com
    depends_on:
      - api
    networks:
      - pingnet
networks:
  pingnet:

1
我能够使用 -links 来解决这个问题,那么在 docker-compose 中有没有办法进行网络设置呢?
版本:'3'
服务:
MOCK:
 image: api-mock:latest
 container_name: api-mock-container
 ports:
    - "8081:80"

api: 
 image: my-service1:latest
 links:
   - MOCK:external-service.com

1

我不是很清楚您试图解决的问题,但如果您想让容器内的external-service.com指向您的“模拟”服务,我认为您可以在docker-compose.yml文件中使用extra_hosts指令来实现。例如,如果我有:

version: "2"

services:
  example:
    image: myimage
    extra_hosts:
      - google.com:172.23.254.1

那将导致容器中的/etc/hosts包含以下内容:
172.23.254.1    google.com

访问 http://google.com 的尝试将会命中我的 web 服务器,地址为 172.23.254.1。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接