Kubernetes Flux CD 持續交付

Kubernetes Flux CD Continuous Delivery

Flux CD 是一個強大的 GitOps 工具,專為 Kubernetes 設計,實現持續交付和自動化部署。本文將深入探討 Flux CD 的核心概念、安裝配置、進階功能,以及與 ArgoCD 的比較分析。

Flux CD 概述與架構

什麼是 Flux CD

Flux CD 是由 Weaveworks 開發的開源 GitOps 工具,現為 CNCF 畢業專案。它透過監控 Git 儲存庫的變更,自動將應用程式和基礎設施配置同步到 Kubernetes 叢集中。

核心設計理念

Flux CD 遵循 GitOps 的核心原則:

  • 宣告式配置:所有系統狀態都以宣告式方式定義在 Git 中
  • 版本控制:Git 作為唯一的真實來源(Single Source of Truth)
  • 自動同步:持續監控並自動調和實際狀態與期望狀態
  • 審計追蹤:所有變更都透過 Git 提交記錄追蹤

架構元件

Flux CD v2 採用模組化架構,由多個專門的 Controller 組成:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
┌─────────────────────────────────────────────────────────────┐
│                     Flux CD 架構                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────┐  ┌─────────────────┐                  │
│  │ Source          │  │ Kustomize       │                  │
│  │ Controller      │  │ Controller      │                  │
│  │                 │  │                 │                  │
│  │ - GitRepository │  │ - Kustomization │                  │
│  │ - HelmRepository│  │                 │                  │
│  │ - Bucket        │  │                 │                  │
│  │ - OCIRepository │  │                 │                  │
│  └────────┬────────┘  └────────┬────────┘                  │
│           │                    │                            │
│           v                    v                            │
│  ┌─────────────────┐  ┌─────────────────┐                  │
│  │ Helm            │  │ Notification    │                  │
│  │ Controller      │  │ Controller      │                  │
│  │                 │  │                 │                  │
│  │ - HelmRelease   │  │ - Provider      │                  │
│  │                 │  │ - Alert         │                  │
│  │                 │  │ - Receiver      │                  │
│  └─────────────────┘  └─────────────────┘                  │
│                                                             │
│  ┌─────────────────┐                                       │
│  │ Image           │                                       │
│  │ Automation      │                                       │
│  │ Controllers     │                                       │
│  │                 │                                       │
│  │ - ImageRepository                                       │
│  │ - ImagePolicy   │                                       │
│  │ - ImageUpdate   │                                       │
│  │   Automation    │                                       │
│  └─────────────────┘                                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

各元件功能說明:

元件功能
Source Controller管理各種來源(Git、Helm、OCI、S3)的資源擷取
Kustomize Controller處理 Kustomization 資源的調和
Helm Controller管理 Helm Chart 的安裝和升級
Notification Controller處理事件通知和 Webhook 接收
Image Automation Controllers自動化容器映像的更新

Flux CLI 安裝與 Bootstrap

安裝 Flux CLI

macOS(使用 Homebrew)

1
brew install fluxcd/tap/flux

Linux

1
curl -s https://fluxcd.io/install.sh | sudo bash

Windows(使用 Chocolatey)

1
choco install flux

驗證安裝

1
2
flux --version
# flux version 2.3.0

環境檢查

在執行 Bootstrap 之前,建議先檢查叢集環境:

1
2
3
4
5
6
7
# 檢查 Kubernetes 叢集是否符合 Flux 要求
flux check --pre

# 輸出範例:
# ► checking prerequisites
# ✔ Kubernetes 1.28.0 >=1.25.0-0
# ✔ prerequisites checks passed

Bootstrap 到 GitHub

Bootstrap 過程會在 Git 儲存庫中建立 Flux 配置,並將 Flux 元件安裝到叢集中:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 設定 GitHub Token
export GITHUB_TOKEN=<your-token>

# 執行 Bootstrap
flux bootstrap github \
  --owner=<your-github-username> \
  --repository=fleet-infra \
  --branch=main \
  --path=clusters/production \
  --personal

參數說明:

  • --owner:GitHub 組織或使用者名稱
  • --repository:儲存 Flux 配置的儲存庫名稱
  • --branch:使用的 Git 分支
  • --path:叢集配置的路徑
  • --personal:使用個人儲存庫(非組織儲存庫)

Bootstrap 到 GitLab

1
2
3
4
5
6
7
8
export GITLAB_TOKEN=<your-token>

