PVE 9.1 尝鲜记:如何『原生』运行 Docker 镜像

warning: 这篇文章距离上次修改已过220天,其中的内容可能已经有所变动。

早上骑车时,收到友人消息说,ProxmoxVE 9.1(下面简称PVE 9.1)几天前正式发布,现在可以更新了。这个版本最大的亮点在于,提供了对运行OCI镜像的实验性支持,也就是说可以在宿主机上『直接』跑Docker镜像了。

具体详情下面还要继续谈,不过作为新特性,而且是一直想要的,那当然是要先睹为快了。

1. 前言

前段时间,笔者给家里母鸡折腾上了PVE 9.0,一直相安无事。

转眼一个月过去了,前几天时间,PVE 9.1正式发布,带来了很多新功能,其中的重点当然就是对于OCI镜像的实验性支持。这里摘抄一段官方Release Notes的机翻版本:

OCI(开放容器倡议)是一种标准的容器分发格式,用户现在可以直接从镜像仓库下载广泛采用的 OCI 镜像,也可以手动上传镜像,用作 LXC 容器的模板。

换句话说,PVE 9.1可以直接从Docker仓库(以及其他遵守OCI规范的仓库,例如ghcr.io)拉取镜像,转换为LXC,然后直接运行——这也是标题中『原生』运行Docker镜像的由来,毕竟不是通过Docker直接运行,所以『原生』得打个双引号。

好处自然是显而易见的:可以对接目前已经广泛存在的大量Docker应用镜像,且理论上以后不必再使用VM/LXC安装Docker再来运行这些应用镜像了,多多少少提高了性能,也易于管理。不过需要注意,目前对于OCI镜像的支持还是实验性的(官方说法是『技术预览版』),且相对传统Docker程序部署来说还有一定的不同之处,因此不建议用于生产环境或跑重要的应用程序。不过今天我们只是用来玩玩,足够了。

网上已经有一些教程,教你怎么运行简单应用程序,例如容器版nginx。不过这似乎都简单了些,因此今天要玩就玩个大的:运行一个使用Docker Compose分发的软件,Bitmagnet

当然必须说明的是,测试结束之后我还是会用回去之前的部署方式,也就是在LXC里面运行Docker的,因为毕竟折腾与易用有时候很难共存,且这种新方式还有几个比较大的问题,下面再说。

2. 升级PVE

从9.0升级到9.1是典型的小版本升级,一般来说只需要在WebUI上点点就行了。但考虑到小版本升级有时候需要动内核(比如这次),因此有条件的话,最好还是准备好IPMI或者IPKVM等工具,再不济现场升级也行,以免出个什么事救不回来。

准备好之后,WebUI进入节点——更新,找到升级按钮,按下去

之后会弹出来控制台窗口,确保留足硬盘空间(页面提示『解压后占用』的空间的3倍左右为宜),然后按Y确认,让他自动跑一圈升级就行了。

因为动了内核,升级完成后执行reboot命令重启即可。这样操作完,系统就是最新版本了。如果你之前执行过去除未订阅弹窗的代码,升级完后务必再执行一次,否则又得弹窗了。

3. 尝鲜OCI功能

3.1 配置代理 下载镜像

我们先来看Bitmagnet的安装文档

它的安装方式是Docker Compose,而Compose文件,说白了,就是告诉Docker要下载什么镜像,如何配置的文件。因为PVE 9.1的OCI容器功能暂不支持载入此文件,因此我们必须手动解析它,并根据需要配置。

首先看我们需要什么镜像:

services:
  bitmagnet:
    image: ghcr.io/bitmagnet-io/bitmagnet:latest
  # ...省略...

  postgres:
    image: postgres:16-alpine
  # ...省略...

很显然,根据镜像名规则,我们需要下载最新版本的ghcr.io/bitmagnet-io/bitmagnet16-alpine版本的postgres。前者托管于ghcr,后者托管于Docker.io,但由于众所周知(服务器线路非优化+间歇性阻断)的原因,直接下载效果不理想,因此我们需要通过某种加速手段去拉取。一般而言,当然可以使用各种镜像加速服务,不过因为笔者网内已经有配置好的加密代理服务(对外暴露HTTP代理),因此我们直接利用就行了。

需要注意的是,虽然拉取程序可以读取环境变量中的代理服务器信息,但PVE的WebUI的后台程序的执行环境是独立的,因此不论在/etc/environment还是/etc/profile设置环境变量,都是没用的,顶多只是控制台中可以加速而已。为了让WebUI中也可以实现镜像加速,我们必须换个地方设置。

执行systemctl status pvedaemon,查看进程的service文件位置:

root@fairy:~# systemctl status pvedaemon
● pvedaemon.service - PVE API Daemon
     Loaded: loaded (/usr/lib/systemd/system/pvedaemon.service; enabled; preset: enabled)
     Active: active (running) since Tue 2025-11-25 13:33:59 CST; 6h ago
.....

# 显然,就是 /usr/lib/systemd/system/pvedaemon.service

确定位置后,用你喜欢的文本编辑器打开这个service文件,在[service]小节下添加环境变量配置:

[Service]
Environment="http_proxy=http://your.proxy.server:port"
Environment="https_proxy=http://your.proxy.server:port"

# 以下是原来的文件内容,不用管他

保存好,然后执行:

systemctl daemon-reload
systemctl restart pvedaemon

这样就配置好代理了。

接着,进入WebUI,在左侧找到节点的放CT模板的存储盘,在里面就可以找到新选项Pull from OCI Registry了:

点击按钮后弹出提示框,根据Compose文件分别填写两个镜像的名称,并确认即可(可以直接复制粘贴完整镜像名,系统会自动识别出冒号分隔的版本信息,并对应填写):

此时如果前面代理服务器配置正确的话,拉取镜像速度就会很快,而且代理服务器上也可以看到有流量传输:

10.0.0.233就是代理服务器10.0.0.233就是代理服务器

两个镜像都下载下来后,同一页面应该可以看到结果。

3.2 配置数据库容器

我们先来配置数据库。

因为Docker镜像已经被转换为了LXC,因此无需再额外担心挂载卷的问题,默认的持久化就是做在LXC的磁盘上(当然你也可以在容器创建好后,像标准LXC那样自行添加挂载点);当然也无需担心端口映射的问题,因为LXC容器默认就是一人一个IP,相当于Docker的Macvlan。

创建容器过程和普通LXC是一致的,选择镜像模板的时候选刚刚下载的数据库镜像就行:

CPU、磁盘和内存看着配,反正后续还能扩容,笔者给他的配置是1核心,5G硬盘,256MB内存和256MB的SWAP。

网络部分需要注意一下:LXC默认情况下会挂接到vmbr0,也就是平时我们访问的那个网桥(单网口机器的话,物理口也会挂到这个网桥上),但如果你不想让数据库被内网访问,那么可以提前在节点——系统——网络处,先开好另一个vmbr(类似于VMWare Workstation的『仅主机』模式),并在这里相应配置就行,IP填一个不碍事的就好。这里因为是测试,就直接使用vmbr0,IP分配10.0.0.156

配好后点击完成,系统会自动识别出来这是一个OCI镜像,并做相关的自动配置,如创建存储文件夹等等:

全部工作做完后,先不急着启动。阅读Compose文件可知,容器启动是有顺序的,先启动数据库再启动本体,而且还需要配置环境变量,来控制容器内程序的行为:

  postgres:
    environment:
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=bitmagnet
      - PGUSER=postgres

进入容器——选项,打开开机自启动,并修改启动顺序,笔者将启动顺序设定为容器ID,这样便于对号入座。

相对于普通的LXC容器,OCI容器在配置项最下面多出来了两个配置选项。我们先来看Environment,不用说,这就是配置环境变量的地方,只需双击打开,然后在里面新建上面列出的三个环境变量,填入对应值,就可以了:

一切配置完成,就可以回到概要页面,启动容器。这样,数据库容器就配置好了。

3.3 配置本体

本体的配置方法大同小异,也是用同样的方法新建容器,填写参数,选择网络并配置IP(如果你上面新建了内部使用的vmbr1,别忘了在新建容器完成后添加这个接口),然后配置自启动顺序(确保在数据库之后启动),以及对应的环境变量。配置时需要注意,因为我们不是在Docker内运行,没有主机名来指向数据库容器,所以只需填入数据库IP地址就行了。

重头戏来了:阅读Compose文件可以发现,里面还有Command小节:

  bitmagnet:
    command:
      - worker
      - run
      - --keys=http_server
      - --keys=queue_server
      # disable the next line to run without DHT crawler
      - --keys=dht_crawler

换句话说,程序依靠这些参数来启动,并确定工作模式,因此自然也不能遗漏掉。这就需要我们刚刚提到的第二个新增选项Entrypoint(入口点)了,这是容器启动后所执行的命令,默认情况下就是里面的可执行文件。想要添加command小节的参数,只需要把里面的项用空格隔开之后,追加到入口点配置之后即可:

配置完成,点击OK保存,最后点击右上角启动。这样,就算是配置完了,可以在浏览器打开本体的IP地址加上对应端口来使用服务:

挂机一下午,在DHT网络中找到了不少好东西挂机一下午,在DHT网络中找到了不少好东西

4. 此方法的缺点

讲缺点之前还得说一句,目前版本的OCI镜像功能还是测试版,很多功能都是缺的,有待磨合,所以下面所说的内容可能在不久之后就发生变化,请以实际为准。

4.1 无法直接加载Docker Compose

目前很多用Docker分发的软件都附带了Docker Compose,来方便配置所依赖的多个镜像,如数据库等。但是PVE的OCI镜像功能,如刚刚所演示的那样,我们需要手动分析Compose文件并新建和配置对应容器,这当然是不便的。

当然如果目标程序是单容器的,或者说你的基础环境里面已经有对应的数据库等配套措施,那么自然不必再额外安装,所以...看情况吧。

4.2 多容器管理不便

本质上,这个做法还是把OCI镜像转换为LXC容器来运行的,而PVE里面的LXC更像是一台台的虚拟机,其间的联系并不多,上面的拆开安装的方式,也会在左侧的列表中留下多个容器,显得不美观。

理想状况下,对于使用多容器的程序,最好有某种方式来归类为一组,例如结合上面的Docker Compose文件,同一个文件的为一组,统一管理,内部有单独的启动顺序等信息。当然我不确定后期PVE开发组会不会添加这个功能,反正目前(2025年11月25日)是没有的。

4.3 缺乏Docker的很多功能

Compose文件里面还有别的东西,是没有添加进去的,例如健康检查。就算是depends_on选项,也只是粗略的按照启动顺序的方式来进行,而不是源文件中的配置,『数据库健康检查通过后再启动本体』。

当然说句实话,官方也没有把这玩意称为是『Docker on PVE』之类的东西,只是说可以运行OCI镜像,而Docker镜像就是按照OCI规范封装的而已。不过考虑到绝大多数应用都基于Docker的情况下,也许顺便支持一下,会比较好。

4.4 容器升级困难

这个应该也是开发中的功能,网上有人尝试升级容器,看样子还需要手动跑一次上面的流程才行,不确定具体怎么处理,因为笔者不把他用在生产环境,因此略过,但确实存在这个问题。

5. 写在最后

简单尝鲜下,一个下午就过去了。

目前这个测试版基本功能是有的,『能用』,但距离『好用』还有一些距离,所以短时间内我可能还会继续开标准的LXC,然后在里面安装Docker来运行程序。

不过我倒是很看好他,毕竟少一层套娃,就少一层性能损耗嘛。

(完)


木头箱子脆脆,但是这样正好

如无特殊声明,本站内容遵循 CC BY-NC-SA 4.0 协议

转载请注明出处并保留作者信息,谢谢!

本站由 搬瓦工VPS 强力驱动

none
最后修改于:2025年11月25日 20:34

已有 2 条评论

  1. 博主速度真快,我也是刚看到这个消息,没想到博主已经完成全流程测试了。 现在看来 PVE 原生的 Docker 还处于半残废状态,期待以后能够完整的支持 Docker Compose 这一套吧。

    1. 目前只能等了,而且老实说,我认为他的 Docker Compose 支持感觉有些悬,可能不会有原生那么顺滑(毕竟是转 LXC,他们似乎有想复用 LXC 控制面板的想法)

添加新评论

提醒:『评论回复邮件提醒』功能正在测试中
评论后,如果站长有回复,会有邮件通知