NGINX 常被用作反向代理伺服器,搭配 NGINX Unit 管理後端動態應用程式。本文說明如何設定 NGINX 代理請求到 NGINX Unit,包含 upstream 設定與負載平衡組態。同時也涵蓋如何安全地暴露 NGINX Unit 控制 API,以及如何在 Docker 容器中佈署和管理 NGINX Unit,包含版本控制和零停機佈署的策略。最後,文章提供了一些最佳實踐建議,例如自動化佈署流程、監控和日誌記錄,以及 API 安全措施。

NGINX 與 NGINX Unit 的整合應用

前言

在現代化的網路架構中,NGINX 作為一個高效能的網頁伺服器與反向代理伺服器,經常被用來與 NGINX Unit 整合,以提供動態應用程式的託管與負載平衡功能。本文將詳細介紹如何組態 NGINX 以代理請求至後端的 NGINX Unit 伺服器,並探討相關的安全性與容器化佈署的議題。

組態 NGINX 代理請求至 NGINX Unit

設定範例

server {
    # 典型的 NGINX 伺服器設定與安全指令
    location / {
        # NGINX 代理設定
        proxy_pass http://unit_backend;
    }
}

設定解說

在上述設定中,我們定義了一個 server 區塊,並在其中使用 location 指令來指定對根路徑 / 的請求處理方式。透過 proxy_pass 指令,我們將請求代理至名為 unit_backend 的 upstream 伺服器群組。

上游伺服器設定

