从"我来部署"到"Git 自动部署"
从 CI/CD 演进到 GitOps,是现代云原生团队的必经之路。
一、为什么要从 CI/CD 进化到 GitOps?
传统 CI/CD 模式大致是:
bash
代码提交 → CI 构建镜像 → 推送镜像 → kubectl apply
问题很明显:
-
部署状态不可追溯
-
生产环境"漂移"(drift)
-
权限过大(CI 直接操作 K8s)
-
多集群部署极其痛苦
GitOps 的核心思想
**Git = 唯一事实源(Single Source of Truth)**
bash
Git 仓库状态 == 集群真实状态
而 ArgoCD,就是 GitOps 在 Kubernetes 领域的事实标准。
二、整体架构(Go + ArgoCD + GitOps)
- 全链路架构图(文字版)
css
Developer
│
▼
Git Push (Go Code)
│
▼
CI (GitHub Actions / GitLab CI)
│
├─ go test
├─ docker build
└─ push image
│
▼
GitOps Repo (K8s YAML / Helm / Kustomize)
│
▼
ArgoCD
│
▼
Kubernetes (Kind / Prod Cluster)
- 职责边界非常清晰
|-------------|--------------|
| 组件 | 只负责什么 |
| CI | 构建、测试、镜像推送 |
| GitOps Repo | 声明期望状态 |
| ArgoCD | 同步 Git → K8s |
| K8s | 运行状态 |
三、示例
- main.go
go
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
// 启动 HTTP 服务器,监听 8080 端口
r.Run(":8080")
}
- Dockerfile
apache
# 第一阶段:编译阶段
FROM golang:1.25.5-alpine AS builder
# 设置环境变量(国内环境建议开启代理加快下载速度)
ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn,direct
# 设置工作目录
WORKDIR /app
# 复制依赖文件并下载(利用 Docker 缓存)
COPY go.mod go.sum ./
RUN go mod download
# 复制源代码并编译
COPY . .
# CGO_ENABLED=0 确保静态链接,能在 alpine 下运行
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main .
# 第二阶段:运行阶段
FROM alpine:latest
# 安装基础工具(可选)
RUN apk --no-cache add ca-certificates
WORKDIR /root/
# 从编译阶段复制二进制文件
COPY --from=builder /app/main .
# 暴露 Gin 和 Prometheus 监听的端口
EXPOSE 8080
# 运行应用
CMD ["./main"]
四、CI:只做一件事------构建并推镜像
- Gitlab CI
bash
docker-build:
image: "172.16.10.185:5000/docker:20.10.16"
stage: build
script:
- docker build -t imoowi/golang_per_day:$CI_COMMIT_TAG --cpu-shares 2 .
- docker push imoowi/golang_per_day:$CI_COMMIT_TAG
tags:
- runner-pipeline-name
only:
- tag
- 注意:CI 不再 kubectl apply, 这是GitOps 的第一条铁律。
五、GitOps仓库设计
- 推荐的结构
powershell
gitops-repo/
├── apps/
│ └── gin-app/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
└── argocd/
└── gin-app.yaml
- Deployment
makefile
apiVersion: apps/v1
kind: Deployment
metadata:
name: gin-app
namespace: codee-jun
spec:
replicas: 1
selector:
matchLabels:
app: gin-app
template:
metadata:
labels:
app: gin-app
spec:
containers:
- name: gin-app
image: imoowi/golang_per_day:day75
imagePullPolicy: IfNotPresent # 优先使用本地 load 进去的镜像
ports:
- containerPort: 8080
六、ArgoCD安装(Kind示例)
ruby
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
#端口转发访问:
kubectl port-forward svc/argocd-server -n argocd 8080:443
七、ArgoCD Application(核心)
bash
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: gin-app
namespace: argocd
spec:
project: default
source:
repoURL: https://gitlab.domain.com/imoowi/golang_per_day
path: apps/gin-app
targetRevision: main
destination:
server: https://kubernetes.default.svc
namespace: codee-jun
syncPolicy:
automated:
prune: true
selfHeal: true
这三行是灵魂:
bash
automated:
prune: true
selfHeal: true
意味着:
-
Git 删除 = K8s 删除
-
人工改集群 = ArgoCD 自动修正
八、完整发布流程
- 开发提交 Go 代码 2. CI 构建镜像并推送 3. 修改 GitOps Repo 中镜像 tag 4. Git push 5. ArgoCD 自动同步 6. Pod 滚动更新完成
九、GitOps 带来的工程化收益
- 和传统 CI/CD 对比
|------|---------|------------|
| 纬度 | 传统CI/CD | GitOps |
| 状态可见 | ❌ | ✅ |
| 回滚 | 麻烦 | git revert |
| 多集群 | 地狱 | 天然支持 |
| 审计 | 几乎没有 | Git天生 |
| 权限 | CI超级大 | ArgoCD最小化 |
十、总结
CI 负责构建,Git 声明期望,ArgoCD 保证一致性
友情链接:加班费计算器(vx小程序搜索"加班计")
*源码地址*
评论区给
如果您喜欢这篇文章,请您(点赞、分享、亮爱心),万分感谢!