迟来的更新,祝各位 7.24 运维节快乐~


CNB.COOL

腾讯云推出的云原生构建平台(Cloud Native Build,以下简称 CNB),通过容器化技术和声明式开发环境,改变了传统开源项目中繁琐、重复的环境搭建方式。

为满足更广泛的构建与发布需求,CNB 最近上线了对 Buildx 多架构构建的支持。开发者可以直接在 CNB 上构建面向多平台(如 x86_64、arm64、loong64 等)的镜像,实现一次构建、多平台部署,从而加速软件交付流程,进一步释放云原生的技术潜力。

自年初起,我开始着手将项目迁移至龙芯平台。在此过程中,龙芯平台的应用编译与打包面临不少挑战。恰好 CNB 公测多架构构建能力,我第一时间进行了尝试,并对原有构建流程进行了优化与重构。

关于 LoongArch64

可能大家曾在央视新闻中看到,我国自主研发的新一代通用处理器 龙芯 3C6000 系列正式发布。这款处理器就是基于 LoongArch 的。LoongArch 是由龙芯中科推出的一种国产自主指令集架构(ISA),采用 RISC 设计理念,其 64 位版本即为 LoongArch64。

随着国产软硬件生态的快速发展,LoongArch64 在操作系统、编译器、应用软件等领域获得了越来越多的支持,社区活跃度不断提升,也吸引了众多开发者参与其中。

构建 LoongArch64 镜像的挑战

在早期,我们经历了两个阶段:

1、GitLab + 龙芯服务器,在龙芯服务器上编译镜像,再推送到 Docker Hub。
这需要自行维护一套Git服务器并配合一台LoongArch64的服务器,还需要解决推送到 Docker Hub 的网络问题。

2、GitHub Action,使用 Qemu 模拟 LoongArch64 环境,进行编译打包,并上传到 ghcr。

  • GitHub Action Runner 性能有限
    GitHub 官方提供的免费 Runner 配置较低,执行大型编译任务速度慢,效率低。

  • 众所周知的网络因素
    国内开发者访问 ghcr.io、github.com 等平台时常遇到连接超时或下载缓慢问题,严重影响构建稳定性与开发效率。

  • GitHub Action 语法逻辑相对复杂
    GitHub Action 的配置语法相对晦涩,对新手不够友好,稍微复杂一点的工作流编排就需要较高的上手成本。

为什么选择 CNB.COOL?

在探索更高效构建方式的过程中,我们发现了由腾讯云支持的 CNB.COOL 云原生构建平台:

1、提供免费资源
CNB 提供最高 64 核 CPU、128GB 内存的免费开发与构建资源,构建资源充足。
提供了免费的Docker制品,默认为100G,并支持私有镜像。

2、网络稳定快速
由腾讯云提供网络服务,在国内访问速度优秀,拉取 CNB Docker 制品无网络问题。
开发/编译环境内置网络加速服务,外网资源无需配置加速器,可直达访问镜像源。

3、即开即用,无需复杂配置
可自定义开发环境,我们也做好了一些镜像,预装了多种工具链,你可以开箱即用。

4、友好界面,易于上手
全中文文档支持 + 完备的案例库,帮助你快速上手。
可视化配置、CI 容器在线 Debug,实时日志输出,相比 GitHub Action 更易操作。

Buildx 体验

CNB 借助 containerd-snapshotter 特性,在 rootless 模式下实现了对多平台构建的模拟与支持,使得开发者无需特权权限也能完成跨架构镜像的构建任务,大幅提升了构建环境的安全性与可移植性。

⚠️ 目前该能力正在公测中,我们也是在第一时间体验了一下。如果您也想体验,可以通过流水线中指定 runner.tags: cnb:arch:amd64:containerd-snapshotter,可以将构建指定到支持 containerd-snapshotter 特性的集群。(未来这个标签会去掉,仅供测试使用)

在本文的实践中,我们通过 CNB 平台构建了一个自动化流水线,定期检查并构建最新的 LoongArch64 架构 Alpine 镜像。

创建 Buildx 使用的 Dockerfile

构建此类的镜像比较简单,例如下面是一个完整的 Dockerfile。

1
2
3
FROM scratch
ADD alpine-minirootfs-VERSION-loongarch64.tar.gz /
CMD ["/bin/sh"]

创建 cnb.yml

cnb.yml 是云原生构建配置文件。该文件描述了当仓库发生一些事件时(有新的 Commit 被推送、有新的 PR 请求等), 云原生构建是否应该启动构建任务,如果启动构建的话,构建任务的每一步分别做什么。

