代码一推自动上线:EKS + CodePipeline + Argo CD 搭建 GitOps 实战

代码一推自动上线:EKS + CodePipeline + Argo CD 搭建 GitOps 实战

K8s 应用部署还在手写 kubectl apply 脚本?配置漂移查不出来?回滚得翻半天 Git log?

亚马逊云科技官博最近发了一篇实战文章:在中国区 EKS 上用 Code 家族(CodeCommit + CodePipeline + CodeBuild)+ Argo CD 搭一套完整的 GitOps CI/CD。代码一推,镜像自动构建,K8s 应用自动更新,全程不用手动敲命令。

这篇从痛点出发,走一遍完整搭建流程。

传统 CI/CD 的痛

先说为什么要 GitOps。传统 K8s 部署流程这几个问题你一定遇过:

  1. 手动脚本,出错难查deploy.sh 写了一堆 kubectl 命令,哪天参数写错了,排查半天
  2. 配置漂移:有人直接在集群里改了配置,Git 里的和实际跑的不一样,出问题了才发现
  3. 回滚困难:想回到上个版本,得找到上次的镜像 tag、对应的 YAML 文件,手动重新 apply
  4. 权限混乱:谁都能 kubectl 操作集群,改了什么没有审计记录

GitOps 的解法:Git 仓库是唯一真相来源。所有变更走 Git,Argo CD 自动同步到集群。

方案架构

scss 复制代码
开发者 → CodeCommit(代码仓库)
         ↓ (代码推送触发)
      CodePipeline(流水线编排)
         ↓
      CodeBuild(构建镜像) → ECR(镜像仓库)
         ↓ (更新 manifest 仓库镜像版本)
      CodeCommit(清单仓库)
         ↓ (Argo CD 监控变更)
      Argo CD → EKS(自动部署/更新)

两个 Git 仓库分开管:

  • 代码仓库(cicd-test-app):业务代码 + Dockerfile + buildspec.yml
  • 清单仓库(cicd-test-manifests):K8s deployment.yaml

核心组件

组件 作用
CodeCommit 托管 Git 仓库,代码变更的入口
CodePipeline 流水线编排,串联 CI 各阶段
CodeBuild 构建容器镜像,推送到 ECR
ECR 私有镜像仓库
Argo CD GitOps CD 工具,监控清单仓库并同步到集群
Amazon EKS 托管 K8s 集群

搭建步骤

1. 创建 EKS 集群

bash 复制代码
eksctl create cluster \
  --name gitops-demo \
  --region cn-north-1 \
  --nodegroup-name workers \
  --node-type t3.medium \
  --nodes 2

2. 创建两个 CodeCommit 仓库

bash 复制代码
# 应用代码仓库
aws codecommit create-repository \
  --repository-name cicd-test-app

# K8s 清单仓库
aws codecommit create-repository \
  --repository-name cicd-test-manifests

3. 准备应用代码

示例用 Go 写一个简单 HTTP 服务:

go 复制代码
package main

import (
    "fmt"
    "log"
    "net/http"
    "os"
)

const Version = "v1.0.0"

func handler(w http.ResponseWriter, r *http.Request) {
    hostname, _ := os.Hostname()
    fmt.Fprintf(w, "Hello from EKS! Version: %s | Host: %s\n",
        Version, hostname)
}

func main() {
    http.HandleFunc("/", handler)
    http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(http.StatusOK)
        fmt.Fprint(w, "OK")
    })
    log.Printf("Starting on :8080, version %s", Version)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Dockerfile(多阶段构建,最终镜像很小):

dockerfile 复制代码
FROM public.ecr.aws/docker/library/golang:1.22-alpine AS builder
WORKDIR /app
COPY main.go .
RUN go build -o server main.go

FROM public.ecr.aws/docker/library/alpine:latest
RUN apk --no-cache add ca-certificates
COPY --from=builder /app/server /root/
EXPOSE 8080
CMD ["/root/server"]

4. 配置 CodeBuild(buildspec.yml)

yaml 复制代码
version: 0.2
phases:
  pre_build:
    commands:
      - echo Logging in to ECR...
      - ECR_URI=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com.cn
      - aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_URI
      - VERSION=$(grep -oP 'const Version = "\K[^"]+' main.go)
  build:
    commands:
      - docker build -t $IMAGE_REPO_NAME:$VERSION .
      - docker tag $IMAGE_REPO_NAME:$VERSION $ECR_URI/$IMAGE_REPO_NAME:$VERSION
  post_build:
    commands:
      - docker push $ECR_URI/$IMAGE_REPO_NAME:$VERSION
      - echo Build completed, image tag $VERSION

5. 创建 CodePipeline

