栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何配置Docker端口映射以将Nginx用作上游代理?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何配置Docker端口映射以将Nginx用作上游代理?

@T0xicCode的答案是正确的,但是我认为我会扩展细节,因为实际上花了大约20个小时才能最终实现可行的解决方案。

如果您希望在自己的容器中运行Nginx并将其用作反向代理,以在同一服务器实例上负载均衡多个应用程序,那么您需要遵循的步骤如下:

链接您的容器

docker run
您使用容器时,通常可以通过在中输入shell脚本
User Data
来声明指向任何其他 _正在运行的_容器的链接。这意味着您需要按顺序启动容器,只有后者才能链接到前者。像这样:

#!/bin/bashsudo docker run -p 3000:3000 --name API mydockerhub/apisudo docker run -p 3001:3001 --link API:API --name App mydockerhub/appsudo docker run -p 80:80 -p 443:443 --link API:API --link App:App --name Nginx mydockerhub/nginx

因此,在此示例中,该

API
容器未链接到任何其他
App
容器,但是该 容器已链接到
API
并且
Nginx
链接到
API
App

其结果是更改了

env
vars和
/etc/hosts
位于
API
and
App
容器内的文件。结果看起来像这样:

/ etc / hosts

cat /etc/hosts
在您的
Nginx
容器中运行将产生以下结果:

172.17.0.5  0fd9a40ab5ec127.0.0.1   localhost::1 localhost ip6-localhost ip6-loopbackfe00::0 ip6-localnetff00::0 ip6-mcastprefixff02::1 ip6-allnodesff02::2 ip6-allrouters172.17.0.3  App172.17.0.2  API

ENV Vars

env
在您的
Nginx
容器中运行将产生以下结果:

API_PORT=tcp://172.17.0.2:3000API_PORT_3000_TCP_PROTO=tcpAPI_PORT_3000_TCP_PORT=3000API_PORT_3000_TCP_ADDR=172.17.0.2APP_PORT=tcp://172.17.0.3:3001APP_PORT_3001_TCP_PROTO=tcpAPP_PORT_3001_TCP_PORT=3001APP_PORT_3001_TCP_ADDR=172.17.0.3

我已经截断了许多实际的var,但是以上是将流量代理到容器所需的键值。

要获取一个shell在运行中的容器中运行上述命令,请使用以下命令:

sudo docker exec -i -t Nginx bash

您可以看到,您现在同时具有

/etc/hosts
文件条目和
env
var,它们包含所链接的任何容器的本地IP地址。据我所知,这是在运行带有声明的链接选项的容器时发生的所有情况。但是您现在可以使用此信息
nginx
Nginx
容器中进行配置。

配置Nginx

这是个棘手的地方,有两种选择。您可以选择将站点配置为指向

/etc/hosts
docker
创建文件中的条目,或者可以使用
ENV
vars
sed
nginx.conf
文件
/etc/nginx/sites-enabled
夹中的conf文件和其他任何conf文件运行字符串替换(我用过)以插入IP。价值观。

选项A:使用ENV Vars配置Nginx

这是我选择的选项,因为我无法使用

/etc/hosts
file选项。我将尽快尝试选项B,并用任何发现更新本文。

此选项与使用

/etc/hosts
文件选项之间的主要区别在于,如何编写
Dockerfile
脚本以使用shell脚本作为
CMD
参数,而该脚本又处理字符串替换以将IP值复制
ENV
到conf文件中。

这是我最终得到的一组配置文件:

Docker文件

FROM ubuntu:14.04MAINTAINER Your Name <you@myapp.com>RUN apt-get update && apt-get install -y nano htop git nginxADD nginx.conf /etc/nginx/nginx.confADD api.myapp.conf /etc/nginx/sites-enabled/api.myapp.confADD app.myapp.conf /etc/nginx/sites-enabled/app.myapp.confADD Nginx-Startup.sh /etc/nginx/Nginx-Startup.shEXPOSE 80 443CMD ["/bin/bash","/etc/nginx/Nginx-Startup.sh"]

nginx.conf

daemon off;user www-data;pid /var/run/nginx.pid;worker_processes 1;events {    worker_connections 1024;}http {    # Basic Settings    sendfile on;    tcp_nopush on;    tcp_nodelay on;    keepalive_timeout 33;    types_hash_max_size 2048;    server_tokens off;    server_names_hash_bucket_size 64;    include /etc/nginx/mime.types;    default_type application/octet-stream;    # Logging Settings    access_log /var/log/nginx/access.log;    error_log /var/log/nginx/error.log;    # Gzip Settingsgzip on;    gzip_vary on;    gzip_proxied any;    gzip_comp_level 3;    gzip_buffers 16 8k;    gzip_http_version 1.1;    gzip_types text/plain text/xml text/css application/x-javascript application/json;    gzip_disable "MSIE [1-6].(?!.*SV1)";    # Virtual Host Configs      include /etc/nginx/sites-enabled/*;    # Error Page Config    #error_page 403 404 500 502 /srv/Splash;}

注意:重要的是要包含

daemon off;
nginx.conf
文件中,以确保容器在启动后不会立即退出。

api.myapp.conf

upstream api_upstream{    server APP_IP:3000;}server {    listen 80;    server_name api.myapp.com;    return 301 https://api.myapp.com/$request_uri;}server {    listen 443;    server_name api.myapp.com;    location / {        proxy_http_version 1.1;        proxy_set_header Upgrade $http_upgrade;        proxy_set_header Connection 'upgrade';        proxy_set_header Host $host;        proxy_set_header X-Real-IP $remote_addr;        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_set_header X-Forwarded-Proto $scheme;        proxy_cache_bypass $http_upgrade;        proxy_pass http://api_upstream;    }}

Nginx-Startup.sh

#!/bin/bashsed -i 's/APP_IP/'"$API_PORT_3000_TCP_ADDR"'/g' /etc/nginx/sites-enabled/api.myapp.comsed -i 's/APP_IP/'"$APP_PORT_3001_TCP_ADDR"'/g' /etc/nginx/sites-enabled/app.myapp.comservice nginx start

我把它留给你做你的最多的内容作业

nginx.conf
api.myapp.conf

魔术发生在

Nginx-Startup.sh
我们用来
sed
APP_IP
已写入到文件和文件
upstream
块中的占位符上进行字符串替换的地方。
api.myapp.conf``app.myapp.conf

这个ask.ubuntu.com问题很好地说明了这一点:
使用命令在文件中查找和替换文本

GOTCHA
在OSX上,以

sed
不同方式处理选项,特别是
-i
标志。在Ubuntu上,该
-i
标志将处理“就地”替换;它将打开文件,更改文本,然后“保存”相同的文件。在OSX上,该
-i
标志
需要 您想要结果文件具有的文件扩展名。如果使用的文件没有扩展名,则必须输入’‘作为
-i
标志值。

GOTCHA
要在

sed
用于查找要替换的字符串的正则表达式中使用ENV变量,需要将变量包装在双引号中。因此,正确的,尽管看上去有些古怪的语法如上所述。

因此docker启动了我们的容器并触发了

Nginx-Startup.sh
脚本运行,该脚本用于
sed
将值更改为我们在命令中提供
APP_IP
的相应
ENV
变量
sed
。现在我们的
/etc/nginx/sites-enabled
目录中有conf文件,这些文件具有
ENV
docker在启动容器时设置的vars
的IP地址。在
api.myapp.conf
文件中,您将看到
upstream
块已更改为:

upstream api_upstream{    server 172.0.0.2:3000;}

您看到的IP地址可能有所不同,但我注意到它通常是

172.0.0.x

现在,您应该正确路由所有路由。

GOTCHA
运行初始实例启动后,您将无法重新启动/重新运行任何容器。Docker在启动时为每个容器提供了一个新IP,并且似乎没有重复使用以前使用的任何容器。因此

api.myapp.com
,第一次将获得172.0.0.2,但是下次将获得172.0.0.4。但是
Nginx
将已经在其conf文件或该
/etc/hosts
文件中设置了第一个IP
,因此它将无法确定的新IP
api.myapp.com
。据我有限的理解,此解决方案很可能会使用
CoreOS
etcd
服务,并且它的服务就像
ENV
注册到同一
CoreOS
集群的所有计算机的共享一样。这是我要设置的下一个玩具。

选项B:使用

/etc/hosts
文件条目

应该
是更快,更轻松的方法,但是我无法使其正常工作。从表面上看,您只是将

/etc/hosts
条目的值输入到您的
api.myapp.conf
app.myapp.conf
文件中,但是我无法使用此方法。

这是我所做的尝试

api.myapp.conf

upstream api_upstream{    server API:3000;}

考虑到我的

/etc/hosts
文件中有一个这样的条目:
172.0.0.2API
我认为它只会提取值,但似乎没有。

Elastic LoadBalancer
从所有可用区的采购也遇到了一些辅助问题,因此当我尝试此路线时可能就是问题所在。相反,我不得不学习如何在Linux中处理替换字符串,所以这很有趣。我将在一段时间内尝试一下,看看效果如何。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/403515.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号