這一篇中使用 Nginx
部署閘道器中心
,用來代理伺服器中服務。閘道器中心
有優點也有缺點,也可以不採用閘道器
系統。
部署
Nginx閘道器
系統需要使用域名,沒有域名無法處理
閘道器概述
閘道器(Gateway)
是轉發其它伺服器通訊資料的伺服器,接收客戶端傳送來的請求時,它就像自己擁有資源的源伺服器一樣對請求進行
處理。有時候客戶端可能都不會察覺,自己的通訊目標是一個閘道器。
這是 維基百科
中對 閘道器
的描述。
Nginx
可以利用代理機制實現 閘道器係統
本篇中要做的是部署一個 Nginx
服務作為閘道器
,此 Nginx
代理轉發伺服器中其它服務:例如 Portainer
伺服器只暴露此 Nginx閘道器
,Nginx閘道器
根據實際請求服務(根據域名區分)轉發到對應服務。
這種 Nginx閘道器
系統訪問具有一定的優點和缺點,
優點:
- 可以對服務提供統一管理,例如給服務統一設定
HTTPS
、 壓縮等功能 - 對於擁有公網 IP 不足,但具有多臺伺服器的場景,可以提供一種解決公網 IP 不足的方案
缺點:
- 因為閘道器服務作為所有服務入口,那麼閘道器承載了所有訪問壓力。
- 對閘道器服務依賴性較強,當閘道器一掛掉,那所有服務對於外網都處於都不可見狀態。
PS: 兩個缺點可以對閘道器做負載均衡來解決。
閘道器
在系統基本上都隨處可見,只是可能利用其它方案實現 閘道器
。
例如後端微服務系統中便會提供一個閘道器,根據請求和伺服器狀態處理轉發,
要根據業務場景來採用不同的解決方案。
在當前場景時,作為個人伺服器,訪問壓力和伺服器依賴性這問題都不需要考慮,而使用 Nginx
閘道器則能更方便的提供 HTTPS
和壓縮等功能,並且可以使用子域名
Nginx
Nginx 概述
Nginx
是一個高效能的網頁伺服器,也是目前使用最廣泛的網頁伺服器之一。Nginx
也可以用作反向代理和負載均衡,
本文中閘道器
便是使用的 Nginx
中 反向代理 功能
Nginx
是一個很強大的伺服器,我對他也僅僅會簡單使用,有興趣的朋友可以深入學習:Nginx 開發從入門到精通
Nginx 部署
Docker Compose 配置
version: '3.9'
services:
nginx:
image: nginx:latest
container_name: gateway
restart: always
ports:
- 80:80 #啟動埠
- 443:443
volumes: #資料卷對映地址
- /volumes/gateway/conf.d:/etc/nginx/conf.d
- /volumes/gateway/nginx.conf:/etc/nginx/nginx.conf
- /volumes/gateway/logs:/var/log/nginx
作為閘道器服務,監聽埠 80(HTTP) 和埠 443(HTTPS)。
配置中使用 Volume
對 Nginx
日誌 、 conf.d 和 nginx.conf(配置檔案) 掛載到宿主機
PS:
Nginx
容器讀取配置檔案的目錄地址為 /etc/nginx/nginx.conf
nginx.conf 為 配置檔案, Docker
掛載檔案時,宿主機中需要具有此檔案,需要在伺服器中先建立該檔案。
Nginx 檔案
nginx.conf 配置檔案中監聽 80 埠,
events {
worker_connections 1024;
}
http {
include mime.types;
default_type text/html;
sendfile on;
keepalive_timeout 65;
charset utf-8;
server {
listen 80;
error_log /var/log/nginx/portainer/error.log;
access_log /var/log/nginx/portainer/access.log;
location / {
proxy_pass http://10.0.24.12:9000;
}
}
}
這是一個簡單的 nginx.conf 配置,監聽 80 埠,用於以內網連線轉發到 9000 埠(Portainer
視覺化客戶端)。
也就是訪問 80 埠會被轉發到 Portainer
視覺化客戶端
- events: 此模組用於處理
Nginx
連線的配置。 其中 worker_connections 屬性表示最大併發數量 - http: 此模組用於處理 HTTP 監聽。此模組中最重要是 server 屬性,表示
虛擬伺服器(站點)
,在虛擬伺服器
中可以監聽埠,代理其它伺服器或者掛載靜態檔案。
serser 模組 可以設定多個。- listen: 監聽埠號
- error_log、access_log:設定日誌路徑,
- location:此屬性用於匹配 URL 請求,在這裡直接使用 proxy_pass 屬性代理 9000 埠
PS: 其它屬性不熟悉的可以自行查詢,都是些簡單的配置屬性
作為一個閘道器
,後續要管理更多服務,為了方便查詢日誌,將每個應用日誌分開儲存,這也就是配置 error_log、access_log 的原因。
當然也可以不配置,在每一個應用中檢視日誌。
日誌目錄需要預先定義。Dockerfile
中 使用了 /volumes/gateway/logs 掛載了 /var/log/nginx/。
sudo mkdir -p /volumes/gateway/logs/portainer
可以使用 Portainer
進行部署,部署成功後如直接訪問 80 埠會直接訪問到 Portainer
Nginx 配置
壓縮配置
Nginx
提供了強大的效能優化功能,最常見的就是壓縮。
Nginx
中配置壓縮也特別簡單,只需要在 nginx.conf 檔案中設定 gzip 相關屬性即可
gzip 屬性在 http、server、location 三個模組都可以設定。
由於此服務是閘道器
,直接設定在 http 模組,為所有服務提供壓縮功能。
http {
include mime.types;
default_type text/html;
sendfile on;
keepalive_timeout 65;
charset utf-8;
# 開啟壓縮
# 壓縮版本
# 檔案壓縮型別
gzip_types text/plain text/css application/javascript application/json application/xml;
#設定壓縮比率
gzip_comp_level 5;
}
-
gzip:是否開啟
ZIP
壓縮,該屬性值可以設定為 on 或 off。 -
gzip_type: 用於對匹配到的
MIME
型別檔案進行壓縮。其中 text/html 型別無論是否設定肯定會被壓縮 -
gzip_comp_level:設定
GZIP
壓縮比,值的範圍為:1-9,1:壓縮比最小,處理最快;9:壓縮比最大,處理最慢
在 nginx.conf 配置檔案中新增 gzip 相關屬性後,需要重新載入配置檔案。
Nginx
中提供了重新載入配置檔案命令 (nginx -s reload) ,此命令可以實現平滑更新,不重啟服務的情況下進行更新。
docker exec -it gateway nginx -s reload
重新載入之後可以分別訪問 80 和 9000 埠,來測試檔案大小和訪問速度
-
9000
-
80
可以看到通過 Nginx
閘道器代理壓縮後的檔案大小遠遠小於 9000 埠的,並且訪問速度大大提高。這就是通過設定閘道器代理的好處之一
PS:載入時注意要使用清空快取並進行重新整理
PS:使用
閘道器
後,可以將 伺服器 9000 防火牆關閉,只使用閘道器
訪問
server_name
在剛才使用了 Nginx
閘道器監聽 80 代理了 9000 埠。那麼怎麼代理多個應用呢?
server 屬性作為一個 虛擬主機
概念,可以使用多個 server 代理多個應用。
使用多個 server,需要一個前置條件,那麼判斷具體請求的應用?
解決這個問題就需要使用到 Nginx
中 server_name 屬性和 域名
server 屬性中有一個 server_name 屬性,這個屬性值會匹配請求中的 host 屬性。
當請求中的 host 屬性匹配 service_name 屬性值,就執行此 server 。
通過 server_name 和不同的域名,可以決定請求的真正服務。
域名需要備案,需要時間,不過也很簡單。域名本身也不貴。我具有一個已經備過案的域名: mwjz.live 。
主域名都會部署主站,像 Portainer
這些服務則使用子域名。子域名不需要付費,在雲應用廠商中直接配置解析規則即可。
我的域名同樣在 騰訊雲 購買的,在騰訊雲已購買域名中配置子域名解析規則即可
在此配置了一個 portainer 子域名用來訪問 Portainer
服務。 完整的子域名是 portainer.mwjz.live
PS:當配置完域名解析,會有一段時間的延遲
在 nginx.conf 可以將 portainer.mwjz.live 配置於 server_name
server {
listen 80;
#填寫繫結證照的域名
server_name portainer.mwjz.live;
#日誌
error_log /var/log/nginx/portainer/error.log;
access_log /var/log/nginx/portainer/access.log;
location / {
proxy_pass http://10.0.24.12:9000;
}
}
配置並重新載入閘道器(Nginx)
服務後,就可以使用域名訪問
docker exec -it gateway nginx -s reload
可以看到訪問 portainer.mwjz.live 就可以訪問到 Portainer
客戶端。
同理當配置多個 server 管理時,只需要配置不同的 server_name。
HTTPS 和 HTTP2
HTTPS 證照
當今時代 網站基本上都已經使用 HTTPS
了。
HTTPS
需要申請證照,可以購買付費的,也可以申請免費的,甚至可以自己建立證照。
騰訊雲伺服器中有第三方提供了一年的免費證照。只需要申請就可以使用
申請成功後下載 Nginx
版本然後將證照後上傳伺服器使用。
將證照上傳到了 /volumes/gateway/conf.d/ssl/portainer/ 目錄。
因為配置 Nginx
閘道器時,將 /etc/nginx/conf.d 掛載到宿主機 /volumes/gatewal/conf.d 目錄,
所以也相當於將證照存放在 Nginx
容器中 /etc/nginx/conf.d/ssl/portainer/ 目錄。
Nginx 配置 HTTPS
server {
#SSL 訪問埠號為 443
listen 443 ssl;
#填寫繫結證照的域名
server_name portainer.mwjz.live;
#日誌
error_log /var/log/nginx/portainer/error.log;
access_log /var/log/nginx/portainer/access.log;
#證照檔案
ssl_certificate /etc/nginx/conf.d/ssl/portainer/portainer.mwjz.live_bundle.crt;
#證照金鑰檔案
ssl_certificate_key /etc/nginx/conf.d/ssl/portainer/portainer.mwjz.live.key;
ssl_ciphers SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!3DES:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://10.0.24.12:9000;
}
}
server {
listen 80;
#填寫繫結證照的域名
server_name portainer.mwjz.live;
#日誌
error_log /var/log/nginx/portainer/error.log;
access_log /var/log/nginx/portainer/access.log;
location / {
proxy_pass http://10.0.24.12:9000;
}
}
HTTPS
埠為 443
監聽埠後加上 SSL 表示開啟 HTTPS
開啟 SSL,必須提供證照檔案
- ssl_certificate: 提供給虛擬伺服器的
PEM
格式證照
- ssl_certificate_key: 提供給虛擬伺服器的
PEM
格式證照的的金鑰 - ssl_ciphers: 首選加密套件
- ssl_protocols: 允許的加密協議
- ssl_prefer_server_ciphers: 指定在使用 SSLv3 和 TLS 協議時,伺服器密碼應優先於客戶端密碼。
更新配置檔案後進行重新載入,便可以使用 HTTPS
協議訪問
docker exec -it gateway nginx -s reload
HTTP 跳轉 HTTPS
現在各大網站使用 HTTPS
協議後,使用 HTTP
訪問時會返回 307 響應,然後切換為 HTTPS
協議訪問。
這是使用 HTTP
協議訪問 Github
,可以看到返回了一個 307,隨後就跳轉 HTTPS
協議了。
這個操作其實很簡單,只需要將 80 埠返回 307 和對應的地址。
server {
#SSL 訪問埠號為 443
listen 443 ssl;
#填寫繫結證照的域名
server_name portainer.mwjz.live;
#日誌
error_log /var/log/nginx/portainer/error.log;
access_log /var/log/nginx/portainer/access.log;
#證照檔案
ssl_certificate /etc/nginx/conf.d/ssl/portainer/portainer.mwjz.live_bundle.crt;
#證照金鑰檔案
ssl_certificate_key /etc/nginx/conf.d/ssl/portainer/portainer.mwjz.live.key;
ssl_ciphers SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!3DES:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://10.0.24.12:9000;
}
}
server {
listen 80;
return 307 https://$host$request_uri;
}
在 80 埠的 虛擬主機
中返回 307 狀態碼和 HTTPS
協議的請求。
此時將所有的 80 請求轉成 443,在之後新增其它應用時只需要設定 443 埠即可
$host: 請求的 host 地址。$request_uri:請求的路由地址
此時使用 HTTP
協議請求 Portainer
便也會返回 307,隨後使用 HTTPS
協議重新請求。
HTTP2
Nginx
配置 HTTP2
很簡單,只需要在 監聽埠號後新增 http2 標識
server {
#SSL 訪問埠號為 443
listen 443 ssl http2;
#填寫繫結證照的域名
server_name portainer.mwjz.live;
#日誌
error_log /var/log/nginx/portainer/error.log;
access_log /var/log/nginx/portainer/access.log;
#證照檔案
ssl_certificate /etc/nginx/conf.d/ssl/portainer/portainer.mwjz.live_bundle.crt;
#證照金鑰檔案
ssl_certificate_key /etc/nginx/conf.d/ssl/portainer/portainer.mwjz.live.key;
ssl_ciphers SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!3DES:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://10.0.24.12:9000;
}
}
重新載入配置檔案後再訪問 Portainer
便可以看到相應為 HTTP2
docker exec -it gateway nginx -s reload
PS:如果沒有 協議 選項,使用右鍵開啟