為什么需要pod
最為熟知的一句話:pod是k8s的最小調度單位。剛開始聽到這句話時會想,已經有容器了,k8s為什么還要搞個pod出來?容器和pod是什么關系?容器的本質是進程,而k8s本質上類似操作系統。
熟悉Linux的都知道,一個應用往往不只一個進程孤伶伶地運行,而是以進程組的方式協同運行。更確切地說,Linux中“進程”都是線程,多個線程組成一個線程組,它們之間共享文件、信號、數據內存等,通過緊密協作完成一個應用程序的職責。
在Linux中pid=1的進程是init,后續所有進程都是它的子進程,它負責維護進程數(pstree查看進程樹)狀態,如回收子進程等。但是容器中pid=1的進程是應用,在一個容器中很難管理pid不等于1的其他進程。這就是容器的設計是單進程模型,不具有管理多進程的能力。所以對于Linux進程組中每一個進程,k8s中都需要一個單獨的容器,這些容器需要互相依賴緊密合作,pod的概念就應運而生。
容器和pod的關系
pod由一個或多個容器組成,它們共享網絡、存儲和容器的運行配置。pod中的容器總是同時被調度,有共同的運行環境。
pod的意義
pod只是邏輯的概念,pod內的容器共享了某些資源,k8s引入pod目的是容器設計模式。
pod是如何實現的
一個有A、B兩個容器的pod,如果使用docker拉起,那AB會存在依賴關系,如A先啟動,B共享A的Volume等資源。而在pod設計中容器是對等關系,所以k8s引入Infra中間容器。在一個pod中Infra容器是第一個被創建的,其他的容器通過Join Network Namespace的方式與Infra關聯。
Infra容器必須占用足夠小的資源,它使用k8s.gcr.io/pause的特殊鏡像,是一個由匯編語言編寫、永遠處于暫停狀態的容器,只有100-200KB。
Infra容器“Hold住”Network Namespace后,用戶容器會可以加入到Infra容器的Network Namespace。Pod內的容器看到的網絡設備跟Infra容器一樣,共享這個Network Namespace的IP地址與端口號,可以直接使用localhost進行通信。 k8s在調度時將pod作為一個整體調度到某個節點,容器內可以用過所以基于容器內共享的網絡、磁盤等信息,需要基于pod層級去設計。單獨對用戶容器配置是不可取的,因為中間容器Infra的rootfs里幾乎什么都沒有,沒有隨意發揮的空間。所以pod的本質類似于虛擬機,容器類似于虛擬機里的應用程序。