资讯动态

LXC与Docker的本质区别:系统容器 vs 应用容器

发布时间:2026/10/27 12:14:18 来源:尧图企业网站定制
容器这个词现在被说得太泛了Docker、Podman、containerd、LXC 全被塞进同一个筐里结果很多刚接触的人以为它们是一回事。实际上 LXC 比 Docker 早好几年出现走的是另一条技术路线——它更像轻量级虚拟机而不是应用打包工具。这篇就围绕 LXC 和容器的关系展开把 LXC 到底是什么、它和 Docker 的本质区别在哪、底层靠什么机制隔离、实际怎么用、哪些场景该选它一条线讲透。不管你是刚听说 LXC 想搞清楚概念还是已经在用 Docker 但想弄明白容器底层原理或者手上有一批老服务想低成本容器化下面这些内容都能直接拿去参考。1. LXC 到底是个什么东西1.1 从轻量级虚拟机这个定位说起LXC 全称 Linux Containers直译就是 Linux 容器。这个名字容易让人误解以为它和 Docker 是同类竞品其实它出现得更早设计目标也不一样。LXC 想解决的核心问题是能不能在一台物理机上跑多个相互隔离的 Linux 系统环境每个环境有自己的 init 进程、自己的用户空间、自己的网络栈但共享同一个内核。这个定位非常关键。你可以把它理解成系统级容器——它虚拟化的是整个操作系统环境而不是单个应用。启动一个 LXC 容器你得到的是一个完整的 Linux 用户空间里面有 init、有 systemd或其它 init 系统、有完整的包管理、有独立的 /etc 和 /var。登录进去之后感觉就像 SSH 到了一台独立的小机器。我最早接触 LXC 是在一个需要跑多套测试环境的场景里。当时用虚拟机跑每套环境光启动就要一分多钟内存开销也大换成 LXC 之后启动时间压到一两秒单机密度翻了好几倍。这个体验差异让我意识到LXC 的价值不在于打包应用而在于快速复制系统环境。所以理解 LXC 的第一把钥匙是它虚拟化的粒度是操作系统不是进程。这个定位决定了它后面所有的设计取舍也决定了它和 Docker 的分工。1.2 LXC 和传统虚拟机的边界在哪很多人第一次听说 LXC 会问那它和 KVM、VMware 这些虚拟机有什么区别答案就一个字内核。传统虚拟机通过 Hypervisor 虚拟出完整的硬件包括 CPU、内存、磁盘控制器、网卡然后在这个虚拟硬件上装一个完整的操作系统包括它自己的内核。也就是说虚拟机里跑的内核和宿主机内核是两套完全独立的东西。好处是隔离彻底坏处是资源开销大——每个虚拟机都要为内核和硬件模拟付出代价。LXC 不虚拟硬件也不虚拟内核。它直接复用宿主机的内核通过内核提供的命名空间namespace和控制组cgroup机制把进程隔离开让每个容器以为自己独占一台机器。容器里没有独立内核所有容器共享宿主内核。这个差异带来的直接后果是对比维度传统虚拟机LXC 容器内核每个虚拟机独立内核共享宿主内核启动速度数十秒到分钟级秒级甚至亚秒级内存开销每实例需预留内核与硬件模拟内存仅用户空间开销隔离强度硬件级隔离最强内核级隔离较强可运行异构系统可以如 Linux 上跑 Windows不行只能跑 Linux密度单机十几个到几十个单机上百个这张表里最关键的一行是可运行异构系统。因为共享内核LXC 容器里只能跑 Linux而且对内核版本有依赖——容器里的用户空间工具链要和宿主内核兼容。这一点在做系统级容器时经常被忽略后面会专门讲。1.3 LXC 在容器技术谱系里的位置把时间线拉出来看会更清楚。LXC 的核心机制namespace 和 cgroup在 2000 年代中后期陆续进入 Linux 内核LXC 项目本身在 2008 年前后成型提供了一套用户态工具来管理这些内核能力。它的目标是让系统容器变得易用。Docker 在 2013 年出现一开始底层其实也用过 LXC 作为执行驱动后来换成了自研的 libcontainer再后来演变成 runc。Docker 的关键创新不在隔离机制本身而在于把镜像分层镜像仓库声明式构建这套工程化流程做出来了让容器从系统管理员的工具变成了开发者的交付格式。所以谱系大致是这样内核提供 namespace/cgroup 这些原语LXC 把它们封装成系统容器工具Docker 在同样的原语上封装出应用容器生态。两者不是替代关系而是同一套底层能力面向不同场景的两种封装。理解这个谱系很重要因为它解释了一个常见困惑为什么 LXC 容器里可以跑 systemd而 Docker 容器里跑 systemd 那么别扭因为 LXC 的设计前提就是容器是一个系统Docker 的设计前提是容器是一个进程。2. 隔离的底层namespace 与 cgroup 到底做了什么2.1 namespace让进程看不见外面的世界LXC 能做到隔离靠的第一根支柱是 namespace。这个词在编程里常被翻译成命名空间但在容器语境下它的作用更接近视图隔离——它让一组进程看到一套独立的系统资源视图看不到宿主机上其它进程的那一套。Linux 内核目前提供多种 namespace每种负责隔离一类资源PID namespace隔离进程 ID 空间。容器里的第一个进程 PID 是 1它看不到宿主机上的其它进程宿主机上普通权限也看不到容器内进程。Mount namespace隔离挂载点。容器有自己的文件系统挂载树容器内挂载东西不影响宿主机。Network namespace隔离网络栈。每个容器可以有独立的网卡、IP、路由表、iptables 规则。UTS namespace隔离主机名和域名。容器可以有自己的 hostname。IPC namespace隔离进程间通信资源比如共享内存、信号量。User namespace隔离用户和组 ID。容器内的 root 可以映射到宿主机上的普通用户这是一层重要的安全缓冲。Cgroup namespace隔离 cgroup 视图让容器看到自己的资源限制视图。LXC 在创建容器时会为容器进程组合这些 namespace。组合的方式决定了容器的隔离程度。比如默认情况下 LXC 会启用 PID、Mount、Network、UTS、IPC 这几个User namespace 是否启用取决于配置——这一点很关键因为不开 User namespace 的话容器内的 root 就是宿主机上的 root逃逸风险会高很多。我见过不少人在测试环境图省事直接关掉 User namespace 映射结果容器里一个误操作就把宿主机的文件权限改了。这个坑后面会详细说。2.2 cgroup给容器戴上资源缰绳namespace 解决的是看不见cgroup 解决的是用多少。光隔离视图不够如果某个容器里的进程疯狂吃 CPU 或内存会把整台宿主机拖垮。cgroup 就是用来限制、统计、隔离资源使用的。cgroup 主要管这几类资源CPU可以限制 CPU 配额cpu.max、设置权重cpu.weight控制容器能用多少 CPU 时间。内存限制内存上限memory.max超过会触发 OOM 或回收还能统计内存使用。IO限制块设备的读写带宽和 IOPS。PIDs限制容器内最大进程数防止 fork 炸弹把宿主机拖死。cgroup 有两个版本v1 和 v2。v1 是分控制器挂载的结构比较乱v2 是统一层级结构清晰现在主流发行版都在往 v2 迁移。LXC 对两个版本都支持但配置写法有差异。如果你在较新的系统上跑 LXC大概率是 cgroup v2配置资源限制时要注意用 v2 的接口。举个实际例子。假设你要限制某个 LXC 容器的内存为 2GB在 cgroup v2 环境下LXC 配置里大致是这样# 在容器配置文件中设置内存限制 lxc.cgroup2.memory.max 2G lxc.cgroup2.memory.swap.max 0这里第二行把 swap 关掉是为了让内存限制更硬——否则容器内存超了会往 swap 里挤限制效果打折扣。这个细节在文档里不一定显眼但实际做资源隔离时很重要。2.3 两根支柱如何协同namespace 和 cgroup 是配合使用的。创建容器时LXC 先通过 clone 系统调用带上 namespace 标志创建隔离的进程视图然后把容器进程放进一个 cgroup 里施加资源限制最后在 mount namespace 里 pivot_root 到容器根文件系统。这个流程里有个容易忽略的点cgroup 的挂载和 namespace 的创建顺序会影响容器内能否看到资源限制。如果 cgroup namespace 没启用容器内看到的 cgroup 视图是宿主机的容器里的进程可能误以为自己能用全部资源。LXC 较新版本默认会处理好这个但如果你手工调配置要留意。另外User namespace 的映射关系直接影响文件权限。LXC 默认会把容器内的 rootuid 0映射到宿主机上的一个非特权 uid 区间比如 100000 起始。这意味着容器内 root 创建的文件在宿主机上看到的所有者是 100000 这个普通用户。这个机制是安全的关键但也带来一个副作用如果你在宿主机上直接操作容器根文件系统里的文件会遇到权限对不上的问题需要 idmap 工具处理。3. LXC 与 Docker不是替代是两条路3.1 设计哲学的差异系统容器 vs 应用容器这是理解两者关系最重要的一节。LXC 和 Docker 用的底层原语几乎一样但设计哲学完全不同导致使用方式、运维模式、适用场景都分道扬镳。LXC 的模型是容器即系统。一个容器是一个长期运行的、有完整 init 的系统环境。你会像管理一台服务器一样管理它登录进去、装软件、配服务、看日志、重启服务。容器的生命周期以天、周、月计。Docker 的模型是容器即进程。一个容器通常只跑一个前台进程进程退出容器就结束。镜像不可变配置通过环境变量和挂载注入日志走标准输出。容器的生命周期以分钟、小时计随时可以销毁重建。这个差异直接体现在使用体验上。用 LXC你lxc-start一个容器然后lxc-attach进去像 SSH 一样操作。用 Docker你docker run一个镜像进程跑完就退出要看状态用docker logs要改配置就重建容器。我个人的判断标准很简单如果你的服务需要进去维护LXC 更顺手如果你的服务追求不可变、可重建Docker 更合适。很多传统企业应用比如某些老版本中间件、需要图形界面的管理工具、需要 systemd 管理多进程的服务用 LXC 迁移成本低得多因为不用改造应用架构。3.2 镜像与交付方式的根本分歧Docker 最核心的创新是镜像分层和 Dockerfile。镜像分层让构建、传输、复用变得极其高效Dockerfile 让构建过程可声明、可版本化镜像仓库让分发标准化。这套东西解决的是应用交付问题。LXC 的交付方式是模板template和容器快照。LXC 提供一系列模板脚本可以从发行版仓库拉取一个最小系统生成容器根文件系统。你也可以把一个配好的容器打包成 tar 包分发。但这套流程没有分层、没有声明式构建、没有标准仓库工程化程度远不如 Docker。这个差异的实际影响是用 LXC 做大规模部署时配置管理要靠外部工具Ansible、SaltStack 之类来保证一致性用 Docker 时镜像本身就是一致性保证。所以如果你的场景是几十上百个需要精细配置的系统环境LXC 加配置管理工具是可行路线如果是大量无状态应用实例Docker 生态明显更省心。3.3 什么时候该选 LXC 而不是 Docker说了这么多差异落到选型上我总结几个 LXC 明显更合适的场景第一需要完整系统环境的测试/开发场景。比如你要测试某个软件在不同发行版上的安装行为或者要模拟一套多机集群环境。LXC 启动快、开销小起十几个不同发行版的容器做测试比虚拟机轻量得多。第二遗留系统容器化。有些老系统依赖 systemd 管理多个服务、依赖特定的 init 行为、依赖完整的包管理。硬塞进 Docker 要改一堆东西用 LXC 基本可以原样迁移只是从物理机/虚拟机换成了容器。第三需要长期运行、需要进去维护的环境。比如内部的一些管理后台、构建服务器、跳板环境。这类环境的特点是变更不频繁、需要人工介入、生命周期长LXC 的系统模型更贴合。第四学习和研究容器底层。因为 LXC 暴露的抽象层次更接近内核原语用它来理解 namespace、cgroup、pivot_root 这些机制比用 Docker 更直观。Docker 把太多细节封装掉了。反过来如果你的场景是微服务、CI/CD 流水线、需要频繁弹性伸缩的无状态服务Docker或更上层的 Kubernetes是更自然的选择没必要为了底层而选 LXC。4. 动手跑一个 LXC 容器4.1 环境准备与安装先说明一下不同发行版的包名和默认配置有差异下面以主流发行版为例。安装 LXC 本身不复杂关键是装完之后要确认内核支持情况。在 Debian/Ubuntu 系上sudo apt update sudo apt install lxc lxc-templates在 RHEL/CentOS 系上包名通常是lxc和lxc-templates但要注意较新版本可能默认只提供 cgroup v2 支持老配置写法会不生效。装完之后先做一次环境检查lxc-checkconfig这个命令会逐项检查内核是否启用了必要的 namespace、cgroup 控制器、以及一些安全特性。输出里如果有enabled之外的状态就要留意。常见的缺失项是 User namespace 没启用这在某些发行版上默认是关的需要改内核参数。检查通过后看一下默认的容器存储路径和网络配置lxc-config lxc.lxcpath lxc-config lxc.net.0.type默认存储路径一般是/var/lib/lxc每个容器一个子目录里面放配置文件和根文件系统。网络默认可能是空无网络或者 veth 桥接取决于发行版。如果默认没网络后面创建容器时要显式配。4.2 创建第一个容器LXC 创建容器用lxc-create需要指定模板。模板决定了容器里装什么系统sudo lxc-create -n test01 -t download -- -d ubuntu -r jammy -a amd64这条命令的意思是创建一个名为test01的容器用download模板下载 Ubuntu 22.04jammy的 amd64 版本。download模板会从镜像源拉取最小根文件系统比从发行版仓库慢慢装快得多。创建过程中会提示你确认发行版、版本、架构确认后开始下载。下载完成后容器就存在于/var/lib/lxc/test01/下了。这里有个实操细节download模板依赖网络如果下载慢或者失败可以换镜像源或者用本地已有的模板缓存。另外创建时如果提示 GPG 校验失败通常是镜像源的签名问题可以临时加--no-validate跳过但生产环境不建议这么做应该换一个可信源。创建完成后先别急着启动看一眼配置文件sudo cat /var/lib/lxc/test01/config重点关注这几行lxc.net.0.type网络类型、lxc.rootfs.path根文件系统路径、lxc.idmapuid 映射。如果网络是empty容器起来后没有网络需要手动加 veth 配置。4.3 启动、登录与日常操作启动容器sudo lxc-start -n test01启动是后台的加-F可以前台运行看输出调试时很有用。启动后查看状态sudo lxc-info -n test01会显示状态、PID、IP如果配了网络、内存和 CPU 使用。要进容器操作sudo lxc-attach -n test01lxc-attach会给你一个容器内的 shell默认是 root。这个体验和 SSH 进去很像但注意它是直接 attach 到容器的 namespace不经过网络所以即使容器没配网络也能用。日常操作命令比较直观sudo lxc-stop -n test01 # 停止 sudo lxc-freeze -n test01 # 冻结暂停所有进程 sudo lxc-unfreeze -n test01 # 解冻 sudo lxc-destroy -n test01 # 销毁不可恢复lxc-freeze这个能力 Docker 里没有直接对应它把容器内所有进程挂起适合做快照前的静默。这个特性在做容器迁移或备份时挺有用。4.4 网络配置让容器能通外网默认创建出来的容器网络往往是empty也就是只有一个 loopback。要让容器通外网最常用的方式是 veth 对加网桥。先在宿主机上确认有网桥。如果没有创建一个sudo ip link add name lxcbr0 type bridge sudo ip addr add 10.0.3.1/24 dev lxcbr0 sudo ip link set lxcbr0 up然后修改容器配置加上网络段# /var/lib/lxc/test01/config lxc.net.0.type veth lxc.net.0.link lxcbr0 lxc.net.0.flags up lxc.net.0.ipv4.address 10.0.3.100/24 lxc.net.0.ipv4.gateway 10.0.3.1这里给容器配了静态 IP。也可以不配 IP让容器内用 DHCP但需要宿主机上有 DHCP 服务。静态 IP 在测试环境里更可控推荐。配好重启容器lxc-info里应该能看到 IP。要通外网还需要在宿主机上做 NATsudo iptables -t nat -A POSTROUTING -s 10.0.3.0/24 -o eth0 -j MASQUERADE sudo sysctl -w net.ipv4.ip_forward1这两条的意思是允许转发并把容器网段的出站流量做源地址转换。做完之后容器内ping外网应该就通了。注意eth0要换成宿主机实际的出口网卡名。提示iptables 规则重启会丢生产环境要写进持久化配置或用 nftables 的持久化机制。测试环境图省事可以每次手动加。5. 那些文档里不写的坑5.1 User namespace 映射踩坑实录前面提过 User namespace 是安全关键但它的映射机制在实际操作中很容易出问题。我踩过最典型的一个坑是这样的容器跑起来之后在宿主机上ls -l容器的根文件系统目录发现所有文件的所有者都是100000这种数字而不是正常的 root。这不是 bug是 idmap 的正常表现。LXC 默认把容器内 uid 0 映射到宿主机 uid 100000 起始的区间。所以容器内 root 创建的文件宿主机上看到的是 100000。问题在于如果你在宿主机上直接往容器根文件系统里拷文件拷进去的文件所有者是宿主机的当前用户容器内看到的所有者就乱了可能导致容器内服务读不了文件。解决办法有两个一是用lxc-usernsexec在正确的映射下操作文件二是干脆在宿主机上以 100000 身份操作。更省事的办法是通过lxc-attach进容器操作避免在宿主机侧直接碰容器文件系统。还有一个更隐蔽的坑如果宿主机上/etc/subuid和/etc/subgid没给当前用户分配足够的映射区间创建容器时会报映射失败。这个文件里要有类似youruser:100000:65536的行表示给这个用户分配从 100000 开始的 65536 个 uid。很多发行版装完 LXC 不会自动配这个需要手动加。5.2 cgroup v1 与 v2 的配置不兼容这个坑在新老系统混用的环境里特别常见。老教程里的 LXC 资源限制配置长这样lxc.cgroup.memory.limit_in_bytes 2G lxc.cgroup.cpu.shares 512这是 cgroup v1 的写法。在 cgroup v2 的系统上这些配置要么不生效要么直接报错。v2 的写法是lxc.cgroup2.memory.max 2G lxc.cgroup2.cpu.weight 100注意lxc.cgroup变成了lxc.cgroup2参数名也变了。判断系统用的是哪个版本stat -fc %T /sys/fs/cgroup/输出cgroup2fs就是 v2tmpfs就是 v1。混用配置的后果是资源限制静默失效——容器看起来起来了但限制没生效某个容器吃满内存把宿主机拖垮排查半天才发现是配置写错了版本。这个坑我建议在每台机器上先确认 cgroup 版本再决定配置写法。5.3 容器内 systemd 起不来的排查链路LXC 容器里跑 systemd 是常见需求但经常遇到 systemd 起不来、容器启动后卡住或者直接退出的情况。这个问题的排查链路值得完整走一遍。第一步看容器日志。lxc-start -F -n test01前台启动观察输出。如果 systemd 报 Failed to mount cgroup 之类基本就是 cgroup 挂载问题。第二步确认容器配置里 cgroup 相关设置。LXC 较新版本需要显式允许容器内挂载 cgrouplxc.mount.auto cgroup:mixed这行的意思是让 LXC 自动在容器内挂载 cgroupmixed表示混合模式兼容性较好。没有这行容器内 systemd 找不到 cgroup 挂载点就会失败。第三步检查容器内是否有/run/systemd/system目录。systemd 用这个目录判断自己是不是 PID 1。如果容器根文件系统是从最小系统模板来的可能缺这个目录需要手动创建。第四步如果 systemd 起来了但服务起不来检查容器内是否缺少必要的内核模块或设备节点。LXC 默认会创建一些基础设备节点但某些服务需要额外设备要在配置里用lxc.cgroup2.devices.allow放行。这套排查链路走下来大部分 systemd 相关问题都能定位。核心思路是先确认 cgroup 挂载再确认 systemd 的 PID 1 判断最后看具体服务的设备/权限需求。5.4 容器逃逸风险与加固要点LXC 的隔离强度不如虚拟机这是共享内核的必然结果。所以用 LXC 跑不可信负载时要格外注意加固。几个关键点务必启用 User namespace 映射。不开的话容器内 root 就是宿主机 root一个内核漏洞就可能逃逸。开了之后即使容器内 root 被攻破在宿主机上也只是普通用户权限。限制 capabilities。容器默认可能带一堆 capability很多用不上。在配置里用lxc.cap.drop把不需要的去掉比如sys_admin、sys_module这类高危能力除非确实需要否则一律 drop。只读挂载敏感路径。容器如果不需要写某些宿主机路径就挂成只读。LXC 配置里可以用lxc.mount.entry精细控制挂载选项。限制设备访问。默认容器能访问的设备越少越好用 cgroup 的 devices 控制器白名单机制只放行必要设备。这些加固措施会牺牲一些便利性但换来的是实打实的安全边界。我的经验是内部可信环境可以适当放宽对外暴露或跑第三方代码的环境必须严格加固。6. 把 LXC 用在对的地方6.1 多发行版测试环境的快速搭建这是 LXC 最让我省心的场景。假设你要验证某个脚本在 Ubuntu、Debian、CentOS、Alpine 上的行为差异用虚拟机要装四套系统用 LXC 就是四条命令sudo lxc-create -n u22 -t download -- -d ubuntu -r jammy -a amd64 sudo lxc-create -n d12 -t download -- -d debian -r bookworm -a amd64 sudo lxc-create -n c9 -t download -- -d centos -r 9-Stream -a amd64 sudo lxc-create -n a318 -t download -- -d alpine -r 3.18 -a amd64四条命令下去几分钟内四套环境就绪每套占几百 MB 磁盘、几十 MB 内存。启动全部for c in u22 d12 c9 a318; do sudo lxc-start -n $c; done然后逐个lxc-attach进去跑测试。测完lxc-destroy清掉不留痕迹。这个流程比虚拟机快一个数量级比 Docker 更贴近真实系统——因为容器里是完整的发行版用户空间包管理、init、系统库都是真的测试结果更有参考价值。6.2 遗留服务的低成本容器化迁移手上有一批跑在老版本系统上的服务依赖 systemd、依赖特定内核参数、依赖一堆系统级配置。直接上 Docker 要改架构成本高。用 LXC 的迁移路径是这样的先在宿主机上创建对应发行版的容器把原服务的配置、数据、依赖原样搬进去调整网络和存储挂载然后启动测试。因为容器里是完整系统原服务的启动脚本、systemd unit、依赖关系基本不用改。迁移过程中要注意两点一是内核参数依赖容器共享宿主内核原服务如果依赖特定内核版本或模块要确认宿主内核满足二是设备访问原服务如果直接操作某些设备要在 LXC 配置里放行对应设备。这个路径的好处是迁移风险低、周期短适合那些能跑就别动的遗留系统。迁完之后至少获得了环境隔离和快速复制的能力比继续堆在物理机上强。6.3 资源受限环境下的密度优势在边缘设备或资源紧张的宿主机上LXC 的密度优势很明显。一台 8GB 内存的机器跑虚拟机可能只能开三四个跑 LXC 容器能开十几个甚至更多因为每个容器只占用户空间的内存没有内核和硬件模拟的开销。这个优势在需要多套隔离环境但预算有限的场景下很实用。比如一个小型团队需要给每个成员配一套独立的开发环境用 LXC 在一台中等配置的服务器上就能搞定每人一个容器互不干扰资源用 cgroup 限制好谁也影响不到谁。不过密度上去了运维复杂度也上去了。十几个容器的手工管理会很累这时候要配合配置管理工具或者自己写脚本批量操作。LXC 的命令行工具支持批量操作lxc-ls列出所有容器配合 shell 循环就能做批量启停、批量执行命令。6.4 什么情况下应该果断放弃 LXC说了这么多 LXC 的好也得说清楚它的边界。以下几种情况我建议直接选 Docker 或其它方案别在 LXC 上耗需要跨平台或跨内核版本。LXC 依赖宿主内核容器内用户空间和宿主内核要兼容。如果你的环境内核版本五花八门LXC 的兼容性维护会很痛苦。需要强隔离的多租户场景。共享内核意味着隔离强度有上限跑不可信的多租户负载虚拟机或专门的沙箱方案更稳妥。需要成熟的镜像生态和 CI/CD 集成。Docker 的镜像分层、仓库、构建工具链是 LXC 比不了的如果你的流程重度依赖这些选 Docker。团队没有系统管理经验。LXC 的系统容器模型要求使用者懂 Linux 系统管理会配网络、会调 cgroup、会排查 systemd 问题。如果团队偏应用开发、系统功底弱Docker 的上手门槛低得多。选型的本质是匹配场景和团队能力没有绝对的好坏。LXC 在它擅长的领域很能打但硬把它用在不适配的场景只会给自己找麻烦。7. 我个人的几点使用体会用 LXC 这些年有几个体会是文档里不会写、但实际很影响体验的。第一容器根文件系统的备份比想象中重要。LXC 容器是有状态的里面的配置、数据都在根文件系统里。一旦容器损坏重建成本不低。我的做法是定期对重要容器做lxc-snapshot或者直接 tar 打包根文件系统出问题能快速回滚。这个习惯救过我好几次。第二网络配置尽量静态化。动态分配 IP 在容器数量少的时候没问题数量一多排查问题时找不到对应容器很麻烦。静态 IP 加清晰的命名规范能让运维效率高不少。第三cgroup 限制宁紧勿松。刚开始用的时候容易图省事不设限制结果某个容器内存泄漏把整台机器拖垮。后来我养成习惯每个容器创建时就设好内存和 CPU 上限哪怕设得宽松一点也比不设强。第四别把 LXC 当 Docker 用。我见过有人试图在 LXC 里套 Docker或者在 LXC 里跑一堆短生命周期进程结果各种别扭。LXC 的模型是长期运行的系统顺着这个模型用才顺逆着用只会给自己添堵。最后分享一个排查小技巧容器起不来又没明显报错时先lxc-start -F前台跑看输出再检查/var/log/lxc/下的日志最后用lxc-attach试试能不能进——能进说明 namespace 创建成功问题在容器内 init进不去说明容器根本没起来问题在 LXC 配置或内核层面。这个二分法能快速缩小排查范围。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