flux bootstrap gitlab \
  --owner=<your-gitlab-username> \
  --repository=fleet-infra \
  --branch=main \
  --path=clusters/production \
  --personal

Bootstrap 到 Bitbucket

1
2
3
4
5
6
7
8
export BITBUCKET_TOKEN=<your-token>

flux bootstrap bitbucket-server \
  --owner=<your-project> \
  --repository=fleet-infra \
  --branch=main \
  --path=clusters/production \
  --hostname=bitbucket.example.com

驗證安裝

1
2
3
4
5
6
7
8
# 檢查 Flux 元件狀態
flux check

# 查看所有 Flux 資源
flux get all

# 查看 Flux 系統 Pod
kubectl get pods -n flux-system

GitRepository 與 Kustomization

GitRepository 資源

GitRepository 定義了 Flux 應監控的 Git 儲存庫來源:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# gitrepository.yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: podinfo
  namespace: flux-system
spec:
  interval: 1m
  url: https://github.com/stefanprodan/podinfo
  ref:
    branch: master
  secretRef:
    name: git-credentials  # 私有儲存庫需要

使用 SSH 認證

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: private-repo
  namespace: flux-system
spec:
  interval: 5m
  url: ssh://git@github.com/org/private-repo.git
  ref:
    branch: main
  secretRef:
    name: ssh-credentials
---
apiVersion: v1
kind: Secret
metadata:
  name: ssh-credentials
  namespace: flux-system
type: Opaque
stringData:
  identity: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    ...
    -----END OPENSSH PRIVATE KEY-----    
  known_hosts: |
    github.com ecdsa-sha2-nistp256 AAAA...    

使用 HTTP 基本認證

1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: Secret
metadata:
  name: git-credentials
  namespace: flux-system
type: Opaque
stringData:
  username: git
  password: <personal-access-token>

指定特定標籤或提交

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: app-source
  namespace: flux-system
spec:
  interval: 5m
  url: https://github.com/org/app
  ref:
    # 使用特定標籤
    tag: v1.2.0
    # 或使用 SemVer 範圍
    # semver: ">=1.0.0 <2.0.0"
    # 或使用特定提交
    # commit: abc123def456

Kustomization 資源

Kustomization 定義了如何將來源中的配置應用到叢集:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# kustomization.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: podinfo
  namespace: flux-system
spec:
  interval: 10m
  targetNamespace: default
  sourceRef:
    kind: GitRepository
    name: podinfo
  path: ./kustomize
  prune: true
  healthChecks:
    - apiVersion: apps/v1
      kind: Deployment
      name: podinfo
      namespace: default
  timeout: 2m

依賴管理

Kustomization 可以定義依賴關係,確保資源按正確順序部署:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: infrastructure
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: fleet-infra
  path: ./infrastructure
  prune: true
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  interval: 10m
  dependsOn:
    - name: infrastructure
  sourceRef:
    kind: GitRepository
    name: fleet-infra
  path: ./apps
  prune: true

變數替換

Flux 支援使用 PostBuild 進行變數替換:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: fleet-infra
  path: ./apps
  prune: true
  postBuild:
    substitute:
      cluster_env: production
      cluster_region: ap-northeast-1
    substituteFrom:
      - kind: ConfigMap
        name: cluster-settings
      - kind: Secret
        name: cluster-secrets

在 YAML 檔案中使用變數:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  template:
    spec:
      containers:
        - name: app
          env:
            - name: ENVIRONMENT
              value: ${cluster_env}
            - name: REGION
              value: ${cluster_region}

強制同步

1
2
3
4
5
# 手動觸發同步
flux reconcile kustomization podinfo

# 使用 --with-source 同時更新來源
flux reconcile kustomization podinfo --with-source

HelmRepository 與 HelmRelease

HelmRepository 資源

HelmRepository 定義了 Helm Chart 的來源儲存庫:

1
2
3
4
5
6
7
8
9
# helmrepository.yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
  name: bitnami
  namespace: flux-system
spec:
  interval: 1h
  url: https://charts.bitnami.com/bitnami

OCI 格式的 Helm Repository

1
2
3
4
5
6
7
8
9
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
  name: podinfo
  namespace: flux-system
spec:
  interval: 1h
  type: oci
  url: oci://ghcr.io/stefanprodan/charts

需要認證的 Repository

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
  name: private-charts
  namespace: flux-system
