当前位置:首页 ? 虚拟化资讯 ? 一文教你探测虚拟环境是物理机、虚拟机还是容器?

一文教你探测虚拟环境是物理机、虚拟机还是容器?

来源:51CTO 作者: 更新时间:2021/1/8 10:13:01

摘要:目前裸机(物理机)、虚拟机、容器是云计算提供计算服务的三种主流形式。那么如何判断一个虚拟shell环境到底是物理机、虚拟机还是容器呢?

  目前裸机(物理机)、虚拟机、容器是云计算提供计算服务的三种主流形式。那么如何判断一个虚拟shell环境到底是物理机、虚拟机还是容器呢?

  更进一步,如果是物理机,这个物理机厂商是什么,虚拟机到底是 KVM 还是 XEN,容器是 Docker 还是 rkt、lxc 等?

  更进一步,如果是虚拟机,是否可以判断这个虚拟机是运行在 AWS 还是阿里或者 OpenStack,是否能够获取虚拟机的 UUID、instance-type、vpc-id、安全组等信息?

  这有点像我们在开发中经常使用的反射(reflection)机制,通过反射可以知道一个类实例(instance)的类(class)是什么,更进一步可以知道这个类的父类是什么、实现了哪些方法、包含哪些属性等。

  以下是我用到的一些方法,仅供参考。

  1、判断容器

  目前还没有什么方法能够100%准确判断虚拟环境是否是容器,至少我没有找到相关文献。

  如果环境有systemd-detect-virt命令,则可以直接通过systemd-detect-virt -c命令判断,如果输出为none则不是容器,否则会输出容器类型,比如lxc。目前很少容器里面放systemd的,我见过的就只有 LXD 的ubuntu镜像,因此这种方法适用性不广。

  除此之外,可通过其他tricks判断,最简便的方法判断PID为1的进程,如果该进程就是应用进程则判断是容器,而如果是init进程或者systemd进程,则不一定是容器,当然不能排除是容器的情况,比如LXD/lXC实例的进程就为/sbin/init。

  容器和虚拟机不一样的是,容器和宿主机是共享内核的,因此理论上容器内部是没有内核文件的,除非挂载了宿主机的/boot目录:

  另外,我们知道容器是通过cgroup实现资源限制,每个容器都会放到一个cgroup组中,如果是Docker,则cgroup的名称为docker-xxxx,其中xxxx为Docker容器的UUID。

  而控制容器的资源,本质就是控制运行在容器内部的进程资源,因此我们可以通过查看容器内部进程为1的cgroup名称获取线索。

  如下是我通过 Docker 跑 busybox 的 cgroup 信息:

  我们不仅可以知道这是 Docker 容器,还获取了 Docker 容器的 UUID 为 9ba…11。

  根据如上的结论,判断一个虚拟环境是否 Docker 的脚本为:

  当然如果仅仅判断是否 Docker 容器,还能通过判断是否存在 .dockerenv 文件区分是否Docker 容器:

  rkt 容器类似,输出结果如下:

  如上的 \x2d 为-号:

  因此判断一个虚拟环境是否 rkt 的脚本为:

  好奇 AWS lambda 的运行环境是什么,于是写了个函数输出 /proc/1/cgroup,结果为:

  猜测是一种叫 sandbox 的运行环境,估计也是一种容器。

  判断虚拟环境是否为容器环境相对比较复杂,目前没有完美的方案,总结过程如下:

  判断是否可运行 systemd-detect-virt -c 命令,如果输出为 none 则不是容器,否则可确定容器类型。

  判断 PID 1 如果为应用本身,则该虚拟环境是容器,否则不能确定是否是容器。

  判断是否存在加载的内核文件,如果不存在,则可判断为容器,否则不能确定是否为容器。

  判断是否存在 /.dockerenv 文件,如果存在则为 Docker 容器,否则不能确定是否为容器。读取 /proc/1/cgroup 文件,判断是否包含 docker、rkt 等关键字,如果包含,则说明为容器,否则不能确定是否为容器。

  另外,需要特别注意的是,容器必须最先判断,因为容器本身并没有任何的硬件虚拟化,容器看到的硬件特性信息和宿主机看到的完全一样,因此下面介绍的通过lscpu以及DMI信息判断是否是虚拟机或者物理机,对容器并不适用。换句话说,不能因为lscpu的Hypervisor vendor值为KVM就说明一定是KVM虚拟机,因为它也有可能是容器。下文均假设已经排除为容器的情况。

  2、判断物理机

  如果使用了 systemd,则可以直接通过 systemd-detect-virt 命令判断是否物理机:

  如果输出为 none,则说明是物理机。

  当然也可根据 lscpu 命令输出,看是否有 Hypervisor vendor 属性,如果没有该属性,则一般为物理机,如果存在该属性则一定是虚拟机:

  获取物理机的信息最直接的方式是查看 DMI 信息 /sys/firmware/dmi/tables/DMI,使用 dmidecode 命令解码:

  如上可以看出这是台物理机,厂商为 HP,型号为 ProLiant DL380 Gen9,序列号为6CU6468KKD。

  通过 ipmitool 命令可以查看物理服务器的带外 IP:

  当然如果是虚拟机,如上命令会执行失败。另外也可以通过其他命令查看物理信息,如lshw 命令。

  3、判断虚拟机

  其实前面已经提到了,如果使用了systemd,则可以直接通过 systemd-detect-virt 命令判断是否虚拟机:

  如果是虚拟机,则会输出虚拟机类型,如 kvm、oracle(virtualbox)、xen 等。

  当然也可根据 lscpu 命令输出,查看 Hypervisor vendor 属性值:

  通过如上命令,我的一台 AWS 虚拟机输出为 Xen,阿里云虚拟机为 KVM,VirtualBox虚拟机也输出为 KVM,这是因为我使用了 KVM 硬件加速虚拟化。

  我的搬瓦工虚拟机输出也为 KVM,可见搬瓦工主机也是 KVM 虚拟机。

  通过如上方法可以获取虚拟机的虚拟化类型,能否获取更多信息呢?参考物理机的获取方式,我们可以通过 dmidecode 命令获取更多的虚拟机信息。比如我在一台 OpenStack 虚拟机运行如下命令:

  如上 Manufacturer 为 OpenStack Foundation,说明运行在 OpenStack 平台,Version为 Nova 版本,根据 OpenStack 的 releases 可知 15.0.1 对应为 OpenStack Ocata 版本,而 UUID 即虚拟机的 UUID。

  AWS 上的一台虚拟机输出为:

  在 Version 中标明了 amazon 字样。

  阿里云虚拟机如下(感谢L神提供的输出):

  可见虽然可以从 system 信息中获取云厂商的线索,但其实虚拟机的 system 信息并没有统一的标准,有的在 version 中体现,有的在 Product Name 中表现,完全取决于云厂商自己的配置。

  如上整合如下脚本初略判断:

  如上也可以判断公有云是否基于 OpenStack 实现,比如华为虚拟机输出为 OpenStack,可大致猜测华为的公有云是基于 OpenStack 实现的。

  AWS 以及 OpenStack 系的虚拟机还可以通过 metadata 或者 ConfigDrive 获取更多信息,以 metadata 为例:

  获取虚拟机的 ID:

  获取 instance type (规格):

  获取虚拟机的公有IP(弹性IP),这个挺有用的,因为在虚拟机没法通过ifconfig查看弹性IP,经常登录虚拟机后,忘记自己的公有IP:

  其他的比如 vpc-id、ami id(镜像id)、安全组、公钥名等都可以通过该方式获取。

  如果是 OpenStack,还可以使用 OpenStack 的 metadata 获取更多信息:

  如上可获取虚拟机的租户 ID、volume type 等信息。当然邪恶点可以通过查看 userdata获取虚拟机初始化 root 密码。AWS 甚至可以查看 AccessKeyId 以及SecretAccessKey。

  4、总结

  如上总结了几种判断虚拟化环境类型的方法,不一定准确,仅供参考,当然也可能还有其他更好的方法。

  如下是根据前面的结论写的一个探测虚拟化类型的脚本,不一定健壮完备,仅供参考:

  责任编辑:张华

机房360微信公众号订阅
扫一扫,订阅更多数据中心资讯

本文地址:http://cczmydr.881xtd.com/news/202118/n9335136024.html 网友评论:阅读次数:
版权声明:凡本站原创文章,未经授权,禁止转载,否则追究法律责任。
相关评论
正在加载评论列表...
评论表单加载中...
  • 我要分享
推荐图片
网站地图 菠萝彩票怎么样登入 568专业彩票网登入 幸运彩票app版登入
大型电玩游戏 申搏官网138 申博会员登录 菲律宾太阳城
99彩平台直营网 九乐棋牌礼包 og东方馆投注平台 红中彩票官网
幸运彩票开户登入 568专业彩票网网址登入 双色球幸运彩票网登入 568专业彩票网娱乐登入
幸运彩票如何开户登入 幸运彩票如何开户登入 568专业彩票网会员中心登入 幸运彩票娱乐登入
988xsb.com S618M.COM 4444ib.com XSB183.COM 1112938.COM
255PT.COM 111xsb.com 985ib.com 638PT.COM 588BBIN.COM
5555XSB.COM DC738.COM 768XTD.COM 295SUN.COM 131ib.com
877TGP.COM 78XTD.COM 22sbsg.com 333xsb.com 132sun.com