有点黑客帝国的意思,我就想探索下怎么判断当前终端所处环境是容器里还是就在物理机上,或者是虚拟机?
容器和虚拟机的区别:容器共享内核,虚拟机独享内核
虚拟机和物理机的区别:虚拟机是软件模拟的完整硬件系统功能的、完全隔离环境的计算机系统。只要模拟的全面,是没有太大差别的。除了性能差异,毕竟软件做了硬件的事。
以下测试环境:
容器 docker
虚拟机 私有CVM
物理机 ubuntu
方法一:
systemd-detect-virt
如果是容器会显示 docker
如果是CVM会显示 kvm
如果是物理机会显示 none
但有的环境,比如容器里可能没有这个命令。
方法二:
判断内核路径是否存在
$(cat /proc/cmdline | tr ' ' '\n' | awk -F '=' '/BOOT_IMAGE/{print $2}') | test -e
如果是容器会显示 /boot/目录下一个文件但 No such file or directory
如果是虚拟机会显是 /boot/目录下一个文件Permission denied 至少是存在的。
如果是物理机 同上
方法三:
容器是通过 cgroup 实现资源限制,判断容器是否在一个 cgroup 组中
cat /proc/1/cgroup
如果容器会显示(以docker为例)
12:cpuset:/kubepods/burstable/podc....
11:cpuacct,cpu:/kubepods/burstable/podc....
10:oom:/
9:pids:/kubepods/burstable/podc....
8:memory:/kubepods/burstable/podc....
7:perf_event:/kubepods/burstable/podc....
6:hugetlb:/kubepods/burstable/podc....
5:devices:/kubepods/burstable/podc....
4:blkio:/kubepods/burstable/podc....
3:net_cls:/kubepods/burstable/podc....
2:freezer:/kubepods/burstable/podc....
1:name=systemd:/kubepods/burstable/podc....
如果虚拟机会显示
12:pids:/
11:freezer:/
10:hugetlb:/
9:oom:/
8:cpuacct,cpu:/
7:net_cls:/
6:blkio:/
5:devices:/
4:cpuset:/
3:memory:/
2:perf_event:/
1:name=systemd:/
区别还是挺明显的
物理机同上
方法四
Hypervisor是所有虚拟化技术的核心。Hypervisor是一种运行在物理服务器和操作系统之间的中间软件层,可允许多个操作系统和应用共享一套基础物理硬件,所以看是否有Hypervisor vendor属性,如果没有该属性,则一般为物理机,如果存在该属性则一定是虚拟机或容器。
lscpu | grep 'Hypervisor vendor'
如果是容器会显示 Hypervisor vendor: KVM
如果是虚拟机会显是 Hypervisor vendor: KVM
如果是物理机会显示为空 没有
方法五
DMI (Desktop Management Interface, DMI)是帮助收集电脑系统信息的管理系统。
DMI充当了管理工具和系统层之间接口的角色。我们可以通过它了解电脑厂商、序列号、电脑厂商、串口信息以及其它系统配件信息。
sudo dmidecode -t system
如果是容器会显示
/dev/mem: No such file or directory
如果是虚拟机会显是
Handle 0x0100, DMI type 1, 27 bytes
System Information
Manufacturer: Smdbmds
Product Name: KVM
如果是物理机会显示
Handle 0x0001, DMI type 1, 27 bytes
System Information
Manufacturer: System manufacturer
Product Name: System Product Name
Version: System Version
综上,有些命令并不能百分百区别出物理机,虚拟机,容器,但是还是有一定分辨能力。