在控制台创建 Pipeline:

  • Source:关联 CodeCommit 的 cicd-test-app 仓库
  • Build:选择 CodeBuild 项目
  • 触发条件:代码推送到 main 分支自动触发

6. 准备 K8s 清单(deployment.yaml)

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cicd-demo
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: cicd-demo
  template:
    metadata:
      labels:
        app: cicd-demo
    spec:
      containers:
      - name: app
        image: <ACCOUNT_ID>.dkr.ecr.cn-north-1.amazonaws.com.cn/cicd-test-app:v1.0.0
        ports:
        - containerPort: 8080
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: cicd-demo-svc
spec:
  type: LoadBalancer
  selector:
    app: cicd-demo
  ports:
  - port: 80
    targetPort: 8080

7. 部署 Argo CD

bash 复制代码
# 安装 Argo CD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# 获取初始密码
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

# 暴露 UI
kubectl port-forward svc/argocd-server -n argocd 8080:443

8. 配置 Argo CD 应用

bash 复制代码
argocd app create cicd-demo \
  --repo https://git-codecommit.cn-north-1.amazonaws.com.cn/v1/repos/cicd-test-manifests \
  --path . \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace default \
  --sync-policy automated \
  --auto-prune \
  --self-heal

关键参数:

  • --sync-policy automated:检测到 Git 变更自动同步
  • --auto-prune:Git 里删了的资源,集群里也自动删
  • --self-heal:有人手动改了集群配置,自动恢复到 Git 定义的状态

实际工作流程

应用发新版本:

  1. 改 main.go 里的 Version = "v2.0.0"
  2. git push 到 CodeCommit
  3. CodePipeline 自动触发 → CodeBuild 构建 v2.0.0 镜像 → 推送到 ECR
  4. 更新清单仓库的 deployment.yaml 里的镜像 tag
  5. Argo CD 检测到清单变更 → 自动滚动更新 EKS 里的 Pod

回滚也简单:git revert 清单仓库到上个 commit,Argo CD 自动同步回旧版本。

这套方案好在哪

  1. 全自动化:代码推送到应用上线,分钟级完成,不用手动操作
  2. 配置不漂移--self-heal 确保集群状态永远和 Git 一致
  3. 回滚秒级:Git revert 一下就行,不用找旧镜像旧配置
  4. 审计完整:谁改了什么,Git log 里全有
  5. 权限收敛:开发者只需要 Git 权限,不需要直接访问 K8s 集群

踩坑提醒

  1. 中国区 ECR 域名 :是 .amazonaws.com.cn,不是 .amazonaws.com
  2. IRSA 权限:Argo CD 访问 CodeCommit 需要配 IRSA(IAM Roles for Service Accounts),别用明文密码
  3. 镜像版本更新:CodeBuild 构建完镜像后,还需要更新清单仓库的 tag。可以在 buildspec 里加个 git push 步骤,或者用 Argo CD Image Updater 自动检测新镜像
  4. Argo CD 同步频率:默认 3 分钟检查一次 Git 变更,想更快可以配 webhook

亚马逊云科技官博原文:aws.amazon.com/cn/blogs/ch... Amazon EKS:aws.amazon.com/cn/eks/ Argo CD:argo-cd.readthedocs.io/ CodePipeline:aws.amazon.com/cn/codepipe...

相关推荐
Freed&5 天前
阿里云 OSS 至 AWS S3 跨云迁移实施指南
阿里云·云计算·aws
故乡dee云7 天前
AWS CloudFront 使用教程:CDN 加速功能和网站部署优化
云计算·aws
国际云,接待11 天前
AWS RDS 备份与 PITR 恢复演练:从保留期、恢复命令到应用切换验证
运维·云计算·aws·灾难恢复·数据库备份·rds
国际云,接待13 天前
AWS账单防爆雷实战:Budgets、Cost Anomaly Detection与预算动作联动
人工智能·aws·twitter·finops·云成本·budgets
故乡dee云13 天前
AWS 月度账单怎么看?费用明细、扣款时间和结算规则说明
云计算·aws
xywww16815 天前
Claude Opus 5 API 接入实战:国内项目上线前的网络、Key、限流和排错清单
大数据·linux·网络·数据库·云计算·aws
Geek-Chow19 天前
ALB SSL policy conflict (AWS Load Balancer Controller)
网络协议·ssl·aws
2601_9557597220 天前
AWS 账号能转成企业账号吗?NiceCloud 把变更要点说清楚
云计算·aws
2601_9557598820 天前
AWS 一个邮箱能注册几个账号?NiceCloud 说明管理规则
云计算·aws
曾阿伦20 天前
Windows 下运行 Hadoop 并部署到 AWS EMR 指南
hadoop·windows·aws