對於此示例,我們假設有兩個集群的場景:暫存(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
公眾號:黑客下午茶