自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一文教你探測(cè)虛擬環(huán)境是物理機(jī)、虛擬機(jī)還是容器?

開(kāi)發(fā) 前端
目前裸機(jī)(物理機(jī))、虛擬機(jī)、容器是云計(jì)算提供計(jì)算服務(wù)的三種主流形式。那么如何判斷一個(gè)虛擬shell環(huán)境到底是物理機(jī)、虛擬機(jī)還是容器呢?

目前裸機(jī)(物理機(jī))、虛擬機(jī)、容器是云計(jì)算提供計(jì)算服務(wù)的三種主流形式。那么如何判斷一個(gè)虛擬shell環(huán)境到底是物理機(jī)、虛擬機(jī)還是容器呢?

更進(jìn)一步,如果是物理機(jī),這個(gè)物理機(jī)廠商是什么,虛擬機(jī)到底是 KVM 還是 XEN,容器是 Docker 還是 rkt、lxc 等?

更進(jìn)一步,如果是虛擬機(jī),是否可以判斷這個(gè)虛擬機(jī)是運(yùn)行在 AWS 還是阿里或者 OpenStack,是否能夠獲取虛擬機(jī)的 UUID、instance-type、vpc-id、安全組等信息?

這有點(diǎn)像我們?cè)陂_(kāi)發(fā)中經(jīng)常使用的反射(reflection)機(jī)制,通過(guò)反射可以知道一個(gè)類(lèi)實(shí)例(instance)的類(lèi)(class)是什么,更進(jìn)一步可以知道這個(gè)類(lèi)的父類(lèi)是什么、實(shí)現(xiàn)了哪些方法、包含哪些屬性等。

以下是我用到的一些方法,僅供參考。

1、判斷容器

目前還沒(méi)有什么方法能夠100%準(zhǔn)確判斷虛擬環(huán)境是否是容器,至少我沒(méi)有找到相關(guān)文獻(xiàn)。

如果環(huán)境有systemd-detect-virt命令,則可以直接通過(guò)systemd-detect-virt -c命令判斷,如果輸出為none則不是容器,否則會(huì)輸出容器類(lèi)型,比如lxc。目前很少容器里面放systemd的,我見(jiàn)過(guò)的就只有 LXD 的ubuntu鏡像,因此這種方法適用性不廣。

除此之外,可通過(guò)其他tricks判斷,最簡(jiǎn)便的方法判斷PID為1的進(jìn)程,如果該進(jìn)程就是應(yīng)用進(jìn)程則判斷是容器,而如果是init進(jìn)程或者systemd進(jìn)程,則不一定是容器,當(dāng)然不能排除是容器的情況,比如LXD/lXC實(shí)例的進(jìn)程就為/sbin/init。

容器和虛擬機(jī)不一樣的是,容器和宿主機(jī)是共享內(nèi)核的,因此理論上容器內(nèi)部是沒(méi)有內(nèi)核文件的,除非掛載了宿主機(jī)的/boot目錄:

另外,我們知道容器是通過(guò)cgroup實(shí)現(xiàn)資源限制,每個(gè)容器都會(huì)放到一個(gè)cgroup組中,如果是Docker,則cgroup的名稱(chēng)為docker-xxxx,其中xxxx為Docker容器的UUID。

而控制容器的資源,本質(zhì)就是控制運(yùn)行在容器內(nèi)部的進(jìn)程資源,因此我們可以通過(guò)查看容器內(nèi)部進(jìn)程為1的cgroup名稱(chēng)獲取線(xiàn)索。

如下是我通過(guò) Docker 跑 busybox 的 cgroup 信息:

我們不僅可以知道這是 Docker 容器,還獲取了 Docker 容器的 UUID 為 9ba…11。

根據(jù)如上的結(jié)論,判斷一個(gè)虛擬環(huán)境是否 Docker 的腳本為:

當(dāng)然如果僅僅判斷是否 Docker 容器,還能通過(guò)判斷是否存在 .dockerenv 文件區(qū)分是否Docker 容器:

rkt 容器類(lèi)似,輸出結(jié)果如下:

如上的 \x2d 為-號(hào):

