私有化輕量級持續整合部署方案--02-Nginx閘道器服務

莫問今朝乄發表於2022-02-16
提示:本系列筆記全部存在於 Github, 可以直接在 Github 檢視全部筆記

這一篇中使用 Nginx 部署閘道器中心,用來代理伺服器中服務。閘道器中心有優點也有缺點,也可以不採用閘道器系統。

部署 Nginx閘道器 系統需要使用域名,沒有域名無法處理

閘道器概述

閘道器(Gateway) 是轉發其它伺服器通訊資料的伺服器,接收客戶端傳送來的請求時,它就像自己擁有資源的源伺服器一樣對請求進行
處理。有時候客戶端可能都不會察覺,自己的通訊目標是一個閘道器。

這是 維基百科 中對 閘道器 的描述。

Nginx 可以利用代理機制實現 閘道器係統

本篇中要做的是部署一個 Nginx 服務作為閘道器,此 Nginx 代理轉發伺服器中其它服務:例如 Portainer
伺服器只暴露此 Nginx閘道器Nginx閘道器 根據實際請求服務(根據域名區分)轉發到對應服務。

這種 Nginx閘道器 系統訪問具有一定的優點和缺點,

優點:

  1. 可以對服務提供統一管理,例如給服務統一設定 HTTPS 、 壓縮等功能
  2. 對於擁有公網 IP 不足,但具有多臺伺服器的場景,可以提供一種解決公網 IP 不足的方案

缺點:

  1. 因為閘道器服務作為所有服務入口,那麼閘道器承載了所有訪問壓力。
  2. 對閘道器服務依賴性較強,當閘道器一掛掉,那所有服務對於外網都處於都不可見狀態。

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)

配置中使用 VolumeNginx 日誌conf.dnginx.conf(配置檔案) 掛載到宿主機

PS:Nginx 容器讀取配置檔案的目錄地址為 /etc/nginx/nginx.conf

nginx.conf配置檔案Docker 掛載檔案時,宿主機中需要具有此檔案,需要在伺服器中先建立該檔案。

私有化輕量級持續整合部署方案--02-Nginx閘道器服務

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_logaccess_log 的原因。

當然也可以不配置,在每一個應用中檢視日誌。

日誌目錄需要預先定義。Dockerfile 中 使用了 /volumes/gateway/logs 掛載了 /var/log/nginx/

sudo mkdir -p /volumes/gateway/logs/portainer

私有化輕量級持續整合部署方案--02-Nginx閘道器服務

可以使用 Portainer 進行部署,部署成功後如直接訪問 80 埠會直接訪問到 Portainer

私有化輕量級持續整合部署方案--02-Nginx閘道器服務 私有化輕量級持續整合部署方案--02-Nginx閘道器服務 私有化輕量級持續整合部署方案--02-Nginx閘道器服務

Nginx 配置

壓縮配置

Nginx 提供了強大的效能優化功能,最常見的就是壓縮。

Nginx 中配置壓縮也特別簡單,只需要在 nginx.conf 檔案中設定 gzip 相關屬性即可

gzip 屬性在 httpserverlocation 三個模組都可以設定。

由於此服務是閘道器,直接設定在 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 壓縮,該屬性值可以設定為 onoff

  • 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

重新載入之後可以分別訪問 809000 埠,來測試檔案大小和訪問速度

  • 9000

    私有化輕量級持續整合部署方案--02-Nginx閘道器服務
  • 80

    私有化輕量級持續整合部署方案--02-Nginx閘道器服務

可以看到通過 Nginx閘道器代理壓縮後的檔案大小遠遠小於 9000 埠的,並且訪問速度大大提高。這就是通過設定閘道器代理的好處之一

PS:載入時注意要使用清空快取並進行重新整理

PS:使用閘道器後,可以將 伺服器 9000 防火牆關閉,只使用閘道器訪問

server_name

在剛才使用了 Nginx閘道器監聽 80 代理了 9000 埠。那麼怎麼代理多個應用呢?

server 屬性作為一個 虛擬主機 概念,可以使用多個 server 代理多個應用。

使用多個 server,需要一個前置條件,那麼判斷具體請求的應用?

解決這個問題就需要使用到 Nginxserver_name 屬性和 域名

server 屬性中有一個 server_name 屬性,這個屬性值會匹配請求中的 host 屬性。
當請求中的 host 屬性匹配 service_name 屬性值,就執行此 server

通過 server_name 和不同的域名,可以決定請求的真正服務。

域名需要備案,需要時間,不過也很簡單。域名本身也不貴。我具有一個已經備過案的域名: mwjz.live

主域名都會部署主站,像 Portainer 這些服務則使用子域名。子域名不需要付費,在雲應用廠商中直接配置解析規則即可。

我的域名同樣在 騰訊雲 購買的,在騰訊雲已購買域名中配置子域名解析規則即可

私有化輕量級持續整合部署方案--02-Nginx閘道器服務

在此配置了一個 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

私有化輕量級持續整合部署方案--02-Nginx閘道器服務

可以看到訪問 portainer.mwjz.live 就可以訪問到 Portainer 客戶端。

同理當配置多個 server 管理時,只需要配置不同的 server_name

HTTPS 和 HTTP2

HTTPS 證照

當今時代 網站基本上都已經使用 HTTPS 了。

HTTPS 需要申請證照,可以購買付費的,也可以申請免費的,甚至可以自己建立證照。

騰訊雲伺服器中有第三方提供了一年的免費證照。只需要申請就可以使用

私有化輕量級持續整合部署方案--02-Nginx閘道器服務

申請成功後下載 Nginx 版本然後將證照後上傳伺服器使用。

私有化輕量級持續整合部署方案--02-Nginx閘道器服務

將證照上傳到了 /volumes/gateway/conf.d/ssl/portainer/ 目錄。

私有化輕量級持續整合部署方案--02-Nginx閘道器服務

因為配置 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

私有化輕量級持續整合部署方案--02-Nginx閘道器服務

HTTP 跳轉 HTTPS

現在各大網站使用 HTTPS 協議後,使用 HTTP 訪問時會返回 307 響應,然後切換為 HTTPS 協議訪問。

私有化輕量級持續整合部署方案--02-Nginx閘道器服務

這是使用 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 協議重新請求。

私有化輕量級持續整合部署方案--02-Nginx閘道器服務

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

私有化輕量級持續整合部署方案--02-Nginx閘道器服務

PS:如果沒有 協議 選項,使用右鍵開啟

私有化輕量級持續整合部署方案--02-Nginx閘道器服務

相關文章