上一篇 下一篇 分享链接 返回 返回顶部

如何在香港服务器Ubuntu系统中把LXD容器和Ceph存储绑在一起,跑出高密度虚拟化

发布人:Minchunlin 发布时间:2025-08-30 09:49 阅读量:711


凌晨 3 点,香港葵涌机房外的走廊还吹着湿热的风。我和同事靠着机柜门坐着,盯着笔电上最后一批容器迁移的进度条。客户白天流量太猛,只能夜里切。我们要在不加物理服务器的前提下,把一堆 KVM 小机“装进”更轻的容器里,同时把分散的本地盘汇成一套可横向扩展的分布式存储。

这就是我把 LXD 和 Ceph 绑在一起的开始:容器算力的密度 + Ceph 的弹性与可靠性。

方案总览(先看图,再落地)

结构简图
               ┌──────────────────────────┐
               │        LXD 集群          │
               │  lxd-01  lxd-02  lxd-03  │
               │     |       |       |    │
客户端网络 ────┼─────┴───────┴───────┼───── 公网/业务VLAN
               │                       │
               │       存储网络(25G)   │
               └───────┬───────┬──────┘
                       │       │
             ┌─────────┴───────┴─────────┐
             │          Ceph 集群         │
             │  mon/mgr:3 节点           │
             │  osd:NVMe 全闪 3~5 节点    │
             └───────────────────────────┘
  • 计算层:LXD 集群,跑容器(需要时也能跑 LXD VM)。
  • 存储层:Ceph(RBD)作为 LXD 的后端存储池。容器根盘、快照、克隆都走 RBD。
  • 网络:业务/管理与存储网络分离,存储走 25GbE,MTU 9000。
  • 目标:同等服务器数量下容器密度提升 2~3 倍,同时支持在线扩容与秒级快照/克隆。

硬件与网络清单(真实可买得到的货)

角色 型号/参数 数量 关键点
LXD 计算节点 2U 双路(如 Supermicro/戴尔同级)/ Intel Xeon Silver/ 256–512GB RAM 3–5 CPU 频率 > 核数,容器更吃单核
系统盘 2 × 480GB SATA SSD(RAID1) 每节点 只放 OS/日志
存储网卡 2 × 25GbE(Mellanox CX4/5) 每节点 LACP 绑到存储交换机对
业务网卡 2 × 10/25GbE 每节点 业务/公网/管理 VLAN
Ceph OSD 盘 6 × 3.84TB NVMe(如 PM9A3/U.2) 每 OSD 节点 全闪,RBD 延迟稳
Ceph 节点数 3(起步)→ 5(建议) 3 副本或 2+1 EC 视负载
交换机 2 × ToR(支持 MLAG/VSX) 存储与业务网络隔离,MTU 9000

香港带宽贵、机柜紧:算力密度和能耗比是第一优先,所以我选了全闪 Ceph + 容器化 LXD。

软件版本与基线

  • Ubuntu Server:22.04 LTS(长期维护,内核新;24.04 也可,按你团队基线即可)
  • LXD:使用 LTS 通道(snap 安装),集群模式
  • Ceph:近两代稳定分支(如 Reef 或之后的稳定版),用 cephadm 部署
  • 时钟:Chrony,全节点同源;NTP 漂移会把 Ceph 选主搞崩

内核参数/网卡:开启 GRO/LRO 合理性评估;MTU 9000 的链路端到端一致

步骤 1:操作系统基线与内核调优

# 关闭 swap(容器密度高时,swap 容易把 I/O 打爆)
sudo swapoff -a
sudo sed -ri 's/^(\/swap.*)$/#\1/' /etc/fstab

# 调高文件句柄与aio
cat <<'EOF' | sudo tee /etc/sysctl.d/99-lxd-ceph.conf
fs.aio-max-nr = 1048576
fs.file-max = 2000000
net.core.somaxconn = 1024
net.core.rmem_default = 262144
net.core.wmem_default = 262144
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.core.netdev_max_backlog = 250000
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
net.ipv4.tcp_congestion_control = bbr
EOF
sudo sysctl --system

# CPU 调到性能模式
sudo apt-get -y install linux-tools-common linux-tools-generic
for c in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo performance | sudo tee $c; done

步骤 2:部署 Ceph(cephadm,先把存储打好)

在 任一 Ceph 管理节点:

# 准备
sudo apt -y update && sudo apt -y install podman lvm2
curl -fsSL https://download.ceph.com/keys/release.asc | sudo gpg --dearmor -o /usr/share/keyrings/ceph.gpg

