侧边栏壁纸
  • 累计撰写 89 篇文章
  • 累计创建 31 个标签
  • 累计收到 21 条评论

目 录CONTENT

文章目录

GitLab CI/CD + ArgoCD GitOps 现代化 DevOps 流水线实战:从代码提交到 K8s 全自动部署

Administrator
2026-05-06 / 0 评论 / 0 点赞 / 0 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

📌 前置知识:本文默认读者具备 Docker 容器化、Kubernetes 基础操作经验,熟悉 Shell 脚本编写。文中所有示例基于 GitLab CI/CD 16.x、ArgoCD 2.10+、Kubernetes 1.29+ 环境。

一、引言:从"人肉部署"到 GitOps 的演进之路

在微服务架构时代,一个项目往往由十几个甚至几十个服务组成。如果仍然通过"手动打包 → 手动上传 → 手动部署"的方式发布,不仅效率低下,更会带来不可控的人为失误风险:

  • 生产环境与测试环境配置不一致,导致"在我机器上明明是好的"经典问题
  • 回滚依赖备份文件和人工记忆,容易出错且无法追溯
  • 不同开发人员操作习惯不同,线上环境逐渐变得不可复现

GitOps 应运而生——它的核心思想只有一句话:将 Git 仓库作为系统单一真相来源(Single Source of Truth)。所有部署配置、环境参数、基础设施代码全部存储在 Git 中,任何变更都必须通过 Git 操作来完成,从而实现:

  • 环境一致性:所有环境的配置均来自同一套 Git 定义
  • 版本可控:每一次部署都有对应的 Git commit 可追溯
  • 一键回滚:回滚即 git revert,无需手动操作
  • 审计友好:Git 操作日志天然就是完整的审计记录

本文将手把手搭建一套完整的 GitOps 流水线:

代码提交(GitLab)
    ↓ git push
GitLab CI/CD (构建 + 镜像推送)
    ↓ push image to Harbor
ArgoCD (监听 Git 仓库 → 自动同步到 K8s)
    ↓ kubectl apply
Kubernetes 集群 (各环境 Namespace)

二、环境准备:集群与基础设施搭建

2.1 Kubernetes 集群准备

使用 kubeadm 搭建三节点集群(1 个 Master + 2 个 Worker),最低配置建议:

# 节点规划
master: 2C4G Ubuntu 22.04 LTS  # 10.0.0.10
worker1: 2C4G Ubuntu 22.04 LTS # 10.0.0.11
worker2: 2C4G Ubuntu 22.04 LTS # 10.0.0.12

初始化 Master 节点:

# 所有节点安装依赖
sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl

# 安装 containerd
sudo apt-get install -y containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd

# 安装 kubeadm/kubelet/kubectl
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

# Master 初始化(Pod CIDR 使用 Calico 默认值)
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12

# 配置 kubectl
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 安装网络插件 Calico
kubectl apply -f https://docs.projectcalico.com/manifests/calico.yaml

2.2 GitLab 部署(支持 Runner)

使用 Docker Compose 部署 GitLab CE:

# docker-compose-gitlab.yml
version: '3.8'
services:
  gitlab:
    image: gitlab/gitlab-ce:16.8.0-ce.0
    container_name: gitlab
    hostname: gitlab.example.com
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://10.0.0.20'
        gitlab_rails['gitlab_shell_ssh_port'] = 2222
        nginx['listen_port'] = 80
        postgresql['shared_buffers'] = 256MB
        redis['maxmemory'] = 256mb
    ports:
      - "80:80"
      - "2222:22"
    volumes:
      - /data/gitlab/config:/etc/gitlab
      - /data/gitlab/logs:/var/log/gitlab
      - /data/gitlab/data:/var/opt/gitlab
    restart: unless-stopped
    privileged: true
mkdir -p /data/gitlab/{config,logs,data}
docker-compose -f docker-compose-gitlab.yml up -d

⚠️ 注意:首次启动需要等待 5~10 分钟初始化,完成后访问 http://10.0.0.20 设置 root 密码。

2.3 Harbor 私有镜像仓库部署

Harbor 是企业级 Docker 镜像仓库,支持镜像安全扫描、RBAC 权限控制、镜像复制等功能,是 GitOps 流水线的中转站。

# docker-compose-harbor.yml (Harbor 2.10)
version: '3.8'
services:
  harbor:
    image: goharbor/harbor-core:v2.10.1
    container_name: harbor
    restart: always
    volumes:
      - /data/harbor/data:/data
      - ./ harbor.cfg:/etc/harbor/harbor.cfg:ro
    network_mode: host
    command: core

