我在 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
在容器内部解析,ping
ing api 确实有效,但是,nginx 在那里做它自己的事情。
我也读过相关内容dnsmasq
,但是,我想在不安装此软件包的情况下运行它,我在这里还有其他选择吗?
答案1
没有办法强制 nginx 使用 /etc/hosts 中的条目。
但是,您可以在 nginx 配置中使用 map { } 来告诉 nginx 如何将主机名转换为 IP。您需要一个脚本将 /etc/hosts 转换为可以在 map 中使用的格式,即hostname ip
vs 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,并将它们放在不同的主机端口上以连接负载均衡器。