系统级 Runner 接入
1106 字约 4 分钟
概述
系统管理员可以在 admin 管理平台 添加机器,作为 云原生构建/云原生开发 功能的 Runner,供用户使用。
CNB 支持 Linux、Mac 和 Windows 构建机。
两种托管模式
系统托管(默认)
由 CNB 平台调度管理的机器,需要机器和平台可以互相访问,通过 ip:port 的方式添加。
自托管
由用户自行管理的机器,仅要求机器能直接访问CNB平台即可,通过唯一标识的方式添加。
系统环境要求
Linux 构建机
- TencentOS 3.2 / TencentOS 3.1 / CentOS 8 及衍生版
- 内核版本推荐 5.4+
- docker >= 26.1.5
- 可监听 8087, 8088 端口
MAC 构建机
- git >= 2.43.0
- 可监听 8087、8088 端口
由于 Mac 不支持 OverlayFS,读秒克隆会降级为普通克隆。
Windows 构建机
- 建议 Windows 10 及以上
- git >= 2.43.0
- 可监听 8087、8088 端口
由于 Windows 不支持 OverlayFS,读秒克隆会降级为普通克隆。
配置过程
1. 配置 Linux 构建机 (标准方案)
a-download.sh
b-sysctl.sh
c-raid0.sh
d-daemon-json.sh
e-install-docker.sh
f-install-docker-plugin.sh
g-install-runner-config.sh
h-install-runner.sh
i-install-binfmt.sh
j-install-clean-cgroup.sh
#!/bin/bash
# =============================================================================
# Script: a-download.sh
# Description: 下载 CI Runner 所需的 Docker 组件到 files/ 目录
# Note: 下载内容包括 Docker 二进制包、docker-compose、docker-buildx
# 同时下载 x86_64 和 aarch64 两个架构,文件名以架构结尾
# GitHub 资源支持代理加速,设置 USE_GITHUB_PROXY=true 启用
# Usage: USE_GITHUB_PROXY=true ./a-download.sh
# =============================================================================
set -eo pipefail
# -----------------------------------------------------------------------------
# Constants
# -----------------------------------------------------------------------------
TARGET_DOCKER_VERSION="27.5.1"
TARGET_COMPOSE_VERSION="v2.40.3"
TARGET_BUILDX_VERSION="v0.21.0"
DOWNLOAD_DIR="$(cd "$(dirname "$0")/files" && pwd)"
mkdir -p "$DOWNLOAD_DIR"
# GitHub 代理,设置 USE_GITHUB_PROXY=true 启用代理
GITHUB_PROXY_BASE="https://ghfast.top"
# 拼接 GitHub 下载地址,根据 USE_GITHUB_PROXY 决定是否走代理
github_url() {
local url="$1"
if [[ "${USE_GITHUB_PROXY}" == "true" ]]; then
echo "${GITHUB_PROXY_BASE}${url}"
else
echo "$url"
fi
}
# -----------------------------------------------------------------------------
# Download for all architectures
# -----------------------------------------------------------------------------
for HOST_ARCH in x86_64 aarch64; do
ARCH="${ARCH_MAP[$HOST_ARCH]}"
echo "========================================"
echo "Downloading for ${HOST_ARCH} (${ARCH})"
echo "========================================"
# Docker binaries
echo "[1/3] Docker ${TARGET_DOCKER_VERSION}..."
wget --show-progress -O "${DOWNLOAD_DIR}/docker-${TARGET_DOCKER_VERSION}-${HOST_ARCH}.tgz" \
"https://mirrors.cloud.tencent.com/docker-ce/linux/static/stable/${HOST_ARCH}/docker-${TARGET_DOCKER_VERSION}.tgz"
# docker-compose
echo "[2/3] docker-compose ${TARGET_COMPOSE_VERSION}..."
wget --show-progress -O "${DOWNLOAD_DIR}/docker-compose-${HOST_ARCH}" \
"$(github_url "https://github.com/docker/compose/releases/download/${TARGET_COMPOSE_VERSION}/docker-compose-linux-${HOST_ARCH}")"
chmod +x "${DOWNLOAD_DIR}/docker-compose-${HOST_ARCH}"
# docker buildx
echo "[3/3] docker buildx ${TARGET_BUILDX_VERSION}..."
wget --show-progress -O "${DOWNLOAD_DIR}/docker-buildx-${HOST_ARCH}" \
"$(github_url "https://github.com/docker/buildx/releases/download/${TARGET_BUILDX_VERSION}/buildx-${TARGET_BUILDX_VERSION}.linux-${HOST_ARCH}")"
chmod +x "${DOWNLOAD_DIR}/docker-buildx-${HOST_ARCH}"
done
echo "========================================"
echo "All downloads completed:"
ls -lh "${DOWNLOAD_DIR}/docker-${TARGET_DOCKER_VERSION}"-* \
"${DOWNLOAD_DIR}/docker-compose-"* \
"${DOWNLOAD_DIR}/docker-buildx-"*#!/bin/bash
# =============================================================================
# Script: a-sysctl.sh
# Description: 安装依赖并配置内核参数(转发、inotify、IPv6 等)
# Note: 自动适配 dnf / yum / apt-get 包管理器
# 配置方式为幂等:已存在的参数会更新值,不存在的会追加
# =============================================================================
set -eo pipefail
# Install dependencies based on package manager
if command -v dnf &>/dev/null; then
dnf -y install lvm2 libcgroup-tools
elif command -v yum &>/dev/null; then
yum -y install lvm2 libcgroup-tools
elif command -v apt-get &>/dev/null; then
apt-get -y install lvm2 cgroup-tools
else
echo "Unsupported package manager" >&2
exit 1
fi
# -----------------------------------------------------------------------------
# Configure sysctl parameter: update if exists, append if not
# Usage: configure_sysctl "parameter" "value"
# -----------------------------------------------------------------------------
configure_sysctl() {
local param="$1"
local value="$2"
local conf_file="/etc/sysctl.conf"
if grep -q "^${param}\s*=" "$conf_file" 2>/dev/null; then
sed -i "s|^${param}\s*=.*|${param} = ${value}|" "$conf_file"
else
echo "${param} = ${value}" >> "$conf_file"
fi
}
# -----------------------------------------------------------------------------
# Configure kernel parameters
# -----------------------------------------------------------------------------
# Container runtime optimizations
configure_sysctl "net.ipv4.ip_forward" "1"
configure_sysctl "fs.inotify.max_user_instances" "10000"
configure_sysctl "fs.inotify.max_user_watches" "819200"
configure_sysctl "net.core.netdev_max_backlog" "65536"
# Disable IPv6
configure_sysctl "net.ipv6.conf.all.disable_ipv6" "1"
configure_sysctl "net.ipv6.conf.default.disable_ipv6" "1"
configure_sysctl "net.ipv6.conf.lo.disable_ipv6" "1"
# Apply configuration
sysctl -p#!/bin/bash
# =============================================================================
# Script: b-raid0.sh
# Description: 检测数据盘并配置挂载:单盘直接格式化挂载,多盘创建 RAID0
# Note: 系统盘通过 df / 自动识别并排除
# 数据盘统一挂载到 /data,使用 XFS 文件系统(ftype=1)
# 多盘时自动处理已有的 /dev/md0 或 /dev/md127
# 需要提前安装 mdadm 工具
# =============================================================================
set -eo pipefail
# -----------------------------------------------------------------------------
# Constants
# -----------------------------------------------------------------------------
MOUNT_POINT="/data"
RAID_DEVICE="/dev/md0"
FS_TYPE="xfs"
MOUNT_OPTS="defaults,pquota"
# 检测系统盘并排除,获取数据盘列表
SYSTEM_DISK=$(df / --output=source | tail -n1)
DATA_DISKS=$(lsblk -d -o NAME,TYPE | awk '/disk/ {print "/dev/"$1}' | grep -v "$SYSTEM_DISK" | grep -v "/dev/md")
DATA_DISK_COUNT=$(echo "$DATA_DISKS" | grep -c . || true)
# -----------------------------------------------------------------------------
# format_and_mount: 格式化设备并挂载到 /data,同时更新 fstab
# $1 - 设备路径,如 /dev/sdb 或 /dev/md0
# -----------------------------------------------------------------------------
format_and_mount() {
local device="$1"
if ! mountpoint -q "$MOUNT_POINT"; then
echo "mount $device to $MOUNT_POINT"
mkfs.xfs -f -n ftype=1 "$device"
mkdir -p "$MOUNT_POINT"
mount -o "$MOUNT_OPTS" "$device" "$MOUNT_POINT"
else
echo "$MOUNT_POINT is already mounted"
fi
# 更新 fstab:移除该设备旧的 UUID 记录,追加新记录
local uuid
uuid=$(blkid -s UUID -o value "$device")
grep -v "$uuid" /etc/fstab > /etc/fstab.tmp || true
echo "UUID=$uuid $MOUNT_POINT $FS_TYPE $MOUNT_OPTS 0 0" >> /etc/fstab.tmp
mv /etc/fstab.tmp /etc/fstab
}
# -----------------------------------------------------------------------------
# 单盘模式:直接格式化数据盘并挂载
# -----------------------------------------------------------------------------
if [[ "$DATA_DISK_COUNT" -eq 1 ]]; then
echo "数据盘数量等于 1"
format_and_mount "$DATA_DISKS"
df -Th
# -----------------------------------------------------------------------------
# RAID0 (multiple disks)
# -----------------------------------------------------------------------------
elif [[ "$DATA_DISK_COUNT" -gt 1 ]]; then
echo "数据盘数量大于 1"
if fdisk -l 2>/dev/null | grep -q '/dev/md0'; then
echo "/dev/md0 已存在"
elif fdisk -l 2>/dev/null | grep -q '/dev/md127'; then
echo "发现 /dev/md127,迁移为 /dev/md0"
mdadm --stop /dev/md127
mdadm --assemble "$RAID_DEVICE" --name=0 --update=name $DATA_DISKS
mdadm --detail --scan > /etc/mdadm.conf
else
echo "/dev/md0 不存在,进行初始化"
yes | mdadm -C -a yes "$RAID_DEVICE" -l 0 -n "$DATA_DISK_COUNT" $DATA_DISKS
mdadm -D "$RAID_DEVICE"
mkfs.xfs -f -n ftype=1 "$RAID_DEVICE"
mdadm --detail --scan > /etc/mdadm.conf
fi
mkdir -p "$MOUNT_POINT"
format_and_mount "$RAID_DEVICE"
cat /etc/fstab
df -Th
# -----------------------------------------------------------------------------
# No data disks
# -----------------------------------------------------------------------------
else
echo "数据盘小于1,不进行任何磁盘操作"
fi#!/bin/bash
# =============================================================================
# Script: c-daemon-json.sh
# Description: 配置 Docker daemon.json(数据目录、镜像加速、buildkit 等)
# Note: Docker 数据目录设置为 /data/docker,需要先完成磁盘挂载
# 镜像加速使用腾讯云内网地址,仅适用于腾讯云 CVM
# =============================================================================
set -eo pipefail
mkdir -p /etc/docker
cat>/etc/docker/daemon.json<<EOF
{
"default-address-pools": [
{
"base": "172.17.0.0/12",
"size": 24
}
],
"data-root": "/data/docker",
"registry-mirrors": ["https://mirror.ccs.tencentyun.com"],
"features": {
"buildkit": true
}
}
EOF
#cat> /etc/docker/daemon.json <<EOF
#{
# "debug": true,
# "data-root": "/data/docker",
# "registry-mirrors": ["https://mirror.ccs.tencentyun.com"],
# "features": {
# "buildkit": true
# },
# "metrics-addr": "$(ip route get 1 | awk '{print $7; exit}'):9323",
# "icc": false,
# "bip": "172.17.0.1/16"
#}
#EOF
cat /etc/docker/daemon.json#!/bin/bash
# =============================================================================
# Script: d-install-docker.sh
# Description: 安装 Docker 二进制文件并配置 systemd 服务(docker、containerd)
# Note: 需要 Docker tgz 包已通过 a-download.sh 下载到 files/ 目录
# Docker 数据目录为 /data/docker,需要先完成磁盘挂载
# 安装完成后会自动启用并启动 docker、docker.socket、containerd
# =============================================================================
set -eo pipefail
# -----------------------------------------------------------------------------
# Constants
# -----------------------------------------------------------------------------
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
FILES_DIR="$SCRIPT_DIR/files"
TARGET_DOCKER_VERSION="27.5.1"
SERVICE_DIR="/usr/lib/systemd/system"
ARCH="$(arch)"
# -----------------------------------------------------------------------------
# Stop existing Docker services
# -----------------------------------------------------------------------------
systemctl stop docker docker.socket containerd 2>/dev/null || true
# -----------------------------------------------------------------------------
# Install Docker binaries
# -----------------------------------------------------------------------------
tar -xvf "${FILES_DIR}/docker-${TARGET_DOCKER_VERSION}-${ARCH}.tgz" -C /root/
cp /root/docker/* /usr/bin/
# -----------------------------------------------------------------------------
# Write docker.service
# -----------------------------------------------------------------------------
cat > "${SERVICE_DIR}/docker.service" << 'EOF'
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target docker.socket firewalld.service containerd.service time-set.target
Wants=network-online.target containerd.service
Requires=docker.socket
[Service]
Type=notify
EnvironmentFile=-/etc/sysconfig/docker
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock $OPTIONS
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutStartSec=0
RestartSec=2
Restart=always
# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both the old, and new location are accepted by systemd 229 and up, so using the old location
# to make them work for either version of systemd.
StartLimitBurst=3
# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
# this option work for either version of systemd.
StartLimitInterval=60s
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Comment TasksMax if your systemd version does not support it.
# Only systemd 226 and above support this option.
TasksMax=infinity
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
OOMScoreAdjust=-500
[Install]
WantedBy=multi-user.target
EOF
# -----------------------------------------------------------------------------
# Write docker.socket
# -----------------------------------------------------------------------------
cat > "${SERVICE_DIR}/docker.socket" << 'EOF'
[Unit]
Description=Docker Socket for the API
[Socket]
ListenStream=/run/docker.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker
[Install]
WantedBy=sockets.target
EOF
# -----------------------------------------------------------------------------
# Write containerd.service
# -----------------------------------------------------------------------------
cat > "${SERVICE_DIR}/containerd.service" << 'EOF'
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target dbus.service
[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/bin/containerd
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
EOF
# -----------------------------------------------------------------------------
# Enable and start services
# -----------------------------------------------------------------------------
systemctl daemon-reload
systemctl enable docker docker.socket containerd
systemctl start docker docker.socket containerd
echo "Docker installed ($(arch)):"
echo "docker ps:"
docker ps#!/bin/bash
# =============================================================================
# Script: d-install-docker-plugin.sh
# Description: 从 files/ 目录安装 docker-compose 和 docker-buildx 到 Docker CLI 插件目录
# Note: 需要先执行 a-download.sh 下载插件文件
# 插件安装路径: /usr/libexec/docker/cli-plugins/
# 自动根据当前架构选择对应的二进制文件
# =============================================================================
set -eo pipefail
# -----------------------------------------------------------------------------
# Constants
# -----------------------------------------------------------------------------
PLUGIN_SRC_DIR="$(cd "$(dirname "$0")/files" && pwd)"
PLUGIN_DST_DIR="/usr/libexec/docker/cli-plugins"
# -----------------------------------------------------------------------------
# Install Docker CLI plugins
# -----------------------------------------------------------------------------
mkdir -p "$PLUGIN_DST_DIR"
cp "${PLUGIN_SRC_DIR}/docker-compose-$(arch)" "$PLUGIN_DST_DIR/docker-compose"
cp "${PLUGIN_SRC_DIR}/docker-buildx-$(arch)" "$PLUGIN_DST_DIR/docker-buildx"
echo "Docker CLI plugins installed ($(arch)):"
echo "$PLUGIN_DST_DIR:"
ls -lh "$PLUGIN_DST_DIR"#!/bin/bash
# 证书文件列表
CERTS=("orange-ca.pem" "orange-runner.crt" "orange-runner.key")
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CERTS_DIR="${SCRIPT_DIR}/files"
# 检查并复制证书文件
for cert in "${CERTS[@]}"; do
if [[ ! -f "${CERTS_DIR}/${cert}" ]]; then
echo "错误: 证书文件不存在 ${CERTS_DIR}/${cert}"
exit 1
fi
cp "${CERTS_DIR}/${cert}" /etc/orange-ci/
done
mkdir -p /etc/orange-ci
cat>/etc/orange-ci/runner-config.json<<EOF
{
"cpus": 64,
"defaultCpus": 8,
"memory": 128,
"useCgroupParent": true,
"quotaSize": {
"volume": "512G",
"container": "256G",
"workspace": "512G"
},
"xfsPath": "/data/orange-ci",
"maxWorkspacePerGit": 30,
"volumes": [
"/var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo",
"/var/lib/lxcfs/proc/diskstats:/proc/diskstats",
"/var/lib/lxcfs/proc/loadavg:/proc/loadavg",
"/var/lib/lxcfs/proc/meminfo:/proc/meminfo",
"/var/lib/lxcfs/proc/slabinfo:/proc/slabinfo",
"/var/lib/lxcfs/proc/stat:/proc/stat",
"/var/lib/lxcfs/proc/swaps:/proc/swaps",
"/var/lib/lxcfs/proc/uptime:/proc/uptime",
"/var/lib/lxcfs/sys/devices/system/cpu:/sys/devices/system/cpu"
],
"dockerArgsForDind": [
"-v /var/lib/lxcfs:/var/lib/lxcfs"
],
"networkIsolation": true
}
EOF
echo "/etc/orange-ci:"
ls -lh /etc/orange-ci#!/bin/bash
# =============================================================================
# Script: e-install-runner.sh
# Description: 使用 docker-compose 部署 Orange CI Runner 和 lxcfs 容器
# Note: 需要 Docker 和 docker-compose 插件已安装
# compose 文件生成到 /opt/orange/docker-compose.yml
# 可通过环境变量 RUNNER_VERSION 指定 Runner 版本(默认 latest)
# =============================================================================
set -eo pipefail
# -----------------------------------------------------------------------------
# Constants
# -----------------------------------------------------------------------------
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
COMPOSE_FILE="/opt/orange/docker-compose.yml"
COMPOSE_DIR="$(dirname "$COMPOSE_FILE")"
RUNNER_VERSION="${RUNNER_VERSION:-latest}"
# -----------------------------------------------------------------------------
# Write docker-compose.yml
# -----------------------------------------------------------------------------
mkdir -p "$COMPOSE_DIR"
cat > "$COMPOSE_FILE" << EOF
services:
orange-runner:
image: cnbcool/orange-runner:${RUNNER_VERSION}
restart: always
network_mode: host
privileged: true
container_name: orange-runner
volumes:
- /dev:/dev
- /data/orange-ci:/data/orange-ci:rshared
- /etc/orange-ci:/etc/orange-ci
- /etc/docker:/etc/docker:ro
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
- /usr/libexec/docker/cli-plugins:/usr/libexec/docker/cli-plugins
- /var/log/orange-runner:/data/orange-runner/
- /sys/fs/cgroup:/sys/fs/cgroup
cgroup: host
pid: host
orange-lxcfs:
image: orangeci/lxcfs:latest
pull_policy: always
restart: always
container_name: orange-lxcfs
network_mode: none
privileged: true
cgroup: host
pid: host
volumes:
- /var/lib/lxcfs:/var/lib/lxcfs:rshared
EOF
# -----------------------------------------------------------------------------
# Pull images and start services
# -----------------------------------------------------------------------------
docker compose -f "$COMPOSE_FILE" pull
docker compose -f "$COMPOSE_FILE" up -d#!/bin/bash
# =============================================================================
# Script: f-install-binfmt.sh
# Description: 安装 binfmt systemd 服务,实现多架构容器构建支持
# Note: 依赖 Docker 服务已启动,会在服务启动时自动注册 binfmt
# 包含交叉验证:安装全部架构后反向验证异架构是否正常
# =============================================================================
set -eo pipefail
# -----------------------------------------------------------------------------
# Write binfmt.service
# -----------------------------------------------------------------------------
cat > /usr/lib/systemd/system/binfmt.service << 'EOF'
[Unit]
Description=binfmt
Requires=proc-sys-fs-binfmt_misc.mount docker.service
After=proc-sys-fs-binfmt_misc.mount docker.service
[Service]
Type=oneshot
Restart=on-failure
RestartSec=10s
# 主服务
ExecStart=/bin/bash -c 'docker run --privileged --rm tonistiigi/binfmt --install all && docker run --rm --platform $(arch | sed -e 's/x86_64/arm64/' -e 's/aarch64/amd64/') alpine arch'
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable binfmt.service
systemctl start binfmt.service
journalctl --no-pager -n35 -u binfmt#!/bin/bash
# =============================================================================
# Script: g-install-clean-cgroup.sh
# Description: 安装 cgroup 清理定时任务,定期清理残留 cgroup、orphan 挂载和 ifb 网卡
# Note: 每 10 分钟自动清理一次(通过 systemd timer 实现)
# 同时清理 containerd 中已被 Docker 回收但仍残留的容器
# 同时支持 cgroup v1 和 cgroup v2
# =============================================================================
set -eo pipefail
# -----------------------------------------------------------------------------
# Write clean-cgroup.sh
# -----------------------------------------------------------------------------
cat > /usr/bin/clean-cgroup.sh << 'CLEANCGROUP_SCRIPT'
#!/bin/bash
if grep -q cgroup2 /proc/mounts ; then
# clean expired cgroup
# links 2 说明只有两个链接 一个是. 一个是父目录中的自身 即没有子目录的..
find /sys/fs/cgroup/ -maxdepth 1 -type d -links 2 -mmin +10 -name 'cnb.*.slice' -delete
# clean orphan slice
for slice in $(systemctl list-units 'cnb*' |grep slice |awk '{print $1}'); do
if [ ! -d "/sys/fs/cgroup/$slice" ]; then
systemctl stop "$slice"
fi
done
# clean orphan mount
mounts=$(mount | grep cnb- | awk '{print $3}')
for mount in $mounts; do
slice=$(echo "$mount" | grep -oE 'cnb-\w+-\w+-\w+' | sed 's/-/./g').slice
if [ ! -d "/sys/fs/cgroup/$slice" ] && [ -d "$mount" ]; then
umount "$mount"
fi
done
else
find /sys/fs/cgroup/ -maxdepth 2 -type d -links 2 -mmin +10 -name 'cnb*' -delete
# clean orphan mount
mounts=$(mount | grep cnb- | awk '{print $3}')
for mount in $mounts; do
pipeline_id=$(echo "$mount" | grep -oE 'cnb-\w+-\w+-\w+')
if [ ! -d "/sys/fs/cgroup/memory/$pipeline_id" ] && [ -d "$mount" ]; then
umount "$mount"
fi
done
fi
# clean ifb
veths=$(ls /sys/class/net | grep '\-ifb' | sed 's/-ifb//')
for veth in $veths; do
# 如果源网卡不存在 ifb则删除
if [ ! -e "/sys/class/net/$veth" ]; then
ip link delete "${veth}-ifb"
fi
done
ctr_containers=$(ctr -n moby c ls -q)
for container in $ctr_containers; do
if ! docker container inspect "$container" &> /dev/null; then
ctr -n moby c rm "$container"
fi
done
CLEANCGROUP_SCRIPT
chmod +x /usr/bin/clean-cgroup.sh
# -----------------------------------------------------------------------------
# Write clean-cgroup.service
# -----------------------------------------------------------------------------
cat > /usr/lib/systemd/system/clean-cgroup.service << 'EOF'
[Unit]
Description=clean cgroup and mount for cnb
[Service]
ExecStart=/usr/bin/clean-cgroup.sh
EOF
# -----------------------------------------------------------------------------
# Write clean-cgroup.timer
# -----------------------------------------------------------------------------
cat > /usr/lib/systemd/system/clean-cgroup.timer << 'EOF'
[Unit]
Description=clean cgroup for cnb every 10min
[Timer]
OnUnitInactiveSec=10m
OnBootSec=10m
OnActiveSec=0
[Install]
WantedBy=multi-user.target
EOF
# -----------------------------------------------------------------------------
# Enable timer
# -----------------------------------------------------------------------------
systemctl daemon-reload
systemctl enable --now clean-cgroup.timer2. 配置自托管构建机
2.1 管理后台创建自托管 RUNNER
注
配置的标签以 cnb 开头。

① 在管理后台下载证书。
② 将证书压缩包上传到构建机配置目录,并解压。
- Linux:
/etc/orange-ci - Mac:
$HOME/orange-ci/etc/orange-ci - Windows:
C:/etc/orange-ci
③ 安装脚本会根据指定目录否有 orange-ci.pem orange-runer.crt orange-runner.key,来决定是否开启 TLS 校验。
2.2 接入自托管 RUNNER
注
① CONNECTOR_ENDPOINT: 请务必确认当前环境是否开启了 HTTPS 和当前环境域名,wss://connector.yourdomain,并替换接入脚本的该变量。
② SELF_HOSTED_ID: 管理后台配置完成步骤 2 后,可以获得该 RUNNER 的唯一标识。
③ 在 .\orange-runner.exe start 或 orange-runner start 前,可以使用 .\orange-runner.exe 或 ./orange-runner 启动服务可以直观的看到报错日志。
④ Windows 下文件找不到,关闭隐藏文件的后缀,确认是否符合预期。
⑤ Windows 创建文件可能有 Bom 头的问题,请注意检查。
- 一键接入脚本
curl -fsSL https://docs.cnb.share.ralphlauren.cn/system-runner/scripts/linux.sh | CONNECTOR_ENDPOINT=wss://connector.cnb.share.ralphlauren.cn SELF_HOSTED_ID=xxxx-xxxx-xxxx bash- 配置和存储目录
① 配置证书目录: `/etc/orange-ci`
② RUNNER 配置文件: `/etc/orange-ci/runner-config.json`
③ 数据存储目录: `/data/orange-ci`- 其他常用命令
# 安装服务
orange-runner install
# 启动服务
orange-runner start
# 停止服务
orange-runner stop
# 卸载 service
orange-runner uninstall
# 删除全局命令
rm /usr/local/bin/orange-runner
# 查询 service 运行状态
orange-runner status
# 查看日志
tail -f /data/orange-runner/logs/app.log- 一键接入脚本
curl -fsSL https://docs.cnb.share.ralphlauren.cn/system-runner/scripts/mac.sh | CONNECTOR_ENDPOINT=wss://connector.cnb.share.ralphlauren.cn SELF_HOSTED_ID=xxxx-xxxx-xxxx bash- 配置和存储目录
① 配置证书目录: `$HOME/orange-ci/etc/orange-ci`
② RUNNER 配置文件: `$HOME/orange-ci/etc/orange-ci/runner-config.json`
③ 数据存储目录: `$HOME/orange-ci/data/orange-ci`- 其他常用命令
# 安装服务
orange-runner install
# 启动服务
orange-runner start
# 停止服务
orange-runner stop
# 卸载 service
orange-runner uninstall
# 删除全局命令
rm /usr/local/bin/orange-runner
# 查询 service 运行状态
orange-runner status
# 查看日志
tail -f /data/orange-runner/logs/app.log- 一键接入脚本
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Confirm:$False -Force ; invoke-webrequest https://docs.cnb.share.ralphlauren.cn/system-runner/scripts/windows.ps1 -outfile windows.ps1; $env:CONNECTOR_ENDPOINT='wss://connector.cnb.share.ralphlauren.cn'; $env:SELF_HOSTED_ID='xxxx-xxxx-xxxx'; ./windows.ps1- 配置和存储目录
① 配置证书目录: `C:/etc/orange-ci`
② RUNNER 配置文件: `C:/etc/orange-ci/runner-config.json`
③ 数据存储目录: `C:/data/orange-ci`- 常用命令
# cd 到 orange-runner.exe 所在目录
cd $HOME\Downloads\orange-runner
# 启动服务
.\orange-runner.exe start
# 停止服务
.\orange-runner.exe stop
# 卸载 service
.\orange-runner.exe uninstall
# 删除 exe 文件
Remove-Item -Path .\orange-runner.exe
# 查询 service 运行状态
.\orange-runner.exe status
# 查看日志
Get-Content 'C:\data\orange-runner\logs\app.log' -Wait -Tail 10常见问题
- docker buildx 多平台构建时,构建 arm 平台镜像出现以下报错:Error while loading /usr/sbin/dpkg-split: No such file or directory
解决办法:
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes- 宿主机 git clone 正常。流水线容器内 clone 代码,访问端口超时
原因:需要开启 ipv4 转发,cat /proc/sys/net/ipv4/ip_forward 需要是 1 。如果没有开启,执行下面命令编辑: