代码一推自动上线: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...

相关推荐
亚马逊云开发者5 小时前
MySQL 实时入湖零运维?S3 Tables 两种方案实战
aws
亚马逊云开发者21 小时前
5000 台 IoT 设备的异常检测,全 Serverless 架构月成本几十美元——Lambda + DynamoDB + Step Functions 实战
aws
亚马逊云开发者21 小时前
WAF 误杀了正常请求怎么补数据?CloudFront + Lambda@Edge 双函数架构实战
aws
亚林瓜子1 天前
AWS EB使用自定义镜像
云计算·bug·aws·ami·fix·eb·al2023
长征coder1 天前
AWS-S2上传提示证书错误
aws
亚马逊云开发者2 天前
SDLC 过时了?从 2x 到 20x 效能的 AIDLC 转型实践 | Kiro + OpenClaw 实战
aws
亚马逊云开发者2 天前
从本地到云端 | OpenClaw Agent + Bedrock AgentCore SDK 部署全攻略
aws
Blue summer2 天前
使用AWS SSO + Terraform 管理AWS资源
云计算·aws·terraform
亚马逊云开发者3 天前
不用 Docker 也能跑 AI Agent | OpenClaw + Podman + EC2 Graviton + ECR 容器化部署全攻略
aws