从“我来部署”到“Git 自动部署”

从 CI/CD 演进到 GitOps,是现代云原生团队的必经之路。

一、为什么要从 CI/CD 进化到 GitOps?

传统 CI/CD 模式大致是:

代码提交 → CI 构建镜像 → 推送镜像 → kubectl apply

问题很明显:

  • 部署状态不可追溯

  • 生产环境“漂移”(drift)

  • 权限过大(CI 直接操作 K8s)

  • 多集群部署极其痛苦

GitOps 的核心思想

**Git = 唯一事实源(Single Source of Truth)**
Git 仓库状态 == 集群真实状态

ArgoCD,就是 GitOps 在 Kubernetes 领域的事实标准。

二、整体架构(Go + ArgoCD + GitOps)

1. 全链路架构图(文字版)

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)

2. 职责边界非常清晰

组件
只负责什么
CI
构建、测试、镜像推送
GitOps Repo
声明期望状态
ArgoCD
同步 Git → K8s
K8s
运行状态

三、示例

1. main.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")
}

2. Dockerfile

# 第一阶段:编译阶段
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:只做一件事——构建并推镜像

1. Gitlab CI

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

2. 注意:CI 不再 kubectl apply, 这是GitOps 的第一条铁律。

五、GitOps仓库设计

1. 推荐的结构

gitops-repo/
├── apps/
│   └── gin-app/
│       ├── deployment.yaml
│       ├── service.yaml
│       └── kustomization.yaml
└── argocd/
    └── gin-app.yaml

2. Deployment

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示例)

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(核心)

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

这三行是灵魂:

automated:

  prune: true

  selfHeal: true

意味着:

  • Git 删除 = K8s 删除

  • 人工改集群 = ArgoCD 自动修正

八、完整发布流程

1. 开发提交 Go 代码 2. CI 构建镜像并推送 3. 修改 GitOps Repo 中镜像 tag 4. Git push 5. ArgoCD 自动同步 6. Pod 滚动更新完成

九、GitOps 带来的工程化收益

1. 和传统 CI/CD 对比

纬度
传统CI/CD
GitOps
状态可见
回滚
麻烦
git revert
多集群
地狱
天然支持
审计
几乎没有
Git天生
权限
CI超级大
ArgoCD最小化

十、总结

CI 负责构建,Git 声明期望,ArgoCD 保证一致性


友情链接:加班费计算器(vx小程序搜索“加班计”)


*源码地址*

评论区给

如果您喜欢这篇文章,请您(点赞、分享、亮爱心),万分感谢!

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