upstream unit_backend { server 127.0.0.1:8080; # 設定 NGINX Unit 監聽的介面與埠號 # 在負載平衡的情況下,可以新增多個伺服器 # server 10.0.0.12:8080; # server 10.0.1.12:8080; }


### NGINX 與 NGINX Unit 的協同運作

NGINX Unit 是一個動態應用程式閘道器,可以作為網頁伺服器、反向代理、負載平衡器等多種角色。在反向代理的場景中,NGINX 伺服器通常與 NGINX Unit 組態在相同的實體或虛擬機器上。upstream 區塊中的 `server` 指令指定了 NGINX Unit 的監聽介面與埠號,例如 `127.0.0.1:8080`

#### 負載平衡設定
在需要負載平衡的情況下,NGINX 可以組態多個遠端伺服器。在 upstream 區塊中,可以定義多個 `server` 指令,指向不同的 NGINX Unit 伺服器,例如:
```nginx
upstream unit_backend {
    server 10.0.0.12:8080;
    server 10.0.1.12:8080;
}

這些 NGINX Unit 伺服器需要組態相同的應用程式,並監聽相同的埠號(例如 8080)。

安全地提供 NGINX Unit 控制 API

設定範例

server {
    listen 443 ssl;
    ssl_certificate /path/to/ssl/cert.pem;
    ssl_certificate_key /path/to/ssl/cert.key;
    
    # 設定使用者端憑證驗證
    ssl_client_certificate /path/to/ca.pem;
    ssl_verify_client on;
    
    # 網路存取控制
    # allow 1.2.3.4;  # 請更新為您的管理系統 IP 地址
    deny all;
    
    # HTTP 基本認證
    auth_basic "Restricted";
    auth_basic_user_file /path/to/htpasswd;
    
    location / {
        proxy_pass http://unix:/var/run/control.unit.sock;
    }
}

#### 內容解密:

此設定範例展示瞭如何透過 NGINX 反向代理安全地存取 NGINX Unit 的控制介面。首先,我們組態了 SSL/TLS 加密連線,指定了伺服器的憑證與私鑰。接著,透過 ssl_client_certificatessl_verify_client 指令,要求使用者端提供由指定 CA 簽署的憑證,以進行雙向認證。此外,我們還啟用了根據 IP 的存取控制與 HTTP 基本認證,以進一步加強安全性。

在容器化環境中使用 NGINX Unit

設定範例

首先,建立一個名為 unit-conf.json 的組態檔案,用於定義 NGINX Unit 的監聽器與應用程式:

{
    "listeners": {
        "*:8080": {
            "pass": "applications/php_project"
        }
    },
    "applications": {
        "php_project": {
            "type": "php",
            "processes": 1,
            "root": "/var/app",
            "index": "index.php"
        }
    }
}

接著,建立一個 Dockerfile,使用官方的 NGINX Unit 映象作為基礎:

FROM nginx/unit
ADD . /var/app/
ADD unit-conf.json /var/lib/unit/conf.json

建置 Docker 映象並執行:

docker build -t unit-example .
docker run -p 8080:8080 unit-example

驗證服務是否正常執行:

curl localhost:8080

#### 內容解密:

此範例展示瞭如何將 NGINX Unit 用作容器化環境中的中介軟體伺服器。首先,我們建立了一個組態檔案 unit-conf.json,定義了監聽器與應用程式的組態。接著,透過 Dockerfile 將應用程式碼與組態檔案新增到 NGINX Unit 映象中。最後,建置並執行 Docker 映象,將容器的 8080 埠對應到主機的 8080 埠,以供外部存取。

NGINX Unit 與 Docker 的整合應用

NGINX Unit 是一個動態的 Web 應用伺服器,能夠與 Docker 無縫整合,提供高效的應用佈署和管理功能。透過 Docker,我們可以使用 -v 引數掛載磁碟區,進而暴露主機的檔案系統。如果透過 Dockerfile 中的 CMD 指令覆寫控制介面,並由 Docker proxy 暴露,這樣就可以遠端重新組態 Unit 容器。這種組態允許新增存在於主機檔案系統上的應用程式,並重新組態 Unit 的監聽器,透過控制 API 遠端服務這些應用程式。此技術對於本地開發環境非常有用。

在 Docker 中使用 NGINX Unit

佈署新版本應用程式

在實際應用中,我們經常需要在不造成停機的情況下佈署新版本的應用程式。NGINX Unit 的 API 提供了一個簡單有效的方法來實作這一點。以下是一個具體的範例:

假設我們的應用程式目錄結構如下:

/var/app/
├── version-1
│ ├── index.php
│ └── ...
└── version-2
    ├── index.php
    └── ...

目前的 Unit 組態如下:

{
    "listeners": {
        "*:8080": {
            "pass": "applications/php_project_version_1"
        }
    },
    "applications": {
        "php_project_version_1": {
            "type": "php",
            "processes": 2,
            "root": "/var/app/version-1",
            "index": "index.php"
        }
    }
}

建立新版本的應用程式組態

首先,我們需要建立一個名為 php-v2.json 的檔案,內容如下:

{
    "type": "php",
    "processes": 2,
    "root": "/var/app/version-2",
    "index": "index.php"
}

透過 API 新增新版本的應用程式

接下來,我們使用 curl 命令透過 API 新增新版本的應用程式:

sudo curl -X PUT -d @php-v2.json \
    --unix-socket /var/run/control.unit.sock \
    http://localhost/config/applications/php_project_version_2

驗證組態

驗證 Unit 的組態是否正確:

sudo curl --unix-socket /var/run/control.unit.sock \
    http://localhost/config

輸出結果應該包含兩個版本的應用程式組態:

{
    "listeners": {
        "*:8080": {
            "pass": "applications/php_project_version_1"
        }
    },
    "applications": {
        "php_project_version_1": {
            "type": "php",
            "processes": 2,
            "root": "/var/app/version-1",
            "index": "index.php"
        },
        "php_project_version_2": {
            "type": "php",
            "processes": 2,
            "root": "/var/app/version-2",
            "index": "index.php"
        }
    }
}

切換到新版本的應用程式

使用以下命令將監聽器 *:8080 切換到新的應用程式版本:

sudo curl -X PUT -d '"php_project_version_2"' \
    --unix-socket /var/run/control.unit.sock \
    'http://localhost/config/listeners/*:8080/application'

再次驗證組態:

sudo curl --unix-socket /var/run/control.unit.sock \
    http://localhost/config

輸出結果應該顯示監聽器已經被重新組態到新的應用程式版本:

{
    "listeners": {
        "*:8080": {
            "pass": "applications/php_project_version_2"
        }
    },
    "applications": {
        "php_project_version_1": {
            "type": "php",
            "processes": 2,
            "root": "/var/app/version-1",
            "index": "index.php"
        },
        "php_project_version_2": {
            "type": "php",
            "processes": 2,
            "root": "/var/app/version-2",
            "index": "index.php"
        }
    }
}

移除舊版本的應用程式

最後,移除舊版本的應用程式:

sudo curl -X DELETE \
    --unix-socket /var/run/control.unit.sock \
    http://localhost/config/applications/php_project_version_1

詳細解說

為何使用 NGINX Unit 與 Docker 的整合

NGINX Unit 提供了一個動態的應用伺服器,能夠與 Docker 無縫整合。這種整合允許開發者更靈活地佈署和管理應用程式,特別是在需要頻繁更新和擴充套件的現代 Web 架構中。

組態新版本的應用程式

在上述範例中,我們首先建立了一個新的 JSON 組態檔 php-v2.json,用於定義新版本的 PHP 應用程式。這個檔案包含了新版本應用程式的根目錄和索引檔案等資訊。

使用 API 管理應用程式

NGINX Unit 提供了強大的 API,使得我們可以透過簡單的 HTTP 請求來管理應用程式的組態。這包括新增、更新和刪除應用程式,以及切換監聽器的目標應用程式。

切換監聽器到新版本

透過更新監聽器的組態,我們可以將流量無縫地切換到新版本的應用程式,而不需要停機或中斷服務。

清理舊版本

一旦新版本穩定執行,我們可以安全地移除舊版本的應用程式,釋放資源並保持環境的整潔。

Mermaid 圖表示例

以下是展示 NGINX Unit 與 Docker 整合流程的 Mermaid

  graph LR;
    A[開始] --> B[建立新版本應用程式組態];
    B --> C[透過 API 新增新版本應用程式];
    C --> D[驗證組態];
    D --> E[切換監聽器到新版本];
    E --> F[驗證切換結果];
    F --> G[移除舊版本應用程式];

圖表翻譯: 此圖表展示了使用 NGINX Unit 與 Docker 進行零停機佈署的流程。首先,建立新版本的應用程式組態。接著,透過 API 將新版本上線並驗證組態。然後,切換監聽器到新版本並再次驗證。最後,移除舊版本,完成整個佈署流程。

隨著雲原生技術的發展,NGINX Unit 與 Docker 的整合將在未來的 Web 架構中扮演越來越重要的角色。預計會有更多的企業採用這種技術組合來提升他們的應用佈署和管理能力。

程式碼範例解說

在上述範例中,我們使用了多個 curl 命令來與 NGINX Unit 的 API 互動。這些命令示範瞭如何新增、更新和刪除應用程式,以及如何切換監聽器的目標應用程式。

curl 命令詳解

sudo curl -X PUT -d @php-v2.json \
    --unix-socket /var/run/control.unit.sock \
    http://localhost/config/applications/php_project_version_2

此命令使用 PUT 方法將 php-v2.json 中的組態上傳到 NGINX Unit,並命名為 php_project_version_2

內容解密:

  • -X PUT 指定 HTTP 請求方法為 PUT。
  • -d @php-v2.json 將檔案 php-v2.json 的內容作為請求主體。
  • --unix-socket /var/run/control.unit.sock 指定使用 Unix Socket 連線到 NGINX Unit 的控制介面。
  • http://localhost/config/applications/php_project_version_2 是 API 的端點,用於建立新的應用程式組態。

最佳實踐建議

  1. 自動化佈署流程:將上述步驟自動化,整合到 CI/CD 管道中,以實作完全自動化的佈署流程。
  2. 監控和日誌記錄:在佈署過程中加入監控和日誌記錄,以確保每個步驟的正確執行和及時發現問題。
  3. 安全措施:確保 API 端點的安全性,使用適當的身份驗證和授權機制,防止未授權存取。

結語

NGINX Unit 與 Docker 的整合為現代 Web 架構提供了強大的支援。透過本文介紹的方法,您可以實作高效、靈活的應用佈署和管理,為您的業務帶來更大的價值。