私有化輕量級持續集成部署方案–02-Nginx網關服務


提示:本系列筆記全部存在於
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 掛載文件時,宿主機中需要具有此文件,需要在伺服器中先創建該文件。

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 //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

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



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

  • 80

可以看到通過 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 這些服務則使用子域名。子域名不需要付費,在雲應用廠商中直接配置解析規則即可。

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

在此配置了一個 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 //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 //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 //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 //10.0.24.12:9000;
    }
}
server {
    listen 80;
    return 307 //$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 //10.0.24.12:9000;
    }
}

重新載入配置文件後再訪問 Portainer 便可以看到相應為 HTTP2

docker exec -it gateway nginx -s reload

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

Tags: