简介:面向SDN初学者与网络工程师,这份教程详解Ubuntu 20.0.4系统下OpenDaylight控制器的完整部署过程。内容从实验背景与目的切入,先介绍OpenFlow协议在SDN中的作用,再分步讲解更新系统软件源、安装并配置JDK 8环境变量(JAVA_HOME、java -version验证)、添加Maven仓库与GPG密钥、校验Maven版本、从官网下载OpenDaylight并解压启动,以及通过Karaf安装REST API、L2 Switch、OpenFlow插件等组件。教程还设计了Mininet生成拓扑连接OpenDaylight并执行ping命令抓包的验证环节,帮助读者用Wireshark分析OpenFlow 1.3协议交互过程。文档以docx格式呈现,共1个文件,压缩包大小1.25MB,资源已被1338人学习。教程源自真实实验记录,每一步都配有执行命令与用途说明,整体为可复现的实验手册,并提及软件源更新失败、Maven仓库不可用等常见问题的处理思路,适合需要完成SDN课程实验、撰写网络实验报告的高校学生,也适合希望快速搭建OpenDaylight开发环境的网络工程师。对于SDN入门而言,这份资料既能巩固OpenFlow协议原理,也能积累控制器部署实战经验。
1. Ubuntu 20.04 跑通 OpenDaylight 的入口,先看版本与运行形态
标题写的是“Ubuntu20.0.4”,业内通常指 Ubuntu 20.04 LTS。OpenDaylight(下称 ODL)是一套 SDN 控制器,实际是一个运行在 Karaf 容器里的 Java 程序,安装方式不像普通软件那样apt install完事,而是下载发行包、配好 JDK、启动容器、再安装功能组件。安装本身不复杂,真正的门槛在版本对齐:ODL 各发行版要求的 Java 版本不同,Ubuntu 20.04 默认源里的 JDK 又不止一个,装错版本会在启动阶段直接报类加载错误。本文从环境检查开始,把“下载、启动、验证、排错、服务化”一条链路写清楚,适合第一次在 20.04 上部署 ODL 的网络工程师,也适合后续要接 OpenFlow 交换机做实验的开发者。
2. 安装 OpenDaylight 前,在 Ubuntu 20.04 上核对 JDK、内存与端口
2.1 Java 版本先对齐,再谈下载
ODL 本质是跑在 Karaf 里的 Java 应用,JDK 版本直接影响能不能启动。较新的 ODL 主版本普遍要求 JDK 11 及以上,JDK 8 只能跑老发行版,Ubuntu 20.04 系统自带的 openjdk-8 如果直接拿来启动新版 ODL,最常见的报错是UnsupportedClassVersionError,还有一类表现为 Karaf 启动到一半进程直接退出,日志里只留一行 Java 版本不满足的提示。常见做法是先明确你要装的 ODL 版本,再去官网发行说明里核对对应的 JDK,然后用 apt 装指定版本,避免多个 JDK 混用把JAVA_HOME指向错误位置。
sudo apt update sudo apt install -y openjdk-11-jdk java -version readlink -f "$(which java)"第一段命令安装 openjdk-11-jdk,第二段验证当前生效的 Java 版本,第三段readlink找出 java 可执行文件的真实路径。这个真实路径后面要写成JAVA_HOME,因为很多 ODL 启动脚本只认JAVA_HOME/bin/java,不认 PATH 里的软链路径。装完建议把环境变量写进 profile:
echo "export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64" | sudo tee /etc/profile.d/java.sh echo "export PATH=\$JAVA_HOME/bin:\$PATH" | sudo tee -a /etc/profile.d/java.sh source /etc/profile.d/java.sh这里把JAVA_HOME指向 openjdk-11 的安装目录,PATH 追加到$JAVA_HOME/bin,写在/etc/profile.d/java.sh里保证所有登录用户都能读到。注意echo里的\$PATH必须转义,否则写入文件时变量会被当场展开成当前 PATH 值,后面登录时 PATH 里就没有 Java 目录了。常见误用是把JAVA_HOME写进某个用户自己的.bashrc,然后用 systemd 启动 ODL 时报找不到 Java,原因就是 systemd 默认不加载用户 shell 配置文件。
2.2 内存、磁盘与系统架构检查
ODL 是内存大户,一个只装了 OpenFlow 和 RESTCONF 基础功能的实例,启动后 Java 进程常驻内存 2GB 左右,如果还要跑拓扑服务和多个南向插件,建议空闲内存不低于 4GB。在 VMware 或 VirtualBox 里用 Ubuntu 20.04 虚拟机跑 ODL 时,虚拟机内存至少分配 4GB,否则 Karaf 启动到一半会被系统 OOM 杀掉,卡在“进程刚起来就消失”的状态。磁盘方面,ODL 发行包解压后约 1GB,data/log和data/tmp目录会持续写日志,给/opt或安装目录所在分区留 10GB 空间比较稳妥。
free -h df -h /opt uname -mfree -h看可用内存,df -h /opt确认安装目录所在磁盘剩余空间,uname -m输出x86_64表示 64 位 x86 架构,输出aarch64则是 ARM 架构。ODL 官方发行包同时提供 x86_64 和 ARM 版本,在树莓派、RK3588 这类 ARM 开发板上跑时记得选对应架构的包,ARM 上部分第三方 feature 没有预编译,只能自己编译源码,这一点比 x86 要麻烦不少。
2.3 端口清单与占用检查
ODL 固定监听几个端口,安装前先确认这些端口没有被占用,省得后面排查半天。最核心的是 8101 和 8181 两个:8101 是 Karaf SSH 控制台,8181 是 HTTP 管理界面和 RESTCONF API 入口。OpenFlow 南向协议默认端口是 6633,但多数 ODL 发行版要求显式监听 6653,实际用哪个以配置为准。
| 端口 | 用途 | 默认协议 |
|---|---|---|
| 8101 | Karaf SSH 控制台 | SSH |
| 8181 | HTTP 管理界面 / RESTCONF | HTTP |
| 6633 / 6653 | OpenFlow 控制器监听 | TCP |
| 8080 | 部分版本管理服务备用 | HTTP |
检查端口占用用ss -ltnp,只看感兴趣的几个端口:
ss -ltnp | grep -E '8101|8181'如果输出为空说明端口空闲。如果已有进程占用,ss输出里能看到进程 PID,配合ps -p PID -o comm=确认是什么程序占着。常见占用来源是之前装过的 ZooKeeper、其他 Karaf 实例或系统自带的端口映射服务,优先级高的处理办法是停掉旧进程,而不是硬改 ODL 端口,因为改端口要同时改etc/jetty.xml和etc/org.apache.karaf.shell.cfg多处配置,容易漏。
3. 下载 OpenDaylight 发行包并启动 Karaf 容器
3.1 选对发行包类型,用 wget 拉取
ODL 的发布包在官网 Release 页面,每个版本提供一个.tar.gz格式的发行包,文件名通常类似opendaylight-<版本号>.tar.gz。注意发行包和源码包要区分:源码包是给二次开发用的,部署控制器直接下载二进制发行包即可。常见误区是去 Ubuntu 源里apt search opendaylight,20.04 官方源里的 ODL 版本老旧,和当下 OpenFlow 交换机固件的兼容性不一定好,建议直接下载官网对应版本的包。
cd /opt sudo wget -O opendaylight.tgz <官网发行包链接> sudo tar xf opendaylight.tgz sudo ls -d opendaylight-*/下载到/opt下,用-O统一命名成opendaylight.tgz,方便后续脚本引用,然后解压。tar解压出的目录名带版本号,例如opendaylight-0.18.0之类,这就是 ODL 的家目录。解压后先别急着启动,确认一下bin/karaf文件有执行权限,权限不对时启动脚本会报Permission denied,这类问题在把包解压到挂载盘时很常见。
3.2 创建专用用户并设置目录属主
不推荐用 root 直接跑 ODL。Java 进程一旦被攻破,root 权限会让影响范围扩大很多;而且 ODL 会在data目录下持续写入日志和临时文件,以 root 运行后这些文件属主全是 root,后续切回普通用户维护时清理日志要反复加sudo。常见做法是创建专用系统用户:
sudo useradd -r -m -s /bin/bash odl sudo chown -R odl:odl /opt/opendaylight-* sudo -u odl /opt/opendaylight-*/bin/karafuseradd -r创建系统用户,-m同时建 home 目录,-s /bin/bash保证能登录调试。chown -R把整个 ODL 目录属主改成odl,否则首次启动时 Karaf 写不了data/tmp和data/log下的文件。最后一条命令用sudo -u odl切换到专用用户身份前台启动 Karaf,前台启动能看到完整启动日志,适合第一次部署时观察是否报错。
3.3 首次启动后先装 feature,再重启加载
bin/karaf启动后,终端进入 Karaf 控制台,提示符变成opendaylight-user@root>。看到提示符不代表 ODL 已经就绪,因为控制器核心功能是按 feature 模块加载的,默认只启动了一个容器壳,OpenFlow 插件、RESTCONF 接口都要手动安装。这一步是新手最容易卡住的地方:启动后访问 8181 端口发现打不开,以为安装失败,实际只是没装 HTTP 相关 feature。
feature:install odl-restconf odl-openflowplugin-flow-services这条命令在 Karaf 控制台里执行,安装 RESTCONF 北向接口和 OpenFlow 流表服务组件。feature:install是 Karaf 的统一安装命令,注意拼写是feature单数,写成features:install会报命令不存在。安装过程中控制台有可能短暂无响应,这是 Karaf 在下载并解析依赖 bundle,属正常现象。装完执行shutdown -r重启容器,让所有 feature 完整加载,然后退出控制台:
shutdown -r重启后再次进入控制台,输入feature:list -i可以查看已安装的 feature 列表,确认odl-restconf和odl-openflowplugin-flow-services都在其中。如果以后每次启动都想自动加载这些模块,可以把 feature 列表写进etc/org.apache.karaf.features.cfg的featuresBoot配置项,用逗号分隔,这样免去每次手动安装。手动安装的方式适合先验证功能,验证通过后再固化到配置里。
3.4 清理 Karaf 缓存的两个场景
ODL 跑久了或者升级 feature 之后,偶尔会出现模块加载不全、控制台命令找不到的情况,常见处理是清缓存重启。Karaf 默认缓存目录是data/cache,里面存放已解析的 bundle 状态,强制清空可以用:
sudo -u odl /opt/opendaylight-*/bin/karaf cleanclean参数会在启动时删除缓存并重新解析所有 feature,启动时间比正常启动长不少。需要知道的是:clean不是常规操作,只在怀疑缓存损坏时才用。平时遇到 feature 装了没生效,先执行feature:list -i看列表,确认已安装再考虑重启;动不动就clean会掩盖真正的问题(比如写错了 feature 名或版本不匹配)。
4. 验证 OpenDaylight 服务状态并处理安装排错
4.1 从 SSH 控制台检查模块运行状态
Karaf 启动完成后,8101 端口开始监听 SSH。用 SSH 客户端连接时,用户名和默认密码都是karaf,连接命令如下:
ssh -p 8101 karaf@localhost提示密码时输入karaf即可进入控制台。注意 8101 的 SSH 是 Karaf 内置的,和 Ubuntu 系统的 OpenSSH 没有关系,即使系统 sshd 没启动也不影响这个端口。进入控制台后检查两个东西:已经安装的 feature 和 OpenFlow bundle 的运行状态。
feature:list -i bundle:list | grep -i openflowfeature:list -i只显示已安装的 feature,确认odl-openflowplugin-flow-services在列表里;bundle:list | grep -i openflow查看 OpenFlow 相关 bundle 的状态,第一列是 bundle ID,状态列应该是Active。如果看到Resolved或Installed,说明 bundle 没启动成功,多半是依赖缺失或端口被占。生产环境建议修改etc/users.properties里的默认密码,否则任何能访问 8101 端口的人都能直接拿到 Karaf 控制台权限,这个文件里把karaf = karaf, group这行改成强密码即可。
4.2 用 HTTP 和 curl 探测 RESTCONF 是否可用
SSH 控制台确认的是模块加载状态,业务上最关心的是北向接口能不能调。ODL 的 RESTCONF 服务监听 8181,浏览器访问http://<服务器IP>:8181/index.html可以看到登录页面,默认管理员账号密码是admin/admin。也可以不看页面,直接 curl 探测 API:
curl -u admin:admin http://localhost:8181/restconf/operational/network-topology:network-topology返回 200 状态码和一串 JSON 数据,说明 RESTCONF 服务正常;返回 401 是认证失败,检查账号密码;返回 404 说明 URL 路径不对,不同版本的 RESTCONF 模块挂载路径略有差异。这条 curl 命令同时也是后续写自动化脚本时的探活命令,判断 ODL 是否存活比单纯看端口要可靠,端口在监听但 RESTCONF 模块没加载完的情况并不少见。
4.3 安装期常见报错与排查路径
安装过程中遇到最多的是下面几类问题,按出现频率排序:
JAVA_HOME 指向错误或 JDK 版本不对。启动脚本找 Java 失败时报Unable to find any Javadoc或直接提示JAVA_HOME没有指向 JDK,此时回到第 2 章检查/etc/profile.d/java.sh和bin/karaf脚本里的JAVA_HOME变量。如果启动过程报UnsupportedClassVersionError,是 JDK 版本低于 ODL 要求,换更高版本 JDK 即可。
8101 端口连不上。Ubuntu 服务器上执行ssh -p 8101提示 Connection refused,先确认 Karaf 进程活着:ps -ef | grep karaf,如果进程存在但端口没监听,大概率是 Karaf 还在启动过程中,等待 1 到 2 分钟再试。进程都没了就看内存是否够,dmesg | tail里有 OOM 记录就可以确认。
feature 安装报 “Command not found”。输入feature:install提示找不到命令,通常是 Karaf 控制台没完全就绪,等待几秒再输入,或者执行shell:init重新初始化命令补全。更隐蔽的情况是拼写错误,feature和features只差一个字母,命令却完全不同。
日志定位。所有安装期问题最终都集中在日志里排查,ODL 日志目录是/opt/opendaylight-*/data/log/,核心文件是karaf.log。也可以在 Karaf 控制台里执行log:tail实时跟踪日志输出。排查顺序建议是:先看进程在不在,再看端口通不通,再看日志里最后的异常堆栈,最后回到 feature 安装列表确认模块状态。
5. 把 OpenDaylight 注册成 systemd 服务,开机自启并接管日志
前面的启动方式适合调试,生产环境要把 ODL 交给 systemd 管理。相比自己写启动脚本,systemd 的好处是崩溃自动拉起、开机自动启动、日志统一进 journalctl,用一套命令就能查状态和日志。
新建/etc/systemd/system/opendaylight.service:
[Unit] Description=OpenDaylight SDN Controller After=network.target [Service] Type=simple User=odl Group=odl WorkingDirectory=/opt/opendaylight Environment=JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 ExecStart=/opt/opendaylight/bin/karaf run Restart=on-failure RestartSec=30 SuccessExitStatus=143 [Install] WantedBy=multi-user.targetExecStart用了karaf run,这是 Karaf 4 提供的前台运行模式,systemd 必须管理前台进程才能可靠判断服务存活;如果写成不带run的bin/karaf,Karaf 会 fork 出子进程后父进程退出,systemd 会认为服务启动失败。SuccessExitStatus=143表示进程被 SIGTERM 结束时 systemd 不把它当错误,因为systemctl stop会主动发 SIGTERM 给 Java 进程。Environment不能省,systemd 不加载用户的.bashrc和/etc/profile.d,非 root 用户的JAVA_HOME必须显式写在这里,User=odl也要和安装时创建的用户保持一致。
启动并设置开机自启:
sudo systemctl daemon-reload sudo systemctl enable --now opendaylight systemctl status opendaylight journalctl -u opendaylight -fenable --now同时完成开机自启和立即启动。status查看服务运行状态和最近日志,journalctl -u opendaylight -f实时跟踪 ODL 输出。相比直接看data/log/karaf.log,journalctl 的优势是重启轮转后日志不会丢。如果服务反复重启,用journalctl -u opendaylight -u 30看最近 30 行日志定位原因,常见问题是WorkingDirectory写错导致 ODL 找不到etc目录、User=odl对安装目录没有写权限,以及JAVA_HOME路径和实际 JDK 安装位置不一致。
服务托管后的验证方式和第 4 章一样:先看端口再 curl RESTCONF。唯一区别是确认 systemd 把进程真正拉起来了,执行systemctl status opendaylight看到Active: active (running)后再测 8101 和 8181。后续要调整 JVM 内存,编辑/opt/opendaylight/bin/setenv里的KARAF_OPTS=-Xmx4G并重启服务即可。
本文还有配套的精品资源,点击获取