# cephadm 安装
curl -fsSL https://raw.githubusercontent.com/ceph/ceph/reef/src/cephadm/cephadm \
  | sudo python3 - add-repo --release reef
curl -fsSL https://raw.githubusercontent.com/ceph/ceph/reef/src/cephadm/cephadm \
  | sudo python3 - install

# 引导(填管理网 IP)
sudo cephadm bootstrap --mon-ip 10.0.10.11 \
  --initial-dashboard-user admin --initial-dashboard-password 'YourStrongPwd!'

把其它存储节点加入集群:

# 在 bootstrap 节点执行
sudo cephadm add-repo --release reef
sudo cephadm install ceph-common

# 添加主机
ceph orch host add ceph-02 10.0.10.12
ceph orch host add ceph-03 10.0.10.13
# 如有更多 OSD 节点继续加

# 让 Ceph 自动识别全部可用 NVMe 作为 OSD
ceph orch apply osd --all-available-devices

创建 RBD 专用池 并开启应用标识:

ceph osd pool create lxd-ceph 256 256 replicated
ceph osd pool application enable lxd-ceph rbd

PG 数:全闪+25G 网络,我常用起步 256,节点多时再调。太少会热点,太多占内存。

给 LXD 一个专用的 Ceph 用户(最小权限):

ceph auth get-or-create client.lxd mon 'profile rbd' osd 'profile rbd pool=lxd-ceph' \
  > /etc/ceph/ceph.client.lxd.keyring
ceph auth get-key client.lxd > /etc/ceph/client.lxd.key

步骤 3:LXD 集群初始化(计算面)

在每个 LXD 节点:

# 安装 LXD(LTS 通道)
sudo snap install lxd --channel=6.0/stable   # 如用 5.x LTS 亦可,保持集群一致
sudo usermod -aG lxd $USER
newgrp lxd

用 preseed 一次性初始化(以首节点为例):

cat <<'YAML' > lxd-preseed.yaml
config: {}
cluster:
  enabled: true
  server_name: lxd-01
  member_config: []
  cluster_address: ""        # 首节点为空
  cluster_certificate: ""
  cluster_password: "JoinMe!"
networks:
- name: br0
  type: bridge
  config:
    ipv4.address: 10.10.10.1/24
    ipv4.nat: "true"
    ipv6.address: fd42:1000::1/64
    ipv6.nat: "true"
storage_pools: []
profiles:
- name: default
  description: Default profile
  devices:
    eth0:
      name: eth0
      network: br0
      type: nic
    root:
      path: /
      pool: default
      type: disk
projects: []
cluster_certificate: ""
YAML

lxd init --preseed < lxd-preseed.yaml

把 其余 LXD 节点 加入集群(在新节点上):

lxd init
# 选择加入现有集群,填:lxd-01 的 IP、cluster password、本节点名(lxd-02 / lxd-03)

初次装完默认只有本地 default 存储池(通常是 dir/zfs)。下一步我们把 Ceph 作为 LXD 的主存储池。

步骤 4:把 Ceph RBD 接到 LXD

在 任一 LXD 集群成员(建议首节点):

# 把 Ceph 配置与密钥分发到每个 LXD 节点
sudo mkdir -p /etc/ceph
sudo scp ceph-01:/etc/ceph/ceph.conf /etc/ceph/
sudo scp ceph-01:/etc/ceph/client.lxd.key /etc/ceph/
sudo chmod 600 /etc/ceph/client.lxd.key

# 创建 LXD 存储池(类型 rbd)
lxc storage create ceph rbd \
  source=lxd-ceph \
  ceph.cluster_name=ceph \
  ceph.user.name=client.lxd \
  ceph.user.key="$(sudo cat /etc/ceph/client.lxd.key)"

把 默认 profile 的根盘指向 Ceph 池:

# 新建一个 profile,避免直接改 default
lxc profile create ceph-root
lxc profile copy default ceph-root
lxc profile device set ceph-root root pool ceph

验证:

lxc launch images:ubuntu/22.04 u1 --profile ceph-root
lxc exec u1 -- df -h /
# 在 Ceph 上看 rbd 镜像
rbd -p lxd-ceph ls

步骤 5:网络与 IP 策略(香港机房的“土办法”和“正解”)

三种常用打法:

  • NAT 网桥(最简单):如上 br0,容器出公网 NAT。适合内部服务或少量暴露端口。
  • routed NIC(推荐):机房给一段 /29 或 /28,LXD 宿主做路由,把公网/业务 IP 直接路由到容器。
  • SR-IOV 直通(高性能/低抖动):适合对延迟极敏感的容器(例如边缘网关)。

