AWS 上的多容器 Docker - Nginx 使用主机 /etc/hosts 解析器

AWS 上的多容器 Docker - Nginx 使用主机 /etc/hosts 解析器

我在 Amazon Elastic Beanstalk 上有一个多容器 docker 环境,其中包含以下Dockerrun.aws.json文件:

{ 
    "AWSEBDockerrunVersion": 2, 
    "containerDefinitions": [ 
      { 
        "name": "web", 
        "memoryReservation": 256, 
        "image": "my/nginx/repo/image",  
        "portMappings": [ 
          { 
            "hostPort": 80, 
            "containerPort": 80 
          } 
        ], 
        "links": [ 
          "api" 
        ], 
        "essential": true 
      }, 
      { 
        "name": "api", 
        "memoryReservation": 256, 
        "image": "my-api/repo", 
        "essential": true, 
        "portMappings": [ 
          { 
            "hostPort": 3000, 
            "containerPort": 80 
          } 
        ]
      } 
    ] 
  }

最终,我希望 nginx 服务的节点应用程序能够解析来自链接容器的命名地址的请求,因此在我的web图像(节点应用程序)中,我想发出请求http://api/some/resource并让 nginx 将其解析为 api 容器。

现在,由于 docker 根据指定的链接为 api 容器添加了主机条目,我希望 nginx 服务器能够从 hostsetc/hosts文件中解析地址,但是我发现 nginx 使用它自己的解析器。在对该问题进行一些研究后,我发现在非 Elastic Beanstalk 多容器解决方案和用户定义网络中,解析器将由 docker 在 上提供127.0.0.11,但是由于目前无法在 中定义用户定义网络Dockerrun.aws.json,因此我一直在寻找其他解决方案。可以links在容器内部解析,pinging api 确实有效,但是,nginx 在那里做它自己的事情。

我也读过相关内容dnsmasq,但是,我想在不安装此软件包的情况下运行它,我在这里还有其他选择吗?

答案1

没有办法强制 nginx 使用 /etc/hosts 中的条目。

但是,您可以在 nginx 配置中使用 map { } 来告诉 nginx 如何将主机名转换为 IP。您需要一个脚本将 /etc/hosts 转换为可以在 map 中使用的格式,即hostname ipvs ip hostname

以下是示例地图:

map $container_hostname $container_ip {
    default 127.0.0.1;
    containerA X.X.X.X;
    containerB Y.Y.Y.Y;
}

稍后您可以在配置文件中执行以下操作:

server_name   ~^(www\.)?(?<container_hostname>.+)$;

location / {
    proxy_pass http://$container_ip:80;
}

nginx 会匹配请求server_name并且存储在$container_hostname中:

http://nginx.org/en/docs/http/server_names.html#regex_names

然后它会在映射中查找主机名,获取相应的IP并将其传递给proxy_pass。

更多地图信息:http://nginx.org/en/docs/http/ngx_http_map_module.html

答案2

没有 nginx - 没有问题。只需将其替换为应用程序负载均衡器。那么链接容器内的请求怎么办?它们无论如何都会直接进入链接容器,绕过 nginx,所以这里没用。您可以在容器内使用端口 80,并将它们放在不同的主机端口上以连接负载均衡器。

相关内容