CI/CD实战 - 一行代码自动上线,GitHub Actions + Docker + K8S全搞定!⚡

6 阅读6分钟

第14天:CI/CD实战 - 一行代码自动上线,GitHub Actions + Docker + K8S全搞定!⚡

一、最简单的CI/CD流水线(3步上线)

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

传统发布 vs 现代CI/CD:

传统:
代码写完 → 打包 → 传给运维 → 登录服务器 → 停服务 → 上传 → 启动 → 祈祷 🙏

CI/CD:
代码push → 自动构建 → 自动测试 → 自动部署 → 自动通知 ✅

二、10分钟搭建完整流水线

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

步骤1:GitHub仓库配置

  1. 打开你的GitHub仓库
  2. 点 Settings → Secrets and variables → Actions
  3. 添加这些密钥:
    • DOCKER_USERNAME:Docker Hub用户名
    • DOCKER_PASSWORD:Docker Hub密码
    • KUBECONFIG:K8S配置文件(base64编码)

步骤2:创建CI/CD配置文件

在项目根目录创建:.github/workflows/deploy.yml

name: Deploy to Kubernetes

on:
  push:
    branches: [ main ]  # main分支推送时触发
  pull_request:
    branches: [ main ]  # PR时也触发测试

jobs:
  # 1. 测试阶段
  test:
    runs-on: ubuntu-latest
    steps:
    - name: 检出代码
      uses: actions/checkout@v3
    
    - name: 设置JDK
      uses: actions/setup-java@v3
      with:
        java-version: '17'
    
    - name: 运行测试
      run: |
        mvn clean test
        echo "✅ 测试通过!"

  # 2. 构建镜像阶段
  build:
    needs: test  # 依赖test阶段
    runs-on: ubuntu-latest
    
    steps:
    - name: 检出代码
      uses: actions/checkout@v3
    
    - name: 设置JDK
      uses: actions/setup-java@v3
      with:
        java-version: '17'
    
    - name: 构建JAR包
      run: mvn clean package -DskipTests
    
    - name: 登录Docker Hub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}
    
    - name: 构建并推送Docker镜像
      run: |
        # 构建镜像
        docker build -t ${{ secrets.DOCKER_USERNAME }}/user-service:${{ github.sha }} .
        
        # 打标签
        docker tag ${{ secrets.DOCKER_USERNAME }}/user-service:${{ github.sha }} \
                  ${{ secrets.DOCKER_USERNAME }}/user-service:latest
        
        # 推送到Docker Hub
        docker push ${{ secrets.DOCKER_USERNAME }}/user-service:${{ github.sha }}
        docker push ${{ secrets.DOCKER_USERNAME }}/user-service:latest
        
        echo "✅ 镜像推送完成!"

  # 3. 部署到K8S阶段
  deploy:
    needs: build  # 依赖build阶段
    runs-on: ubuntu-latest
    
    steps:
    - name: 检出代码
      uses: actions/checkout@v3
    
    - name: 设置K8S配置
      run: |
        # 创建.kube目录
        mkdir -p ~/.kube
        
        # 写入K8S配置(从GitHub Secrets读取)
        echo "${{ secrets.KUBECONFIG }}" | base64 -d > ~/.kube/config
        
        # 测试连接
        kubectl cluster-info
        echo "✅ K8S连接成功!"
    
    - name: 部署到K8S
      run: |
        # 替换镜像版本
        sed -i "s|IMAGE_TAG|${{ github.sha }}|g" k8s/deployment.yaml
        
        # 应用配置
        kubectl apply -f k8s/
        
        # 等待部署完成
        kubectl rollout status deployment/user-service --timeout=300s
        
        echo "🎉 部署成功!服务已上线!"
    
    - name: 发送通知
      if: always()
      run: |
        if [ "${{ job.status }}" = "success" ]; then
          echo "✅ 部署成功!"
          # 可以在这里集成钉钉/微信通知
        else
          echo "❌ 部署失败!"
        fi

步骤3:创建Dockerfile(简单版)

# Dockerfile
FROM openjdk:17-jdk-slim

# 复制JAR包
COPY target/*.jar app.jar

# 运行应用
ENTRYPOINT ["java", "-jar", "/app.jar"]

步骤4:创建K8S配置文件

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。 创建 k8s/ 目录,里面放这些文件:

# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service
spec:
  replicas: 2  # 2个副本
  selector:
    matchLabels:
      app: user-service
  template:
    metadata:
      labels:
        app: user-service
    spec:
      containers:
      - name: user-service
        image: 你的用户名/user-service:IMAGE_TAG  # GitHub Actions会替换
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "1Gi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 60
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 5
# k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: user-service
spec:
  selector:
    app: user-service
  ports:
  - port: 80
    targetPort: 8080
  type: ClusterIP
# k8s/hpa.yaml(自动扩缩容)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: user-service-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: user-service
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

步骤5:一键部署

# 提交代码
git add .
git commit -m "添加CI/CD配置"
git push origin main

# 然后去GitHub Actions页面看进度
# 打开 https://github.com/你的用户名/你的仓库/actions

三、高级功能(按需添加)

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

1. 金丝雀发布(逐步放量)

# 在deploy步骤中添加
- name: 金丝雀发布
  run: |
    # 1. 先部署1个副本
    kubectl set image deployment/user-service \
      user-service=你的用户名/user-service:${{ github.sha }}
    
    # 2. 等待健康检查
    sleep 30
    
    # 3. 扩容到2个副本
    kubectl scale deployment/user-service --replicas=2
    
    echo "🟡 金丝雀发布完成,观察5分钟..."
    sleep 300
    
    # 4. 全量发布
    kubectl scale deployment/user-service --replicas=4
    echo "✅ 全量发布完成!"

2. 自动回滚(出问题自动恢复)

- name: 部署并监控
  run: |
    # 部署
    kubectl apply -f k8s/
    
    # 监控5分钟
    for i in {1..30}; do
      # 检查Pod状态
      STATUS=$(kubectl get pods -l app=user-service -o jsonpath='{.items[0].status.phase}')
      
      if [ "$STATUS" != "Running" ]; then
        echo "❌ Pod状态异常: $STATUS,开始回滚..."
        
        # 回滚到上一个版本
        kubectl rollout undo deployment/user-service
        
        # 发送告警
        curl -X POST "钉钉机器人URL" \
          -H "Content-Type: application/json" \
          -d '{"msgtype": "text", "text": {"content": "部署失败,已自动回滚"}}'
        
        exit 1
      fi
      
      echo "监控中... ($i/30)"
      sleep 10
    done
    
    echo "✅ 部署成功,运行稳定"

3. 多环境部署(开发/测试/生产)

# 修改触发条件
on:
  push:
    branches:
      - main       # 生产环境
      - staging    # 预发环境
      - develop    # 开发环境

# 添加环境判断
- name: 选择环境
  run: |
    if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
      echo "ENV=production" >> $GITHUB_ENV
      echo "NAMESPACE=production" >> $GITHUB_ENV
    elif [[ "${{ github.ref }}" == "refs/heads/staging" ]]; then
      echo "ENV=staging" >> $GITHUB_ENV
      echo "NAMESPACE=staging" >> $GITHUB_ENV
    else
      echo "ENV=development" >> $GITHUB_ENV
      echo "NAMESPACE=development" >> $GITHUB_ENV
    fi

- name: 部署到对应环境
  run: |
    # 设置命名空间
    kubectl create namespace ${{ env.NAMESPACE }} 2>/dev/null || true
    
    # 部署
    kubectl apply -f k8s/ -n ${{ env.NAMESPACE }}

四、GitHub Actions实用技巧

1. 缓存加速(构建快10倍)

- name: 缓存Maven依赖
  uses: actions/cache@v3
  with:
    path: ~/.m2
    key: maven-${{ hashFiles('**/pom.xml') }}
    restore-keys: |
      maven-

- name: 缓存Docker镜像
  uses: actions/cache@v3
  with:
    path: /tmp/.buildx-cache
    key: buildx-${{ github.sha }}

2. 矩阵测试(一次测多个版本)

test:
  strategy:
    matrix:
      java: [ '11', '17' ]
      os: [ubuntu-latest, windows-latest]
  runs-on: ${{ matrix.os }}
  steps:
    - name: 测试Java ${{ matrix.java }}
      run: mvn test

3. 人工审批(生产部署需要确认)

deploy-production:
  runs-on: ubuntu-latest
  environment: production  # 需要审批的环境
  
  steps:
  - name: 等待审批
    run: echo "等待审批..."
    
  - name: 部署到生产
    run: |
      echo "开始部署到生产环境..."
      # 部署逻辑

4. 定时任务(每天凌晨构建)

on:
  schedule:
    - cron: '0 2 * * *'  # 每天凌晨2点

五、常见问题解决

1. Docker构建慢?

# 使用多阶段构建 + 缓存
FROM maven:3.8-openjdk-17 AS builder
WORKDIR /app
# 先只复制pom.xml,利用缓存
COPY pom.xml .
RUN mvn dependency:go-offline -B

# 再复制源代码
COPY src ./src
RUN mvn clean package -DskipTests

# 运行阶段
FROM openjdk:17-jdk-slim
COPY --from=builder /app/target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

2. K8S部署失败?

# 查看部署状态
kubectl get deployments
kubectl get pods
kubectl describe pod [pod名称]

# 查看日志
kubectl logs [pod名称]
kubectl logs [pod名称] --previous  # 查看之前容器的日志

# 进入Pod调试
kubectl exec -it [pod名称] -- /bin/sh

# 查看事件
kubectl get events --sort-by='.lastTimestamp'

3. 镜像拉取失败?

# 在deployment中添加imagePullSecrets
spec:
  template:
    spec:
      imagePullSecrets:
      - name: regcred  # 提前创建这个secret

创建secret:

kubectl create secret docker-registry regcred \
  --docker-server=你的仓库地址 \
  --docker-username=你的用户名 \
  --docker-password=你的密码

4. 内存不足?

# 调整资源限制
resources:
  requests:
    memory: "256Mi"  # 最小256MB
    cpu: "100m"      # 最小0.1核
  limits:
    memory: "512Mi"  # 最大512MB
    cpu: "500m"      # 最大0.5核

六、完整实战案例

场景:用户服务CI/CD

项目结构:
user-service/
├── src/                    # 源代码
├── target/                 # 构建输出
├── Dockerfile             # Docker配置
├── k8s/                   # K8S配置
│   ├── deployment.yaml
│   ├── service.yaml
│   └── hpa.yaml
├── .github/workflows/     # GitHub Actions
│   └── deploy.yml
└── pom.xml

工作流程:

  1. 开发:写代码 → push到GitHub
  2. GitHub Actions
    • 自动运行测试
    • 自动构建Docker镜像
    • 自动推送到Docker Hub
    • 自动部署到K8S
  3. K8S
    • 自动拉取新镜像
    • 自动重启Pod
    • 自动健康检查
    • 自动扩缩容
  4. 通知:自动发送部署结果

监控看板:

在GitHub Actions页面,你可以看到:

  • ✅ 绿色:成功
  • ❌ 红色:失败
  • 🟡 黄色:进行中
  • 📊 图表:构建时间趋势

七、更简单的方案:使用现成模板

GitHub Marketplace有很多现成Action:

1. 一键部署到K8S

- name: Deploy to Kubernetes
  uses: azure/k8s-deploy@v1
  with:
    namespace: default
    manifests: k8s/
    images: |
      your-username/your-image:${{ github.sha }}

2. 自动创建PR预览环境

- name: Create Preview Environment
  uses: actions/github-script@v6
  with:
    script: |
      // 自动创建PR对应的环境
      github.rest.actions.createWorkflowDispatch({
        owner: context.repo.owner,
        repo: context.repo.repo,
        workflow_id: 'deploy-preview.yml',
        ref: context.ref
      })

3. 使用现成CI/CD服务

  • Vercel:前端项目,免费
  • Netlify:静态网站,免费
  • Heroku:后端项目,有免费额度
  • Railway:全栈项目,新手友好

八、今天学到什么?

核心思想:

  1. 自动化一切:能自动化的都自动化
  2. 快速反馈:失败快速发现,快速修复
  3. 频繁部署:小步快跑,降低风险
  4. 版本一致:开发=测试=生产

具体技能:

  1. ✅ GitHub Actions基础使用
  2. ✅ 自动化测试、构建、部署
  3. ✅ Docker镜像构建和推送
  4. ✅ K8S自动化部署
  5. ✅ 金丝雀发布和自动回滚
  6. ✅ 多环境管理

最佳实践:

  1. 代码即配置:所有配置都放Git
  2. 流水线即代码:CI/CD配置也放Git
  3. 失败优先:测试失败立即停止
  4. 渐进式发布:先1%,再10%,再100%
  5. 监控一切:部署后自动监控

九、明天预告

明天是最后一天!我们会:

  1. 项目实战:完整的电商微服务系统
  2. 性能优化:从100QPS到10000QPS
  3. 故障演练:模拟真实故障,如何应对
  4. 面试必备:微服务面试题大全
  5. 学习路线:下一步该学什么

明天见!🎉 零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。