spec:
  interval: 1h
  url: https://charts.example.com
  secretRef:
    name: helm-repo-creds
---
apiVersion: v1
kind: Secret
metadata:
  name: helm-repo-creds
  namespace: flux-system
type: Opaque
stringData:
  username: admin
  password: <password>

HelmRelease 資源

HelmRelease 定義了如何安裝和管理 Helm Chart:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# helmrelease.yaml
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: nginx
  namespace: default
spec:
  interval: 5m
  chart:
    spec:
      chart: nginx
      version: ">=15.0.0 <16.0.0"
      sourceRef:
        kind: HelmRepository
        name: bitnami
        namespace: flux-system
      interval: 1h
  values:
    replicaCount: 2
    service:
      type: ClusterIP

從 Git 安裝 Helm Chart

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: app-charts
  namespace: flux-system
spec:
  interval: 5m
  url: https://github.com/org/charts
  ref:
    branch: main
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: my-app
  namespace: default
spec:
  interval: 5m
  chart:
    spec:
      chart: ./charts/my-app
      sourceRef:
        kind: GitRepository
        name: app-charts
        namespace: flux-system

使用 ValuesFrom 引用外部值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: app
  namespace: default
spec:
  interval: 5m
  chart:
    spec:
      chart: app
      sourceRef:
        kind: HelmRepository
        name: app-charts
        namespace: flux-system
  valuesFrom:
    - kind: ConfigMap
      name: app-values
      valuesKey: values.yaml
    - kind: Secret
      name: app-secrets
      valuesKey: secrets.yaml
  values:
    # 這裡的值會覆蓋 valuesFrom 中的值
    replicas: 3

升級和回滾策略

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: app
  namespace: default
spec:
  interval: 5m
  chart:
    spec:
      chart: app
      sourceRef:
        kind: HelmRepository
        name: charts
        namespace: flux-system
  install:
    remediation:
      retries: 3
  upgrade:
    remediation:
      retries: 3
      remediateLastFailure: true
    cleanupOnFail: true
  rollback:
    timeout: 5m
    cleanupOnFail: true
  test:
    enable: true
    timeout: 5m

Drift Detection

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: app
  namespace: default
spec:
  interval: 5m
  driftDetection:
    mode: enabled  # enabled, warn, disabled
    ignore:
      - paths: ["/spec/replicas"]
        target:
          kind: Deployment
  chart:
    spec:
      chart: app
      sourceRef:
        kind: HelmRepository
        name: charts
        namespace: flux-system

多租戶與多叢集管理

多租戶架構

Flux 支援在同一叢集中為不同團隊提供隔離的 GitOps 工作流程:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
clusters/
├── production/
│   ├── flux-system/           # Flux 系統配置
│   │   ├── gotk-components.yaml
│   │   ├── gotk-sync.yaml
│   │   └── kustomization.yaml
│   └── tenants/               # 租戶配置
│       ├── team-a/
│       │   ├── rbac.yaml
│       │   ├── git-repository.yaml
│       │   └── kustomization.yaml
│       └── team-b/
│           ├── rbac.yaml
│           ├── git-repository.yaml
│           └── kustomization.yaml

租戶 RBAC 配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# tenants/team-a/rbac.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: team-a
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: team-a
  namespace: team-a
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: team-a-admin
  namespace: team-a
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: admin
subjects:
  - kind: ServiceAccount
    name: team-a
    namespace: team-a

租戶來源配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# tenants/team-a/git-repository.yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: team-a-apps
  namespace: team-a
spec:
  interval: 5m
  url: https://github.com/org/team-a-apps
  ref:
    branch: main
  secretRef:
    name: team-a-git-creds
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: team-a-apps
  namespace: team-a
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: team-a-apps
  path: ./apps
  prune: true
  targetNamespace: team-a
  serviceAccountName: team-a  # 使用租戶的 ServiceAccount

多叢集管理

儲存庫結構

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
fleet-infra/
├── clusters/
│   ├── production/
│   │   ├── flux-system/
│   │   └── apps.yaml
│   ├── staging/
│   │   ├── flux-system/
│   │   └── apps.yaml
│   └── development/
│       ├── flux-system/
│       └── apps.yaml
├── infrastructure/
│   ├── base/
│   │   ├── cert-manager/
│   │   ├── ingress-nginx/
│   │   └── kustomization.yaml
│   ├── production/
│   │   └── kustomization.yaml
│   └── staging/
│       └── kustomization.yaml
└── apps/
    ├── base/
    │   └── podinfo/
    ├── production/
    │   └── kustomization.yaml
    └── staging/
        └── kustomization.yaml

