Skip to content

私有部署

適用對象:要把 Argus 推到 staging / production 的 SRE / 平台 admin。 玩玩看:先讀 安裝與啟動

部署形態

Argus 是 單一二進位 + 單一 Postgres metastore 的純 self-hosted 服務。

text
                ┌──────────────┐
   user ─────►  │ Reverse Proxy│  ─── TLS terminate ─►  Argus :8080
                │ (nginx /     │                        │
                │  traefik)    │                        ▼
                └──────────────┘                  ┌──────────────┐
                                                  │ Metastore PG │
                                                  │ (private VPC)│
                                                  └──────────────┘

                                                        │ sync / execute
                                ┌──────────────────────┴─────────────────┐
                                ▼                                          ▼
                       managed DB instance 1                      managed DB instance N
                       (production)                                (staging / dev)

容量

部署規模適用建議資源Metastore
Small< 50 user / < 100 DB2 vCPU / 4 GB / 20 GB diskPG 14+,db.t3.small 等
Medium< 500 user / < 1000 DB4 vCPU / 8 GB / 50 GB diskdb.m6i.large + replica
Large> 500 user / > 1000 DB8 vCPU / 16 GB + HAdb.m6i.xlarge + replica

99% bottleneck 在 metastore,不在 Argus server 本身。優先把 PG 規劃好。

Step-by-step

1. 規劃網路拓撲

決定:

  • Argus server 放哪?通常內網,外網不直暴
  • Metastore 放哪?必須私網,不可從外網直連
  • 反向代理在哪?通常公司既有 ingress(nginx / traefik / Cloudflare Tunnel)
  • 對外網址(external_url)?必須有 TLS

2. 準備 metastore

bash
# 連到 PG superuser 帳號
psql -U postgres <<SQL
CREATE USER argusdev WITH PASSWORD '<strong-random>';
CREATE DATABASE argusdev OWNER argusdev ENCODING 'UTF8' LC_COLLATE 'C' LC_CTYPE 'C' TEMPLATE template0;
GRANT CONNECT ON DATABASE argusdev TO argusdev;
SQL

不建議事項:

  • 不要把 Argus metastore 與你管理的 production DB 放同一個 cluster
  • 不要用 superuser 當 metastore 連線 user
  • 不要手動改 metastore schema(會破壞 Migration 版本檢查)

3. 部署 Argus binary / container

yaml
version: "3.9"
services:
  argus:
    image: <your-registry>/argus:v3.18
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      PG_URL: "postgresql://argusdev:${ARGUS_PG_PASSWORD}@metastore.internal:5432/argusdev?sslmode=require"
    command:
      - "--external-url=https://argus.corp.example"
      - "--port=8080"
      - "--enable-json-logging"
      - "--bootstrap-admin-login-id=ops-bootstrap"
    volumes:
      - argus-data:/var/opt/argus
volumes:
  argus-data:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: argus
spec:
  replicas: 1                                    # 開 HA 才 >1
  selector:
    matchLabels: { app: argus }
  template:
    metadata:
      labels: { app: argus }
    spec:
      containers:
        - name: argus
          image: <your-registry>/argus:v3.18
          ports:
            - containerPort: 8080
          envFrom:
            - secretRef:
                name: argus-secret           # PG_URL 在這
          args:
            - "--external-url=https://argus.corp.example"
            - "--port=8080"
            - "--enable-json-logging"
          readinessProbe:
            httpGet: { path: /readyz, port: 8080 }
            initialDelaySeconds: 10
          livenessProbe:
            httpGet: { path: /healthz, port: 8080 }
            initialDelaySeconds: 30
          resources:
            requests: { cpu: "500m", memory: "1Gi" }
            limits:   { cpu: "2",    memory: "4Gi" }

參考完整 helm chart:helm-charts/(repo root)。

4. 反向代理 + TLS

Argus 自身 terminate TLS。一定要走前面的反向代理。

範例(nginx):

nginx
upstream argus_upstream {
  server 127.0.0.1:8080;
  keepalive 32;
}

server {
  listen 443 ssl http2;
  server_name argus.corp.example;

  ssl_certificate     /etc/ssl/argus.crt;
  ssl_certificate_key /etc/ssl/argus.key;
  ssl_protocols TLSv1.2 TLSv1.3;

  client_max_body_size 32m;        # SQL 大塊上傳 / Export 結果

  location / {
    proxy_pass http://argus_upstream;
    proxy_http_version 1.1;
    proxy_set_header Host              $host;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # gRPC-web / streaming
    proxy_buffering off;
    proxy_read_timeout 600s;
    proxy_send_timeout 600s;
  }
}

server {
  listen 80;
  server_name argus.corp.example;
  return 301 https://$host$request_uri;
}

關鍵:

  • X-Real-IP / X-Forwarded-For 必傳,否則 audit log 上 actor_ip 看不到真實 IP
  • proxy_read_timeout 拉長到 ≥ 10 分鐘,照顧長時間執行的 SQL Editor query
  • proxy_buffering off 給 streaming response 用

5. 第一次啟動 + 種子 admin

啟動時帶 --bootstrap-admin-login-idenv-vars)。

bash
# 第一次啟動:log 會列出 day-1 admin 的初始密碼(如 --bootstrap-admin-password 未指定)
docker compose up -d
docker compose logs argus | grep -i 'bootstrap admin'

⚠️ 初始密碼只印一次。複製進公司密碼管理工具,立即 rotate(首次登入時系統會強制要求改)。

6. 健康檢查 + smoke test

bash
curl -fs https://argus.corp.example/healthz   # 200
curl -fs https://argus.corp.example/readyz    # 200

# Bootstrap admin 登入
curl -X POST -H "Content-Type: application/json" \
  -d '{"loginId":"ops-bootstrap","password":"<initial>"}' \
  https://argus.corp.example/v1/auth/login
# 應該回 access_token 與要求重設密碼的旗標

走一遍 提交第一個變更 驗證主動線。

7. 觀測與備份

  • 接 metrics:GET /metrics(Prometheus 格式)
  • 接 log:JSON log 進 ELK / Loki / Datadog
  • 備份:備份與災備
  • Audit log 留存:Audit Log

升級

詳見 升級與遷移。原則:

  1. 備份 metastore
  2. 看 changelog(特別是 migration 段)
  3. 滾動更新 image / binary
  4. 啟動時自動跑 migration(fail-fast)
  5. 跑 smoke test

HA 模式

--ha flag 啟用後:

  • 多副本共享 metastore;leader election 由內部 lock 處理
  • 同一時間只有一個副本跑非冪等 runner(taskrun-scheduler / plancheck-scheduler)
  • 其他副本只服務讀請求 / 認證

HA 主要解決「server 單點故障」。Metastore 的 HA 自行規劃(PG 自身 streaming replication / managed RDS)。

安全 checklist

  • [ ] 反向代理 + TLS 設定完成
  • [ ] Metastore 在私網、用專用 user、強密碼、SSL
  • [ ] Audit log 留存 ≥ 法遵要求(通常 ≥ 1 年)
  • [ ] 自動備份 + 恢復演練(備份與災備
  • [ ] Day-1 admin 初始密碼已 rotate
  • [ ] 至少一個 break-glass 帳號(不接 IdP)
  • [ ] 觀測 / 警報接通(CPU / mem / 5xx / latency)
  • [ ] 文件登錄變更聯絡人 / on-call

相關

Argus — 公司內部資料庫變更審計平台