在这个例子中,我们假设一个有两个集群的场景:staging 集群和 production 集群。 最终目标是利用 Flux 和 Kustomize 来管理这两个集群,同时尽量减少重复声明。
我们将配置 Flux,以便使用 HelmRepository和HelmRelease自定义资源来安装、测试和升级一个演示应用。
Flux将监控 Helm 代码库,并根据 semver 版本号范围自动将 Helm 版本升级到最新的 chart 版本。
您需要一个 Kubernetes 集群版本 1.21 或更高版本。 要进行快速本地测试,您可以使用Kubernetes kind。 其他 Kubernetes 设置也同样适用。
为了遵循本指南,您需要一个 GitHub 帐户和一个
可以创建存储库的个人访问令牌(检查repo下的所有权限)。
使用 Homebrew 在 macOS 或 Linux 上安装 Flux CLI:
brew install fluxcd/tap/flux或者通过使用 Bash 脚本下载预编译的二进制文件来安装 CLI:
xxxxxxxxxxcurl -s https://fluxcd.io/install.sh | sudo bashGit 存储库包含以下顶级目录:
xxxxxxxxxx├── apps│ ├── base│ ├── production│ └── staging├── infrastructure│ ├── configs│ └── controllers└── clusters├── production└── staging
应用程序配置结构如下:
xxxxxxxxxx./apps/├── base│ └── podinfo│ ├── kustomization.yaml│ ├── namespace.yaml│ ├── release.yaml│ └── repository.yaml├── production│ ├── kustomization.yaml│ └── podinfo-patch.yaml└── staging├── kustomization.yaml└── podinfo-patch.yaml
在 apps/base/podinfo/ 目录中,我们有一个对两个集群具有公共值的Flux HelmRelease:
xxxxxxxxxxapiVersionhelm.toolkit.fluxcd.io/v2beta2kindHelmReleasemetadata namepodinfo namespacepodinfospec releaseNamepodinfo chart spec chartpodinfo sourceRef kindHelmRepository namepodinfo namespaceflux-system interval50m values ingress enabledtrue classNamenginx在 apps/staging/ 目录中,我们有一个带有暂存特定值的 Kustomize 补丁:
xxxxxxxxxxapiVersionhelm.toolkit.fluxcd.io/v2beta2kindHelmReleasemetadata namepodinfospec chart spec version">=1.0.0-alpha" test enabletrue values ingress hostshostpodinfo.staging请注意,version: ">=1.0.0-alpha"我们配置 Flux 以自动升级
HelmRelease到最新的图表版本,包括 alpha、beta 和预发布版本。
在 apps/production/ 目录中,我们有一个 Kustomize 补丁,其中包含特定于生产的值:
xxxxxxxxxxapiVersionhelm.toolkit.fluxcd.io/v2beta2kindHelmReleasemetadata namepodinfo namespacepodinfospec chart spec version">=1.0.0" values ingress hostshostpodinfo.production请注意,version: ">=1.0.0"我们将 Flux 配置为自动升级
HelmRelease到 latest stable chart 版本(alpha、beta 和预发布版本将被忽略)。
基础设施结构如下:
xxxxxxxxxx./infrastructure/├── configs│ ├── cluster-issuers.yaml│ └── kustomization.yaml└── controllers├── cert-manager.yaml├── ingress-nginx.yaml└── kustomization.yaml
在 infrastructure/controllers/ 目录中,我们有 FluxHelmRepository和HelmRelease如下定义:
xxxxxxxxxxapiVersionhelm.toolkit.fluxcd.io/v2beta2kindHelmReleasemetadata namecert-manager namespacecert-managerspec interval30m chart spec chartcert-manager version"1.x" sourceRef kindHelmRepository namecert-manager namespacecert-manager interval12h values installCRDstrue请注意,interval: 12h我们将 Flux 配置为每十二小时拉取一次 Helm 仓库索引以检查更新。
如果1.x找到与 semver 范围匹配的新 chart 版本,Flux 将升级该版本。
在 infrastructure/configs/ 目录中,我们有 Kubernetes 自定义资源,例如 Let's Encrypt issuer:
xxxxxxxxxxapiVersioncert-manager.io/v1kindClusterIssuermetadata nameletsencryptspec acme # Replace the email address with your own contact email emailfluxcdbot@users.noreply.github.com serverhttps//acme-staging-v02.api.letsencrypt.org/directory privateKeySecretRef nameletsencrypt-nginx solvershttp01 ingress classnginx在 clusters/production/infrastructure.yaml中,我们替换 Let's Encrypt 服务器值以指向生产 API:
xxxxxxxxxxapiVersionkustomize.toolkit.fluxcd.io/v1kindKustomizationmetadata nameinfra-configs namespaceflux-systemspec # ...omitted for brevity dependsOnnameinfra-controllers patchespatch - op: replace path: /spec/acme/server value: https://acme-v02.api.letsencrypt.org/directory target: kind: ClusterIssuer name: letsencrypt请注意,dependsOn 我们告诉 Flux 首先安装或升级控制器,然后再安装或升级配置。
这确保在 Flux 应用任何自定义资源之前,Kubernetes CRD 已在集群上注册。
clusters 目录包含 Flux 配置:
xxxxxxxxxx./clusters/├── production│ ├── apps.yaml│ └── infrastructure.yaml└── staging├── apps.yaml└── infrastructure.yaml
在 clusters/staging/ 目录中,我们有 Flux Kustomization 定义,例如:
xxxxxxxxxxapiVersionkustomize.toolkit.fluxcd.io/v1kindKustomizationmetadata nameapps namespaceflux-systemspec interval10m0s dependsOnnameinfra-configs sourceRef kindGitRepository nameflux-system path./apps/staging prunetrue waittrue请注意,使用path: ./apps/staging,我们配置 Flux 来同步暂存 Kustomize overlay,并
使用dependsOn告诉 Flux 在部署应用程序之前创建基础设施项。
在您的个人 GitHub 帐户上 Fork 此存储库并导出您的 GitHub 访问令牌、用户名和存储库名称:
xxxxxxxxxxexport GITHUB_TOKEN=<your-token>export GITHUB_USER=<your-username>export GITHUB_REPO=<repository-name>验证您的暂存集群是否满足先决条件:
xxxxxxxxxxflux check --pre将 kubectl 上下文设置为您的暂存集群并引导 Flux:
xxxxxxxxxxflux bootstrap github \ --context=staging \ --owner=${GITHUB_USER} \ --repository=${GITHUB_REPO} \ --branch=main \ --personal \ --path=clusters/stagingbootstrap 命令提交目录中 Flux 组件的清单clusters/staging/flux-system,
并在 GitHub 上创建具有只读访问权限的部署密钥,以便它可以拉取集群内的更改。
观察在staging安装的 Helm 版本:
x$ watch flux get helmreleases --all-namespaces
NAMESPACE NAME REVISION SUSPENDED READY MESSAGE cert-manager cert-manager v1.11.0 False True Release reconciliation succeededingress-nginx ingress-nginx 4.4.2 False True Release reconciliation succeededpodinfo podinfo 6.3.0 False True Release reconciliation succeeded验证是否可以通过 ingress 访问演示应用程序:
xxxxxxxxxx$ kubectl -n ingress-nginx port-forward svc/ingress-nginx-controller 8080:80 &
$ curl -H "Host: podinfo.staging" http://localhost:8080{ "hostname": "podinfo-59489db7b5-lmwpn", "version": "6.2.3"}通过设置生产集群的上下文和路径在生产中引导 Flux:
xxxxxxxxxxflux bootstrap github \ --context=production \ --owner=${GITHUB_USER} \ --repository=${GITHUB_REPO} \ --branch=main \ --personal \ --path=clusters/production观察生产 reconciliation:
xxxxxxxxxx$ flux get kustomizations --watch
NAME REVISION SUSPENDED READY MESSAGE apps main/696182e False True Applied revision: main/696182e flux-system main/696182e False True Applied revision: main/696182e infra-configs main/696182e False True Applied revision: main/696182e infra-controllers main/696182e False True Applied revision: main/696182e 如果要向fleet添加集群,请首先在本地克隆您的 repo:
xxxxxxxxxxgit clone https://github.com/${GITHUB_USER}/${GITHUB_REPO}.gitcd ${GITHUB_REPO}使用您的集群名称在其中创建一个目录clusters:
xxxxxxxxxxmkdir -p clusters/dev从暂存区复制同步清单:
xxxxxxxxxxcp clusters/staging/infrastructure.yaml clusters/devcp clusters/staging/apps.yaml clusters/dev您可以在apps里面创建一个 dev overlay,确保
将spec.path内部更改clusters/dev/apps.yaml为path: ./apps/dev。
将更改推送到主分支:
xxxxxxxxxxgit add -A && git commit -m "add dev cluster" && git push将 kubectl 上下文和路径设置为您的开发集群并引导 Flux:
xxxxxxxxxxflux bootstrap github \ --context=dev \ --owner=${GITHUB_USER} \ --repository=${GITHUB_REPO} \ --branch=main \ --personal \ --path=clusters/dev如果您想要启动一个相同的环境,您可以引导一个集群
如 production-clone 并重用production定义。
引导production-clone集群:
xxxxxxxxxxflux bootstrap github \ --context=production-clone \ --owner=${GITHUB_USER} \ --repository=${GITHUB_REPO} \ --branch=main \ --personal \ --path=clusters/production-clone将更改拉到本地:
xxxxxxxxxxgit pull origin main创建kustomization.yaml在clusters/production-clone目录中:
xxxxxxxxxxapiVersion: kustomize.config.k8s.io/v1beta1kind: Kustomizationresources:- flux-system- ../production/infrastructure.yaml- ../production/apps.yaml
请注意,除了flux-system kustomize overlay之外,我们还包括
来自生产目录的infrastructure和apps清单。
将更改推送到主分支:
xxxxxxxxxxgit add -A && git commit -m "add production clone" && git push告诉 Flux 在集群上部署生产工作负载production-clone:
xxxxxxxxxxflux reconcile kustomization flux-system \ --context=production-clone \ --with-source 在拉取请求合并到主分支并在集群上同步之前,应该在 CI 中验证对 Kubernetes 清单或存储库结构的任何更改。
此存储库包含以下 GitHub CI 工作流程: