当前位置: 首页 > article >正文

OpenWrt 与 Docker:打造轻量级容器化应用平台技术分享

文章目录

    • 前言
    • 一、OpenWrt 与 Docker 的集成前提
      • 1.1 硬件与内核要求
      • 1.2 软件依赖
    • 二、Docker 环境部署与验证
      • 2.1 基础服务配置
      • 2.2 存储驱动适配
    • 三、容器化应用部署实践
      • 3.1 资源限制策略
      • 3.2 Docker Compose 适配
    • 四、性能优化与监控
      • 4.1 容器资源监控
      • 4.2 镜像精简策略
    • 五、典型问题解决方案
      • 5.1 端口冲突处理
      • 5.2 低性能设备适配
    • 六、内网穿透远程访问
      • 6.1 下载公钥
      • 6.2 将cpolar源添加至包管理器
      • 6.3 更新包管理器
      • 6.4 安装cpolar插件
      • 6.5 重启OpenWRT
      • 6.6 为OpenWRT Web管理界面配置公网地址
    • 总结
      • 附:硬件兼容性测试列表

前言

OpenWrt 作为一个高度可定制的嵌入式 Linux 发行版,其模块化设计为 Docker 容器化部署提供了可能性。

将 Docker 引入 OpenWrt 环境,能够带来以下优势:

  • 简化应用部署: 无需手动安装依赖和配置环境,只需使用 Docker 镜像即可快速部署应用。
  • 隔离性与安全性: Docker 容器提供应用隔离,避免应用之间的相互干扰和潜在安全风险。
  • 资源利用率提升: Docker 容器共享宿主机的内核,占用资源更少,能够充分利用 OpenWrt 设备的有限资源。
  • 可移植性与可扩展性: Docker 镜像可以在不同的 OpenWrt 设备之间轻松迁移和部署,方便扩展应用规模。
  • 版本控制与回滚: Docker 镜像具有版本控制功能,可以方便地回滚到之前的版本。

然而,受限于默认内核配置和硬件资源,在 OpenWrt 上运行 Docker 需解决内核功能支持存储架构适配两大核心问题。本文将基于技术实践,分享在 OpenWrt 设备上搭建 Docker 环境的完整方案,涵盖从内核编译到容器优化的全流程。

请添加图片描述


一、OpenWrt 与 Docker 的集成前提

1.1 硬件与内核要求

  • 硬件配置
    CPU 需支持硬件虚拟化(ARMv7+/x86_64),内存 ≥1GB,存储空间 ≥4GB(建议通过 USB 扩展存储)。
  • 内核编译
    OpenWrt 默认内核未启用 Docker 依赖的以下模块,需通过 make menuconfig 手动启用:
    # 必需内核选项
    CONFIG_CGROUPS=y          # 控制组资源隔离
    CONFIG_NAMESPACES=y       # 容器命名空间
    CONFIG_VETH=y             # 虚拟以太网设备
    CONFIG_BRIDGE=y           # 网桥支持
    CONFIG_OVERLAY_FS=y       # Overlay 文件系统
    

1.2 软件依赖

  • 第三方软件源
    OpenWrt 官方源不提供 Docker 软件包,需通过第三方源(如 istore)安装:
    # 添加 ARM 架构源示例
    echo "src/gz istore https://istore.linkease.com/repo/arm_cortex-a9" >> /etc/opkg/customfeeds.conf
    opkg update
    opkg install docker dockerd
    
  • 存储配置
    挂载可读写分区作为 Docker 数据目录:
    mkdir -p /mnt/docker
    mount /dev/sda1 /mnt/docker  # 假设 sda1 为扩展存储设备
    dockerd --data-root=/mnt/docker &
    

二、Docker 环境部署与验证

2.1 基础服务配置

# 启动 Docker 守护进程(指定存储路径)
/etc/init.d/docker start --data-root=/mnt/docker# 验证 Docker 安装
docker info | grep "Storage Driver"  # 应返回 overlay2

2.2 存储驱动适配

若使用 overlay2 驱动,需确保:

  1. 内核版本 ≥4.0
  2. 文件系统为 ext4/btrfs
  3. 执行 mount -t overlay overlay -o lowerdir=/mnt/docker,upperdir=/mnt/docker/diff,workdir=/mnt/docker/work /mnt/merged 测试挂载

三、容器化应用部署实践

3.1 资源限制策略

通过 cgroups 控制容器资源开销:

# 限制容器内存为 256MB,CPU 权重为 50%
docker run -d --name my_app \--memory=256m \--cpu-shares=512 \-p 8080:80 \nginx:alpine

3.2 Docker Compose 适配

OpenWrt 需手动安装 Python 环境:

opkg install python3 python3-pip
pip3 install docker-compose

编写 docker-compose.yml

version: "3.8"
services:web:image: nginx:alpineports:- "8080:80"deploy:resources:limits:cpus: "0.5"memory: 256M

四、性能优化与监控

4.1 容器资源监控

# 实时查看容器资源占用
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"# 生成性能报告
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \docker.io/docker/docker-bench-security

4.2 镜像精简策略

  • 使用多阶段构建(Multi-stage Build)
  • 选择 Alpine 基础镜像
  • 移除调试工具(如 curl/telnet

示例 Dockerfile:

FROM golang:1.18 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o main .FROM alpine:3.15
COPY --from=builder /app/main /
CMD ["/main"]

五、典型问题解决方案

5.1 端口冲突处理

禁用 OpenWrt 默认占用的 80 端口服务:

/etc/init.d/uhttpd stop
/etc/init.d/uhttpd disable

5.2 低性能设备适配

  • 镜像构建:在 x86 主机交叉编译镜像后推送至仓库
  • 资源分配:使用 --cpuset-cpus 绑定特定 CPU 核心
  • 日志优化:限制容器日志大小防止存储溢出
    docker run --log-driver=json-file \--log-opt max-size=10m \--log-opt max-file=3
    

六、内网穿透远程访问

如果想实现出门在外,也能随时随地访问家中的OpenWRT软路由系统,但因为没有公网IP而无法实现。可以借助cpolar内网穿透工具来实现公网访问!接下来介绍一下如何安装cpolar内网穿透并实现公网访问!

首先需要在终端SSH连接OpenWRT系统,输入OpenWRT登录时的root账号密码password即可成功连接。

6.1 下载公钥

首先执行下方命令下载公钥:

wget -O cpolar-public.key http://openwrt.cpolar.com/releases/public.key

6.2 将cpolar源添加至包管理器

echo "src/gz cpolar_packages http://openwrt.cpolar.com/releases/packages/$(. /etc/openwrt_release ; echo $DISTRIB_ARCH)"  >>  /etc/opkg/customfeeds.conf

6.3 更新包管理器

opkg update

image-20240417113415168

6.4 安装cpolar插件

opkg install cpolar
opkg install luci-app-cpolar
opkg install luci-i18n-cpolar-zh-cn

image-20240417154604437

image-20240417154621079

image-20240417154643961

6.5 重启OpenWRT

reboot

然后可以看到OpenWRT重启,重启后重新登录OpenWRT后台,在左侧菜单的服务中就会出现cpolar服务,绑定token即可正常使用:

image-20240417121451765

6.6 为OpenWRT Web管理界面配置公网地址

首先,在OpenWRT管理界面左侧菜单中进入服务,选择cpolar内网穿透。

image-20240417155727891

然后,点击打开webui管理界面:http://localhost:9200,在跳转的浏览器网页中输入你注册的cpolar账号密码进行登录:

image-20240417155834051

登录后,点击左侧仪表盘的隧道管理——创建隧道,

创建一个 OpenWRT Web管理界面的公网http地址隧道

  • 隧道名称:可自定义命名,注意不要与已有的隧道名称重复,本例中使用:openwrt
  • 协议:选择http
  • 本地地址:80
  • 域名类型:免费选择随机域名
  • 地区:选择China VIP

点击创建

image-20240417160315275

隧道创建成功后,点击左侧的状态——在线隧道列表,查看所生成的公网访问地址,有两种访问方式,一种是http 和https,任选其一即可。

image-20240417160543521

使用Cpolar生成的公网地址,在手机或任意设备的浏览器进行登录访问,即可成功看到 OpenWRT Web管理界面,这样一个可以远程访问的公网地址就创建好了,使用了cpolar的公网域名,无需自己购买云服务器,即可到公网访问本地内网的openwrt系统了!

ps:如果我们需要长期异地远程访问OpenWRT Web管理界面,由于刚才创建的是随机的地址,24小时会发生变化。另外它的网址是由随机字符生成,不容易记忆。如果想把域名变成固定的二级子域名,并且不想每次都重新创建隧道来远程访问,我们可以选择创建一个固定不变的公网地址来解决这个问题。

《使用cpolar为本地openwrt web管理界面配置固定公网地址》

总结

在 OpenWrt 上部署 Docker 需克服内核适配与资源限制两大挑战。通过自定义编译内核、扩展存储设备、限制容器资源,可在低功耗设备上实现轻量级容器化应用的稳定运行。建议优先部署无状态服务(如 HTTP API 代理),并严格监控资源使用情况。对于高负载场景,仍推荐使用 x86 架构设备作为生产环境载体。


附:硬件兼容性测试列表

设备型号CPU 架构内存Docker 运行状态
Raspberry Pi 4BARM Cortex-A724GB✔️ 稳定
GL-iNet MT1300ARM Cortex-A71GB⚠️ 需关闭 Swap
x86 工控机Intel Celeron8GB✔️ 最佳性能

相关文章:

OpenWrt 与 Docker:打造轻量级容器化应用平台技术分享

文章目录 前言一、OpenWrt 与 Docker 的集成前提1.1 硬件与内核要求1.2 软件依赖 二、Docker 环境部署与验证2.1 基础服务配置2.2 存储驱动适配 三、容器化应用部署实践3.1 资源限制策略3.2 Docker Compose 适配 四、性能优化与监控4.1 容器资源监控4.2 镜像精简策略 五、典型问…...

tkinter的文件对话框:filedialog

诸神缄默不语-个人技术博文与视频目录 文章目录 一、前言二、tkinter.filedialog模块详解2.1 模块导入方式2.2 通用参数说明 三、五大核心函数实战3.1 选择单个文件 - askopenfilename()3.2 多文件选择 - askopenfilenames()3.3 保存文件对话框 - asksaveasfilename()3.4 选择目…...

C++初阶----模板初阶

引言 什么是模板 模板是泛型编程的基础,泛型编程是以一种独立于任何特定类型的方式编写代码。 模板也是创建泛型类或者函数的蓝图。 如:库容器,迭代器和算法,都是泛型编程的例子 1. 泛型编程 首先,我们应该了解什么是…...

网络流量分析 | 流量分析基础

流量分析是网络安全领域的一个子领域,其主要重点是调查网络数据,以发现问题和异常情况。本文将涵盖网络安全和流量分析的基础知识。 网络安全与网络中的数据 网络安全的两个最关键概念就是:认证(Authentication)和授…...

幻读是什么项目中是怎么保证不会出现幻读

幻读(Phantom Read)是数据库并发控制中的一种现象,指的是在事务处理中,一个事务在读取某个数据范围时,另一个事务插入、删除或者修改了该数据范围,导致第一个事务再次读取数据时,看到的数据发生…...

C语言实现对哈希表的操作:创建哈希表与扩容哈希表

一. 简介 前面文章简单了解了哈希表 这种数据结构,文章如下: 什么是哈希表-CSDN博客 本文来学习一下哈希表,具体学习一下C语言实现对哈希表的简单实现。 二. C语言实现对哈希表的操作 1. 哈希表 哈希表(Hash Table&#xff…...

MYSQL 常用字符串函数 和 时间函数详解

一、字符串函数 1、​CONCAT(str1, str2, …) 拼接多个字符串。 SELECT CONCAT(Hello, , World); -- 输出 Hello World2、SUBSTRING(str, start, length)​​ 或 ​SUBSTR() 截取字符串。 SELECT SUBSTRING(MySQL, 3, 2); -- 输出 SQ3、LENGTH(str)​​ 与 ​CHAR_LENGTH…...

通过API接口在自己的独立站系统上架商品信息。(实战案例)

以下是一个通过API接口在独立站系统上架商品信息的实战案例,以某跨境电商独立站集成亚马逊产品数据为例,详细说明技术实现流程和关键代码逻辑: 案例背景 某跨境电商独立站需要从亚马逊平台同步商品数据(标题、价格、库存、图片、…...

C语言文件操作完全手册:读写·定位·实战

1.什么是文件 1.1文件的概念 文件(File)是计算机中用于持久化存储数据的基本单位。它可以存储文本、图片、音频、程序代码等各种信息,并在程序运行结束后仍然保留数据。 1.2文件名 一个文件要有一个唯一的文件标识,以便用户识别…...

多模态大语言模型arxiv论文略读(三十七)

A Spectrum Evaluation Benchmark for Medical Multi-Modal Large Language Models ➡️ 论文标题:A Spectrum Evaluation Benchmark for Medical Multi-Modal Large Language Models ➡️ 论文作者:Jie Liu, Wenxuan Wang, Yihang Su, Jingyuan Huan, …...

IDEA创建Gradle项目然后删除报错解决方法

根据错误信息,你的项目目录中缺少Gradle构建必需的核心文件(如settings.gradle/build.gradle),且IDEA可能残留了Gradle的配置。以下是具体解决方案: 一、问题根源分析 残留Gradle配置 你通过IDEA先创建了Gradle子模块…...

SpringBoot 学习

什么是 SpringBoot SpringBoot 是基于 Spring 生态的开源框架,旨在简化 Spring 应用的初始化搭建和开发配置。它通过约定大于配置的理念,提供快速构建生产级应用的解决方案,显著降低开发者对 XML 配置和依赖管理的负担。 特点: …...

MoE架构解析:如何用“分治”思想打造高效大模型?

在人工智能领域,模型规模的扩大似乎永无止境。从GPT-3的1750亿参数到传闻中的GPT-4万亿级规模,每一次突破都伴随着惊人的算力消耗。但当我们为这些成就欢呼时,一个根本性问题愈发尖锐:如何在提升模型能力的同时控制计算成本&#…...

云服务器和独立服务器的区别在哪

在当今数字化的时代,服务器成为了支撑各种业务和应用的重要基石。而在服务器的领域中,云服务器和独立服务器是两个备受关注的选项。那么,它们到底有何区别呢? 首先,让我们来聊聊成本。云服务器通常采用按需付费的模式…...

使用 Pandas 进行多格式数据整合:从 Excel、JSON 到 HTML 的处理实战

前言 在数据处理与分析的实际场景中,我们经常需要整合不同格式的数据,例如 Excel 表格、JSON 配置文件、HTML 报表等。本文以一个具体任务(蓝桥杯模拟练习题)为例,详细讲解如何使用 Python 的 Pandas 库结合其他工具&…...

深入解析 Linux 中动静态库的加载机制:从原理到实践

引言 在 Linux 开发中,动静态库是代码复用的核心工具。静态库(.a)和动态库(.so)的加载方式差异显著,直接影响程序的性能、灵活性和维护性。本文将深入剖析两者的加载机制,结合实例演示和底层原…...

VuePress 使用教程:从入门到精通

VuePress 使用教程:从入门到精通 VuePress 是一个以 Vue 驱动的静态网站生成器,它为技术文档和技术博客的编写提供了优雅而高效的解决方案。无论你是个人开发者、团队负责人还是开源项目维护者,VuePress 都能帮助你轻松地创建和管理你的文档…...

Kafka与Spark-Streaming

大数据处理的得力助手:Kafka与Spark-Streaming 在大数据处理的领域中,Kafka和Spark-Streaming都是极为重要的工具。今天,咱们就来深入了解一下它们,看看这些技术是如何让数据处理变得高效又强大的。先来说说Kafka,它是…...

【设计】接口幂等性设计

1. 幂等性定义 接口幂等性: 无论调用次数多少,对系统状态的影响与单次调用相同。 比如用户支付接口因网络延迟重复提交了三次。 导致原因: 用户不可靠(手抖多点)网络不可靠(超时重传)系统不可…...

闲聊人工智能对媒体的影响

技术总是不断地改变信息的传播方式。互联网促进了社交媒体的蓬勃发展。 网络媒体成为主流。大语言模型为代表的人工智能的出现,又会对媒体传播带来怎样的改变呢?媒体的演变反映了社会和技术的演变。 人工智能(AI) 将继续对整个媒体行业产生变革性的影响。…...

卷积神经网络--手写数字识别

本文我们通过搭建卷积神经网络模型,实现手写数字识别。 pytorch中提供了手写数字的数据集 ,我们可以直接从pytorch中下载 MNIST中包含70000张手写数字图像:60000张用于训练,10000张用于测试 图像是灰度的,28x28像素 …...

Pandas 数据导出:如何将 DataFrame 追加到 Excel 的不同工作表

在数据分析和数据处理过程中,将数据导出到 Excel 文件是一个常见的需求。Pandas 提供了强大的功能来实现这一需求,尤其是将数据追加到同一个 Excel 文件的不同工作表(Sheet)中。本文将详细介绍如何使用 Pandas 实现这一功能&#…...

Unity中数据和资源加密(异或加密,AES加密,MD5加密)

在项目开发中,始终会涉及到的一个问题,就是信息安全,在调用接口,或者加载的资源,都会涉及安全问题,因此就出现了各种各样的加密方式。 常见的也是目前用的最广的加密方式,分别是:DE…...

SQL Server 2019 安装与配置详细教程

一、写在最前的心里话 和 MySQL 对比,SQL Server 的安装和使用确实要处理很多细节: 需要选择配置项很多有“定义实例”的概念,同一机器可以运行多个数据库服务设置身份验证方式时,需要同时配置 Windows 和 SQL 登录要想 Spring …...

Qt 调试信息重定向到本地文件

1、在Qt软件开发过程中,我们经常使用qDebug()输出一些调试信息在QtCreator终端上。 但若将软件编译、生成、打包为一个完整的可运行的程序并安装在系统中后,系统中没有QtCreator和编译环境,那应用程序出现问题,如何输出信息排查…...

MyBatisPlus文档

一、MyBatis框架回顾 使用springboot整合Mybatis,实现Mybatis框架的搭建 1、创建示例项目 (1)、创建工程 新建工程 创建空工程 创建模块 创建springboot模块 选择SpringBoot版本 (2)、引入依赖 <dependencies><dependency><groupId>org.springframework.…...

Memcached 主主复制架构搭建与 Keepalived 高可用实现

实验目的 掌握基于 repcached 的 Memcached 主主复制配置 实现通过 Keepalived 的 VIP 高可用机制 验证数据双向同步及故障自动切换能力 实验环境 角色IP 地址主机名虚拟 IP (VIP)主节点10.1.1.78server-a10.1.1.80备节点10.1.1.79server-b10.1.1.80 操作系统: CentOS 7 软…...

Android 使用支付接口,需要进行的加密逻辑:MD5、HMAC-SHA256以及RSA

目录 前言MD5HMAC-SHA256RSA其他 前言 不使用加密​​&#xff1a;支付系统如同「裸奔」&#xff0c;面临数据泄露、资金被盗、法律追责等风险。 正确使用加密​​&#xff1a;构建「端到端安全防线」&#xff0c;确保交易合法可信&#xff0c;同时满足国际合规要求。 支付系…...

软件工程效率优化:一个分层解耦与熵减驱动的系统框架

软件工程效率优化&#xff1a;一个分层解耦与熵减驱动的系统框架** 摘要 (Abstract) 本报告构建了一个全面、深入、分层的软件工程效率优化框架&#xff0c;旨在超越简单的技术罗列&#xff0c;从根本的价值驱动和熵减原理出发&#xff0c;系统性地探讨提升效率的策略与实践。…...

鸿蒙ArkUI之相对布局容器(RelativeContainer)实战之狼人杀布局,详细介绍相对布局容器的用法,附上代码,以及效果图

在鸿蒙应用开发中&#xff0c;若是遇到布局相对复杂的场景&#xff0c;往往需要嵌套许多层组件&#xff0c;去还原UI图的效果&#xff0c;若是能够掌握相对布局容器的使用&#xff0c;对于复杂的布局场景&#xff0c;可直接减少组件嵌套&#xff0c;且随心所欲完成复杂场景的布…...