叢集特定配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# clusters/production/apps.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./apps/production
  prune: true
  postBuild:
    substitute:
      cluster_name: production
      cluster_env: prod

使用 Kustomize Overlays

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# apps/base/podinfo/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: podinfo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: podinfo
  template:
    metadata:
      labels:
        app: podinfo
    spec:
      containers:
        - name: podinfo
          image: ghcr.io/stefanprodan/podinfo:6.4.0
          resources:
            requests:
              cpu: 100m
              memory: 64Mi
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# apps/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: production
resources:
  - ../base/podinfo
patches:
  - patch: |
      - op: replace
        path: /spec/replicas
        value: 3      
    target:
      kind: Deployment
      name: podinfo

Image Automation Controller

Image Automation Controller 可以自動偵測容器映像更新並提交到 Git 儲存庫。

安裝 Image Automation Controllers

1
2
3
4
5
6
7
flux bootstrap github \
  --components-extra=image-reflector-controller,image-automation-controller \
  --owner=<your-username> \
  --repository=fleet-infra \
  --branch=main \
  --path=clusters/production \
  --personal

ImageRepository 資源

定義要監控的容器映像儲存庫:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata:
  name: podinfo
  namespace: flux-system
spec:
  image: ghcr.io/stefanprodan/podinfo
  interval: 5m
  secretRef:
    name: regcred  # 私有儲存庫需要

私有 Registry 認證

1
2
3
4
5
6
7
8
apiVersion: v1
kind: Secret
metadata:
  name: regcred
  namespace: flux-system
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: <base64-encoded-docker-config>

ImagePolicy 資源

定義映像版本選擇策略:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 使用 SemVer 策略
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
  name: podinfo
  namespace: flux-system
spec:
  imageRepositoryRef:
    name: podinfo
  policy:
    semver:
      range: ">=5.0.0 <6.0.0"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 使用數字策略(適用於 build number)
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
  name: app
  namespace: flux-system
spec:
  imageRepositoryRef:
    name: app
  policy:
    numerical:
      order: asc
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 使用字母順序策略
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
  name: app
  namespace: flux-system
spec:
  imageRepositoryRef:
    name: app
  policy:
    alphabetical:
      order: desc
  filterTags:
    pattern: "^main-[a-f0-9]+-(?P<ts>[0-9]+)"
    extract: "$ts"

ImageUpdateAutomation 資源

設定自動更新配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
  name: flux-system
  namespace: flux-system
spec:
  interval: 30m
  sourceRef:
    kind: GitRepository
    name: flux-system
  git:
    checkout:
      ref:
        branch: main
    commit:
      author:
        email: fluxcdbot@example.com
        name: fluxcdbot
      messageTemplate: |
        Automated image update

        Automation name: {{ .AutomationObject }}

        Files:
        {{ range $filename, $_ := .Changed.FileChanges -}}
        - {{ $filename }}
        {{ end -}}

        Objects:
        {{ range $resource, $changes := .Changed.Objects -}}
        - {{ $resource.Kind }} {{ $resource.Name }}
          Changes:
        {{- range $_, $change := $changes }}
            - {{ $change.OldValue }} -> {{ $change.NewValue }}
        {{ end -}}
        {{ end -}}        
    push:
      branch: main
  update:
    path: ./clusters/production
    strategy: Setters

在 YAML 中使用 Marker

在 Deployment 中標記需要自動更新的映像:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
apiVersion: apps/v1
kind: Deployment
metadata:
  name: podinfo
spec:
  template:
    spec:
      containers:
        - name: podinfo
          image: ghcr.io/stefanprodan/podinfo:6.4.0 # {"$imagepolicy": "flux-system:podinfo"}

通知與警報整合

Notification Controller

Flux 的 Notification Controller 支援多種通知管道。

Provider 資源

Slack 通知

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
  name: slack
  namespace: flux-system
spec:
  type: slack
  channel: flux-alerts
  secretRef:
    name: slack-webhook
---
apiVersion: v1
kind: Secret
metadata:
  name: slack-webhook
  namespace: flux-system
type: Opaque
stringData:
  address: https://hooks.slack.com/services/xxx/yyy/zzz

Microsoft Teams 通知

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
  name: teams
  namespace: flux-system