Harbor 配置文件 harbor.cfg

hostname = harbor.example.com
harbor_admin_password = Harbor12345
db_password = root123
# 生产环境务必配置 HTTPS
# ssl_cert = /data/cert/server.crt
# ssl_cert_key = /data/cert/server.key

部署后访问 Harbor,创建一个名为 spring-boot-app 的公开项目(用于存放应用镜像)。

三、GitLab CI/CD 流水线设计

3.1 项目结构

spring-boot-app/
├── .gitlab-ci.yml          # CI/CD 流水线配置
├── src/                    # 源代码(Spring Boot 项目)
├── docker/
│   └── Dockerfile          # 多阶段构建 Dockerfile
├── k8s/                    # K8s 部署配置(ArgoCD 监听此目录)
│   ├── base/               # 基础配置(deployment、service 等)
│   │   ├── deployment.yaml
│   │   ├── service.yaml
│   │   └── ingress.yaml
│   └── overlays/           # 环境差异配置
│       ├── dev/
│       │   └── kustomization.yaml
│       ├── test/
│       │   └── kustomization.yaml
│       └── prod/
│           └── kustomization.yaml
└── scripts/
    └── docker-build.sh

3.2 Docker 多阶段构建优化

生产级 Dockerfile 最小化镜像体积,提升冷启动速度:

# docker/Dockerfile
# ============ 构建阶段 ============
FROM maven:3.9-eclipse-temurin-21-alpine AS builder
WORKDIR /build

# 利用 Maven 缓存加速重复构建
COPY pom.xml .
RUN mvn dependency:go-offline -B

COPY src ./src
RUN mvn clean package -DskipTests -B

# ============ 运行阶段(极简镜像)===========
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app

# 安全最佳实践:以非 root 用户运行
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

