懒猫微服进阶心得(十五):超越systemd,不用每次开机都再安装软件~

前言

懒猫微服是分层文件系统,所以在之前的文章里前面我们使用用 systemctl --user 在开机时自动安装软件,解决重启丢包的问题。但说实话,每次开机都要跑一遍 apt install,当面对软件包过多以及网络延迟的问题的时候,使用dkpg会卡住,这不够优雅,所以才有了这个方案。

后来我换了个思路:既然懒猫微服天生就是为 Docker 而生的,为什么不直接用容器来跑这些工具呢?

想想看,htop、iotop、glances 这些运维神器,本质上就是读取 /proc/sys 里的系统信息。只要让容器能访问宿主机的这些文件,不就能正常工作了吗?

这篇文章就来聊聊怎么用 Docker 容器跑系统监控工具。不用装软件,不怕重启丢失,一条命令就能用,用完自动清理。这让我们既享受了分层文件系统的优势,也不用再为软件持久化烦恼了。

关于镜像源:本文使用了 docker.1ms.run 作为镜像加速站,仅作示例,不对镜像源的可用性负责。如果某个镜像拉取失败,可以换成其他镜像源,比如 dockerpull.orgdocker.xuanyuan.me 等。

进程监控类

htop - 经典进程查看器

我们习惯的使用方式是 apt install htop,但在懒猫微服的分层文件系统下重启后会丢失。所以我们可以用Docker来一键设置:

1
pg-docker run --rm -it --pid host docker.1ms.run/frapsoft/htop

这条命令的作用是:启动一个包含 htop 工具的 Docker 容器,并以交互式方式查看宿主机的进程列表。容器停止后会自动删除。htop 是一个用于实时查看和管理系统进程的交互式工具。我们可以逐部分解析一下这条命令:

  1. docker run:
    这是 Docker 命令,用来启动一个新的容器并执行指定的命令。
  2. --rm:
    这个选项表示容器在停止后会被自动删除。这样可以避免容器停留在系统上,占用空间。
  3. -it:
    • -i 表示让容器保持交互模式(interactive),即允许你输入命令。
    • -t 表示分配一个伪终端(tty),让你可以以终端方式与容器交互。
  4. --pid host:
    这个选项使得容器能够访问宿主机的进程信息。正常情况下,容器只能看到自己内部的进程,但通过 --pid host,容器可以查看宿主机的所有进程,这样你就可以通过 htop 查看宿主机的进程。
  5. frapsoft/htop:
    这是一个 Docker 镜像的名称,它提供了一个包含 htop 工具的容器镜像。运行这个镜像会启动 htop,让你可以在容器中查看进程。

为了方便,还可以在 .bashrc 里加个 alias,这样就能像本地命令一样直接敲 htop 使用了。

1
2
echo "alias htop='pg-docker run --rm -it --pid host docker.1ms.run/frapsoft/htop'" >> ~/.bashrc
source ~/.bashrc

在重启之后我们看到镜像没有丢失,还在本地存在,所以这个方式是可行的。

1
2
3
4
lzcbox-e66ccc4a ~ # pg-docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.1ms.run/library/alpine latest a40c03cbb81c 3 days ago 8.44MB
docker.1ms.run/frapsoft/htop latest 4b76ab24430c 9 years ago 8.19MB

如果你经常玩docker,那么除了–pid之外一定都不陌生。对于默认来讲,–pid 的参数是 private,所以我们常说每个容器有独立的进程命名空间,容器只能看到自己内部的进程。用了**--pid host** 之后,容器就可以共享宿主机的进程命名空间。这样,容器可以查看宿主机上的所有进程,而不仅仅是容器内部的进程。所以我们可以用它来做一些监控。甚至还有,**--pid container:<container_id>**:- 容器将能够看到并与指定容器的进程共享命名空间。通常在多容器间需要共享进程信息或调试时使用。例如,一个容器需要查看另一个容器的进程或进行故障排查。当然我们这里不做仔细展开。

关于 Docker 参数解释以及 alias、bashrc 的修改,这里只以 htop 为例,后面的工具不再赘述。

同理我们也可以测试其他工具。

glances - 全能系统监控

1
2
3
pg-docker run --rm -it --pid host --net host \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
docker.1ms.run/nicolargo/glances

glances 比 htop 更全面,是个「一屏看所有」的监控工具。CPU、内存、网络、磁盘、Docker 容器状态全都有。参数说明:

  • --pid host:读取宿主机进程信息
  • --net host:读取宿主机网络信息
  • -v docker.sock:让 glances 能监控 Docker 容器

btop - htop 的现代化替代

1
pg-docker run --rm -it --pid host terorie/btop

btop 界面更炫酷,功能也更丰富,支持鼠标操作。不过这个镜像比较冷门,docker.1ms.run 等加速站可能没缓存,所以这里直接用 Docker Hub 官方源。如果拉取慢,可以换成其他加速源试试。

ctop - Docker 容器专用监控

1
2
3
pg-docker run --rm -it \
-v /var/run/docker.sock:/var/run/docker.sock \
quay.io/vektorlab/ctop

这个镜像来自 quay.io(Red Hat 的镜像仓库),国内访问通常比 Docker Hub 顺畅,可以直接拉取。ctop 专门用来监控 Docker 容器的资源占用。

不过要注意,ctop 默认连接 /var/run/docker.sock,这是系统 Docker 的 socket。如果你想监控 playground 里的容器,需要挂载 playground 的 socket:

1
2
3
pg-docker run --rm -it \
-v /data/playground/docker.sock:/var/run/docker.sock:ro \
quay.io/vektorlab/ctop

netshoot - 网络排障瑞士军刀

1
pg-docker run --rm -it --net host --pid host --privileged docker.1ms.run/nicolaka/netshoot

netshoot 内置了 tcpdump、iftop、nmap、curl、dig 等一堆网络工具,临时排查问题特别方便。网络监控工具必须加 --net host,否则测的是容器网络而不是宿主机网络。

进入容器后,先用 ip link 查看网卡名。懒猫微服的主网卡通常是 enp2s0 而不是 eth0

1
2
3
4
# 进入容器后
ip link # 查看网卡列表
iftop -i enp2s0 # 监控主网卡流量
tcpdump -i enp2s0 # 抓包

注意:netshoot 里没有 nethogs,如果需要按进程查看流量,可以用 alpine 临时安装:

1
pg-docker run --rm -it --net host --pid host --privileged alpine sh -c "apk add --no-cache nethogs && nethogs"

工具选择指南

工具 特点 适用场景
htop 轻量、经典 快速查看进程,日常使用
btop 界面炫酷、支持鼠标 喜欢好看界面的用户
glances 功能全面、一屏显示所有 需要综合监控的场景
ctop 专注 Docker 容器 监控容器资源占用
netshoot 网络工具箱 网络排障、抓包分析

理解 –pid host 的本质

--pid host 的本质是让容器挂载宿主机的 /proc,而不是容器自己隔离的那份。

容器内的监控工具之所以能工作,是因为 Linux 的系统信息都存在 /proc 虚拟文件系统里:

文件 内容
/proc/cpuinfo CPU 信息
/proc/meminfo 内存信息
/proc/uptime 运行时间
/proc/version 内核版本
/proc/loadavg 系统负载
/proc/<pid>/stat 进程状态

常见工具的数据来源:

工具 读取的文件
htop/top /proc/<pid>/stat, /proc/meminfo, /proc/loadavg
free /proc/meminfo
df /proc/mounts, /proc/diskstats
ps /proc/<pid>/status, /proc/<pid>/cmdline
netstat/ss /proc/net/tcp, /proc/net/udp
vmstat /proc/stat, /proc/vmstat
iostat /proc/diskstats

所以 --pid host 能让这些工具在容器里正常工作,因为它们本质上就是读文件,共享了 /proc 就等于共享了系统信息。

/proc vs /etc/os-release

有个细节需要注意:/proc/version/etc/os-release 记录的是不同层面的信息。

/proc/version 是内核信息,由内核动态生成:

1
2
3
cat /proc/version

Linux version 6.16.6-x64v3-xanmod1 (root@runner-6areqvs9r-project-51590166-concurrent-0) (Debian clang version 19.1.7 (3), Debian LLD 19.1.7) #0~20250909.g439cb47 SMP PREEMPT_DYNAMIC Tue Sep 9 22:24:21 UTC

/etc/os-release 是发行版信息,是静态文件:

1
2
3
4
5
6
7
8
9
10
11
cat /etc/os-release

PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

打个比方:

  • /proc/version = 引擎型号(Linux 6.16)
  • /etc/os-release = 车的品牌(Debian Linux)

同一个内核可以跑不同发行版,所以如果你想让容器里的工具显示正确的操作系统名称,需要手动挂载 /etc/os-release

