【K8s项目源码分析】从文件夹结构看透一个云原生项目的设计逻辑
【K8s项目源码分析】从文件夹结构看透一个云原生项目的设计逻辑
深入分析CAMP项目中各目录的编写顺序与执行顺序,理解架构设计背后的思考
一、引言:为什么文件夹结构很重要?
当我们拿到一个Kubernetes项目时,第一眼看到的就是它的目录结构。很多初学者会被一堆文件夹搞得晕头转向:k8s/、helm/、environments/、clusters/、scripts/、ci-cd/、gitops/……这些文件夹到底谁先谁后?它们之间是什么关系?
本文将抛开业务代码,纯粹从文件夹设计的角度,分析一个企业级K8s项目的演进逻辑。我将从两个维度来拆解:
-
编写顺序(设计时):项目作者从零搭建时,先写哪个文件夹,后写哪个文件夹?
-
执行顺序(运行时):从代码提交到部署完成,各文件夹被触发的先后顺序?
理解这两个顺序,你就能真正读懂一个项目的架构设计。
二、编写顺序:从零搭建项目的7个步骤
所谓“编写顺序”,是指项目作者从零开始构建这个项目时,先写什么文件、后写什么文件。这反映了一个架构师的思考路径。
第1步:应用代码 + Dockerfile
文件夹:camp-backend/、camp-web-frontend/、camp-auth-frontend/
阶段目标:把业务逻辑写出来,让程序本身能运行。
思考过程:“我首先要有一个能跑起来的应用,不管是Python后端还是前端页面。”
关键产出:
-
Python FastAPI代码
-
前端HTML/CSS/JS
-
Dockerfile(定义如何把应用打包成镜像)
此时还没有任何Kubernetes相关文件。
第2步:docker-compose.yaml
阶段目标:在本地单机环境快速启动所有服务。
思考过程:“我需要一个简单的办法,在本机一键启动后端+前端+认证服务,方便开发和调试。但不能每次都手动敲docker run命令。”
关键产出:
-
docker-compose.yaml(定义所有服务的容器化配置)
配合脚本:build-and-run.sh、restart-backend.bat
此时仍然不涉及Kubernetes。
第3步:k8s/ 目录
阶段目标:编写“写死的”Kubernetes YAML文件,确定资源标准形态。
思考过程:“现在我要上Kubernetes了。我需要先确定Deployment、Service、Ingress这些资源到底长什么样——副本数是多少?镜像用哪个?探针怎么配?这些都要先写出来看看效果。”
关键产出:
-
k8s/namespace.yaml -
k8s/configmap.yaml/secret.yaml -
k8s/backend-deployment.yaml -
k8s/service.yaml -
k8s/ingress.yaml -
k8s/horizontal-pod-autoscaler.yaml
设计意义:
k8s/目录是所有后续配置的“黄金样本”。虽然是静态的、写死的YAML,但它为后续Helm模板化提供了标准参照。
text
k8s/backend-deployment.yaml(静态)
replicas: 2
image: camp-backend:latest
resources:
limits:
memory: 512Mi
cpu: 500m
此时面临的问题:“如果开发环境只想用1个副本、生产环境想用5个副本怎么办?总不能改一次文件重新部署一次吧?”
这个痛点催生了第4步。
第4步:helm/ 目录
阶段目标:把“写死的YAML”变成“可填充的动态模板”。
思考过程:“既然不同环境需要不同参数,那我就把那些会变化的数值抽出来变成变量,然后用一个配置文件来填充这些变量。”
关键产出:
-
helm/camp/Chart.yaml(Chart元数据) -
helm/camp/templates/*.yaml(模板文件) -
helm/camp/values.yaml(默认值)
核心转变:
yaml
# k8s/ 方式(静态)
replicas: 2
# helm/ 方式(动态模板)
replicas: {{ .Values.replicaCount }}
但还有新问题:“我确实把数值变成了变量,但values.yaml只有一个文件。每次部署前都要手动修改这个文件里的变量吗?Dev/Staging/Prod用同一个文件,怎么区分?”
这个痛点催生了第5步。
第5步:environments/ 目录
阶段目标:为不同环境(dev/staging/prod)准备独立的配置文件。
思考过程:“我需要把values.yaml里的默认值作为基线,然后为每个环境单独准备一个覆盖文件。部署时根据目标环境选择对应的文件即可。”
关键产出:
-
environments/values-dev.yaml -
environments/values-staging.yaml -
environments/values-prod.yaml
配置分层:
| 层级 | 文件 | 优先级 |
|---|---|---|
| 默认值 | helm/camp/values.yaml |
最低(被覆盖) |
| 环境覆盖 | environments/values-dev.yaml |
中(覆盖默认值) |
| 命令行参数 | --set key=value |
最高(覆盖一切) |
Dev vs Prod配置差异:
yaml
# environments/values-dev.yaml
replicaCount: 1
image.tag: latest
resources:
requests:
memory: "128Mi"
# environments/values-prod.yaml
replicaCount: 5
image.tag: v1.0.0
resources:
requests:
memory: "512Mi"
现在我可以区分环境了,但每次执行Helm命令都很长:
bash
helm install camp ./helm/camp -f environments/values-dev.yaml -n camp-dev
这个痛点催生了第6步。
第6步:clusters/ 目录
阶段目标:集中管理所有可用的Kubernetes集群信息。
思考过程:“我不但要区分环境,还要区分集群——本地Minikube、云端AKS、EKS、GKE。每个集群的连接信息(context、namespace)都不一样,我需要统一管理这些信息。”
关键产出:
-
clusters/cluster-config.yaml
文件结构:
yaml
clusters:
local-dev:
context: minikube
namespace: camp-dev
environments: [dev]
aks-prod:
context: camp-prod-aks
namespace: camp-prod
environments: [prod]
azure:
subscriptionId: "xxx"
现在各文件分工清晰:
| 文件 | 解决什么问题 |
|---|---|
environments/ |
部署什么(用什么配置) |
clusters/cluster-config.yaml |
部署到哪里(目标集群) |
但命令仍然复杂,需要结合集群和环境参数:
bash
helm upgrade --install camp ./helm/camp \ -f environments/values-dev.yaml \ --kube-context minikube \ -n camp-dev
这个痛点催生了第7步。
第7步:scripts/ 目录
阶段目标:封装复杂命令,实现一键部署。
思考过程:“每次都要敲那么长的命令,而且还要先切换集群上下文,太容易出错了。我要写一个脚本,只需要传-c cluster -e env就能自动完成所有步骤。”
关键产出:
| 脚本 | 作用 | 编写顺序内 |
|---|---|---|
make-executable.sh |
给所有脚本加执行权限 | 最先写(否则其他脚本跑不了) |
cluster-manager.sh |
查看/切换/测试集群 | 次之 |
deploy.sh |
执行实际部署 | 最后写(依赖前面所有配置) |
deploy.sh核心流程:
text
解析参数(-c/-e/-t)
→ 检查依赖(kubectl/helm/yq)
→ 读取 clusters/cluster-config.yaml 获取集群配置
→ 切换K8s上下文
→ 读取 environments/values-dev.yaml 获取环境配置
→ 合并Helm values
→ 执行 helm upgrade --install
→ 显示部署状态
→ 输出访问地址
第8步(进阶):ci-cd/ 目录
阶段目标:把scripts/deploy.sh放进CI/CD流水线,实现代码推送即自动部署。
思考过程:“现在手动执行./scripts/deploy.sh已经很方便了。但每次代码更新后,还要手动去跑一次脚本。能不能做到代码推送后自动触发?”
关键产出:
-
.github/workflows/build-and-deploy.yml
流水线步骤:
text
代码推送 → 构建Docker镜像 → 推送到GHCR → 调用scripts/deploy.sh → 部署到目标集群
第9步(进阶):gitops/ 目录
阶段目标:引入GitOps工具(ArgoCD/Flux),让集群自己“拉取”配置,实现声明式部署和自愈能力。
思考过程:“CI/CD流水线直接操作集群虽然方便,但不够安全。如果Git仓库里的配置和集群实际状态不一致怎么办?能不能让集群自己持续监控Git仓库的变化,自动保持同步?”
关键产出:
-
gitops/argocd/application.yaml -
gitops/flux/gitrepository.yaml -
gitops/flux/kustomization.yaml
ArgoCD vs Flux对比:
| 维度 | ArgoCD | Flux |
|---|---|---|
| Application定义 | 一个资源包含源+目标+策略 | 分为GitRepository + Kustomization |
| 部署策略 | 一体化 | 分层(Source层 + Reconciler层) |
| GitOps核心 | Application持续同步 | Kustomization持续同步 |
GitOps工作流:
text
开发者更新Git仓库中的镜像Tag → ArgoCD/Flux检测到变化 → 自动同步到集群
编写顺序总结
| 顺序 | 文件夹 | 核心动机 | 依赖的上一步 |
|---|---|---|---|
| 1 | 应用代码 + Dockerfile | 先有可运行的程序 | 无 |
| 2 | docker-compose.yaml |
本地一键启动 | 第1步 |
| 3 | k8s/ |
确定K8s资源的“标准样子” | 第2步 |
| 4 | helm/ |
把写死的YAML变成动态模板 | 第3步 |
| 5 | environments/ |
支持多环境(dev/staging/prod) | 第4步 |
| 6 | clusters/ |
支持多集群切换 | 第5步 |
| 7 | scripts/ |
封装命令,一键部署 | 第6步 |
| 8 | ci-cd/ |
代码推送即自动部署 | 第7步 |
| 9 | gitops/ |
集群自愈、声明式管理 | 第8步 |
三、执行顺序:从提交代码到服务运行
所谓“执行顺序”,是指当你真正部署应用时,这些文件夹在时间上被触发的先后顺序。
场景1:纯手动部署(不使用CI/CD,不使用GitOps)
bash
./scripts/deploy.sh -c local-dev -e dev -t latest
执行顺序:
| 顺序 | 触发的文件/文件夹 | 具体操作 |
|---|---|---|
| 1 | scripts/deploy.sh |
脚本开始执行 |
| 2 | clusters/cluster-config.yaml |
读取集群配置(context、namespace) |
| 3 | kubectl(切换上下文) |
连接到目标集群 |
| 4 | environments/values-dev.yaml |
读取环境专属配置 |
| 5 | helm/camp/templates/ + helm/camp/values.yaml |
合并所有values,渲染模板 |
| 6 | helm |
执行helm upgrade --install |
| 7 | Kubernetes集群 | 创建/更新Pod、Service、Ingress等资源 |
简图:
text
scripts/deploy.sh
→ clusters/cluster-config.yaml(选目标集群)
→ kubectl use-context(切换集群)
→ environments/values-dev.yaml(读环境配置)
→ helm/(渲染并部署)
→ K8s集群(运行服务)
场景2:CI/CD自动化部署(不使用GitOps)
当代码推送到GitHub时:
| 顺序 | 触发的文件/文件夹 | 具体操作 |
|---|---|---|
| 1 | .github/workflows/build-and-deploy.yml |
GitHub Actions流水线被触发 |
| 2 | 应用代码 + Dockerfile | 构建Docker镜像 |
| 3 | Docker镜像推送 | 推送到GHCR |
| 4 | scripts/deploy.sh |
流水线调用部署脚本 |
| 5 | clusters/cluster-config.yaml |
读取集群配置 |
| 6 | kubectl |
切换集群上下文 |
| 7 | environments/values-*.yaml |
读取环境配置 |
| 8 | helm/ |
渲染并部署到集群 |
简图:
text
git push
→ .github/workflows/(流水线触发)
→ Dockerfile(构建镜像)
→ scripts/deploy.sh(调用部署脚本)
→ clusters/ + environments/ + helm/(部署到目标集群)
场景3:GitOps模式部署
当代码推送到GitHub时:
| 顺序 | 触发的文件/文件夹 | 具体操作 |
|---|---|---|
| 1 | .github/workflows/build-and-deploy.yml |
CI流水线触发 |
| 2 | 应用代码 + Dockerfile | 构建并推送镜像 |
| 3 | 不调用scripts/deploy.sh |
流水线只负责更新Git仓库中的镜像Tag |
| 4 | gitops/argocd/application.yaml |
ArgoCD检测到Git仓库变化 |
| 5 | helm/ + environments/ |
ArgoCD读取Helm Chart和环境配置 |
| 6 | Kubernetes集群 | ArgoCD将变更同步到集群 |
简图:
text
git push
→ .github/workflows/(构建镜像+更新Git配置)
→ gitops/(ArgoCD/Flux检测到变化)
→ helm/ + environments/(读取配置并渲染)
→ K8s集群(自动同步)
注意:在GitOps模式下,scripts/deploy.sh 不会被调用。集群的部署由ArgoCD/Flux自己完成,不需要外部触发。
四、三种模式的执行顺序对比
| 顺序 | 纯手动模式 | CI/CD模式 | GitOps模式 |
|---|---|---|---|
| 1 | scripts/deploy.sh |
.github/workflows/ |
.github/workflows/(仅构建镜像) |
| 2 | clusters/ |
Dockerfile(构建镜像) |
镜像推送到GHCR |
| 3 | kubectl use-context |
scripts/deploy.sh |
更新Git仓库中的镜像Tag |
| 4 | environments/ |
clusters/ |
gitops/(ArgoCD检测变化) |
| 5 | helm/ |
environments/ |
helm/ + environments/ |
| 6 | K8s集群 | helm/ |
K8s集群自动同步 |
| 7 | - | K8s集群 | - |
关键区别:
-
纯手动:所有步骤由开发者手工执行
-
CI/CD:代码推送后自动构建镜像并调用
scripts/deploy.sh -
GitOps:CI只负责构建镜像和更新Git配置,集群通过ArgoCD/Flux自己“拉取”变更
五、总结与思考
6.1 核心洞察
-
编写顺序遵循“由静到动、由简到繁”的原则:
-
先有静态YAML(
k8s/),再有动态模板(helm/) -
先有环境配置(
environments/),再有集群配置(clusters/) -
先有手动脚本(
scripts/),再有自动化流水线(ci-cd/、gitops/)
-
-
执行顺序因部署模式而异:
-
手动模式:
scripts/→clusters/→environments/→helm/→ K8s -
CI/CD模式:
.github/workflows/→scripts/→ 同上 -
GitOps模式:
.github/workflows/→gitops/→ K8s(scripts/被跳过)
-
-
每个文件夹都解决了一个特定的痛点:
-
helm/解决了“静态YAML无法适应多环境”的问题 -
environments/解决了“不同环境需要不同参数”的问题 -
clusters/解决了“多集群连接信息管理”的问题 -
scripts/解决了“命令太长容易出错”的问题 -
ci-cd/解决了“手动部署太慢”的问题 -
gitops/解决了“集群状态与Git不一致”的问题
-
6.2 写给学习者的话
当你面对一个陌生的K8s项目时,不妨从文件夹结构入手,思考两个问题:
-
这个文件夹解决什么问题?(功能定位)
-
这个文件夹在整体架构中处于什么位置?(依赖关系)
理解了这两个问题,你就读懂了项目作者的设计思路。这也是从“会用工具”到“理解架构”的关键一步。
附录:各文件夹速查表
| 文件夹 | 编写顺序 | 执行顺序(手动) | 核心作用 |
|---|---|---|---|
| 应用代码+Dockerfile | 1 | - | 业务逻辑 + 容器化 |
docker-compose.yaml |
2 | - | 本地开发环境 |
k8s/ |
3 | - | 静态YAML参考(不参与部署) |
helm/ |
4 | 5 | 动态模板 + 默认值 |
environments/ |
5 | 4 | 多环境配置 |
clusters/ |
6 | 2 | 多集群配置 |
scripts/ |
7 | 1 | 一键部署脚本 |
ci-cd/ |
8 | - | CI/CD流水线定义 |
gitops/ |
9 | - | GitOps持续同步 |
本文基于开源项目 kubernetes-microservices 的分析整理而成。如有理解不当之处,欢迎交流指正
更多推荐



所有评论(0)