Nginx 是一个多功能工具:网络服务器、负载均衡器、反向代理。在本文中,我将展示如何使用 Nginx 作为云中的中央反向代理,它与 Consul 和本地 DNS 服务器一起使用,为在云中运行的应用程序提供众所周知的域名。
您知道,有时工具很棒,但您希望拥有更多控制权,并且希望真正了解工具解决的问题。这是我的动机……用 Nginx1替换边缘路由器 Traefik 。
Nginx 首先是一个经过验证的、资源有效的、开源的网络服务器。根据 2020 年 3 月的报告,它也是排名第一的网络服务器,市场份额为 37%。 Nginx 是我们在工作中用于负载平衡服务、提供 TLS 以及作为 Kubernetes 集群中的入口服务器的 Web 服务器。
在我的家庭基础设施项目中使用 Nginx 的所有充分理由。 Nginx 将履行几个角色。首先,它将是一个边缘路由器,将外部网络与在我的云中运行的服务连接起来。其次,它将为客户端到服务和服务到服务的通信提供 TLS 加密。
在本文中,我将展示如何启动和配置 Nginx 作为反向代理服务器。
这篇文章最初出现在我的博客。
自定义 Nginx Docker 镜像
自定义 Docker 镜像将基于官方 Nginx 镜像。我将添加两个卷:一个用于提供配置文件,一个用于提供静态内容。这是 Dockerfile:
FROM nginx:1.17.9-alpine VOLUME [ "/etc/nginx/conf.d" ] VOLUME [ "/data/www" ]
我们构建 docker 容器。
>> docker build . -t inginx Sending build context to Docker daemon 2.048kB Step 1/3 : FROM nginx:1.17.9-alpine ---> 377c0837328f Step 2/3 : VOLUME [ "/etc/nginx/conf.d" ] ---> Using cache ---> b1fca48d47f8 Step 3/3 : VOLUME [ "/data/www" ] ---> Using cache ---> 26e85fbde6b0 Successfully built 26e85fbde6b0 Successfully tagged inginx:latest
现在我们需要提供基本配置文件/etc/nginx/conf.d/serve_static.conf
。该文件将创建一个监听端口80
的 Nginx 进程,它将通过显示目录列表/data/www
来服务于路由/static
。
server { listen 80; location /static { root /data/www/; autoindex on; } }
然后,为/data/www/
提供一些文件并运行容器。
docker run -p 80:80 \ -v $PWD/nginx.conf/:/etc/nginx.conf \ -v $PWD/data:/data/www \ --name inginx inginx:latest
在浏览器中输入http://localhost:80/static
,您将看到如下内容:
[](https://res.cloudinary.com/practicaldev/image/fetch/s–_sdX9yKx–/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://admantium.com/images /blog/infra/ic10_nginx_directory_listing.png)
好的。现在让我们将此基本配置演变为反向代理。
Nginx反向代理配置
简而言之,反向代理是接收传入请求并将其转发到另一台服务器的服务器。在生产设置中,您还可以配置不同服务器之间的负载平衡请求、应用修改请求 URI 和修改标头等功能。在我们的例子中,将接受对主机grafana.infra
的请求并将它们转发到在 Consul2注册的同一个命名服务。
让我们一点一点地构建配置文件gateway.conf
。
服务的 DNS 解析
首先,我们需要了解以下 Nginx 配置指令:
-
resolver
:提供DNS解析的服务器 -
upstream
:定义将流量转发到的一个或一组服务器。每个server
可以定义为一个 IP 地址或一个域名。
Grafana 的上游服务器的定义是这样的:
http { resolver 192.168.2.201 valid=10s; upstream grafana { server grafana.service.consul:9090; } }
如您所见,我正在使用本地 DNS 解析器来解析域名grafana.service.consul
– 在幕后,Consul 将为该服务提供真实 IP。
转发传入请求
现在我们需要定义如何接受和处理请求。相关的 Nginx 指令是:
-
server
:定义一个请求处理程序 -
server_name
:该指令定义请求处理程序负责哪个域名,可以在域名中使用多个服务器或通配符 -
listen
:Nginx监听的端口 -
location
:每个位置块定义当 URL 匹配特定路由时要做什么 -
proxy_pass
:传入请求将被转发到的服务器
我们希望将来自grafana.infra
的请求传递到我们的上游grafana
服务器。配置如下:
server { server_name grafana.infra; listen 80; location / { proxy_pass http://grafana; } }
这种配置有效……不完全。由于某些原因,无法正确加载 JavaScript 资源。当我运行 Docker 容器,然后打开浏览器控制台时,我看到:
[](https://res.cloudinary.com/practicaldev/image/fetch/s–dpJ0zeRy–/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://admantium.com/images /blog/infra/ic10_grafana_forwarding_error.png)
这是为什么? Grafana 服务器不知道涉及代理。我们需要添加额外的 HTTP 头来将请求从 Nginx 转发到 Grafana。这些标题是:
proxy_redirect off; proxy_set_header Host $http_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_redirect
– 不要将流量反弹回接收端 -
Host
– 保持与原始请求相同的主机名 -
X-Real-IP
:保留原始请求IP地址 -
X-Forwarded-For
:告诉服务如何路由此请求的 IP 地址列表 -
X-Forwarded-Proto
:保留请求方案
最终配置文件
让我们把所有这些放在一起。最终的配置文件gateway.conf
是这样的:
http { resolver 127.0.0.1 valid=10s; upstream grafana { server grafana.service.consul:9090; } } server { server_name grafana.infra; listen 80; proxy_redirect off; proxy_set_header Host $http_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; location / { proxy_pass http://grafana; } }
运行 Nginx 反向代理
现在我们可以运行 Docker 容器,并在浏览器中访问它。
docker run --network host \ -v $PWD/nginx.conf/:/etc/nginx.conf \ -v $PWD/gateway.conf/:/etc/gateway.conf --name inginx inginx:latest
[](https://res.cloudinary.com/practicaldev/image/fetch/s–bLsVGAQg–/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://admantium.com/images /blog/infra/ic10_grafana_forwarding_success.png)
Grafana 仪表板已正确呈现。
结论
本文展示了如何配置 Nginx 反向代理来访问在 Consul 注册的服务。该配置由两个块组成。第一个块使用本地 DNS 解析来获取在 consul 注册的服务的真实 IP 地址。第二个块在将传入请求转发到 Consul 服务时提供重要的 HTTP 标头。有了这个,你可以定义方便的域名来访问所有的 Consul 服务。
在下一篇文章中,我将展示如何在 Nginx 中添加 TLS 加密。
脚注
-
另一个原因是 Traefik 在访问和错误日志中并不冗长,我试图让它工作但系统没有帮助我。此外,官方 Traefik 文档似乎是为经验丰富的管理员编写的,它缺少上下文和故障排除信息。↩
-
如果你没有看完整的系列:Consul是一个服务注册和发现软件,它提供了一个DNS接口来查找其他服务的动态IP和端口。我使用它来注册作为 Docker 容器运行的服务,例如 Prometheus。↩
原文链接:https://devpress.csdn.net/cicd/62edea197e66823466181a14.html