探索了在多群集环境中使用 GitOps 进行工作负载管理
开发云原生应用程序的企业组织面临着在多个 Kubernetes 群集中大规模部署、配置和提升各种应用程序和服务的挑战。 此环境可能包括 Azure Kubernetes 服务 (AKS) 群集、在其他公有云提供商上运行的群集,或在通过 Azure Arc 连接到 Azure 的本地数据中心运行的群集。请参阅概念性文章,其中探索了业务流程、难题和解决方案体系结构。
本文将引导你了解多群集 Kubernetes 环境中工作负载部署和配置的示例场景。 首先,使用几个 GitHub 存储库和 AKS 群集部署示例基础结构。 接下来,完成一组用例,在这些用例中,你充当不同的角色(平台团队和应用程序团队)在同一环境中工作。
为了成功部署示例,你需要:
- Azure 订阅。 如果你还没有该订阅,请在开始之前先创建试用版订阅。
- Azure CLI
- GitHub CLI
- Helm
- kubectl
- jq
- 具有如下范围的 GitHub 令牌:
repo
、workflow
、write:packages
、delete:packages
、read:org
、delete_repo
。
若要部署示例,请运行以下脚本:
mkdir kalypso && cd kalypso
curl -fsSL -o deploy.sh https://raw.githubusercontent.com/microsoft/kalypso/main/deploy/deploy.sh
chmod 700 deploy.sh
./deploy.sh -c -p <prefix. e.g. kalypso> -o <GitHub org. e.g. eedorenko> -t <GitHub token> -l <azure-location. e.g. chinanorth3>
此脚本可能需要 10-15 分钟才能完成。 完成后,它会在输出中报告执行结果,如下所示:
Deployment is complete!
---------------------------------
Created repositories:
- https://github.com/eedorenko/kalypso-control-plane
- https://github.com/eedorenko/kalypso-gitops
- https://github.com/eedorenko/kalypso-app-src
- https://github.com/eedorenko/kalypso-app-gitops
---------------------------------
Created AKS clusters in kalypso-rg resource group:
- control-plane
- drone (Flux based workload cluster)
- large (Flux based workload cluster)
---------------------------------
备注
如果部署出现问题,可使用以下命令删除所创建的资源:
./deploy.sh -d -p <preix. e.g. kalypso> -o <GitHub org. e.g. eedorenko> -t <GitHub token> -l <azure-location. e.g. chinanorth3>
此部署脚本创建了一个基础结构,如下图所示:
有下面几个平台团队存储库:
- 控制平面:包含使用概括性抽象定义的平台模型,例如环境、群集类型、应用程序和服务、映射规则和配置以及提升工作流。
- 平台 GitOps:包含表示多群集环境拓扑的最终清单,例如在每个环境中有哪些群集类型可用、在其中计划了哪些工作负载以及设置了哪些平台配置值。
- 服务源:包含示例拨号音平台服务的概括性清单模板。
- 服务 GitOps:包含要跨群集部署的示例拨号音平台服务的最终清单。
基础结构还包括几个应用程序团队存储库:
- 应用程序源:包含示例应用程序源代码,其中包括 Docker 文件、清单模板和 CI/CD 工作流。
- 应用程序 GitOps:包含要部署到部署目标的最终示例应用程序清单。
该脚本创建了以下 Azure Kubernetes 服务 (AKS) 群集:
control-plane
- 此群集是不运行任何工作负载的管理群集。control-plane
群集托管 Kalypso 计划程序运算符,该运算符将概括性抽象从控制平面存储库转换到平台 GitOps 存储库中的原始 Kubernetes 清单。drone
- 示例工作负载群集。 此群集已安装 GitOps 扩展,并使用Flux
协调平台 GitOps 存储库中的清单。 对于此示例,drone
群集可表示已启用 Azure Arc 的群集或具有 Flux/GitOps 扩展的 AKS 群集。large
- 示例工作负载群集。 此群集已安装 GitOps 扩展,并使用Flux
协调平台 GitOps 存储库中的清单。
control plane
存储库包含 3 个分支:main
、dev
和 stage
。 dev
和 stage
分支包含特定于 Dev
和 Stage
环境的配置。 另一方面,main
分支不表示任何特定环境。 main
分支的内容是通用的,供所有环境使用。 对 main
分支的任何更改都必须跨环境提升。 例如,只有在 Dev
环境中成功测试后,才能将新应用程序或新模板提升到 Stage
环境。
main
分支:
Folder | 说明 |
---|---|
.github/workflows | 包含实现提升流的 GitHub 工作流。 |
.environments | 包含环境列表,其中包含指向具有环境配置的分支的指针。 |
模板 | 包含各种协调器的清单模板,以及工作负载命名空间的模板。 |
工作负荷 | 包含已加入的应用程序和服务的列表,其中包含指向相应 GitOps 存储库的指针。 |
dev
和 stage
分支:
项 | 说明 |
---|---|
cluster-types | 包含环境中可用群集类型的列表。 群集类型分组到自定义子文件夹中。 每个群集类型都带有一组标签。 它指定用于从 GitOps 存储库提取清单的协调器类型。 子文件夹还包含许多配置映射,其中包含群集类型上可用的平台配置值。 |
configs/dev-config.yaml | 包含配置映射,其中包含适用于环境中所有群集类型的平台配置值。 |
计划 | 包含将工作负载部署目标映射到环境中的群集类型的计划策略。 |
base-repo.yaml | 一个指针,它指向 Control Plane 存储库 (main ) 中计划程序应从中获取模板和工作负载注册的位置。 |
gitops-repo.yaml | 一个指针,它指向 Platform GitOps 存储库中计划程序应对已生成的清单执行拉取请求 (PR) 的位置。 |
提示
Control Plane
存储库中的文件夹结构并不重要。 此示例提供了在存储库中整理文件的一种方法,但你也可随意按自己喜欢的方式进行整理。 计划程序关注的是文件的内容,而不是文件所在的位置。
应用程序团队运行其软件开发生命周期。 他们生成应用程序并跨环境对其进行提升。 该团队不知道哪些群集类型可用,也不知道应用程序将要部署到哪里。 但他们确实知道自己希望在 Dev
环境中部署应用程序来进行功能和性能测试,在 Stage
环境中部署应用程序来进行 UAT 测试。
应用程序团队在应用程序源存储库的工作负载文件中描述了这一意图:
apiVersion: scheduler.kalypso.io/v1alpha1
kind: Workload
metadata:
name: hello-world-app
labels:
type: application
family: force
spec:
deploymentTargets:
- name: functional-test
labels:
purpose: functional-test
edge: "true"
environment: dev
manifests:
repo: https://github.com/microsoft/kalypso-app-gitops
branch: dev
path: ./functional-test
- name: performance-test
labels:
purpose: performance-test
edge: "false"
environment: dev
manifests:
repo: https://github.com/microsoft/kalypso-app-gitops
branch: dev
path: ./performance-test
- name: uat-test
labels:
purpose: uat-test
environment: stage
manifests:
repo: https://github.com/microsoft/kalypso-app-gitops
branch: stage
path: ./uat-test
此文件中有一个列表,上面列出了 3 个部署目标。 这些目标带有自定义标签,并指向应用程序 GitOps 存储库中的文件夹,应用程序团队在这些文件夹中为每个部署目标生成应用程序清单。
通过此文件,应用程序团队向平台团队请求 Kubernetes 计算资源。 作为回应,平台团队必须在控制平面存储库中注册应用程序。
若要注册应用程序,请打开终端并使用以下脚本:
export org=<GitHub org>
export prefix=<prefix>
# clone the control-plane repo
git clone https://github.com/$org/$prefix-control-plane control-plane
cd control-plane
# create workload registration file
cat <<EOF >workloads/hello-world-app.yaml
apiVersion: scheduler.kalypso.io/v1alpha1
kind: WorkloadRegistration
metadata:
name: hello-world-app
labels:
type: application
spec:
workload:
repo: https://github.com/$org/$prefix-app-src
branch: main
path: workload/
workspace: kaizen-app-team
EOF
git add .
git commit -m 'workload registration'
git push
备注
为简单起见,此示例将更改直接推送到 main
。 在实际操作中,你将创建一个拉取请求来提交更改。
这样操作后,应用程序就会加入到控制平面中。 但控制平面仍然不知道如何将应用程序部署目标映射到所有群集类型。
平台团队必须定义如何在 Dev
环境中的群集类型上计划应用程序部署目标。 为此,请使用以下脚本提交 functional-test
和 performance-test
部署目标的计划策略:
# Switch to dev branch (representing Dev environemnt) in the control-plane folder
git checkout dev
mkdir -p scheduling/kaizen
# Create a scheduling policy for the functional-test deployment target
cat <<EOF >scheduling/kaizen/functional-test-policy.yaml
apiVersion: scheduler.kalypso.io/v1alpha1
kind: SchedulingPolicy
metadata:
name: functional-test-policy
spec:
deploymentTargetSelector:
workspace: kaizen-app-team
labelSelector:
matchLabels:
purpose: functional-test
edge: "true"
clusterTypeSelector:
labelSelector:
matchLabels:
restricted: "true"
edge: "true"
EOF
# Create a scheduling policy for the performance-test deployment target
cat <<EOF >scheduling/kaizen/performance-test-policy.yaml
apiVersion: scheduler.kalypso.io/v1alpha1
kind: SchedulingPolicy
metadata:
name: performance-test-policy
spec:
deploymentTargetSelector:
workspace: kaizen-app-team
labelSelector:
matchLabels:
purpose: performance-test
edge: "false"
clusterTypeSelector:
labelSelector:
matchLabels:
size: large
EOF
git add .
git commit -m 'application scheduling policies'
git config pull.rebase false
git pull --no-edit
git push
第一个策略规定,应在带有标签 restricted: "true"
的所有环境群集类型上计划 kaizen-app-team
工作区的所有部署目标(带有标签 purpose: functional-test
和 edge: "true"
)。 可以将工作区视为应用程序团队生成的一组应用程序。
第二个策略规定,应在带有标签 size: "large"
的所有环境群集类型上计划 kaizen-app-team
工作区的所有部署目标(带有标签 purpose: performance-test
和 edge: "false"
)。
推送到 dev
分支会触发计划过程,并创建对 Platform GitOps
存储库中的 dev
分支的 PR:
除了 Promoted_Commit_id
(只跟踪提升 CD 流的信息)外,PR 还包含分配清单。 functional-test
部署目标分配至 drone
群集类型,performance-test
部署目标分配至 large
群集类型。 这些清单将存放在 drone
和 large
文件夹中,其中包含对 Dev
环境中这些群集类型的所有分配。
Dev
环境还包括 command-center
和 small
群集类型:
但是,定义的计划策略仅选择了 drone
和 large
群集类型。
在继续操作之前,请仔细查看为 functional-test
部署目标生成的分配清单。 有 namespace.yaml
、platform-config.yaml
和 reconciler.yaml
清单文件。
namespace.yaml
定义一个命名空间,该命名空间将在运行 hello-world
应用程序的任何 drone
群集上创建。
apiVersion: v1
kind: Namespace
metadata:
name: "dev-drone-hello-world-app-functional-test"
labels:
environment: "dev"
workspace: "kaizen-app-team"
workload: "hello-world-app"
deploymentTarget: "hello-world-app-functional-test"
someLabel: some-value
platform-config.yaml
包含应用程序可在 Dev
环境中使用的任何 drone
群集上可用的所有平台配置值。
apiVersion: v1
kind: ConfigMap
metadata:
name: platform-config
namespace: dev-drone-hello-world-app-functional-test
data:
CLUSTER_NAME: Drone
DATABASE_URL: mysql://restricted-host:3306/mysqlrty123
ENVIRONMENT: Dev
REGION: China North 3
SOME_COMMON_ENVIRONMENT_VARIABLE: "false"
reconciler.yaml
包含 drone
群集用于获取应用程序清单的 Flux 资源,这些清单是由应用程序团队为 functional-test
部署目标准备的。
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
name: "hello-world-app-functional-test"
namespace: flux-system
spec:
interval: 15s
url: "https://github.com/eedorenko/kalypso-tut-test-app-gitops"
ref:
branch: "dev"
secretRef:
name: repo-secret
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: "hello-world-app-functional-test"
namespace: flux-system
spec:
interval: 30s
targetNamespace: "dev-drone-hello-world-app-functional-test"
sourceRef:
kind: GitRepository
name: "hello-world-app-functional-test"
path: "./functional-test"
prune: true
备注
control plane
定义 drone
群集类型使用 Flux
来协调应用程序 GitOps 存储库中的清单。 因此,reconciler.yaml
文件包含了 GitRepository
和 Kustomization
资源。
在批准 PR 并将其合并到 Platform GitOps
存储库后,表示相应群集类型的 drone
和 large
AKS 群集会开始提取分配清单。 drone
群集已安装 GitOps 扩展,指向 Platform GitOps
存储库。 它向 Azure Resource Graph 报告其 compliance
状态:
PR 合并事件在 control plane
存储库中启动 GitHub 工作流 checkpromote
。 此工作流会一直等待,直到所有安装了 GitOps 扩展且正在查看 Platform GitOps
存储库中的 dev
分支的群集都符合 PR 提交。 在此示例中,唯一的此类群集是 drone
。
checkpromote
成功后,它将启动 cd
工作流,将更改(应用程序注册)提升到 Stage
环境中。 为了提高可见性,它会还更新 control plane
存储库中的 git 提交状态:
备注
如果 drone
群集因任何原因无法协调分配清单,提升流将失败。 提交状态将标记为“失败”,并且应用程序注册不会提升到 Stage
环境。
接下来,在 stage 环境中为 uat-test
部署目标配置计划策略:
# Switch to stage branch (representing Stage environemnt) in the control-plane folder
git checkout stage
mkdir -p scheduling/kaizen
# Create a scheduling policy for the uat-test deployment target
cat <<EOF >scheduling/kaizen/uat-test-policy.yaml
apiVersion: scheduler.kalypso.io/v1alpha1
kind: SchedulingPolicy
metadata:
name: uat-test-policy
spec:
deploymentTargetSelector:
workspace: kaizen-app-team
labelSelector:
matchLabels:
purpose: uat-test
clusterTypeSelector:
labelSelector: {}
EOF
git add .
git commit -m 'application scheduling policies'
git config pull.rebase false
git pull --no-edit
git push
该策略规定,应在环境中定义的所有群集类型上计划 kaizen-app-team
工作区中带有 purpose: uat-test
标签的所有部署目标。
将此策略推送到 stage
分支会触发计划过程,该过程会创建一个 PR,其中包含对 Platform GitOps
存储库的分配清单,类似于 Dev
环境的分配清单。
与 Dev
环境一样,在评审 PR 并将其合并到 Platform GitOps
存储库后,control plane
存储库中的 checkpromote
工作流将等待直到具有 GitOps 扩展的群集 (drone
) 协调分配清单。
成功执行后,提交状态会更新。
应用程序团队定期向 Application Source
存储库中的 main
分支提交拉取请求。 将 PR 合并到 main
后,它将启动 CI/CD 工作流。 此处,工作流将手动启动。
转到 GitHub 中的 Application Source
存储库。 在“Actions
”选项卡上,选择“Run workflow
”。
工作流执行以下操作:
- 生成应用程序 Docker 映像并将其推送到 GitHub 存储库包。
- 为
functional-test
和performance-test
部署目标生成清单。 它将使用dev-configs
分支中的配置值。 生成的清单将添加到拉取请求中,并在dev
分支中自动合并。 - 为
uat-test
部署目标生成清单。 它将使用stage-configs
分支中的配置值。
生成的清单将添加到等待审批的 stage
分支拉取请求中:
若要在批准针对 Dev
环境的 PR 之前在 Stage
环境中手动测试应用程序,请先验证 functional-test
应用程序实例在 drone
群集上的工作方式:
kubectl port-forward svc/hello-world-service -n dev-drone-hello-world-app-functional-test 9090:9090 --context=drone
# output:
# Forwarding from 127.0.0.1:9090 -> 9090
# Forwarding from [::1]:9090 -> 9090
运行此命令时,请在浏览器中打开 localhost:9090
。 你将看到以下问候页:
下一步是检查 performance-test
实例在 large
群集上的工作方式:
kubectl port-forward svc/hello-world-service -n dev-large-hello-world-app-performance-test 8080:8080 --context=large
# output:
# Forwarding from 127.0.0.1:8080 -> 8080
# Forwarding from [::1]:8080 -> 8080
这次使用 8080
端口并在浏览器中打开 localhost:8080
。
Dev
环境满足需求后,批准 PR 并将其合并到 Stage
环境中。 之后,在 Stage
环境中针对这两个群集测试 uat-test
应用程序实例。
为 drone
群集运行以下命令,并在浏览器中打开 localhost:8001
:
kubectl port-forward svc/hello-world-service -n stage-drone-hello-world-app-uat-test 8001:8000 --context=drone
为 large
群集运行以下命令,并在浏览器中打开 localhost:8002
:
kubectl port-forward svc/hello-world-service -n stage-large-hello-world-app-uat-test 8002:8000 --context=large
large
群集上的应用程序实例显示以下问候页:
在 Dev
和 Stage
环境中,群集中的应用程序都从同一数据库获取数据。 对其进行更改,并配置 china-north-3
群集,为在 Stage
环境中工作的应用程序提供不同的数据库 URL:
# Switch to stage branch (representing Stage environemnt) in the control-plane folder
git checkout stage
# Update a config map with the configurations for china-north-3 clusters
cat <<EOF >cluster-types/china-north-3/china-north-3-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: china-north-3-config
labels:
platform-config: "true"
region: china-north-3
data:
REGION: China North 3
DATABASE_URL: mysql://west-stage:8806/mysql2
EOF
git add .
git commit -m 'database url configuration'
git config pull.rebase false
git pull --no-edit
git push
计划程序扫描环境中的所有配置映射,并根据标签匹配情况收集每个群集类型的值。 然后,它将 platform-config
配置映射放入 Platform GitOps
存储库中的每个部署目标文件夹。 platform-config
配置映射包含工作负载可在此环境中的此群集类型上使用的所有平台配置值。
几秒钟后,将显示针对 Platform GitOps
存储库中的 stage
分支的新 PR:
批准 PR 并将其合并。
在 large
群集具有新配置后,请在运行以下命令后检查 localhost:8002
处的 uat-test
应用程序实例:
kubectl rollout restart deployment hello-world-deployment -n stage-large-hello-world-app-uat-test --context=large
kubectl port-forward svc/hello-world-service -n stage-large-hello-world-app-uat-test 8002:8000 --context=large
你将看到更新后的数据库 URL:
目前,Stage
环境中仅包含 drone
和 large
群集类型。 将 small
群集类型也包含在 Stage
中。 即使没有表示此群集类型的物理群集,也可以查看计划程序对此更改的反应。
# Switch to stage branch (representing Stage environemnt) in the control-plane folder
git checkout stage
# Add "small" cluster type in china-north-3 region
mkdir -p cluster-types/china-north-3/small
cat <<EOF >cluster-types/china-north-3/small/small-cluster-type.yaml
apiVersion: scheduler.kalypso.io/v1alpha1
kind: ClusterType
metadata:
name: small
labels:
region: china-north-3
size: small
spec:
reconciler: arc-flux
namespaceService: default
configType: configmap
EOF
git add .
git commit -m 'add new cluster type'
git config pull.rebase false
git pull --no-edit
git push
几秒钟后,计划程序会将 PR 提交到 Platform GitOps
存储库。 根据创建的 uat-test-policy
,它将 uat-test
部署目标分配给新的群集类型,因为它适用于环境中所有可用的群集类型。
如果不再需要,请删除你创建的资源。 为此,请运行以下命令:
# In kalypso folder
./deploy.sh -d -p <preix. e.g. kalypso> -o <GitHub org. e.g. eedorenko> -t <GitHub token> -l <azure-location. e.g. chinanorth3>
你已针对多群集 Kubernetes 环境中的一些常见的工作负载管理场景执行了任务。 你可能还想探索许多其他场景。 请继续使用示例,并了解如何实现日常活动中最常见的用例。
若要更深入地了解基础概念和机制,请参阅以下资源: