溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

發(fā)布時間:2021-10-20 16:11:44 來源:億速云 閱讀:908 作者:iii 欄目:web開發(fā)

這篇文章主要講解了“如何判斷虛擬環(huán)境是物理機、虛擬機還是容器”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“如何判斷虛擬環(huán)境是物理機、虛擬機還是容器”吧!

1、判斷容器

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

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

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

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

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

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

如上的 \x2d 為-號:

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

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

  • 判斷是否可運行 systemd-detect-virt -c 命令,如果輸出為 none 則不是容器,否則可確定容器類型。

  • 判斷 PID 1 如果為應(yīng)用本身,則該虛擬環(huán)境是容器,否則不能確定是否是容器。

  • 判斷是否存在加載的內(nèi)核文件,如果不存在,則可判斷為容器,否則不能確定是否為容器。

  • 判斷是否存在 /.dockerenv 文件,如果存在則為 Docker 容器,否則不能確定是否為容器。讀取 /proc/1/cgroup 文件,判斷是否包含 docker、rkt 等關(guān)鍵字,如果包含,則說明為容器,否則不能確定是否為容器。

另外,需要特別注意的是,容器必須最先判斷,因為容器本身并沒有任何的硬件虛擬化,容器看到的硬件特性信息和宿主機看到的完全一樣,因此下面介紹的通過lscpu以及DMI信息判斷是否是虛擬機或者物理機,對容器并不適用。換句話說,不能因為lscpu的Hypervisor vendor值為KVM就說明一定是KVM虛擬機,因為它也有可能是容器。下文均假設(shè)已經(jīng)排除為容器的情況。

2、判斷物理機

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

如果輸出為 none,則說明是物理機。

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

如上可以看出這是臺物理機,廠商為 HP,型號為 ProLiant DL380 Gen9,序列號為6CU6468KKD。

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

3、判斷虛擬機

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

如果是虛擬機,則會輸出虛擬機類型,如 kvm、oracle(virtualbox)、xen 等。

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

通過如上命令,我的一臺 AWS 虛擬機輸出為 Xen,阿里云虛擬機為 KVM,VirtualBox虛擬機也輸出為 KVM,這是因為我使用了 KVM 硬件加速虛擬化。

我的搬瓦工虛擬機輸出也為 KVM,可見搬瓦工主機也是 KVM 虛擬機。

通過如上方法可以獲取虛擬機的虛擬化類型,能否獲取更多信息呢?參考物理機的獲取方式,我們可以通過 dmidecode 命令獲取更多的虛擬機信息。比如我在一臺 OpenStack 虛擬機運行如下命令:

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

AWS 上的一臺虛擬機輸出為:

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

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

獲取虛擬機的 ID:

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

獲取虛擬機的公有IP(彈性IP),這個挺有用的,因為在虛擬機沒法通過ifconfig查看彈性IP,經(jīng)常登錄虛擬機后,忘記自己的公有IP:

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

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

4、總結(jié)

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

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

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

如何判斷虛擬環(huán)境是物理機、虛擬機還是容器

感謝各位的閱讀,以上就是“如何判斷虛擬環(huán)境是物理機、虛擬機還是容器”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對如何判斷虛擬環(huán)境是物理機、虛擬機還是容器這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI