對於此示例,我們假設有兩個叢集的場景:暫存(staging
)和生產(production
)。
最終目標是利用 Flux
和 Kustomize
來管理兩個叢集,同時最大限度地減少重複宣告。
我們將配置 Flux
以使用 HelmRepository
和 HelmRelease
自定義資源安裝、測試和升級演示應用程式。
Flux
將監控 Helm
儲存庫,並根據 semver
範圍自動將 Helm
版本升級到最新的 chart
版本。
準備工作
flux2-kustomize-helm-example
您將需要 Kubernetes
叢集版本 1.16 或更新版本以及 kubectl
版本 1.18 或更新。
對於快速的本地測試,您可以使用
Kubernetes kind。不過,任何其他 Kubernetes 設定也可以正常工作。
為了遵循本指南,您需要一個 GitHub
帳戶和一個可以建立儲存庫的
personal access token(檢查 repo
下的所有許可權)。
使用 Homebrew
在 MacOS
和 Linux
上安裝 Flux CLI
:
brew install fluxcd/tap/flux
或者通過使用 Bash
指令碼下載預編譯的二進位制檔案來安裝 CLI:
curl -s https://fluxcd.io/install.sh | sudo bash
專案結構
Git 儲存庫包含以下頂級目錄:
- apps 目錄包含每個叢集具有自定義配置的 Helm 版本
- infrastructure 目錄包含常見的基礎設施工具,例如 NGINX ingress controller 和 Helm 儲存庫定義
- clusters 目錄包含每個叢集的 Flux 配置
├── apps
│ ├── base
│ ├── production
│ └── staging
├── infrastructure
│ ├── nginx
│ ├── redis
│ └── sources
└── clusters
├── production
└── staging
apps 配置結構為:
- apps/base/ 目錄包含名稱空間和 Helm 釋出定義(release definitions)
- apps/production/ 目錄包含生產 Helm 釋出值(release values)
- apps/staging/ 目錄包含 staging values
./apps/
├── base
│ └── podinfo
│ ├── kustomization.yaml
│ ├── namespace.yaml
│ └── release.yaml
├── production
│ ├── kustomization.yaml
│ └── podinfo-patch.yaml
└── staging
├── kustomization.yaml
└── podinfo-patch.yaml
在 apps/base/podinfo/ 目錄中,我們有一個 HelmRelease
,兩個叢集都有共同的值:
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: podinfo
namespace: podinfo
spec:
releaseName: podinfo
chart:
spec:
chart: podinfo
sourceRef:
kind: HelmRepository
name: podinfo
namespace: flux-system
interval: 5m
values:
cache: redis-master.redis:6379
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
path: "/*"
在 apps/staging/ 目錄中,我們有一個帶有 staging
特定值的 Kustomize 補丁(patch
):
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: podinfo
spec:
chart:
spec:
version: ">=1.0.0-alpha"
test:
enable: true
values:
ingress:
hosts:
- podinfo.staging
請注意,使用 version: ">=1.0.0-alpha"
我們配置 Flux 以自動將 HelmRelease
升級到最新的 chart
版本,包括 alpha
、beta
和預釋出(pre-releases
)。
在 apps/production/ 目錄中,我們有一個帶有生產特定值的 Kustomize 補丁:
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: podinfo
namespace: podinfo
spec:
chart:
spec:
version: ">=1.0.0"
values:
ingress:
hosts:
- podinfo.production
請注意,使用 version: ">=1.0.0"
我們配置 Flux 以自動將 HelmRelease
升級到
最新的穩定 chart
版本(alpha
、beta
和 pre-releases
將被忽略)。
基礎設施:
./infrastructure/
├── nginx
│ ├── kustomization.yaml
│ ├── namespace.yaml
│ └── release.yaml
├── redis
│ ├── kustomization.yaml
│ ├── namespace.yaml
│ └── release.yaml
└── sources
├── bitnami.yaml
├── kustomization.yaml
└── podinfo.yaml
在 infrastructure/sources/ 目錄中,我們有 Helm 儲存庫定義:
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
name: podinfo
spec:
interval: 5m
url: https://stefanprodan.github.io/podinfo
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
name: bitnami
spec:
interval: 30m
url: https://charts.bitnami.com/bitnami
請注意,使用 interval: 5m
我們將 Flux 配置為每五分鐘拉一次 Helm
儲存庫索引。
如果索引包含與 HelmRelease
semver
範圍匹配的新 chart
版本,Flux
將升級該版本。
Bootstrap staging 和 production
叢集目錄包含 Flux
配置:
./clusters/
├── production
│ ├── apps.yaml
│ └── infrastructure.yaml
└── staging
├── apps.yaml
└── infrastructure.yaml
在 clusters/staging/ 目錄中,我們有 Kustomization
定義:
apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
kind: Kustomization
metadata:
name: apps
namespace: flux-system
spec:
interval: 10m0s
dependsOn:
- name: infrastructure
sourceRef:
kind: GitRepository
name: flux-sytem
path: ./apps/staging
prune: true
validation: client
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
kind: Kustomization
metadata:
name: infrastructure
namespace: flux-system
spec:
interval: 10m0s
sourceRef:
kind: GitRepository
name: flux-system
path: ./infrastructure
請注意,使用 path: ./apps/staging
我們配置 Flux
以同步暫存 Kustomize
覆蓋,並使用 dependsOn
我們告訴 Flux
在部署應用程式之前建立基礎設施項。
在您的個人 GitHub
帳戶上 Fork
此儲存庫並匯出您的 GitHub access token
、使用者名稱和儲存庫名稱:
export GITHUB_TOKEN=<your-token>
export GITHUB_USER=<your-username>
export GITHUB_REPO=<repository-name>
驗證您的臨時叢集是否滿足先決條件:
flux check --pre
將 kubectl context
設定為您的 staging 叢集和 bootstrap Flux:
flux bootstrap github \
--context=staging \
--owner=${GITHUB_USER} \
--repository=${GITHUB_REPO} \
--branch=main \
--personal \
--path=clusters/staging
bootstrap 命令在 clusters/staging/flux-system
目錄中提交 Flux 元件的清單,並在 GitHub 上建立一個具有隻讀訪問許可權的部署金鑰,因此它可以在叢集內拉取更改(pull changes
)。
注意在 staging
上安裝的 Helm releases:
$ watch flux get helmreleases --all-namespaces
NAMESPACE NAME REVISION SUSPENDED READY MESSAGE
nginx nginx 5.6.14 False True release reconciliation succeeded
podinfo podinfo 5.0.3 False True release reconciliation succeeded
redis redis 11.3.4 False True release reconciliation succeeded
驗證 demo app
是否可以通過 ingress
訪問:
$ kubectl -n nginx port-forward svc/nginx-ingress-controller 8080:80 &
$ curl -H "Host: podinfo.staging" http://localhost:8080
{
"hostname": "podinfo-59489db7b5-lmwpn",
"version": "5.0.3"
}
通過設定生產叢集的上下文和路徑來引導生產上的 Flux
:
flux bootstrap github \
--context=production \
--owner=${GITHUB_USER} \
--repository=${GITHUB_REPO} \
--branch=main \
--personal \
--path=clusters/production
監控 production reconciliation:
$ watch flux get kustomizations
NAME REVISION READY
apps main/797cd90cc8e81feb30cfe471a5186b86daf2758d True
flux-system main/797cd90cc8e81feb30cfe471a5186b86daf2758d True
infrastructure main/797cd90cc8e81feb30cfe471a5186b86daf2758d True
加密 Kubernetes secrets
為了將 secrets
安全地儲存在 Git 儲存庫中,
您可以使用 Mozilla
的 SOPS CLI
通過 OpenPGP
或 KMS
加密 Kubernetes secrets
。
brew install gnupg sops
為 Flux
生成一個不指定密碼短語(passphrase
)的 GPG
key,並獲取GPG key ID
:
$ gpg --full-generate-key
Email address: fluxcdbot@users.noreply.github.com
$ gpg --list-secret-keys fluxcdbot@users.noreply.github.com
sec rsa3072 2020-09-06 [SC]
1F3D1CED2F865F5E59CA564553241F147E7C5FA4
使用 private key
在叢集上建立 Kubernetes secret:
gpg --export-secret-keys \
--armor 1F3D1CED2F865F5E59CA564553241F147E7C5FA4 |
kubectl create secret generic sops-gpg \
--namespace=flux-system \
--from-file=sops.asc=/dev/stdin
生成 Kubernetes secret manifest
並使用 sops
加密 secret
的資料欄位:
kubectl -n redis create secret generic redis-auth \
--from-literal=password=change-me \
--dry-run=client \
-o yaml > infrastructure/redis/redis-auth.yaml
sops --encrypt \
--pgp=1F3D1CED2F865F5E59CA564553241F147E7C5FA4 \
--encrypted-regex '^(data|stringData)$' \
--in-place infrastructure/redis/redis-auth.yaml
新增 secret 到 infrastructure/redis/kustomization.yaml
:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: redis
resources:
- namespace.yaml
- release.yaml
- redis-auth.yaml
通過編輯 infrastructure.yaml
檔案在叢集上啟用解密:
apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
kind: Kustomization
metadata:
name: infrastructure
namespace: flux-system
spec:
# content omitted for brevity
decryption:
provider: sops
secretRef:
name: sops-gpg
匯出公鑰(public key
),以便任何有權訪問儲存庫的人都可以加密 secrets
但不能解密它們:
gpg --export -a fluxcdbot@users.noreply.github.com > public.key
將更改推送到主分支:
git add -A && git commit -m "add encrypted secret" && git push
驗證是否已在兩個叢集的 redis
名稱空間中建立了 secret
:
kubectl --context staging -n redis get secrets
kubectl --context production -n redis get secrets
您可以使用 Kubernetes secrets
為您的 Helm releases
提供值:
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: redis
spec:
# content omitted for brevity
values:
usePassword: true
valuesFrom:
- kind: Secret
name: redis-auth
valuesKey: password
targetPath: password
在 docs 中瞭解有關 Helm releases values 覆蓋的更多資訊。
新增叢集
如果要將叢集新增到你的 fleet 中,請先在本地克隆儲存庫:
git clone https://github.com/${GITHUB_USER}/${GITHUB_REPO}.git
cd ${GITHUB_REPO}
使用您的叢集名稱在 clusters
中建立一個目錄:
mkdir -p clusters/dev
從 staging
複製同步清單:
cp clusters/staging/infrastructure.yaml clusters/dev
cp clusters/staging/apps.yaml clusters/dev
您可以在 apps
內建立一個 dev overlay
,確保將 clusters/dev/apps.yaml
內的 spec.path
更改為 path: ./apps/dev
。
將更改推送到主分支:
git add -A && git commit -m "add dev cluster" && git push
將 kubectl 上下文和路徑設定為您的 dev cluster 並引導 Flux:
flux bootstrap github \
--context=dev \
--owner=${GITHUB_USER} \
--repository=${GITHUB_REPO} \
--branch=main \
--personal \
--path=clusters/dev
相同的環境
如果你想啟動一個相同的環境,你可以引導一個叢集,例如 production-clone
並重用 production
定義。
引導 production-clone
叢集:
flux bootstrap github \
--context=production-clone \
--owner=${GITHUB_USER} \
--repository=${GITHUB_REPO} \
--branch=main \
--personal \
--path=clusters/production-clone
在本地拉取更改:
git pull origin main
在 clusters/production-clone
目錄中建立一個 kustomization.yaml
:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- flux-system
- ../production/infrastructure.yaml
- ../production/apps.yaml
請注意,除了 flux-system
kustomize overlay,我們還包括來自 production 目錄的 infrastructure
和 apps
清單。
將更改推送到主分支:
git add -A && git commit -m "add production clone" && git push
告訴 Flux 在 production-clone
叢集上部署生產工作負載(production workloads
):
flux reconcile kustomization flux-system \
--context=production-clone \
--with-source
我是為少
微信:uuhells123
公眾號:黑客下午茶