spec:
  type: msteams
  secretRef:
    name: teams-webhook
---
apiVersion: v1
kind: Secret
metadata:
  name: teams-webhook
  namespace: flux-system
type: Opaque
stringData:
  address: https://outlook.office.com/webhook/xxx

Discord 通知

1
2
3
4
5
6
7
8
9
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
  name: discord
  namespace: flux-system
spec:
  type: discord
  secretRef:
    name: discord-webhook

GitHub Commit Status

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
  name: github-status
  namespace: flux-system
spec:
  type: github
  address: https://github.com/org/repo
  secretRef:
    name: github-token

Alert 資源

定義觸發通知的條件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
  name: on-call-webapp
  namespace: flux-system
spec:
  summary: "Cluster production alerts"
  eventMetadata:
    env: production
    cluster: production-east
  providerRef:
    name: slack
  eventSeverity: error
  eventSources:
    - kind: GitRepository
      name: "*"
    - kind: Kustomization
      name: "*"
    - kind: HelmRelease
      name: "*"
      namespace: default
  exclusionList:
    - ".*upgrade.*retries.*"

多級別警報

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 錯誤警報發送到 PagerDuty
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
  name: critical-alerts
  namespace: flux-system
spec:
  providerRef:
    name: pagerduty
  eventSeverity: error
  eventSources:
    - kind: HelmRelease
      name: "*"
      namespace: production
---
# 資訊通知發送到 Slack
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
  name: info-alerts
  namespace: flux-system
spec:
  providerRef:
    name: slack
  eventSeverity: info
  eventSources:
    - kind: GitRepository
      name: "*"
    - kind: Kustomization
      name: "*"

Receiver 資源(Webhook 接收)

允許外部系統觸發 Flux 同步:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: notification.toolkit.fluxcd.io/v1
kind: Receiver
metadata:
  name: github-receiver
  namespace: flux-system
spec:
  type: github
  events:
    - "ping"
    - "push"
  secretRef:
    name: receiver-token
  resources:
    - kind: GitRepository
      name: flux-system
---
apiVersion: v1
kind: Secret
metadata:
  name: receiver-token
  namespace: flux-system
type: Opaque
stringData:
  token: <random-token>

取得 Webhook URL:

1
2
3
4
5
# 取得 Receiver 的 Webhook URL
flux get receiver github-receiver

# 或透過 kubectl
kubectl -n flux-system get receiver github-receiver -o jsonpath='{.status.webhookPath}'

整合 Prometheus 監控

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 啟用 Flux 指標
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: flux-system
  namespace: flux-system
spec:
  endpoints:
    - port: http-prom
  namespaceSelector:
    matchNames:
      - flux-system
  selector:
    matchLabels:
      app.kubernetes.io/part-of: flux

與 ArgoCD 比較

功能比較

特性Flux CDArgoCD
架構分散式 Controller集中式伺服器
UI無內建 UI(有 Weave GitOps)豐富的 Web UI
CLIflux CLIargocd CLI
Helm 支援HelmRelease CRD原生支援
Kustomize 支援Kustomization CRD原生支援
多叢集每叢集獨立安裝集中管理
Image 自動更新內建支援需要 Argo Image Updater
RBACKubernetes RBAC內建細粒度 RBAC
SSO支援 OIDC、LDAP、SAML
資源消耗較低較高
學習曲線中等較陡峭

架構差異

Flux CD

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  Cluster A  │     │  Cluster B  │     │  Cluster C  │
│             │     │             │     │             │
│  ┌───────┐  │     │  ┌───────┐  │     │  ┌───────┐  │
│  │ Flux  │  │     │  │ Flux  │  │     │  │ Flux  │  │
│  └───┬───┘  │     │  └───┬───┘  │     │  └───┬───┘  │
│      │      │     │      │      │     │      │      │
└──────┼──────┘     └──────┼──────┘     └──────┼──────┘
       │                   │                   │
       └───────────────────┼───────────────────┘
                    ┌──────▼──────┐
                    │     Git     │
                    │  Repository │
                    └─────────────┘

ArgoCD

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
                    ┌─────────────────┐
                    │   ArgoCD Hub    │
                    │                 │
                    │  ┌───────────┐  │
                    │  │  ArgoCD   │  │
                    │  │  Server   │  │
                    │  └─────┬─────┘  │
                    └────────┼────────┘
       ┌─────────────────────┼─────────────────────┐
       │                     │                     │