进阶:自己打包docker工具

我们经常习惯使用,fastfetch 显示系统信息,但还是没有找到别人打包好的容器的版本。fastfetch 是 neofetch 的现代替代品,速度更快。

我们可以用使用alpine安装二进制包的方式来运行,也可以自定义Docker images来跑:

先看一个使用alpine安装的:

1
2
3
4
5
6
pg-docker run --rm -it \
--pid host \
--net host \
-v /etc/os-release:/etc/os-release:ro \
-v /etc/hostname:/etc/hostname:ro \
docker.1ms.run/library/alpine sh -c "apk add --no-cache fastfetch && fastfetch"

参数说明:

  • --pid host:让 fastfetch 读到宿主机的 CPU、内存、内核信息
  • -v /etc/os-release:/etc/os-release:ro:让 fastfetch 读到正确的操作系统名称
  • -v /etc/hostname:/etc/hostname:ro:让 fastfetch 读到正确的主机名

虽然不是很完美,但是已经可以读取到大多数的信息了,

再看一个自己打包的Docker版本。

1
2
3
FROM alpine:latest
RUN apk add --no-cache fastfetch
CMD ["fastfetch"]

构建并运行:

1
2
3
4
pg-docker build -t my-fastfetch .
pg-docker run --rm -it --pid host \
-v /etc/os-release:/etc/os-release:ro \
my-fastfetch

同理我们也可以基于alpine构建基于任何软件的镜像工具,我这里再举一个例子,比如iotop。

1
2
pg-docker run --rm -it --pid host --privileged docker.1ms.run/library/alpine sh -c "apk add --no-cache iotop && iotop -o"

关于 /sys 文件系统

除了 /proc,Linux 还有 /sys 虚拟文件系统,存放硬件相关信息:

1
2
3
4
5
6
7
8
9
10
11
# 读网卡 MAC 地址
pg-docker run --rm -it -v /sys:/sys:ro docker.1ms.run/library/alpine cat /sys/class/net/enp2s0/address

# 列出所有网卡
pg-docker run --rm -it -v /sys:/sys:ro docker.1ms.run/library/alpine ls /sys/class/net/

# 读 CPU 温度
pg-docker run --rm -it -v /sys:/sys:ro docker.1ms.run/library/alpine cat /sys/class/thermal/thermal_zone0/temp

# 读磁盘大小
pg-docker run --rm -it -v /sys:/sys:ro docker.1ms.run/library/alpine cat /sys/block/nvme0n1/size

其他命名空间参数

除了 --pid host,Docker 还支持其他命名空间共享:

1
2
3
4
5
6
7
8
9
10
11
# 共享网络命名空间
--net host

# 共享 UTS 命名空间(主机名和域名)
--uts host

# 共享 IPC 命名空间(进程间通信)
--ipc host

# 共享指定容器的进程命名空间
--pid container:<container_id>

--pid container:<container_id> 在多容器调试时很有用,可以让一个容器看到另一个容器的进程。

关于 –privileged

你可能注意到有些命令用了 --privileged,这个参数会让容器获得几乎所有的宿主机权限:

  • 访问所有设备(/dev/*
  • 加载内核模块
  • 修改系统配置
  • 访问完整的 /proc/sys

像 iotop、nethogs 这类需要深度访问内核信息的工具,没有 --privileged 可能跑不起来。但要注意,这个参数权限很大,只在信任的镜像上使用,用完记得 --rm 自动清理。

总结

懒猫微服的分层文件系统固然好,但是常用软件会有丢失安装的问题,所以我们用容器来跑这些监控工具,容器镜像重启不会丢失,配置一个alias和bashrc就可以完美兼容这个feature。

容器里读取宿主机的参数有这三板斧:

  • 看进程用 --pid host
  • 看网络用 --net host
  • 看磁盘用 --privileged

记住这三个,大多数监控工具都能在容器里跑起来。

回头看看,之前用 systemctl --user 开机自动装软件,虽然能用,但每次重启都要跑一遍 apt install,还会受限于软件体积和网络问题。现在换成 Docker 镜像,拉一次就永久缓存,重启秒开,彻底告别「开机等安装」的烦恼。

超越systemd,不用每次开机都再安装软件~

懒猫微服进阶心得(十五):超越systemd,不用每次开机都再安装软件~

https://airag.click/posts/c1ba52cc/

作者

Xu

发布于

2026-01-31

更新于

2026-02-27

许可协议

评论

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×