nginx正则匹配server_name动态解析到后端服务

背景

在公司的kubernetes集群中搭建了selenium grid,用于兼容测试,运行selenium测试用例,通过nginx反向代理浏览器服务的novnc端口提供预览结果界面, 因为要求兼容的浏览器和版本较多,所以每个node 在nginx里单独配置一个server就太麻烦了,也不利于管理。阅读nginx官方文档,发现nginx可以正则匹配server_name。

最终配置

ini 复制代码
server {
	listen 80;
	listen 443 ssl;
    # 域名大概都是这样的: selenium-chrome-node-115-0-20230801.example.net;
	server_name ~^selenium(.*)\.example\.org$;

    ssl_certificate /data/certificate/example-net/tls.crt;
    ssl_certificate_key /data/certificate/example-net/tls.key;

	client_max_body_size 30M;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;

    # 在使用变量来构造某个server地址的时候一定要用resolver指令来指定DNS服务器的地址,因为nginx和后端服务都部署在kubernetes中,所以,需要配置kubernetes的dns服务
    resolver kube-dns.kube-system;

	location / {
        
        set $upstream selenium$1.qa-tools.svc.cluster.local;

        proxy_pass http://$upstream:7900;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_connect_timeout 1d;
        proxy_send_timeout 1d;
        proxy_read_timeout 1d;
	}
}

server_name 配置正则匹配域名

  • server_name ~^selenium(.*).example.org$;

1. 使用正则表达式,server_name必须以波浪号字符开头,否则,它将被视为精确名称

ini 复制代码
服务器名 ~^www\d+\.example\.net$;

不要忘记设置" ^"和" $"锚点。它们不是语法上需要的,而是逻辑上需要的。

2. 域名点应使用反斜杠进行转义。包含字符" {"和" }"的正则表达式应加引号,否则启动时会提示不以";"结尾

server_name "~^(?\w\d { 1,3 } +).example.net$";

3. 命名的正则表达式捕获稍后可以用作变量

ruby 复制代码
server {
    server_name ~^(www\.)?(?<domain>.+)$;
    location / {
        root /sites/$domain ; 
    }
}

server_name另外两种配置方式,精准配置,通配符配置。

重新指定域名解析

首先了解一下为什么要重新指定域名解析,nginx只在start,restart,reload 时,才会连接一次dns服务器,解析一次proxy_pass中的域名,并缓存解析的结果,不再更新,也就是说如果nginx启动后域名的IP地址发生变化,nginx转发请求就会报错。 而本次配置的目的就是通过请求域名决定proxy_pass后面定义的服务名,所以后端服务在启动时没有确定的值,nginx没有缓存服务地址,这时如果直接在nginx中用变量作为反向代理的地址时,请求就会出现"no resolver defined to resolve xxx.xxx"的问题

解决的思路就是利用nginx作为dns客户端,进行动态dns解析。 开源版本的nginx提供了 resolver指令,用来指定dns服务器地址

resolver 官方说明

vbnet 复制代码
Syntax:	resolver address ... [valid=time] [ipv4=on|off] [ipv6=on|off] [status_zone=zone];
Default:	---
Context:	http, server, location

Configures name servers used to resolve names of upstream servers into addresses, for example:

resolver 127.0.0.1 [::1]:5353;

因为nginx和后端服务都部署在kubernetes中,所以,需要配置kubernetes的dns服务 kube-dns.kube-system

设置变量

vbnet 复制代码
  Syntax:	set $variable value;
  Default:	---
  Context:	server
  Sets a value for the specified variable. The value can contain text, variables, and their combination.

参考

相关推荐
致宏Rex14 分钟前
Nginx 负载均衡详解 x Shell 脚本实战
nginx·负载均衡·运维开发
大风吹PP凉2 小时前
34Web服务器(如Apache, Nginx)
服务器·nginx·apache
tian-ming2 小时前
JavaWeb后端开发知识储备1
java·spring boot·nginx·spring·maven
BillKu5 小时前
Linux设置Nginx开机启动
linux·运维·nginx
编程武士9 小时前
nginx openresty lua-resty-http 使用的一些问题记录
nginx·lua·openresty·lua-resty-http
微刻时光11 小时前
Docker部署Nginx
运维·nginx·docker·容器·经验
Fanstay9851 天前
在Linux中使用Nginx和Docker进行项目部署
linux·nginx·docker
尝尝你的优乐美1 天前
Docker部署Vue项目原来可以那么好用
前端·nginx·docker
怕是个胖虎哟1 天前
部署dist包(nginx配置)
前端·nginx
weixin_438197381 天前
K8S实现反向代理,负载均衡
linux·运维·服务器·nginx·kubernetes