Docker撰写:模拟外部服务

时间:2017-03-22 23:39:43

标签: networking docker

我有以下情况:

我的应用程序包含一个调用的Web服务 外部API(比如,一些SaaS服务,ElasticSearch等)。对于非单元测试目的,我们希望控制外部服务,然后还要注入故障。应用程序和“模拟”API是dockerized和 现在我想用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(需要修改Dockerfiles才能安装)
  • 使用docker networks(这对我来说真的不太清楚)

有没有简单的选择来实现我的目标?

修改

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

import requests

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

3 个答案:

答案 0 :(得分: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

如果您想保留容器名称,可以使用links

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

或网络aliases

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 :(得分: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将在172.23.254.1点击我的网络服务器。

答案 2 :(得分:1)

我能够使用-links解决此问题,有没有办法在docker-compose中建立网络?

版本:“ 3”

服务:

PrivelegedActionException