因此判斷一個(gè)虛擬環(huán)境是否 rkt 的腳本為:

好奇 AWS lambda 的運(yùn)行環(huán)境是什么,于是寫(xiě)了個(gè)函數(shù)輸出 /proc/1/cgroup,結(jié)果為:

猜測(cè)是一種叫 sandbox 的運(yùn)行環(huán)境,估計(jì)也是一種容器。

判斷虛擬環(huán)境是否為容器環(huán)境相對(duì)比較復(fù)雜,目前沒(méi)有完美的方案,總結(jié)過(guò)程如下:

  • 判斷是否可運(yùn)行 systemd-detect-virt -c 命令,如果輸出為 none 則不是容器,否則可確定容器類(lèi)型。
  • 判斷 PID 1 如果為應(yīng)用本身,則該虛擬環(huán)境是容器,否則不能確定是否是容器。
  • 判斷是否存在加載的內(nèi)核文件,如果不存在,則可判斷為容器,否則不能確定是否為容器。
  • 判斷是否存在 /.dockerenv 文件,如果存在則為 Docker 容器,否則不能確定是否為容器。讀取 /proc/1/cgroup 文件,判斷是否包含 docker、rkt 等關(guān)鍵字,如果包含,則說(shuō)明為容器,否則不能確定是否為容器。

另外,需要特別注意的是,容器必須最先判斷,因?yàn)槿萜鞅旧聿](méi)有任何的硬件虛擬化,容器看到的硬件特性信息和宿主機(jī)看到的完全一樣,因此下面介紹的通過(guò)lscpu以及DMI信息判斷是否是虛擬機(jī)或者物理機(jī),對(duì)容器并不適用。換句話(huà)說(shuō),不能因?yàn)閘scpu的Hypervisor vendor值為KVM就說(shuō)明一定是KVM虛擬機(jī),因?yàn)樗灿锌赡苁侨萜?。下文均假設(shè)已經(jīng)排除為容器的情況。

2、判斷物理機(jī)

如果使用了 systemd,則可以直接通過(guò) systemd-detect-virt 命令判斷是否物理機(jī):

如果輸出為 none,則說(shuō)明是物理機(jī)。

當(dāng)然也可根據(jù) lscpu 命令輸出,看是否有 Hypervisor vendor 屬性,如果沒(méi)有該屬性,則一般為物理機(jī),如果存在該屬性則一定是虛擬機(jī):

獲取物理機(jī)的信息最直接的方式是查看 DMI 信息 /sys/firmware/dmi/tables/DMI,使用 dmidecode 命令解碼:

如上可以看出這是臺(tái)物理機(jī),廠商為 HP,型號(hào)為 ProLiant DL380 Gen9,序列號(hào)為6CU6468KKD。

通過(guò) ipmitool 命令可以查看物理服務(wù)器的帶外 IP:

當(dāng)然如果是虛擬機(jī),如上命令會(huì)執(zhí)行失敗。另外也可以通過(guò)其他命令查看物理信息,如lshw 命令。

3、判斷虛擬機(jī)

其實(shí)前面已經(jīng)提到了,如果使用了systemd,則可以直接通過(guò) systemd-detect-virt 命令判斷是否虛擬機(jī):

如果是虛擬機(jī),則會(huì)輸出虛擬機(jī)類(lèi)型,如 kvm、oracle(virtualbox)、xen 等。

當(dāng)然也可根據(jù) lscpu 命令輸出,查看 Hypervisor vendor 屬性值:

通過(guò)如上命令,我的一臺(tái) AWS 虛擬機(jī)輸出為 Xen,阿里云虛擬機(jī)為 KVM,VirtualBox虛擬機(jī)也輸出為 KVM,這是因?yàn)槲沂褂昧?KVM 硬件加速虛擬化。

我的搬瓦工虛擬機(jī)輸出也為 KVM,可見(jiàn)搬瓦工主機(jī)也是 KVM 虛擬機(jī)。

通過(guò)如上方法可以獲取虛擬機(jī)的虛擬化類(lèi)型,能否獲取更多信息呢?參考物理機(jī)的獲取方式,我們可以通過(guò) dmidecode 命令獲取更多的虛擬機(jī)信息。比如我在一臺(tái) OpenStack 虛擬機(jī)運(yùn)行如下命令:

如上 Manufacturer 為 OpenStack Foundation,說(shuō)明運(yùn)行在 OpenStack 平臺(tái),Version為 Nova 版本,根據(jù) OpenStack 的 releases 可知 15.0.1 對(duì)應(yīng)為 OpenStack Ocata 版本,而 UUID 即虛擬機(jī)的 UUID。

AWS 上的一臺(tái)虛擬機(jī)輸出為:

在 Version 中標(biāo)明了 amazon 字樣。

阿里云虛擬機(jī)如下(感謝L神提供的輸出):

可見(jiàn)雖然可以從 system 信息中獲取云廠商的線(xiàn)索,但其實(shí)虛擬機(jī)的 system 信息并沒(méi)有統(tǒng)一的標(biāo)準(zhǔn),有的在 version 中體現(xiàn),有的在 Product Name 中表現(xiàn),完全取決于云廠商自己的配置。

如上整合如下腳本初略判斷:

如上也可以判斷公有云是否基于 OpenStack 實(shí)現(xiàn),比如華為虛擬機(jī)輸出為 OpenStack,可大致猜測(cè)華為的公有云是基于 OpenStack 實(shí)現(xiàn)的。

AWS 以及 OpenStack 系的虛擬機(jī)還可以通過(guò) metadata 或者 ConfigDrive 獲取更多信息,以 metadata 為例:

獲取虛擬機(jī)的 ID:

獲取 instance type (規(guī)格):

獲取虛擬機(jī)的公有IP(彈性IP),這個(gè)挺有用的,因?yàn)樵谔摂M機(jī)沒(méi)法通過(guò)ifconfig查看彈性IP,經(jīng)常登錄虛擬機(jī)后,忘記自己的公有IP:

其他的比如 vpc-id、ami id(鏡像id)、安全組、公鑰名等都可以通過(guò)該方式獲取。

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

如上可獲取虛擬機(jī)的租戶(hù) ID、volume type 等信息。當(dāng)然邪惡點(diǎn)可以通過(guò)查看 userdata獲取虛擬機(jī)初始化 root 密碼。AWS 甚至可以查看 AccessKeyId 以及SecretAccessKey。

4、總結(jié)

如上總結(jié)了幾種判斷虛擬化環(huán)境類(lèi)型的方法,不一定準(zhǔn)確,僅供參考,當(dāng)然也可能還有其他更好的方法。

如下是根據(jù)前面的結(jié)論寫(xiě)的一個(gè)探測(cè)虛擬化類(lèi)型的腳本,不一定健壯完備,僅供參考:

 

責(zé)任編輯:張燕妮 來(lái)源: 高效運(yùn)維
相關(guān)推薦

2023-05-29 07:30:56

容器虛擬機(jī)硬件

2023-09-02 21:35:39

Linux虛擬機(jī)

2020-05-25 10:02:38

云計(jì)算軟件開(kāi)發(fā)容器

2018-09-11 15:01:22

Java虛擬機(jī)組成

2020-04-01 22:05:24

虛擬機(jī)HotSpotJava

2014-02-21 11:20:34

KVMXen虛擬機(jī)

2019-07-18 15:01:43

Linux虛擬機(jī)宿主機(jī)

2023-09-03 17:05:20

虛擬機(jī)

2018-08-17 07:49:01

2010-10-13 10:21:37

物理機(jī)虛擬機(jī)遷移

2009-10-13 15:00:36

物理機(jī)虛擬機(jī)網(wǎng)絡(luò)安全

2012-05-18 10:22:23

2009-10-30 09:49:55

2010-07-26 09:02:38

2013-07-17 09:32:58

2017-06-06 15:34:55

2013-06-17 10:16:53

虛擬機(jī)虛擬化安全

2020-03-26 08:39:37

物理機(jī)虛擬機(jī)K8s

2009-12-16 14:33:52

Host訪(fǎng)問(wèn)虛擬機(jī)

2014-12-18 09:41:44

虛擬化遷移
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)