背景
在公司的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另外两种配置方式,精准配置,通配符配置。
- 精准配置,server_name后面可以配置多个域名,用空格分隔,server_name www.example.org www1.example.org www2.example.org;
- 通配符配置,通配符名称只能在名称的开头或结尾以及点边框上包含星号。例如" .example.org mail. ",而名称" www.*.example.org"和" w*.example.org"无效
重新指定域名解析
首先了解一下为什么要重新指定域名解析,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.