前言:
大家好,我是 Evan,今天想快速介紹一下,如何建置當前很紅的自動化工具 n8n,n8n 作為一款強大的原始碼開放( fair-code )自動化工具,提供豐富的節點使其能串接各種服務,實現複雜的自動化流程與應用。目前公司內部也正積極推廣。然而,要將 n8n 從單機運行模式提升至可維護、可擴展的企業級服務,一套穩固的基礎設施與標準化的部署策略便不可或缺。
這次的目標不僅是部署 n8n,更是要實踐「用自動化來管理自動化工具」。因此我將避免手動操作雲端服務商所提供的 UI 介面,轉而採用更自動化的方法,直接透過程式從頭開始建置所有基礎設施與服務。
因此,本文將分享如何運用 LINE 內部的平台,透過 Terraform 的Infrastructure as Code (IaC) 特性與以 ArgoCD 為核心的 GitOps 理念,完整建置一套包含負載均衡並具備高安全性的 n8n 服務。
source: Link
核心理念:
- 基礎設施即代碼 (Infrastructure as Code, IaC): 透過 Terraform 程式碼來定義與管理所有雲端資源(VM、Kubernetes 叢集、LB、DNS)。此舉可確保環境的一致性、可重複性,並實現版本控制。
- GitOps: 以 Git 作為部署的唯一真相來源 (Single Source of Truth)。所有應用程式的配置變更都必須經由 Git 提交,再由 ArgoCD 自動同步至 Kubernetes 叢集,從而建立一個可追蹤、可審計的部署流程。
Part 1: Terraform 自動化建立雲端基礎設施 (IaC)
一切的起點,是定義我們服務所需的雲端資源。我們使用 Terraform 來宣告式地管理所有基礎設施。
Step 1: 環境初始化與 Provider 設定
要與平台溝通,首先必須設定 Terraform 的 provider
。provider.tf
是我們的入口點,它告訴 Terraform 要使用哪個服務商的 API。
# provider.tf
terraform {
required_version = ">= xxx"
required_providers {
選用的服務商 = {
source = "your-company-registry"
version = ">= xxx"
}
}
}
provider "選用的服務商" {
object storage {}
}
💡 實踐技巧:
為了管理敏感憑證與環境變數,我們使用 .envrc 檔案儲存這些資訊,並將其加入 .gitignore。搭配 direnv 工具,可以在進入專案目錄時自動載入環境變數,避免了手動 source 的繁瑣與疏忽,同時有效隔離不同專案的環境。
Step 2: 創建 Kubernetes Service 叢集
n8n 將以容器化的方式運行,因此我們需要一個 Kubernetes cluster。透過 xxx_cluster
資源來定義叢集規格。
# (示意)
resource "xxx_cluster" "n8n-dev" {
k8s_version = "v1.xx.2"
name = "xxx-dev"
network_plugin = "xxx"
# ... 其他設定 ...
}
resource "xxx_pool" "n8n-worker" {
cluster_id = xxx__cluster.n8n-dev.id
flavor_id = "304016xxxx" # VM 的規格
image_id = "e7xxxx-d47f-4573-b1af-xxxxxxxxx # OS 映像檔
quantity = x # 節點數量
# ... 其他設定 ...
}
# 引用 SRE 團隊維護的標準化 Ingress 節點池
module "xxx-pool" {
source = "git::https://xxxxx"
cluster_id = xxx
cmdb_owner = ["xxxxx"]
# ... 其他設定 ...
}
💡 實踐技巧與經驗:
- 模組化 (Modularity): 直接引用由 SRE 團隊提供的 pool Terraform 模組,讓我們無需關心 Ingress Controller (Traefik) 節點的底層細節,只需傳入必要參數,即可獲得一個符合團隊規範的標準化節點池,顯著降低了維護成本並確保一致性。
- 問題排解 (Quota 不足): 執行 terraform apply 時遇到的 Exceeded Quota 錯誤是常見問題。除了刪除閒置資源外,更進階的作法是使用 terraform import 將現存但未被 Terraform 管理的資源,納入當前狀態檔(state)中,以避免重複創建。
Step 3: Terraform State 遠端備份至 object storage
terraform.tfstate
是 Terraform 的核心,記錄了所有受控資源的狀態。將其保存在本地不利於團隊協作且風險極高。因此,我們將其遷移至我們內部儲存空間,它是一個 S3 相容的物件儲存服務。
# backend.tf
terraform {
backend "s3" {
bucket = "xxx-bucket"
endpoint = "https://xxxxx"
region = "xxx"
key = "tfstate.tfstate"
skip_requesting_account_id = true
skip_credentials_validation = true
skip_region_validation = true
use_lockfile = true # 啟用狀態鎖,防止多人同時執行
}
}
💡 關鍵功能:
- 狀態鎖 (State Locking): 遷移至 S3 backend 後,最重要的功能之一就是狀態鎖。當有成員執行 terraform apply 時,Terraform 會在公司內部的 object storage 上創建一個鎖定檔,防止其他人同時修改基礎設施,避免狀態不一致與資源衝突,是團隊協作的必要保障。
- 遷移流程: 從 local backend 遷移至 s3 backend 需謹慎操作。標準流程為:terraform state pull -> 修改backend.tf配置文件 -> terraform init -reconfigure,確保本地的最新狀態能平滑地推送到遠端。
Part 2: 設計高可用網路架構
基礎設施就緒後,我們需要規劃如何將流量安全、高效地引導至我們的 n8n 服務。
Step 4: 雙層負載均衡 (Load Balancer) 架構
為了區分對外提供服務的 UI 和僅供內部系統使用的 Webhook,我們設計了公私網分離的雙層 LB 架構:
- Public LB: