CI-自动构建镜像
CI/CD 已经成为目前开发工作中必须掌握的技能。利用 CI/CD 工具能够大幅提高软件发布和交付速度,同时自动化流程能最大限度减少人工过多参与导致的不确定性。
本文从 CI 工作流中的镜像自动化构建开始,探索 CI/CD 如何实现 DevOps 理念。通过使用 Github Action 和 Docker Hub 实现镜像自动化构建和发布,开启 CI/CD 学习之路。
关于 DevOps、GitOps、CI/CD 的理解:
从我目前的认知和了解,我理解的 DevOps 更多的是较为概括性、统筹的一种理念,或者说是一种思想。而 CI/CD 工具则是对这种思想的具体实现。当然,GitOps 可以把它理解成在 DevOps 理念中,以 Git 作为主线、主要工具,围绕 Git 打造一套 CI/CD 工作流,实际上也是 DevOps 的一种实现形式、或是这种理念 “更具体” 的表述形式。
由于目前还没有接触到一线的生产工作,对此的理解会有欠缺。希望在以后工作中能对自动化软件交付有更深入的理解。
Github Actions
我们可以在这个文档中学习详细的信息:https://docs.github.com/zh/actions
https://docs.github.com/zh/actions/publishing-packages/publishing-docker-images
“在 GitHub Actions 的仓库中自动化、自定义和执行软件开发工作流程。 您可以发现、创建和共享操作以执行您喜欢的任何作业(包括 CI/CD),并将操作合并到完全自定义的工作流程中。”
在使用 Github Page 托管 Hugo 时,就涉及到使用 Github Actions 自动化发布静态网站的步骤。Github Action 是 GitOps 中重要一环。
“GitHub Actions 工作流,使其在存储库中发生事件(例如打开拉取请求或创建问题)时触发 。 工作流包含一个或多个可按顺序或并行运行的作业。 每个作业都将在其自己的虚拟机运行器中或在容器中运行,并具有一个或多个步骤,用于运行定义的脚本或运行动作。”
Github Actions 工作流主要包含以下几个概念:
- Event:这是触发工作流特定活动。例如创建拉取请求、提交推送等。
- Runner:运行 Job,执行工作流的服务器,每个 Runner 一次可以运行一个作业。这些 Runner 是在云上的虚拟机。
- Job:工作流中在同一机器上执行的一组 Step,这些 Step 按照顺序执行,相互依赖。
- Step:组成 Job 的执行单元,可以是脚本、命令等操作。
Workflow示例
Github Actions 的 workflow 放在项目根文件夹 (.git所在的目录) 中的 .github/workflows/
里面。通过 yaml 文件定义。我们先创建一个 build.yaml
来实现提交代码触发镜像自动构建和上传镜像仓库操作。
$ ll
total 28
drwxrwxr-x 5 lzl lzl 4096 1月 25 23:34 ./
drwxrwxrwx 19 root root 4096 1月 21 21:44 ../
drwxrwxr-x 8 lzl lzl 4096 1月 8 17:30 .git/
-rw-rw-r-- 1 lzl lzl 66 1月 3 22:17 .gitattributes
-rw-rw-r-- 1 lzl lzl 43 1月 8 17:30 .gitignore
drwxr-xr-x 7 root root 4096 1月 8 12:06 k8s-practice/
root@nm:/work-place/GitOps# mkdir -p .github/workflows
root@nm:/work-place/GitOps# vim .github/workflows/build.yaml
build.yaml
文件如下:
# name 表示工作流名称 会展示在 Github 网页上
name: build
# on.push.branches 表示 main 有新的提交后 触发工作流
on:
push:
branches:
- 'main'
# 通过 env 我们可以为本次 action 设置环境变量 用在后续各个 steps 中
# 这里我们设置 DOCKERHUB_USERNAME 用于镜像前缀
# Docker Hub 要求个人镜像仓库中的镜像有 username 这个前缀
env:
DOCKERHUB_USERNAME: username
# jobs 定义任务
jobs:
docker:
# 设置这个任务的运行环境
runs-on: ubuntu-latest
# steps 是一个列表 定义了每一个步骤
steps:
- name: Checkout # Checkout 将代码检出到运行环境
uses: actions/checkout@v3
- name: Set outputs # 用来生成本次的短 sha 哈希 用于后面的镜像 tag
id: vars
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
# 初始化 Docker 构建工具链
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
# 登录到 Docker Hub
- name: Login to Docker Hub
uses: docker/login-action@v2
with: # 通过 with 字段向插件提供参数
# env 使用我们上述定义的 env
username: ${{ env.DOCKERHUB_USERNAME }}
# secrets 则是存储在 Github 仓库中的 secrets 稍后会进行配置说明
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build backend and push
uses: docker/build-push-action@v3
with:
# context 定义构建镜像所需目录上下文 不一定是 Dockerfile 的目录
context: ./k8s-practice/demo-app/kubernetes-example/backend
push: true
tags: ${{ env.DOCKERHUB_USERNAME }}/backend:${{ steps.vars.outputs.sha_short }}
- name: Build frontend and push
uses: docker/build-push-action@v3
with:
context: ./k8s-practice/demo-app/kubernetes-example/frontend
push: true
tags: ${{ env.DOCKERHUB_USERNAME }}/frontend:${{ steps.vars.outputs.sha_short }}
不难发现,每一个 Step 都会依赖插件,也就是 uses
字段。Github Actions 插件市场 为我们提供了生产所需的各种插件,每个插件都有对应的文档。
Secret
Docker Hub Secret
由于我们的私有仓库需要身份认证才能获得上传镜像等准入权限,因此需要告知 Github Actions 我们 Docker Hub 的凭证。我们需要创建一个 Access Token。
Actions secrets
然后,将 Docker Hub 的 Access Token 填到 Github 仓库中的 Actions secrets 中。注意 Name 应该和 workflow 文件中的对应,即:DOCKERHUB_TOKEN
。
# secrets 则是存储在 Github 仓库中的 secrets 稍后会进行配置说明
password: ${{ secrets.DOCKERHUB_TOKEN }}
提交代码触发工作流
最后,将我们的代码改动提交main分支,我们能在仓库的 Actions 中看到工作流。
同时,能够查看每一个 Step 的详细过程,以便定位排查问题。
在工作流成功执行完成后,在 Docker Hub 的仓库中也看到了对应的新镜像。