Nginx配置管理(2021)
本来其实是总结博客搭建的,结果总结了半天发现里面最有意义的部分就是我nginx的配置和管理了。所以就单独抽出来水一贴。
以这个博客来说。这个博客是pub域名结尾,那么根据我的策略,国内用户访问其实要经过整整5次nginx转发:CN CDN -> SG CDN -> USA CDN -> k8s nginx -> pub nginx -> Ghost
。
网络转发逻辑虽然确实蠢了一点,但这个问题本身并不复杂,只是没有动手解决罢了。而这背后真正的问题其实是:在这些nginx本身的运行环境和管理方式都有很大差异的情况下的配置与管理的问题(CDN独立于集群管理,且有两个独立的集群)。
我的nginx大概是这么个结构(命名就不要吐槽了,没钱又懒得改)。
首先看2层:
nginx
├── Dockerfile
├── certs
│ ├── xxxxxx
│ └── pub
└── nginxConfig
├── http
├── nginx.conf
└── streams
Dockerfile
不解释了。
certs
里面包含两个域名的证书也不多说了。
nginxConfig
,是具体nginx的配置,里面包含了根nginx.conf
,以及http
和stream
两个folder。其中http
是所有http请求相关配置,streams
里面是tcp/udp的转发配置。
streams
里面就是一个个具体的.conf就不多展开了。这里展开http
这个folder。
http
├── default
└── specific.conf
http
里面主要分两块,一个是specific
,一个是default
。
其中specific
是各个环境、场景定制的配置。但约定所有的定制都只能是覆盖和修改default的配置。对于较少的覆盖,specific
可以和这里一样是一个具体的.conf文件,对于较多的覆盖,specific
可以也是一个folder。
而default
是所有环境、所有场景共享的配置。只要是我所用到的nginx,里面这个folder下的内容要求是完全一致的。
这里先展开default
。
default
├── destination
│ ├── cn.conf
│ ├── defaultProxy.conf
│ ├── sg.conf
│ └── usa.conf
├── https
│ ├── https.conf
│ ├── xxxxxx-certificate.conf
│ └── pub-certificate.conf
└── services
├── 80To443.conf
├── apps.conf
├── infrastructure.conf
├── pub.conf
└── test.conf
destination
里面定义的是几个CDN节点的位置。defaultProxy.conf
里面就是一些默认的proxy配置,被{location}.conf
共同使用。{location}.conf
里面几乎就纯是proxy_pass
。
https
里面就是证书信息。https.conf
里面就是一些通用的https配置。和destination
一样,被{domain}.config
共同使用。而{domain}.config
里就是指一下证书路径。
services
里面包含了所有服务的信息,或者更准确的说,是所有服务的位置信息。
这里进一步阐述一下default/services
的内容。以gogs.xloypaypa.pub
和blog.xloypaypa.pub
为例。
在pub.conf
中,gogs和blog的配置如下:
server {
server_name ~^gogs\..*xloypaypa\.pub$;
access_log /var/log/nginx/pub.gogs.access.log;
include /etc/nginx/http/default/https/pub-certificate.conf;
location / {
include /etc/nginx/http/default/destination/cn.conf;
}
}
server {
server_name ~^blog\..*xloypaypa\.pub$;
access_log /var/log/nginx/pub.blog.access.log;
include /etc/nginx/http/default/https/pub-certificate.conf;
location / {
include /etc/nginx/http/default/destination/usa.conf;
}
}
个人能力有限,到这我就满足了。
对于gogs,由于其服务在国内,那么server_name
不管是gogs.usa.xloypaypa.pub
还是gogs.cn.xloypaypa.pub
还是gogs.xloypaypa.pub
都将被转发至CN CDN
的服务器。而这个博客无论如何都会被转发到USA。
而对于specific
。这里就得话分两头说,先说较为简单的CDN上的nginx。
根据default
的配置,对于其他CDN节点的服务自然会被转发到其他的CDN。但对于自己负责的服务就需要特殊配置。以CN CDN
为例,配置如下:
upstream cn.xloypaypa.pub {
server v2xxx:443;
}
cn.xloypaypa.pub
是配置在nginx/nginx/http/default/destination
的cn.conf
的。
无疑,CN CDN
自然是负责我家里的物理机上的集群的。而我是采用某V姓网络工具,通过内网穿透暴露服务的。因此,CN CDN
上的nginx只需要在specific
里将所有cn的流量转发到这个V姓网络工具即可。
总之,这里就是在default
要求我把流量转发给我自己的时候,转发给真正的目标。仅此而已。
然后CN CDN
的sepcific
里其实也有下面这段配置:
upstream usa.xloypaypa.pub {
server sg.xloypaypa.pub:443;
server usa.xloypaypa.pub:443 backup;
}
这就是默认走sg绕一圈的原因。
根据上面的操作,流量其实已经到了k8s里了。配置的结构大概长这个样子:
http
├── default
│ ├── destination
│ ├── https
│ └── services
├── specific
│ ├── app.conf
│ ├── infrastructure.conf
│ └── pub.conf
└── specific.conf
其中specific.conf
大概长这个样子:
include /etc/nginx/http/specific/*.conf;
include /etc/nginx/http/default/services/*.conf;
简而言之就是一个个覆盖default/services
的东西,只不过不是直接修改,而是新写一个文件,并且确保这个文件比default
里的文件优先级高就好了(specific.conf
就是做这个事情的)。
这里其实是有个缺陷。其实处于根部的nginx.conf
并不会主动加载default
里的任何东西。nginx.conf
里面的配置其实是include /etc/nginx/http/*.conf;
。也就是实际上只会加载specific.conf
。而default
的加载是需要在specific.conf
显式的写出来的。其实稍微抽一下就可以解决,但懒得弄了,没必要。
我大概就是通过这个方式,维护一个统一的default,然后各个环境各自去维护自己的specific.conf完成伪·CDN和两个k8s里面一堆nginx的配置管理的。菜的不行,轻喷。
这里附上一个完整的配置结构:
nginx
├── Dockerfile
├── certs
│ ├── xxxxxx
│ │ ├── cert.pem
│ │ ├── chain.pem
│ │ ├── fullchain.pem
│ │ ├── privkey.pem
│ │ └── README
│ └── pub
│ ├── cert.pem
│ ├── chain.pem
│ ├── fullchain.pem
│ ├── privkey.pem
│ └── README
└── nginxConfig
├── http
│ ├── default
│ │ ├── destination
│ │ │ ├── cn.conf
│ │ │ ├── defaultProxy.conf
│ │ │ ├── sg.conf
│ │ │ └── usa.conf
│ │ ├── https
│ │ │ ├── https.conf
│ │ │ ├── xxxxxx-certificate.conf
│ │ │ └── pub-certificate.conf
│ │ └── services
│ │ ├── 80To443.conf
│ │ ├── apps.conf
│ │ ├── infrastructure.conf
│ │ ├── pub.conf
│ │ └── test.conf
│ ├── specific
│ │ ├── app.conf
│ │ ├── infrastructure.conf
│ │ └── pub.conf
│ └── specific.conf
├── nginx.conf
└── streams
├── gogs.conf
└── ldap.conf
最后解释一下为什么k8s nginx
后面还会有pub nginx
简而言之,就是pub域名毕竟不是亲儿子的。因此专门设置了pub nginx
进行全局限速。至于为什么pub nginx
为什么在k8s nginx
后面,这个主要是懒,直接开会端口冲突。改端口又要防火墙,偷个懒。