routed NIC 示例(业务网是 ens3f0):

lxc network create routed0 \
  ipv4.address=none ipv6.address=none \
  ipv4.nat=false ipv6.nat=false

# profile
lxc profile create routed
cat <<'EOF' | lxc profile edit routed
config: {}
description: routed nic
devices:
  eth0:
    nictype: routed
    parent: ens3f0
    type: nic
  root:
    path: /
    pool: ceph
    type: disk
name: routed
EOF

# 启动容器并手动配置一个 /32 公网
lxc launch images:ubuntu/22.04 web-01 --profile routed
lxc exec web-01 -- bash -lc 'ip addr add 203.0.113.25/32 dev eth0; ip route add default via 203.0.113.1'

坑 1(MTU):存储网 9000、业务网 1500 要分清,容器里 MTU 也要配。否则 Ceph 写入卡顿但 ping 正常,最难排。
坑 2(邻居缓存):routed 模式下 ARP/ND 表要够大,宿主与 ToR 交换机一起调参。

步骤 6:高密度的资源配额与画像

容器配额(profile 里设置):

lxc profile set ceph-root limits.cpu 4                   # 共享4核
lxc profile set ceph-root limits.cpu.allowance 80%       # 总 CPU 占比
lxc profile set ceph-root limits.memory 4GiB
lxc profile set ceph-root limits.memory.swap false
lxc profile set ceph-root limits.processes 32768
lxc profile set ceph-root limits.disk.priority 5

容器 I/O 控制(cgroup v2):对“吵闹邻居”生效,避免一个容器把 NVMe 打满。

# 针对单容器
lxc config set u1 limits.disk.priority 1            # 最高优先级=0,数越大越低
lxc config set u1 limits.network.priority 3

镜像与克隆:RBD 原生支持快照/克隆,LXD copy --refresh、publish 都很快:

# 制作基础镜像
lxc launch images:ubuntu/22.04 base --profile ceph-root
# 装好依赖后发布为自定义镜像
lxc publish base --alias appseed-22.04

# 批量拉起 N 台
for i in $(seq 1 50); do
  lxc launch appseed-22.04 app-$i --profile ceph-root
done

步骤 7:备份、快照与回滚

# 在线快照
lxc snapshot app-01 pre-upgrade

# 回滚
lxc restore app-01 pre-upgrade

# 远端复制(同集群或跨集群)
lxc remote add dr-site 10.0.20.10:8443
lxc copy app-01 dr-site:app-01 --refresh

注意:跨站复制走网络,确保加密与限速,不然轻易把跨境专线打爆。

步骤 8:监控与告警

Ceph:Dashboard + Prometheus/Grafana(OSD 延迟、PG 状态、慢请求)。

LXD:lxc monitor、/metrics 暴露到 Prometheus,重点抓:容器数、CPU steal、内存压力、IOPS。

底座:节点 SMART、NVMe 健康、温度、链路 flap 计数。

我踩过的坑(和怎么处理)

MTU 不一致导致 Ceph 写延迟高

现象:fio 随机写 P99 > 20ms,ping 一切正常。

处理:逐段抓包(容器→宿主→ToR→Ceph),发现业务网 1500、存储 9000,但容器里 MTU 还是 1500,导致分片与重传。统一 MTU 或开 GSO/GRO。

Ceph 选主漂移(时钟)

现象:凌晨业务低谷 mon 乱选,OSD flap。

处理:所有节点用同一对上游 NTP,Chrony makestep 打开;在交换机上开 PTP/Boundary 也可。

容器内大量文件句柄(nginx+epoll+长连接)

现象:报 too many open files,但宿主还很空。

处理:容器 profile 里加 limits.processes 与 security.syscalls.intercept.setrlimit=true,并在容器里调 nofile ulimit。

RBD 特性与内核 rbd 冲突

说明:LXD 用 librbd,一般不映射到内核块设备。但你手工 rbd map 测试时,如果开了 exclusive-lock|object-map,老内核可能出兼容问题。

处理:测试时优先用 rbd-nbd,或升级内核;业务上交给 LXD 调用 librbd。

容器里跑 Docker(DinD)

处理:LXD 支持特权容器+nesting,但建议改用 LXD 直接跑工作负载。实在要嵌套,profile 里开启:

lxc profile set ceph-root security.nesting true
lxc profile set ceph-root security.privileged true   # 有风险,谨慎

实测数据(来自机房深夜跑的 fio 与实际业务)

单 OSD 节点(6×3.84TB NVMe,3 副本)

指标 4KB 随机读 4KB 随机写 64KB 顺序读 64KB 顺序写
IOPS(P50) ~480k ~210k
吞吐(MB/s) ~5200 ~3600
延迟(P99) 1.2 ms 3.8 ms 2.1 ms 4.7 ms

集群层(3 OSD 节点,总 18 块 NVMe):

  • 容器密度:通用 Web/API 容器稳定在 120–180 个/节点(4GiB/容器,CPU 限额 0.5–1 vCPU)。
  • 扩容时间:新容器从镜像到可对外服务 20–40 秒;用 RBD 克隆批量起 50 台 < 2 分钟。
  • 升级窗口:Ceph 滚动升级 OSD(ceph orch restart osd,逐台排空)对 95% 业务无感。

注:你的数据会因 CPU、NVMe 型号、网络与压测方式不同而有波动,但量级和关系大致一致。

运维日常与变更流程(我现在的“顺手流程”)

变更前:

  • lxc export project --instance-only 导出关键实例;
  • ceph df、ceph -s、监控检查无降级;
  • 业务侧开启只读或流量旁路(如有)。

变更中:

  • 先做一台节点(canary),观察 30 分钟各项 p95;
  • 限流:tc qdisc 给复制/迁移流量限速,避免把业务带宽占满。

变更后:

  • 快照打点:lxc snapshot --stateful(如果应用支持);
  • 文档补要点(故障/回退点位、命令/日志)。

成本与收益(为什么值得)

KVM(原) LXD+Ceph(现) 说明
单节点可承载实例数 40–60 120–180 轻量隔离、更少内存开销
实例创建时间 分钟级 秒级 RBD 克隆+轻量 rootfs
存储弹性 Ceph 横向扩展与副本
故障域 主机级 主机/OSD/PG 多层 容错更细粒度
单实例成本 0.4–0.6× 香港机柜/带宽越贵越显著

常用命令“口袋卡”

# LXD
lxc list -c ns4,ep,st --format table
lxc info app-01
lxc config show app-01 --expanded
lxc profile list && lxc profile show ceph-root
lxc storage list && lxc storage info ceph

# Ceph
ceph -s
ceph osd tree
ceph osd df tree
rbd -p lxd-ceph ls && rbd -p lxd-ceph du

安全与隔离说明

  • 优先使用非特权容器(unprivileged),避免 root 映射到宿主 0。
  • AppArmor/seccomp 默认开启;只有明确需求再放权。
  • 多租户:用 project 隔离配额与命名空间;每租户一个 project。
  • 镜像供应链:自建 simplestreams 或从受信镜像源拉取并加签。

故障排查“战例”两则

战例 A:容器随机超时(每小时几次)

  • 发现:dmesg 有 mlx5e 报错,ToR 日志有 ECMP 变更。
  • 定位:交换机做了策略更新,短暂 flap;容器探活阈值太紧。
  • 修复:上游变更窗口管控 + 容器内 net.ipv4.tcp_syn_retries 放宽;LXD 健康探针重试。

战例 B:Ceph 出现慢请求

  • 发现:业务低峰跑了大量快照+克隆;后台 deep-scrub 撞上了。
  • 处理:调低夜间 scrub 的并发与速率;克隆作业限速;关键 PG 绑到延迟更低的机箱。

可复制的最小化落地清单(TL;DR)

  • Ubuntu LTS + 关闭 swap + sysctl/ulimit 调优。
  • 用 cephadm 部署 3+ 全闪 Ceph,建 lxd-ceph RBD 池。
  • LXD 走 LTS 通道,初始化集群,lxc storage create ceph rbd ... 接入 Ceph。
  • 新建 ceph-root profile:根盘在 Ceph、配好 CPU/内存/DISK 限额。
  • 选路由型/直通网卡,统一 MTU。
  • 镜像 → 快照 → 克隆,批量上线应用;Prometheus 全链路观测。
  • 变更有 canary、有回滚点、有速率限制。

最后一个容器的绿灯亮起时,机房外的天空刚泛起鱼肚白。客户的 API 监控线条恢复得很平。我们把笔电合上,靠在机柜边上喘了口气。
高密度虚拟化不是把更多东西硬塞进一台机器,而是把算力、网络、存储拧成一股绳——该快的地方快,该稳的地方稳。LXD 给了我轻盈,Ceph 给了我底气。
如果你也在香港这样的环境里做同样的事,希望这份手册能让你少熬几个夜。

目录结构
全文