AI Infra 训练营
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub

systemd-detect-virt —— 探测当前运行环境的虚拟化类型

一句话定义

systemd-detect-virt 告诉你当前这台机器跑在什么虚拟化技术上:是物理机、KVM/VMware/Hyper-V 虚拟机、还是 LXC/Docker 这种容器。

典型场景

Day0 装 K8s 之前 5 分钟必跑的探机器命令之一。这一步的核心目的是排除 LXC 容器——很多小 IDC 把 LXC 卖成"VPS",外层看像 KVM、内层是容器套娃,K8s 在里面装不上。

systemd-detect-virt              # 一级探测:你跑在啥虚拟化里
systemd-detect-virt --container  # 二级探测:是否再嵌在一个容器里

输出值速查

没有虚拟化(物理机)

$ systemd-detect-virt
none
$ echo $?
1                                # 退出码 1 表示 "none"

注意:none 时退出码是 1,不是 0。在脚本里要小心,set -e 会让脚本因此退出。

虚拟机

输出含义
kvmKVM(Linux 内核虚拟化,最常见的国内云、自建 VM)
qemu纯 QEMU 软件虚拟化(无 KVM 加速,很慢)
vmwareVMware ESXi / Workstation
microsoftHyper-V
xenXen(AWS EC2 旧实例、阿里云某些规格)
oracleVirtualBox(个人桌面、Vagrant 环境)
parallelsmacOS 上的 Parallels
bhyveFreeBSD bhyve
amazonAWS Nitro 系实例(更新的 EC2)

容器

输出含义
dockerDocker 容器
lxcLXC / LXD 容器(装 K8s 的最大坑)
systemd-nspawnsystemd-nspawn 容器
podmanPodman 容器
containerd / cri-containerd普通 K8s pod
wslWSL 1/2(Windows Subsystem for Linux)

为什么 LXC 装 K8s 极难

K8s(更准确说 kubelet)要做几件 LXC 容器里做不了的事:

  1. 加载内核模块(br_netfilter、overlay、ip_tables)—— LXC 没有自己的内核,共享宿主内核,但宿主可能没装这些模块;你也没权限装
  2. 写 /proc/sys/... —— K8s 要调一堆 sysctl 参数,LXC 通常只允许读不允许写
  3. 管自己的 cgroup namespace —— 容器内层 K8s pod 还要再开一层 cgroup,套娃 cgroup 现代 systemd 支持得很差
  4. 网络隔离 —— iptables / nftables 规则、IPVS 转发,LXC 通常被宿主网络策略包住

遇到 LXC,直接换机器,不要花一天试图修。

很多 IDC(特别是国内做"独立 IP VPS"那种)的坑爹之处:

$ systemd-detect-virt
kvm                              # 看起来是 KVM,挺正常

$ systemd-detect-virt --container
lxc                              # 实际是 KVM 里又开了个 LXC,套娃

外层 kvm 看不出来,必须跑 --container 子探测才暴露。买 VPS 之前可以让 IDC 给你跑这一条验证。


三个常用 flag

默认:综合判断

systemd-detect-virt

返回最外层的虚拟化类型。kvm / vmware / none 等。

--container:只判断"是不是在容器里"

systemd-detect-virt --container
# none / lxc / docker / podman / ...

如果不在容器里、即使在 VM 里也返回 none。

--vm:只判断"是不是在 VM 里"

systemd-detect-virt --vm
# none / kvm / vmware / ...

只看 VM 层。

--quiet / -q:静默模式

if systemd-detect-virt -q --container; then
  echo "在容器里"
fi

-q 不输出,只用退出码判断。脚本里常用。

退出码语义:检测到任何虚拟化技术 → 0;检测到 none → 1。和直觉相反——找到东西反而是 0。


装机检测脚本(Day0 §1)

ssh root@$ip '
  echo "=== 虚拟化探测 ==="
  echo "外层: $(systemd-detect-virt)"
  echo "容器: $(systemd-detect-virt --container)"

  if systemd-detect-virt -q --container; then
    case $(systemd-detect-virt --container) in
      lxc|lxc-libvirt)
        echo "❌ LXC 容器,装不了 K8s,换机器"
        exit 1
        ;;
      docker|podman)
        echo "⚠️  你在 Docker/Podman 里,是 DinD 场景?确认一下"
        ;;
      *)
        echo "ℹ️  在容器里但不是 LXC: $(systemd-detect-virt --container)"
        ;;
    esac
  else
    echo "✅ 不在容器里"
  fi
'

放在 Day0 装机第一步的脚本里,一票否决"看起来是 VPS 实际是 LXC"的机器。


相关探测命令

命令用途
systemd-detect-virt虚拟化类型
dmidecode -s system-manufacturer硬件厂商(KVM 显示 "QEMU"、VMware 显示 "VMware")
cat /proc/cpuinfo | grep hypervisorCPU flag 含 hypervisor 表示在 VM 里
cat /sys/class/dmi/id/sys_vendor系统厂商
lscpu | grep Hypervisor检测 hypervisor 类型(lscpu 是更便携的查法)

systemd-detect-virt 是这几个里最准、最快、最好脚本化的。其它命令在不同发行版输出格式差异大。


常见踩坑

坑 1:在 macOS Docker Desktop 里跑 K8s

$ systemd-detect-virt --container
none

$ systemd-detect-virt
none

输出是 none,但你其实在 Docker Desktop 的 Linux VM 里。Docker Desktop 暴露的 Linux VM 看起来像物理机(它 hide 了一层)。这不算坑,因为这个 VM 装 K8s 没问题(minikube / kind 就是这么干的)。

坑 2:套娃虚拟化误判

某些极端情况:嵌套虚拟化(VM 里跑 KVM)—— systemd-detect-virt 只能告诉你最内层。要看完整链路:

dmesg | grep -iE 'hypervisor|kvm|virt' | head

坑 3:脚本里 if 判断逻辑反了

# ❌ 错的:退出码反直觉
if systemd-detect-virt -q; then
  echo "不在虚拟化里"     # 错!退出码 0 表示"在虚拟化里"
fi

# ✅ 对的
if systemd-detect-virt -q; then
  echo "在虚拟化里"
else
  echo "物理机"
fi

总结:找到 = 0、没找到 = 1,和 grep 一样的语义。


关联命令

  • lscpu —— CPU 信息,含 hypervisor 类型
  • dmidecode —— BIOS / 硬件元信息
  • cat /proc/cpuinfo —— hypervisor flag
  • lsblk —— 接下来该看磁盘了
在 GitHub 上编辑此页