┌──────▼──────┐       ┌──────▼──────┐       ┌──────▼──────┐
│  Cluster A  │       │  Cluster B  │       │  Cluster C  │
│             │       │             │       │             │
│  (Agent)    │       │  (Agent)    │       │  (Agent)    │
└─────────────┘       └─────────────┘       └─────────────┘

適用場景

選擇 Flux CD 的情況

  • 去中心化管理:團隊希望每個叢集獨立管理
  • 輕量級需求:資源受限環境
  • 純 GitOps:不需要 UI,完全依賴 Git 操作
  • Image 自動更新:需要自動化容器映像更新
  • Kustomize 優先:大量使用 Kustomize

選擇 ArgoCD 的情況

  • 集中管理:需要統一管理多個叢集
  • 視覺化需求:團隊需要 Web UI
  • 企業功能:需要 SSO、細粒度 RBAC
  • Application 觀察:需要即時查看應用狀態
  • 多租戶隔離:需要 Project 級別的隔離

整合使用

Flux 和 ArgoCD 也可以結合使用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 使用 Flux 管理基礎設施
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: infrastructure
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: fleet-infra
  path: ./infrastructure
  prune: true
---
# 使用 Flux 安裝 ArgoCD
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: argocd
  namespace: flux-system
spec:
  interval: 10m
  dependsOn:
    - name: infrastructure
  sourceRef:
    kind: GitRepository
    name: fleet-infra
  path: ./argocd
  prune: true
---
# ArgoCD 管理應用程式部署
# 由 ArgoCD 處理 Application CRDs

最佳實踐

Git 儲存庫結構

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
fleet-infra/
├── clusters/
│   ├── production/
│   │   ├── flux-system/
│   │   ├── infrastructure.yaml
│   │   └── apps.yaml
│   └── staging/
│       ├── flux-system/
│       ├── infrastructure.yaml
│       └── apps.yaml
├── infrastructure/
│   ├── controllers/
│   │   ├── cert-manager/
│   │   ├── ingress-nginx/
│   │   └── external-secrets/
│   └── configs/
│       ├── cluster-issuers/
│       └── network-policies/
├── apps/
│   ├── base/
│   │   └── app-name/
│   ├── production/
│   └── staging/
└── tenants/
    ├── team-a/
    └── team-b/

安全建議

  1. 使用 SOPS 或 Sealed Secrets 加密敏感資料
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: fleet-infra
  path: ./apps
  prune: true
  decryption:
    provider: sops
    secretRef:
      name: sops-age
  1. 限制 ServiceAccount 權限
1
2
3
4
5
6
7
8
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: tenant-apps
  namespace: tenant-ns
spec:
  serviceAccountName: tenant-sa
  # 限制只能操作特定 namespace
  1. 啟用 Webhook 驗證
1
2
3
4
5
6
7
# 設定 GitHub Webhook Secret
flux create receiver github \
  --type github \
  --secret-ref webhook-secret \
  --event ping \
  --event push \
  --resource GitRepository/flux-system

監控和除錯

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 查看所有 Flux 資源狀態
flux get all -A

# 查看特定資源的事件
flux events --for Kustomization/apps

# 查看 reconciliation 日誌
flux logs --kind=Kustomization --name=apps

# 暫停 reconciliation
flux suspend kustomization apps

# 恢復 reconciliation
flux resume kustomization apps

# 強制同步
flux reconcile kustomization apps --with-source

總結

Flux CD 是一個成熟、靈活的 GitOps 解決方案,特別適合:

  • 追求純粹 GitOps 工作流程的團隊
  • 需要輕量級、去中心化叢集管理的場景
  • 大量使用 Kustomize 和 Helm 的環境
  • 需要自動化容器映像更新的 CI/CD 流程

透過本文的介紹,您應該能夠:

  1. 理解 Flux CD 的核心架構和元件
  2. 完成 Flux CLI 安裝和 Bootstrap
  3. 配置 GitRepository 和 Kustomization 進行應用部署
  4. 使用 HelmRepository 和 HelmRelease 管理 Helm Chart
  5. 實施多租戶和多叢集管理策略
  6. 設定 Image Automation 自動更新容器映像
  7. 整合通知和警報系統
  8. 根據需求選擇 Flux CD 或 ArgoCD

建議從小規模開始實驗,逐步擴展到生產環境,並根據團隊需求調整配置策略。

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy