name: cnb-docker-transfer
description: 利用CNB云端终端免密登录特性,先在CNB上下载Docker镜像,保存为tar.gz文件,然后通过SCP传输到本地,最后用docker load加载。适用于直接拉取失败或网络超时的场景。
CNB Docker 镜像传输方案
目标
通过”CNB下载 → 打包传输 → 本地加载”的方式,绕过本地网络限制获取Docker镜像。
获取CNB连接信息
方式 A:连接cnb终端,从环境变量获取(推荐)
env | grep -i cnb_vscode_remote_ssh_schema
输出示例:vscode://vscode-remote/ssh-remote+cnb-user@cnb.space/workspace/
快速提取:grep -oP '(?<=ssh-remote\+)[^@]+' <<< "$CNB_VSCODE_REMOTE_SSH_SCHEMA"
方式 B:如果cnb终端没有,让用户手动输入连接地址
如果没有CNB终端或环境变量,用户可以手动提供:
例如完整SSH命令:ssh cnb-ebj-1jmkvgl01-001.1852baf2-119e-4636-a5fa-bf1b922c1b55-2i3@cnb.space
完整工作流程
步骤 1:从目标机器连接CNB终端
# 连接CNB(首次连接需输入yes)
ssh <USERNAME>@cnb.space
步骤 2:在CNB上下载目标镜像
# 拉取目标镜像
docker pull <镜像名>:<标签>
# 验证下载成功
docker images | grep <镜像名>
步骤 3:将镜像保存为tar.gz文件
# 压缩保存(推荐)
docker save <镜像名>:<标签> | gzip > <镜像名>_<标签>.tar.gz
# 验证文件创建成功
ls -lh *.tar.gz
exit
# 退出CNB终端
步骤 4:将镜像文件传输到目标机器
在目标机器终端执行:
# 从CNB下载文件到本地
scp <USERNAME>@cnb.space:/workspace/<文件名>.tar.gz ./
# 如果文件不在workspace,先移动到用户目录(在CNB终端执行)
mv <文件名>.tar.gz ~/
then: scp <USERNAME>@cnb.space:~/<文件名>.tar.gz ./
步骤 5:在目标机器加载镜像
# 加载压缩的tar.gz文件
gunzip -c <文件名>.tar.gz | docker load
# 或直接加载
docker load < <文件名>.tar.gz
# 验证加载成功
docker images | grep <镜像名>
步骤 6:验证测试
docker run --rm <镜像名>:<标签> <测试命令>
# 例如:docker run --rm busybox:latest echo "OK"
步骤 7:清理临时文件
# 清理CNB文件(在CNB终端)
rm -f *.tar.gz
# 清理目标机器文件(可选)
rm -f *.tar.gz
快速参考
| 步骤 | 位置 | 命令 | 说明 |
|---|---|---|---|
| 1. 获取用户名 | 任意终端 | env \| grep -i cnb_vscode_remote_ssh_schema |
🚀 快速获取 |
| 手动解析用户名 | 本地 | echo "cnb-user@cnb.space" \| cut -d@ -f1 |
从地址提取 |
| 2. 连接CNB | 本地终端 | ssh <USERNAME>@cnb.space |
首次需输入yes |
| 3. 下载镜像 | CNB终端 | docker pull <镜像名> |
在CNB上下载 |
| 4. 打包镜像 | CNB终端 | docker save <镜像名> \| gzip > <文件>.tar.gz |
压缩保存 |
| 5. 传输文件 | 本地终端 | scp <USERNAME>@cnb.space:<文件> ./ |
SCP下载 |
| 6. 加载镜像 | 本地终端 | gunzip -c <文件>.tar.gz \| docker load |
本地加载 |
| 7. 验证测试 | 本地终端 | docker run --rm <镜像名> echo "OK" |
功能验证 |
实际应用示例
示例1:拯救busybox镜像拉取
# 手动提供连接地址的情况
USERNAME=$(echo "cnb-ebj-1jmkvgl01-001.1852baf2-119e-4636-a5fa-bf1b922c1b55-2i3@cnb.space" | cut -d@ -f1)
echo "使用用户名: $USERNAME"
# 连接CNB并下载busybox
ssh $USERNAME@cnb.space
docker pull busybox:latest
docker save busybox:latest | gzip > busybox_latest.tar.gz
exit
# 传输到本地
scp $USERNAME@cnb.space:~/busybox_latest.tar.gz ./
# 本地加载
gunzip -c busybox_latest.tar.gz | docker load
# 验证
docker run --rm busybox:latest echo "busybox传输成功!"
示例2:从SSH命令解析用户名
# 如果用户直接提供SSH命令
SSH_CMD="ssh cnb-ebj-1jmkvgl01-001.1852baf2-119e-4636-a5fa-bf1b922c1b55-2i3@cnb.space"
USERNAME=$(echo "$SSH_CMD" | sed 's/^ssh //' | awk '{print $1}')
# 或者更简单的方法
USERNAME=$(echo "$SSH_CMD" | grep -o '^ssh [^@]*' | sed 's/^ssh //')
# 或者直接用cut(如果格式固定)
USERNAME=$(echo "$SSH_CMD" | awk '{print $2}' | cut -d@ -f1)
echo "解析到的用户名: $USERNAME"
示例3:批量传输脚本
#!/bin/bash
# 准备多个镜像用于离线环境
USERNAME="cnb-user" # 手动设置或从其他方式获取
IMAGES=("nginx:alpine" "redis:alpine" "openjdk:8-jdk-slim")
for image in "${IMAGES[@]}"; do
name=$(echo $image | sed 's/:/-/g')
# 在CNB操作 ssh $USERNAME@cnb.space "
docker pull $image
docker save $image | gzip > ${name}.tar.gz
"
# 下载到本地 scp $USERNAME@cnb.space:~/${name}.tar.gz ./
# 本地加载 gunzip -c ${name}.tar.gz | docker load
echo "✅ $image 准备完成"
done
用户名解析技巧
常见输入格式及处理方法
完整SSH命令:
ssh cnb-user@cnb.spaceUSERNAME=$(echo "$INPUT" | awk '{print $2}' | cut -d@ -f1)- 仅地址:
cnb-user@cnb.spacebash USERNAME=$(echo "$INPUT" | cut -d@ -f1)
- 仅地址:
带端口:
cnb-user@cnb.space:22USERNAME=$(echo "$INPUT" | cut -d@ -f1)- 复杂SSH命令:
ssh -p 22 cnb-user@cnb.spacebash USERNAME=$(echo "$INPUT" | grep -o '[^@]*@cnb\.space' | cut -d@ -f1)
- 复杂SSH命令:
通用解析函数
parse_cnb_username() {
local input="$1"
# 移除ssh前缀
input=$(echo "$input" | sed 's/^ssh //')
# 提取@cnb.space前的部分
if echo "$input" | grep -q '@cnb\.space'; then
echo "$input" | grep -o '^[^@]*'
else
echo "$input" | cut -d@ -f1
fi
}
# 使用示例
USERNAME=$(parse_cnb_username "ssh cnb-user@cnb.space")
echo $USERNAME # 输出: cnb-user
USERNAME=$(parse_cnb_username "cnb-user@cnb.space")
echo $USERNAME # 输出: cnb-user
故障排除
❌ SCP连接失败
- 检查文件路径是否正确
- 在CNB上使用绝对路径:
~/filename.tar.gz - 尝试移动文件到用户主目录再传输
❌ 镜像加载失败
- 检查文件完整性:
gunzip -t filename.tar.gz - 重新传输文件
- 检查磁盘空间:
df -h
❌ CNB存储空间不足
- 清理不需要的文件:
docker system prune -a - 使用更小的镜像标签
- 分批处理,及时清理临时文件
总结
CNB Docker镜像传输方案是代理方案的完美补充:
- 代理方案:适合大多数常规镜像的快速获取
- 传输方案:适合疑难镜像、大镜像和批量部署场景
结合使用,几乎可以应对任何网络环境下的Docker镜像获取需求!