📚前言
👀回顾,系统学习docker系列已发布内容:
【docker基础】第三课:镜像管理与Dockerfile基础
【docker基础】第五课:Docker网络详解-CSDN博客
【docker基础】第六课:Web应用与数据库容器部署-CSDN博客
【docker基础】 第七课:Docker Compose 多容器实战-CSDN博客
【docker基础】 第八周:容器监控与应用更新策略-CSDN博客
【docker基础】第九周:Docker安全与镜像优化-CSDN博客
🔗相关文档:
【docker基础】Ubuntu 安装 Docker 超详细小白教程
📒本课学习目标:
- CI/CD 基础:持续集成和持续部署的概念
- GitHub Actions:创建 Docker 工作流
- GitHub Secrets:安全存储敏感信息
- Jenkins 集成:Pipeline 配置
- 自动化构建:构建矩阵、条件执行、缓存优化
- 环境部署:开发、测试、生产环境部署策略
🌍Docker第十周:CI/CD集成
欢迎来到 Docker 第十周的学习!本周我们将学习如何将 Docker 与 CI/CD(持续集成/持续部署)工具集成,实现自动化构建和部署。
第一章:CI/CD 基础概念
1.1 什么是 CI/CD
CI(持续集成):开发人员频繁地将代码合并到主分支,每次合并都会自动执行构建和测试。
CD(持续部署):代码通过 CI 测试后,自动部署到生产环境。
1.2 CI/CD 的工作流程
代码提交 →→→ 自动构建 →→→ 自动测试 →→→ 自动部署 →→→ 生产环境
↑ ↓
└──────────────────────────────────────────────┘
(反馈循环)
1.3 为什么 Docker 适合 CI/CD
- 环境一致性:开发、测试、生产环境完全一致
- 快速启动:容器可以在几秒钟内启动
- 资源隔离:不同项目的构建互不影响
- 易于回滚:出现问题可以快速回滚到之前的版本
第二章:GitHub Actions 与 Docker
2.1 什么是 GitHub Actions
GitHub Actions 是 GitHub 提供的 CI/CD 功能,可以自动化构建、测试和部署流程。
2.2 基本概念
- Workflow(工作流):自动化流程的定义
- Job(作业):工作流中的一个任务
- Step(步骤):作业中的具体操作
- Action(动作):可重用的步骤单元
2.3 创建第一个 Docker 工作流
2.3.1 创建工作流文件
在项目根目录创建 .github/workflows/docker.yml 文件:
name: Docker Build and Push
on:
push:
branches:
- main # 当 main 分支有代码推送时触发
pull_request:
branches:
- main # 当有 PR 合并到 main 时触发
jobs:
build:
runs-on: ubuntu-latest
steps:
# 步骤1:检出代码
- name: Checkout code
uses: actions/checkout@v3
# 步骤2:设置 Docker Buildx
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
# 步骤3:登录 Docker Hub
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# 步骤4:构建并推送镜像
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: |
myusername/myapp:latest
myusername/myapp:${{ github.sha }}
2.4 配置 GitHub Secrets
为了安全地存储敏感信息(如 Docker Hub 密码),需要配置 Secrets:
- 进入 GitHub 仓库 → Settings → Secrets and variables → Actions
- 点击 "New repository secret"
- 添加以下 Secrets:
DOCKERHUB_USERNAME:Docker Hub 用户名DOCKERHUB_TOKEN:Docker Hub 访问令牌
2.5 字段说明
| 字段 | 说明 |
|---|---|
name |
工作流的名称 |
on |
触发条件 |
runs-on |
运行的环境 |
uses |
使用的 Action |
with |
Action 的参数 |
${``{ secrets.xxx }} |
引用 Secrets |
${``{ github.sha }} |
Git 提交的 SHA 值 |
第三章:多步骤构建工作流
3.1 构建、测试、部署完整流程
name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
# 作业1:构建和测试
build-and-test:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:5.7
env:
MYSQL_ROOT_PASSWORD: testpass
MYSQL_DATABASE: testdb
options: >-
--health-cmd="mysqladmin ping"
--health-interval=10s
--health-timeout=5s
--health-retries=5
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build application
run: docker build -t myapp:test .
- name: Run tests
run: |
docker run -d --name test-app myapp:test
sleep 5
docker exec test-app npm test
docker stop test-app
# 作业2:构建并推送镜像
build-and-push:
needs: build-and-test # 依赖前一个作业
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' # 只在 main 分支执行
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: |
myusername/myapp:latest
myusername/myapp:${{ github.sha }}
# 作业3:部署到服务器
deploy:
needs: build-and-push
runs-on: ubuntu-latest
steps:
- name: Deploy to server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
docker pull myusername/myapp:latest
docker stop myapp || true
docker rm myapp || true
docker run -d --name myapp -p 80:80 myusername/myapp:latest
3.2 多平台构建
构建支持多个 CPU 架构的镜像:
- name: Build and push (multi-platform)
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64/v8
push: true
tags: |
myusername/myapp:latest
myusername/myapp:${{ github.sha }}
第四章:Docker 与 Jenkins 集成
4.1Jenkins简介
Jenkins 是一个开源的 持续集成/持续部署(CI/CD)自动化工具,用 Java 开发,主要用于:
- 自动化构建
- 自动化测试
- 自动化部署
- 持续交付
Jenkins 的核心功能
| 功能 | 说明 |
|---|---|
| 持续集成(CI) | 频繁地将代码合并到主干,自动执行构建和测试 |
| 持续交付(CD) | 代码通过测试后,自动部署到测试/生产环境 |
| 插件扩展 | 拥有丰富的插件生态系统,支持各种工具集成 |
| 分布式构建 | 支持 Master-Slave 架构,分担构建任务 |
| 流水线(Pipeline) | 用代码定义构建和部署流程 |
工作原理
┌─────────────────────────────────────────────────────────────────┐
│ Jenkins 工作流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 开发者提交代码 │
│ ↓ │
│ Git/GitHub/GitLab │
│ ↓ │
│ Jenkins 拉取代码 │
│ ↓ │
│ 执行构建脚本 │
│ ↓ │
│ 运行测试用例 │
│ ↓ │
│ ┌─────────────────┐ │
│ │ 构建成功? │ │
│ └────────┬────────┘ │
│ │ │
│ ┌────┴────┐ │
│ ↓ ↓ │
│ 是 否 │
│ ↓ ↓ │
│ 部署到 发送通知 │
│ 测试环境 (邮件/Slack) │
│ ↓ │
│ 自动测试 │
│ ↓ │
│ 手动审批(可选) │
│ ↓ │
│ 部署到生产环境 │
│ │
└─────────────────────────────────────────────────────────────────┘
4.2Jenkins 安装与配置
4.2.1 使用 Docker 运行 Jenkins
docker run -d \
--name jenkins \
-p 8080:8080 \
-p 50000:50000 \
-v jenkins_home:/var/jenkins_home \
jenkins/jenkins:lts
4.2.2 获取初始管理员密码
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
4.3 安装推荐插件
首次登录后,选择"安装推荐插件",包括:
- Git 插件
- Docker 插件
- Pipeline 插件
- Blue Ocean(可视化界面)
创建 Jenkins Pipeline示例,在 Jenkins 中创建 Jenkinsfile:
pipeline {
agent {
docker {
image 'node:14-alpine'
args '-p 3000:3000'
}
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build') {
steps {
sh 'npm install'
sh 'npm run build'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
stage('Build Docker Image') {
steps {
sh "docker build -t myapp:${env.BUILD_NUMBER} ."
sh "docker tag myapp:${env.BUILD_NUMBER} myusername/myapp:latest"
}
}
stage('Push to Registry') {
steps {
withCredentials([usernamePassword(credentialsId: 'dockerhub', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
sh 'echo $PASSWORD | docker login -u $USERNAME --password-stdin'
sh 'docker push myusername/myapp:latest'
sh 'docker push myusername/myapp:${env.BUILD_NUMBER}'
}
}
}
stage('Deploy') {
steps {
sh '''
ssh user@server "docker pull myusername/myapp:latest"
ssh user@server "docker stop myapp || true"
ssh user@server "docker rm myapp || true"
ssh user@server "docker run -d --name myapp -p 80:80 myusername/myapp:latest"
'''
}
}
}
post {
always {
cleanWs()
}
}
}
Pipeline 语法说明
| 块 | 说明 |
|---|---|
agent |
指定构建执行的环境 |
environment |
定义环境变量 |
stages |
定义多个阶段 |
stage |
单个阶段(如 Build、Test、Deploy) |
steps |
阶段中的具体步骤 |
post |
Pipeline 执行后的操作 |
第五章:自动化构建与推送
5.1 构建矩阵策略
使用矩阵策略并行构建多个配置:
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14, 16, 18]
platform: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Build
run: npm ci
- name: Build Docker image
run: |
docker build \
--tag myapp:${{ matrix.node-version }} \
--build-arg NODE_VERSION=${{ matrix.node-version }} \
.
5.2 条件执行
根据分支或标签触发不同的构建:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# 只在 main 分支构建并推送
- name: Build and push
if: github.ref == 'refs/heads/main'
run: |
docker build -t myapp:latest .
docker push myapp:latest
# 只在标签发布时构建并推送
- name: Build and push (release)
if: startsWith(github.ref, 'refs/tags/v')
run: |
VERSION=${GITHUB_REF#refs/tags/v}
docker build -t myapp:$VERSION .
docker push myapp:$VERSION
5.3 缓存优化
加速 Docker 构建:
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: myusername/myapp:latest
cache-from: type=gha
cache-to: type=gha,mode=max
第六章:环境部署策略
6.1 开发环境部署
deploy-dev:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/develop'
steps:
- name: Deploy to development
run: |
kubectl config use-context dev
kubectl apply -f k8s/manifests/
6.2 生产环境部署
deploy-prod:
runs-on: ubuntu-latest
needs: deploy-staging
if: startsWith(github.ref, 'refs/tags/v')
steps:
- name: Deploy to production
run: |
kubectl config use-context prod
kubectl set image deployment/myapp app=myusername/myapp:${{ github.ref_name }}
6.3 蓝绿部署
blue-green-deploy:
runs-on: ubuntu-latest
steps:
# 部署蓝色版本
- name: Deploy blue version
run: |
docker-compose -f docker-compose.blue.yml up -d
sleep 10
# 健康检查
- name: Health check
run: |
curl -f http://blue.example.com/health || exit 1
# 切换流量
- name: Switch traffic
run: |
docker-compose -f docker-compose.green.yml rm -f
docker-compose -f docker-compose.blue.yml up -d --scale blue=2
第七章:实战练习
7.1 练习1:创建 GitHub Actions 工作流
- 在 GitHub 上创建新仓库
- 添加 Dockerfile 到仓库
- 创建
.github/workflows/docker.yml - 配置 GitHub Secrets
- 推送代码触发构建
7.2 练习2:多阶段 CI/CD 流程
创建一个完整的工作流,包括:
- 代码检出
- 依赖安装
- 单元测试
- Docker 镜像构建
- 镜像推送
- 服务器部署
7.3 练习3:实现自动化回滚
rollback:
runs-on: ubuntu-latest
if: failure()
steps:
- name: Rollback deployment
if: failure()
run: |
docker pull myusername/myapp:${{ github.event.inputs.previous_tag }}
kubectl rollout undo deployment/myapp
第八章:常见问题与解决方案
8.1 问题:构建超时
解决方案:增加超时时间或优化构建步骤
jobs:
build:
timeout-minutes: 30 # 增加超时时间
8.2 问题:Secrets 无法访问
解决方案:确保 Secrets 名称正确,且在正确的位置引用
# 确保在 Settings → Secrets 中配置
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
8.3 问题:Docker 镜像无法推送
解决方案:检查登录凭据和网络连接
# 本地测试推送
docker login
docker push myusername/myapp:latest
命令速查表
| 操作 | 命令 |
|---|---|
| 登录 Docker Hub | docker login |
| 构建镜像 | docker build -t name:tag . |
| 推送镜像 | docker push username/image:tag |
| 拉取镜像 | docker pull username/image:tag |
本周总结
本周我们学习了:
- CI/CD 基础:持续集成和持续部署的概念
- GitHub Actions:创建 Docker 工作流
- GitHub Secrets:安全存储敏感信息
- Jenkins 集成:Pipeline 配置
- 自动化构建:构建矩阵、条件执行、缓存优化
- 环境部署:开发、测试、生产环境部署策略
练习作业:
- 创建一个 GitHub Actions 工作流,实现自动构建和推送
- 配置 GitHub Secrets 并测试工作流
- 实现蓝绿部署策略