# 只复制最终的 jar 包(不包括源码和构建产物)
COPY --from=builder /build/target/*.jar app.jar

# 开放非特权端口(1024 以下端口需要 root)
ENV JAVA_OPTS="-Xms256m -Xmx512m -XX:+UseG1GC"
EXPOSE 8080

# 使用 exec form 正确处理信号(PID 1)
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

💡 优化要点

  • 使用 eclipse-temurin:21-jre-alpine(~180MB)而非完整 JDK 镜像(~500MB)
  • 多阶段构建确保最终镜像不包含 Maven 源码和缓存
  • USER appuser 遵循最小权限原则
  • EXPOSE 8080 声明应用端口(而非默认的 8080)

3.3 GitLab CI/CD 全流水线配置

.gitlab-ci.yml 是 GitLab 的流水线定义文件,使用 stages 分阶段执行:

# .gitlab-ci.yml
variables:
  # 镜像仓库地址
  HARBOR_URL: "harbor.example.com"
  HARBOR_PROJECT: "spring-boot-app"
  IMAGE_NAME: "${HARBOR_URL}/${HARBOR_PROJECT}/${CI_PROJECT_NAME}:${CI_COMMIT_SHORT_SHA}"
  IMAGE_TAG_LATEST: "${HARBOR_URL}/${HARBOR_PROJECT}/${CI_PROJECT_NAME}:latest"

stages:
  - build
  - test
  - package
  - deploy

# ============ Stage 1: 代码编译 ============
maven-build:
  stage: build
  image: maven:3.9-eclipse-temurin-21-alpine
  cache:
    key: "${CI_COMMIT_REF_SLUG}-maven"
    paths:
      - .m2/repository
  script:
    - mvn clean compile -B
  artifacts:
    paths:
      - target/classes/
    expire_in: 1 hour
  only:
    - main
    - develop
    - merge_requests

# ============ Stage 2: 单元测试 + 代码质量 ============
maven-test:
  stage: test
  image: maven:3.9-eclipse-temurin-21-alpine
  cache:
    key: "${CI_COMMIT_REF_SLUG}-maven"
    paths:
      - .m2/repository
  script:
    - mvn test -B
    # 生成测试覆盖率报告
    - mvn jacoco:report -B
  coverage: '/Total.*?([0-9]{1,3})%/'
  artifacts:
    when: always
    reports:
      junit: target/surefire-reports/TEST-*.xml
      coverage_report:
        coverage_format: cobertura
        path: target/site/jacoco/jacoco.xml
  only:
    - main
    - develop
    - merge_requests

# ============ Stage 3: Docker 镜像构建 + 安全扫描 ============
docker-build:
  stage: package
  image: docker:24-dind
  services:
    - docker:24-dind
  variables:
    DOCKER_HOST: tcp://docker:2376
    DOCKER_TLS_CERTDIR: "/certs"
    DOCKER_TLS_VERIFY: "1"
    DOCKER_CERT_PATH: "$DOCKER_HOST/certs/client"
  before_script:
    # 登录 Harbor(使用 GitLab CI/CD 变量存储凭证)
    - echo "$HARBOR_PASSWORD" | docker login $HARBOR_URL -u "$HARBOR_USERNAME" --password-stdin
  script:
    - cd docker
    - docker build --network=host -t $IMAGE_NAME -t $IMAGE_TAG_LATEST -f Dockerfile ..
    # Trivy 安全扫描(检测 CVE 漏洞)
    - docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
        aquasec/trivy:latest image --severity HIGH,CRITICAL --exit-code 1 --no-progress $IMAGE_NAME
    # 推送镜像到 Harbor
    - docker push $IMAGE_NAME
    - docker push $IMAGE_TAG_LATEST
    # 清理本地镜像节省空间
    - docker rmi $IMAGE_NAME $IMAGE_TAG_LATEST || true
  after_script:
    - docker logout $HARBOR_URL || true
  only:
    - main
    - develop
  tags:
    - dockerRunner

# ============ Stage 4: K8s 配置更新(触发 ArgoCD 同步)===========
k8s-deploy:
  stage: deploy
  image: bitnami/kubectl:1.29
  before_script:
    # 配置 kubectl 访问 K8s 集群
    - kubectl config set-cluster gitops --server=https://10.0.0.10:6443 --insecure-skip-tls-verify=true
    - kubectl config set-credentials gitlab-ci --token=$K8S_DEPLOY_TOKEN
    - kubectl config set-context gitops --cluster=gitops --user=gitlab-ci
    - kubectl config use-context gitops
    # 验证连接
    - kubectl cluster-info
  script:
    # 更新 k8s 配置文件中的镜像版本(Kustomize 方式)
    - cd k8s/overlays/${CI_COMMIT_REF_NAME}-env || cd k8s/overlays/dev
    - |
      # 替换镜像版本为新构建的 SHA
      sed -i "s|image: .*|image: ${IMAGE_NAME}|" base/deployment.yaml
    # 将 k8s 配置变更提交到 GitOps 仓库
    - git config user.email "gitlab-ci@${CI_PROJECT_NAME}.gitlab"
    - git config user.name "GitLab CI"
    - git add .
    - git diff --staged || true
    - git commit -m "[CI] Update image to ${CI_COMMIT_SHORT_SHA} via pipeline" || echo "No changes to commit"
    - git push https://gitlab-ci:${GITOPS_TOKEN}@${CI_REPOSITORY_URL#*://} HEAD:main || echo "Push skipped"
  only:
    - main
    - develop
  when: manual  # 生产环境手动触发部署,避免自动部署风险
  tags:
    - k8sRunner

3.4 GitLab Runner 注册

Runner 是实际执行 CI/CD 任务的 Agent,注册一个专门用于 Docker 构建的 Runner:

# 在 GitLab 服务器上执行
gitlab-runner register \
  --non-interactive \
  --url "http://10.0.0.20" \
  --registration-token "YOUR_REGISTRATION_TOKEN" \
  --executor "docker" \
  --docker-image "docker:24-dind" \
  --docker-privileged \
  --docker-volumes "/certs/client" \
  --description "docker-builder-runner" \
  --tag-list "dockerRunner" \
  --locked="false"

🔒 安全提醒:Docker-in-Docker(dind)模式需要 --docker-privileged,这赋予容器privileged权限。生产环境建议使用 Kaniko 替代 dind,避免特权容器带来的安全风险:

docker-build-kaniko:
  stage: package
  image: gcr.io/kaniko-project/executor:debug
  script:
    - echo "$HARBOR_PASSWORD" | kaniko --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/docker/Dockerfile --destination $IMAGE_NAME
  # 不需要 privileged 模式,更安全

四、ArgoCD GitOps 部署

4.1 ArgoCD 安装

ArgoCD 是声明式的 GitOps 持续交付工具,监听 Git 仓库中的 K8s 配置,自动将集群状态同步到 Git 定义的期望状态。

# 安装 ArgoCD(命名空间级别安装)
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.10.2/manifests/install.yaml

# 安装 ArgoCD CLI
curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/download/v2.10.2/argocd-linux-amd64
chmod +x /usr/local/bin/argocd

# 访问 ArgoCD Server(NodePort 暴露)
kubectl patch svc argocd-server -n argocd -p '{"spec":{"type":"NodePort"}}'
kubectl get svc argocd-server -n argocd

# 获取初始密码
argocd admin initial-password -n argocd

4.2 应用声明(Application)

ArgoCD 的核心是 Application CRD,它定义了"哪个 Git 仓库的哪个路径"映射到"哪个 K8s 集群的哪个命名空间":

# argocd-application-springboot.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: spring-boot-app
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    # GitOps 仓库地址
    repoURL: https://gitlab.example.com/your-group/spring-boot-app.git
    targetRevision: main
    path: k8s/overlays/prod
    # Kustomize 自动处理环境差异化
    kustomize:
      images:
        # ArgoCD 会自动替换镜像版本(与 GitLab CI 中的 sed 等效)
        - harbor.example.com/spring-boot-app/spring-boot-app=spring-boot-app:latest
  destination:
    server: https://kubernetes.default.svc
    namespace: spring-boot-prod
  syncPolicy:
    automated:
      # 自动同步(Push 触发)
      selfHeal: true   # 集群状态被手动修改时自动恢复
      prune: true      # 自动删除 Git 中已不存在的资源
    syncOptions:
      - CreateNamespace=true
      - PrunePropagationPolicy=foreground
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

应用这个 Application:

kubectl apply -f argocd-application-springboot.yaml
argocd app get spring-boot-app  # 查看应用同步状态

4.3 Kustomize 环境差异化配置

Kustomize 是 Kubernetes 原生的配置管理工具,无需模板即可实现环境差异化:

# k8s/base/deployment.yaml(基础配置)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-boot-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: spring-boot-app
  template:
    metadata:
      labels:
        app: spring-boot-app
    spec:
      containers:
        - name: app
          image: harbor.example.com/spring-boot-app/spring-boot-app:latest
          ports:
            - containerPort: 8080
          env:
            - name: JAVA_OPTS
              value: "-Xms256m -Xmx512m"
          livenessProbe:
            httpGet:
              path: /actuator/health/liveness
              port: 8080
            initialDelaySeconds: 60
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /actuator/health/readiness
              port: 8080
            initialDelaySeconds: 30
            periodSeconds: 5
          resources:
            requests:
              cpu: 250m
              memory: 256Mi
            limits:
              cpu: 1000m
              memory: 512Mi
# k8s/overlays/prod/kustomization.yaml(生产环境)
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - ../../base/deployment.yaml
  - ../../base/service.yaml
  - ../../base/ingress.yaml

# 生产环境差异化配置
commonLabels:
  env: prod

images:
  - name: spring-boot-app
    newName: harbor.example.com/spring-boot-app/spring-boot-app
    newTag: latest  # ArgoCD 自动更新此字段

patches:
  # 副本数增加到 5
  - patch: |-
      - op: replace
        path: /spec/replicas
        value: 5
    target:
      kind: Deployment
  # 生产环境更高内存限制
  - patch: |-
      - op: replace
        path: /spec/template/spec/containers/0/resources/limits/memory
        value: "1Gi"
    target:
      kind: Deployment
  # 生产环境配置副本数上限(HorizontalPodAutoscaler)
  - patch: |-
      apiVersion: autoscaling/v2
      kind: HorizontalPodAutoscaler
      metadata:
        name: spring-boot-app-hpa
      spec:
        maxReplicas: 10
        minReplicas: 3
        scaleTargetRef:
          apiVersion: apps/v1
          kind: Deployment
          name: spring-boot-app
    target:
      kind: Deployment

开发环境和测试环境只需覆盖副本数、资源限制等即可:

# k8s/overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - ../../base/deployment.yaml
  - ../../base/service.yaml

commonLabels:
  env: dev

images:
  - name: spring-boot-app
    newTag: dev-latest

patches:
  - patch: |-
      - op: replace
        path: /spec/replicas
        value: 1
    target:
      kind: Deployment

五、生产级安全加固

5.1 GitLab CI/CD 敏感信息管理

切勿将密码和密钥直接写入 .gitlab-ci.yml。使用 GitLab CI/CD Variables:

# GitLab Web UI: Settings → CI/CD → Variables
HARBOR_USERNAME = registry-user
HARBOR_PASSWORD = registry-password-xxx  # Masked,输出时自动隐藏
K8S_DEPLOY_TOKEN = k8s-deploy-token-xxx
GITOPS_TOKEN = gitops-deploy-token-xxx

5.2 Kubernetes Secret 安全

所有密钥使用 Sealed Secrets 或 External Secrets 管理,禁止明文存储:

# external-secrets-pull-based.yaml(External Secrets Operator)
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: harbor-credentials
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: ClusterSecretStore
  target:
    name: harbor-credentials  # ArgoCD 创建的 Secret 名称
    creationPolicy: Owner
  data:
    - secretKey: username
      remoteRef:
        key: production/harbor
        property: username
    - secretKey: password
      remoteRef:
        key: production/harbor
        property: password

5.3 Pod 安全标准(PSS)

强制执行 Pod Security Standards:

# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: spring-boot-prod
  labels:
    # 强制执行 Restricted 策略(禁止 privileged 容器、root 用户等)
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: v1.29
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

5.4 网络策略

使用 Kubernetes NetworkPolicy 实现 Pod 级别的网络隔离:

# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: spring-boot-app-netpol
  namespace: spring-boot-prod
spec:
  podSelector:
    matchLabels:
      app: spring-boot-app
  policyTypes:
    - Ingress
    - Egress
  ingress:
    # 仅允许来自 Ingress Controller 的流量
    - from:
        - namespaceSelector:
            matchLabels:
              name: ingress-nginx
      ports:
        - protocol: TCP
          port: 8080
  egress:
    # 仅允许访问必要的外部服务
    - to:
        - namespaceSelector:
            matchLabels:
              name: redis
        - namespaceSelector:
            matchLabels:
              name: mysql
        - namespaceSelector:
            matchLabels:
              name: elasticsearch
      ports:
        - protocol: TCP
          port: 6379
        - protocol: TCP
          port: 3306
        - protocol: TCP
          port: 9200
    # 允许 DNS 解析
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/name: kube-dns
      ports:
        - protocol: UDP
          port: 53

六、完整 GitOps 流程演示

6.1 开发人员提交流程

# 1. 开发人员提交代码
git checkout -b feature/new-api
git add src/main/java/com/example/Service.java
git commit -m "feat: add new API endpoint"
git push origin feature/new-api

# 2. 创建 Merge Request,触发 CI 测试流水线
# GitLab 自动运行单元测试、集成测试

# 3. 合并到 main 分支
# GitLab CI/CD 自动执行:
#   [build] → [test] → [package: docker build + trivy scan] → [deploy: git push k8s config]

# 4. ArgoCD 检测到 Git 仓库变更,自动同步到 K8s 集群
#   Git 仓库变更 → ArgoCD 发现 diff → 自动 apply 或手动 sync

6.2 ArgoCD CLI 常用命令

# 查看所有应用
argocd app list

# 查看应用详情(同步状态、健康状态、资源列表)
argocd app get spring-boot-app

# 手动同步(当自动同步策略未触发时)
argocd app sync spring-boot-app

# 查看资源健康状态
argocd app resources spring-boot-app

# 回滚到指定版本
argocd app rollback spring-boot-app

# 手动触发镜像更新(无需修改 Git)
argocd app set spring-boot-app --kustomize-images harbor.example.com/spring-boot-app/spring-boot-app:v1.2.3
argocd app sync spring-boot-app

6.3 流水线执行日志分析

当流水线失败时,重点检查以下环节:

# 1. Maven 构建失败:检查 pom.xml 依赖和 Java 版本
# 典型错误:Spring Boot 3.x 需要 Java 17+,但 Runner 使用 Java 11
# 解决:指定 Docker 镜像为 maven:3.9-eclipse-temurin-21-alpine

# 2. Docker build 失败:检查 Dockerfile 路径和构建上下文
# 典型错误:COPY 指令找不到文件
# 解决:确认 docker build -f docker/Dockerfile .. 的上下文正确

# 3. Trivy 安全扫描失败:检查镜像是否包含已知高危漏洞
# 典型错误:扫描到 CRITICAL 漏洞(CVSS ≥ 9.0)
# 解决:更新基础镜像版本,或在 .gitlab-ci.yml 中添加 --ignore-unfixed

# 4. ArgoCD 同步失败:检查 RBAC 权限和 Kustomize 配置
# 典型错误:HPA 补丁格式不正确
# 解决:验证 Kustomize patches 语法
kubectl kustomize k8s/overlays/prod | kubectl apply --dry-run=server

七、监控与可观测性

7.1 ArgoCD 内置监控

ArgoCD 自动收集以下指标(通过 Prometheus 抓取):

# 关键指标
argocd_app_info                    # 应用基本信息
argocd_app_sync_status            # 同步状态(Synced/OutOfSync)
argocd_app_health_status          # 健康状态(Healthy/Degraded)
argocd_app_sync_total             # 同步次数统计
argocd_app_sync_duration_seconds  # 同步耗时
argocd_app_k8s_request_total      # K8s API 请求量

Grafana Dashboard 导入 ID:14584(ArgoCD 官方 Dashboard)。

7.2 与 Spring Boot Actuator 集成

确保 Spring Boot 应用暴露 Actuator 端点,ArgoCD 和 Prometheus 即可监控应用状态:

# application-prod.yml
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
      base-path: /actuator
  endpoint:
    health:
      show-details: always
      probes: true  # K8s 存活/就绪探针依赖
  metrics:
    tags:
      application: ${spring.application.name}

八、常见问题与排查

问题现象排查思路解决方案
ArgoCD 始终处于 OutOfSync检查 Git 仓库可达性和 token 权限验证 deploy token 的 read_repository 权限
Docker build 缓存未命中检查 COPY 指令顺序将依赖文件(pom.xml)COPY 放在源码 COPY 之前
Pod 启动失败(CrashLoopBackOff)kubectl logs + kubectl describe pod检查镜像拉取、内存限制、JVM 参数
Kustomize patches 不生效kubectl kustomize 本地验证检查 patch 路径和 op 类型
GitLab Runner 任务排队检查 Runner 并发数配置在 GitLab Settings → CI/CD → Runners 增加并发数
Trivy 扫描阻断流水线确认是否为已知 CVE更新基础镜像,或添加 --ignore-unfixed 忽略未修复漏洞

九、完整架构总结

┌──────────────────────────────────────────────────────────────────┐
│                      GitLab (代码仓库 + CI/CD)                    │
│  代码提交 → 自动触发流水线 → Maven构建 → Docker镜像构建 → Trivy扫描 │
│       ↓ push image                                                │
│  Harbor 私有镜像仓库                                              │
│  (harbor.example.com)                                            │
└──────────────────────────────────────────────────────────────────┘
                                ↓
┌──────────────────────────────────────────────────────────────────┐
│                   GitOps 仓库 (k8s 配置文件)                       │
│  k8s/overlays/dev | test | prod (Kustomize)                      │
│  当 GitLab CI 更新镜像版本时,GitOps 仓库同步更新                  │
└──────────────────────────────────────────────────────────────────┘
                                ↓
┌──────────────────────────────────────────────────────────────────┐
│                        ArgoCD (GitOps 引擎)                       │
│  持续监听 GitOps 仓库 → 检测到 diff → 自动同步到 K8s 集群          │
│  支持:自动同步、手动同步、回滚、健康检查、重试机制                  │
└──────────────────────────────────────────────────────────────────┘
                                ↓
┌──────────────────────────────────────────────────────────────────┐
│                      Kubernetes 集群                              │
    │  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐               │
    │  │  dev NS     │ │  test NS   │ │  prod NS   │               │
    │  │  1 replica  │ │  2 replicas │ │  5 replicas│               │
    │  │  256Mi mem  │ │  512Mi mem  │ │  1Gi mem   │               │
    │  └─────────────┘ └─────────────┘ └─────────────┘               │
│  HPA 自动扩缩容 + NetworkPolicy 网络隔离 + PSS 安全策略            │
└──────────────────────────────────────────────────────────────────┘
                                ↓
┌──────────────────────────────────────────────────────────────────┐
│                    监控层 (Prometheus + Grafana)                 │
│  应用指标:Actuator/Prometheus | 基础设施:node-exporter          │
│  GitOps 指标:ArgoCD 内置 | 日志:ELK Stack                       │
└──────────────────────────────────────────────────────────────────┘

🎯 核心价值:整个流水线中,开发人员只需关注代码提交,从镜像构建、安全扫描、配置管理到集群部署全部自动化完成,任何操作都有 Git 记录可追溯,环境一致性得到根本保障。


相关标签Docker Kubernetes GitLab ArgoCD GitOps CI/CD Kustomize Harbor

前置文章:建议配合阅读《Kubernetes 实战:将 Spring Boot 3.x 微服务部署到 K8s 集群全攻略》

0

评论区