下面是一个完整的云原生构建配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
main:
"crontab: 0 0,12 * * *":
- docker:
build:
dockerfile: .cnb/Dockerfile
services:
- docker
env:
IMAGE_NAME: ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}
stages:
- name: version check
script: |
remote_latest_version=$(curl -s "https://cz.alpinelinux.org/alpine/latest-stable/releases/loongarch64/latest-releases.yaml" | yq -r '.[0].version')
cnb_version=$(curl -s https://api.cnb.cool/${CNB_REPO_SLUG_LOWERCASE}/-/releases/latest -H 'accept: application/json' -H "Authorization: Bearer ${CNB_TOKEN}" | jq -r '.tag_name')
echo "官方最新版本镜像为:${remote_latest_version}"
if [ -z "${remote_latest_version}" ] || [ "${remote_latest_version}" = "null" ]; then
echo "获取版本失败,流水线异常结束"
exit 1
fi
echo "##[set-output REMOTE_LATEST=${remote_latest_version}]"
echo "##[set-output CNB_VERSION=${cnb_version}]"
exports:
REMOTE_LATEST: REMOTE_LATEST
CNB_VERSION: CNB_VERSION
- name: per build
if: |
[ "$REMOTE_LATEST" != "$CNB_VERSION" ]
script: |
wget "https://cz.alpinelinux.org/alpine/latest-stable/releases/loongarch64/alpine-minirootfs-${REMOTE_LATEST}-loongarch64.tar.gz"
sed -i "s/VERSION/${REMOTE_LATEST}/g" Dockerfile
cat Dockerfile
- name: docker login
if: |
[ "$REMOTE_LATEST" != "$CNB_VERSION" ]
script: docker login -u ${CNB_TOKEN_USER_NAME} -p "${CNB_TOKEN}" ${CNB_DOCKER_REGISTRY}
- name: docker build and push
if: |
[ "$REMOTE_LATEST" != "$CNB_VERSION" ]
script: docker buildx build -t ${IMAGE_NAME}:${REMOTE_LATEST} --platform linux/loong64 --push .
- name: release version
if: |
[ "$REMOTE_LATEST" != "$CNB_VERSION" ]
type: git:release
options:
latest: true
tag: ${REMOTE_LATEST}
title: ${REMOTE_LATEST}
description: 请使用 docker pull docker.cnb.cool/hex/loong/images/alpine:${REMOTE_LATEST} 获取该镜像
allowFailure: false

CNB Flow

大体上,这套流水线充分利用了 CNB.COOL 提供的几个 feature。

定时任务

1
2
main:
"crontab: 0 0,12 * * *":

这行配置定义了一个定时任务,使用 cron 表达式设定构建触发的时间:每天的 0点与12点 各执行一次流水线。你可以将其理解为一个定时“巡检任务”,用于检查并同步官方 Alpine 版本更新。

API 调用

1
2
remote_latest_version=$(curl -s "https://cz.alpinelinux.org/alpine/latest-stable/releases/loongarch64/latest-releases.yaml" | yq -r '.[0].version')
cnb_version=$(curl -s https://api.cnb.cool/${CNB_REPO_SLUG_LOWERCASE}/-/releases/latest ... | jq -r '.tag_name')

在 version check 阶段,通过调用 API 获取版本号。其中使用了 CNB.COOL 的 API 能力。

使用变量

1
2
3
4
5
echo "##[set-output REMOTE_LATEST=${remote_latest_version}]"
echo "##[set-output CNB_VERSION=${cnb_version}]"
exports:
REMOTE_LATEST: REMOTE_LATEST
CNB_VERSION: CNB_VERSION

上述语句使用了 CNB 流水线语法中的 set-output 指令,将变量导出为全局环境变量。接下来的流水线步骤中,就可以直接通过 $REMOTE_LATEST 与 $CNB_VERSION 使用这些值。

条件任务

在流水线中,使用了 if 来设置条件任务。

1
2
if: |
[ "$REMOTE_LATEST" != "$CNB_VERSION" ]

只有当 Alpine 官方版本与当前已发布版本不一致时,才会执行构建,避免不必要的重复构建,节省资源。

多平台构建

借助 Docker Buildx,指定 –platform linux/loong64,完成对 LoongArch64 架构的镜像构建,并直接 –push 到指定仓库。这也正是 CNB 利用 containerd-snapshotter 实现 rootless 模拟多架构构建的体现。

1
docker buildx build -t ${IMAGE_NAME}:${REMOTE_LATEST} --platform linux/loong64 --push .

也支持指定多个平台,例如:

1
docker buildx build -t ${IMAGE_TAG} --platform linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/loong64,linux/arm/v7,linux/arm/v6 --push .

release 插件发版

1
2
3
4
5
6
7
- name: release version
type: git:release
options:
latest: true
tag: ${REMOTE_LATEST}
title: ${REMOTE_LATEST}
description: 请使用 docker pull ...

构建完成后,使用 CNB 内置的 git:release 插件自动打 Git Tag,并生成 Release 说明。这样每一个版本变更都能被记录、回溯,同时便于其他开发者获取最新镜像版本。

CNB.COOL 有非常多的 CI 插件,可以与流水线无缝结合。

CI 插件仓库

CI 调试

有时我们需要调试流水线,每次通过 Push 调试很繁琐。CNB 提供了调试模式,可以开启 Debug 重新构建。

CI Debug

在构建日志页面可以登录容器进行调试。

登录容器

自定义构建环境

在实际构建过程中,我们使用了 yq 这个 YAML 处理工具。CNB 默认的构建环境不内置 yq,因此需要我们自定义一个构建环境镜像。
CNB 支持通过自定义 Dockerfile 定义构建所需环境,只需在项目中添加一个 .cnb/Dockerfile 文件,即可轻松完成环境准备。

例如,我基于 CNB 默认环境,增加一个我需要的组件,作为构建环境。

1
2
From cnbcool/default-dev-env
RUN apt update && apt install -y yq

小结

CI 流水线

通过这套流程,我们实现了:

1、定时检测 Alpine 官方镜像更新
2、自动更新构建脚本并重新构建
3、使用 Buildx 构建 LoongArch64 架构镜像
4、推送镜像至镜像仓库
5、自动发布版本信息

如需深入了解和扩展使用,建议参考以下资源:

CNB 配置和文档

CNB 案例集

Hex Loong

如果你对龙芯移植感兴趣,可以关注我们的组织:

文中提到的 Loong64 Alpine 仓库/制品: