从 macOS 的“执念”到 Linux 的“归宿”:Containerlab 实战避坑与部署全录
摘要:本文记录了在Intel Mac上构建NetDevOps实验环境的实战经验。作者尝试在macOS原生环境安装Containerlab失败后,转而采用UTM虚拟机运行Ubuntu Server的方案。详细介绍了Docker配置、镜像源加速、Containerlab离线安装等关键步骤,并展示了通过VSCode Remote-SSH实现远程开发的技巧。文章重点分享了首个双节点拓扑实验的完整过程,验证
序言:NetDevOps 时代的“利器”之争
在网络架构演进至“网络即代码”(Network as Code)的今日,传统的 GNS3 或 EVE-NG 虽廉颇未老,但在轻量化、容器化及 CI/CD 集成面前,难免显出几分笨重。Containerlab 的崛起,为 SRv6、EVPN 等复杂协议的实验开辟了新径。
然而,在我的 Intel-based MacBook 上,这场本该丝滑的技术升级却演变成了一场关乎“环境底层逻辑”的拉锯战。本文旨在记录这段从“环境误区”走向“原生性能”的完整路径,为同样在 NetDevOps 转型路上的同行者提供一份规避“无效折腾”的实操指南。
虽然 Intel Mac 被认为老旧,但在通过 UTM 构建的标准化 Linux 实验室内,它依然是网络架构师手中稳健的利器。
一、 铩羽而归:macOS 直装的“底层天堑”
初探 Containerlab 时,我抱着对 Homebrew 的盲目信任,指望一行 brew install 搞定一切。现实却给了我沉重一击:Containerlab 并未收录于 Homebrew Core 仓库。即便它在社区声名大噪,但在 macOS 官方生态中仍处于“编外”状态。
随后的 curl 脚本尝试,又在 raw.githubusercontent.com 的连接超时中化为乌有。即便强行将二进制文件塞进 /usr/local/bin,更深层的绝望随之而来:Docker Desktop for Mac 的原罪。
macOS 并非 Linux。Docker Desktop 本质上是在 Mac 中运行了一层极薄的虚拟机。Containerlab 依赖的底层 Linux 网络命名空间(Network Namespace)在 macOS 的网桥结构下,犹如“隔靴搔痒”,性能损耗与功能阉割让复杂的 BGP/EVPN 实验变得摇摇欲坠。此时我才意识到:在非原生土壤上构建精密架构,无异于沙滩筑塔。
二、 转机:拥抱 UTM 与 Ubuntu 的“原生力量”
在意识到宿主机环境的局限性后,我果断调转船头。关于如何在 Intel Mac 上通过 UTM 安装 Ubuntu Server,我在上一篇文章《UTM虚拟机安装与代理配置:从MacOS上安装基于UTM的Ubuntu》中已详细阐述,此处不再赘述。
架构关键点:由于我的 MacBook 搭载的是 Intel 芯片,虚拟机及后续所有二进制包必须严格选择 AMD64 (x86_64) 架构,这是保证指令集兼容性的底线。
三、 筑基:Docker 与环境的“精雕细琢”
在 Ubuntu 虚拟机中安装 Docker 是第一步。为了应对网络环境,我们需要精细化配置。
3.1 基础安装
执行官方一键脚本:
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
3.2 核心配置:Docker 国内镜像源加速
这是保证实验顺利的关键。请按照以下四步操作:
第一步:创建或编辑配置文件 在终端执行,创建配置目录并打开编辑器:
sudo mkdir -p /etc/docker
sudo nano /etc/docker/daemon.json
第二步:添加国内镜像源地址 将以下内容复制并粘贴到文件中。我们配置了多个备选源以确保稳定性:
{
"registry-mirrors": [
"https://docker.1panel.live",
"https://docker.1ms.run",
"https://docker.xuanyuan.me",
"https://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn"
1
}
提示:在 nano 编辑器中,粘贴后按 Ctrl+O 再回车保存,按 Ctrl+X 退出。
第三步:重启 Docker 服务 执行以下命令使配置生效:
sudo systemctl daemon-reload
sudo systemctl restart docker
第四步:验证配置 检查输出中是否有你配置的镜像地址:
docker info | grep "Registry Mirrors" -A 5
3.3 权限松绑
为了避免每次执行命令都要输入 sudo,将当前用户加入 Docker 组:
sudo usermod -aG docker $USER
newgrp docker

通过'docker run hello-world'验证docker应用安装配置成功
四、 进阶:Containerlab 的“离线安装”艺术
在网络受限时,直接在虚拟机下载极慢。我们采用“宿主机下载,虚拟机运行”的策略。
- Mac 下载:访问 Containerlab GitHub Releases,下载
containerlab_linux_amd64.tar.gz。 - SCP 投送:在 Mac 终端执行(假设虚拟机 IP 为 192.168.64.2):
scp ~/Downloads/containerlab_linux_amd64.tar.gz lab@192.168.64.2:/home/lab/
- 解压安装:回到 Ubuntu 终端:
tar -xvf containerlab_linux_amd64.tar.gz
sudo mv containerlab /usr/local/bin/
sudo chmod +x /usr/local/bin/containerlab

Containerlab安装成功后,查看版本信息
技术感悟:很多时候,工具的安装不是目的,对环境掌控的确定性才是。
五、 灵魂连接:VS Code Remote-SSH 的“降维打击”
如果说 Ubuntu 是坚实的躯干,那么 VS Code 便是优雅的大脑。
通过 Remote-SSH 插件,我成功构建了“Mac 端编辑代码、Linux 端运行拓扑”的混合开发范式。这里有一个鲜为人知的坑:VS Code Server 的静默下载。在首次连接时,若虚拟机无法直连外网,远程服务将安装失败。
此时的屏幕:左侧是 UTM 沉稳的 CLI 流,右侧是 VS Code 华丽的 YAML 语法高亮。这种生产力工具的错位组合,正是 NetDevOps 工程师追求的效率平衡点。
5.1 Mac 端配置 code 命令
安装 VS Code 后,按下 Command+Shift+P,搜索并执行:
Shell Command: Install 'code' command in PATH此后,你只需在 Mac 终端输入code .即可开启项目。
5.2 远程连接与环境预热
- 安装 Remote - SSH 插件。
- 点击左下角蓝色图标
><,选择Connect to Host...,输入lab@192.168.64.2。 - 关键细节:首次连接会下载
vscode-server。若虚拟机无法直连外网,请在虚拟机的/etc/environment文件中临时设置代理:
export https_proxy=http://你的代理IP:端口

此处左侧是Linux CLI操作界面,右侧是VS code操作界面
六、 涅槃:第一个拓扑的“呼吸感”
在 VS Code 的远程终端中,我们部署一个双节点拓扑验证成果。
- 创建拓扑:新建
lab.clab.yml。
name: hello-world
topology:
nodes:
r1:
kind: linux
image: frrouting/frr:latest
r2:
kind: linux
image: frrouting/frr:latest
links:
- endpoints: ["r1:eth1", "r2:eth1"]
- 一键部署:看着控制台跳出的漂亮表格,那种从“配置黑盒”走向“链路通透”的确定感,正是 NetDevOps 的魅力所在。
sudo clab deploy -t lab.clab.yml

成功部署clab拓扑
- 验证连通性:
- 进入路由器 CLI 配置 IP:
登录 R1: docker exec -it clab-hello-world-r1 vtysh
在 R1 内输入配置:
conf t
interface eth1
ip address 10.1.1.1/24
no shutdown
exit
exit
登录 R2: 按 Ctrl+D 退出 R1,输入 docker exec -it clab-hello-world-r2 vtysh
在 R2 内输入配置:
conf t
interface eth1
ip address 10.1.1.2/24
no shutdown
exit
exit
连通性测试 (Ping): 在 R2 的 vtysh 界面输入:ping 10.1.1.1
期待结果: 看到 64 bytes from 10.1.1.1: icmp_seq=1 ttl=64 time=0.0xx ms。这标志着你的第一个实验圆满成功!
清理实验环境:
sudo containerlab destroy -t lab1.clab.yml
结语:给同行者的几点诤言
我想对还在 EVE-NG 或 macOS 原生环境里挣扎的同行说:
- 敬畏底层:不要试图在非原生内核上模拟复杂的网络逻辑,虚拟机虽然多了一层,但它带来的稳定性价值千金。
- 工具即生产力:VS Code + Remote-SSH 并不是为了好看,而是为了让你从繁琐的文件传输中解脱,专注于拓扑逻辑本身。
- 接受失败:从
command not found到running的距离,往往就是你从普通网工跨越到网络架构师的距离。
网络仿真的未来是属于容器的,而通往未来的路,往往是从踩过一个又一个坑开始。希望这篇实战笔记,能为你解答学习初期的迷茫。
下一篇预告:我们将深入 Containerlab 内部,手把手教你编写首个 SRv6, BGP EVPN 实验拓扑。欢迎关注,一起见证网络技术的自我迭代。
更多推荐



所有评论(0)