每日一Go-75、CI/CD 到 K8s:云原生ArgoCD / GitOps 全流程实战(Go + Gin)

从"我来部署"到"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)

  1. 全链路架构图(文字版)
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)
  1. 职责边界非常清晰

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

三、示例

  1. 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")
}
  1. 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:只做一件事------构建并推镜像

  1. 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
  1. 注意:CI 不再 kubectl apply, 这是GitOps 的第一条铁律。

五、GitOps仓库设计

  1. 推荐的结构
powershell 复制代码
gitops-repo/
├── apps/
│   └── gin-app/
│       ├── deployment.yaml
│       ├── service.yaml
│       └── kustomization.yaml
└── argocd/
    └── gin-app.yaml
  1. 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 自动修正

八、完整发布流程

  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小程序搜索"加班计")


*源码地址*

评论区给

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

相关推荐
阿里云云原生2 天前
AI 开发新常态:当 Cursor、Claude、Codex 并行,如何统一管理散落的 Skill 资产?
云原生·ai编程
探索云原生3 天前
K8s 1.36 这个 GA 特性,把 initContainer 拉模型的 hack 干掉了
ai·云原生·kubernetes
Java之美3 天前
从edge-trigger到level-trigger,谈谈 Kubernetes controller 的开发范式
云原生
阿里云云原生3 天前
深度解构:当 Append-only 的 SLS 遇上 Update/Delete,是如何实现设计权衡的?
云原生
宋均浩4 天前
# Docker 镜像瘦身实战:从 1.2G 到 80MB 的五个优化步骤
ci/cd·docker
Java之美4 天前
一次k8s升级引发的DevicePlugin注册失败
云原生·kubernetes
秋播4 天前
nerdctl推送rancher本地镜像到harbor
云原生
阿里云云原生5 天前
告别冗长链路!Kafka × Table Bucket 实现开放表格式零 ETL 实时入湖
云原生·kafka
SelectDB5 天前
秒级弹性、最高降本 70%:SelectDB Serverless 如何重塑云数仓资源效率
大数据·后端·云原生
秋播8 天前
国内本地WSL2编译rancher源码
云原生