你好,我是張磊。今天我和你分享的主題是:為什么我們需要 Pod。
在前面的文章中,我詳細(xì)介紹了在 Kubernetes 里部署一個應(yīng)用的過程。在這些講解中,我提到了這樣一個知識點:Pod,是 Kubernetes 項目中最小的 API 對象。如果換一個更專業(yè)的說法,我們可以這樣描述:Pod,是 Kubernetes 項目的原子調(diào)度單位。
不過,我相信你在學(xué)習(xí)和使用 Kubernetes 項目的過程中,已經(jīng)不止一次地想要問這樣一個問題:為什么我們會需要 Pod?
是啊,我們在前面已經(jīng)花了很多精力去解讀 Linux 容器的原理、分析了 Docker 容器的本質(zhì),終于,“Namespace 做隔離,Cgroups 做限制,rootfs 做文件系統(tǒng)”這樣的“三句箴言”可以朗朗上口了,為什么 Kubernetes 項目又突然搞出一個 Pod 來呢?
要回答這個問題,我們還是要一起回憶一下我曾經(jīng)反復(fù)強調(diào)的一個問題:容器的本質(zhì)到底是什么?
你現(xiàn)在應(yīng)該可以不假思索地回答出來:容器的本質(zhì)是進程。
沒錯。容器,就是未來云計算系統(tǒng)中的進程;容器鏡像就是這個系統(tǒng)里的“.exe”安裝包。那么Kubernetes 呢?
你應(yīng)該也能立刻回答上來:Kubernetes 就是操作系統(tǒng)!
非常正確。
現(xiàn)在,就讓我們登錄到一臺 Linux 機器里,執(zhí)行一條如下所示的命令:
$ pstree -g

不難發(fā)現(xiàn),在一個真正的操作系統(tǒng)里,進程并不是“孤苦伶仃”地獨自運行的,而是以進程組的方式,“有原則的”組織在一起。在這個進程的樹狀圖中,每一個進程后面括號里的數(shù)字,就是它的進程組 ID(Process Group ID, PGID)
比如,這里有一個叫作 rsyslogd 的程序,它負(fù)責(zé)的是Linux 操作系統(tǒng)里的日志處理??梢钥吹?,rsyslogd 的主程序 main,和它要用到的內(nèi)核日志模塊 imklog 等,同屬于 1632 進程組。這些進程相互協(xié)作,共同完成 rsyslogd 程序的職責(zé)。
對于操作系統(tǒng)來說,這樣的進程組更方便管理。舉個例子,Linux 操作系統(tǒng)只需要將信號,比如,SIGKILL 信號,發(fā)送給一個進程組,那么該進程組中的所有進程就都會收到這個信號而終止運行。
而 Kubernetes 項目所做的,其實就是將“進程組”的概念映射到了容器技術(shù)中,并使其成為了這個云計算“操作系統(tǒng)”里的“一等公民”。
Kubernetes 項目之所以要這么做的原因,我在前面介紹 Kubernetes 和Borg 的關(guān)系時曾經(jīng)提到過:在 Borg 項目的開發(fā)和實踐過程中,Google 公司的工程師們發(fā)現(xiàn),他們部署的應(yīng)用,往往都存在著類似于“進程和進程組”的關(guān)系。更具體地說,就是這些應(yīng)用之間有著密切的協(xié)作關(guān)系,使得它們必須部署在同一臺機器上。
而如果事先沒有“組”的概念,像這樣的運維關(guān)系就會非常難以處理。
我還是以前面的 rsyslogd 為例子。已知 rsyslogd 由三個進程組成:一個 imklog 模塊,一個imuxsock 模塊,一個 rsyslogd 自己的 main 函數(shù)主進程。這三個進程一定要運行在同一臺機器上,否則,它們之間基于 Socket 的通信和文件交換,都會出現(xiàn)問題。
現(xiàn)在,我要把 rsyslogd 這個應(yīng)用給容器化,由于受限于容器的“單進程模型”,這三個模塊必須被分別制作成三個不同的容器。而在這三個容器運行的時候,它們設(shè)置的內(nèi)存配額都是1GB。
再次強調(diào)一下:容器的“單進程模型”,并不是指容器里只能運行“一個”進程,而是指容器沒有管理多個進程的能力。這是因為容器里 PID=1 的進程就是應(yīng)用本身,其他的進程都是這個 PID=1 進程的子進程??墒?,用戶編寫的應(yīng)用,并不能夠像正常操作系統(tǒng)里的 init 進程或者 systemd 那樣擁有進程管理的功能。比如,你的應(yīng)用是一個 Java Web 程序(PID=1),然后你執(zhí)行 docker exec 在后臺啟動了一個 Nginx 進程(PID=3)??墒?,當(dāng)這個 Nginx 進程異常退出的時候,你該怎么知道呢?這個進程退出后的垃圾收集工作,又應(yīng)該由誰去做呢?
假設(shè)我們的 Kubernetes 集群上有兩個節(jié)點:node-1 上有 3 GB 可用內(nèi)存,node-2 有2.5 GB可用內(nèi)存。
這時,假設(shè)我要用 Docker Swarm 來運行這個rsyslogd 程序。為了能夠讓這三個容器都運行在同一臺機器上,我就必須在另外兩個容器上設(shè)置一個 affinity=main(與 main 容器有親密性)的約束,即:它們倆必須和 main 容器運行在同一臺機器上。
然后,我順序執(zhí)行:“docker run main”“docker run imklog”和“docker run imuxsock”,創(chuàng)建這三個容器。
這樣,這三個容器都會進入 Swarm 的待調(diào)度隊列。然后,main容器和 imklog 容器都先后出隊并被調(diào)度到了 node-2 上(這個情況是完全有可能的)。
可是,當(dāng) imuxsock 容器出隊開始被調(diào)度時,Swarm 就有點懵了:node-2 上的可用資源只有0.5 GB 了,并不足以運行 imuxsock 容器;可是,根據(jù)affinity=main 的約束,imuxsock 容器又只能運行在 node-2 上。
這就是一個典型的成組調(diào)度(gang scheduling)沒有被妥善處理的例子。
在工業(yè)界和學(xué)術(shù)界,關(guān)于這個問題的討論可謂曠日持久,也產(chǎn)生了很多可供選擇的解決方案。
比如,Mesos 中就有一個資源囤積(resource hoarding)的機制,會在所有設(shè)置了Affinity約束的任務(wù)都達到時,才開始對它們統(tǒng)一進行調(diào)度。而在 Google Omega 論文中,則提出了使用樂觀調(diào)度處理沖突的方法,即:先不管這些沖突,而是通過精心設(shè)計的回滾機制在出現(xiàn)了沖突之后解決問題。
可是這些方法都談不上完美。資源囤積帶來了不可避免的調(diào)度效率損失和死鎖的可能性;而樂觀調(diào)度的復(fù)雜程度,則不是常規(guī)技術(shù)團隊所能駕馭的。
但是,到了 Kubernetes 項目里,這樣的問題就迎刃而解了:Pod是 Kubernetes 里的原子調(diào)度單位。這就意味著,Kubernetes 項目的調(diào)度器,是統(tǒng)一按照Pod 而非容器的資源需求進行計算的。
所以,像 imklog、imuxsock 和 main 函數(shù)主進程這樣的三個容器,正是一個典型的由三個容器組成的 Pod。Kubernetes 項目在調(diào)度時,自然就會去選擇可用內(nèi)存等于 3 GB 的 node-1 節(jié)點進行綁定,而根本不會考慮 node-2。
像這樣容器間的緊密協(xié)作,我們可以稱為“超親密關(guān)系”。這些具有“超親密關(guān)系”容器的典型特征包括但不限于:互相之間會發(fā)生直接的文件交換、使用 localhost 或者 Socket 文件進行本地通信、會發(fā)生非常頻繁的遠(yuǎn)程調(diào)用、需要共享某些 Linux Namespace(比如,一個容器要加入另一個容器的 Network Namespace)等等。
這也就意味著,并不是所有有“關(guān)系”的容器都屬于同一個 Pod。比如,PHP 應(yīng)用容器和MySQL 雖然會發(fā)生訪問關(guān)系,但并沒有必要、也不應(yīng)該部署在同一臺機器上,它們更適合做成兩個 Pod。
不過,相信此時你可能會有第二個疑問:
對于初學(xué)者來說,一般都是先學(xué)會了用 Docker 這種單容器的工具,才會開始接觸 Pod。
而如果 Pod 的設(shè)計只是出于調(diào)度上的考慮,那么Kubernetes 項目似乎完全沒有必要非得把Pod 作為“一等公民”吧?這不是故意增加用戶的學(xué)習(xí)門檻嗎?
沒錯,如果只是處理“超親密關(guān)系”這樣的調(diào)度問題,有 Borg 和Omega 論文珠玉在前,Kubernetes 項目肯定可以在調(diào)度器層面給它解決掉。
不過,Pod 在 Kubernetes 項目里還有更重要的意義,那就是:容器設(shè)計模式。
為了理解這一層含義,我就必須先給你介紹一下Pod 的實現(xiàn)原理。
首先,關(guān)于 Pod 最重要的一個事實是:它只是一個邏輯概念。
也就是說,Kubernetes 真正處理的,還是宿主機操作系統(tǒng)上Linux 容器的 Namespace 和Cgroups,而并不存在一個所謂的 Pod 的邊界或者隔離環(huán)境。
那么,Pod 又是怎么被“創(chuàng)建”出來的呢?
答案是:Pod,其實是一組共享了某些資源的容器。
具體的說:Pod 里的所有容器,共享的是同一個 Network Namespace,并且可以聲明共享同一個 Volume。
那這么來看的話,一個有 A、B 兩個容器的 Pod,不就是等同于一個容器(容器 A)共享另外一個容器(容器 B)的網(wǎng)絡(luò)和 Volume 的玩兒法么?
這好像通過 docker run --net --volumes-from 這樣的命令就能實現(xiàn)嘛,比如:
$ docker run --net=B--volumes-from=B --name=A image-A ...
但是,你有沒有考慮過,如果真這樣做的話,容器 B 就必須比容器 A先啟動,這樣一個 Pod 里的多個容器就不是對等關(guān)系,而是拓?fù)潢P(guān)系了。
所以,在 Kubernetes 項目里,Pod 的實現(xiàn)需要使用一個中間容器,這個容器叫作 Infra 容器。在這個 Pod 中,Infra 容器永遠(yuǎn)都是第一個被創(chuàng)建的容器,而其他用戶定義的容器,則通過Join Network Namespace 的方式,與 Infra 容器關(guān)聯(lián)在一起。這樣的組織關(guān)系,可以用下面這樣一個示意圖來表達:




如上圖所示,這個 Pod 里有兩個用戶容器 A 和 B,還有一個 Infra 容器。很容易理解,在Kubernetes 項目里,Infra 容器一定要占用極少的資源,所以它使用的是一個非常特殊的鏡像,叫作:k8s.gcr.io/pause。這個鏡像是一個用匯編語言編寫的、永遠(yuǎn)處于“暫?!睜顟B(tài)的容器,解壓后的大小也只有 100~200 KB 左右。
而在 Infra 容器“Hold 住”Network Namespace 后,用戶容器就可以加入到 Infra 容器的Network Namespace 當(dāng)中了。所以,如果你查看這些容器在宿主機上的 Namespace 文件(這個 Namespace 文件的路徑,我已經(jīng)在前面的內(nèi)容中介紹過),它們指向的值一定是完全一樣的。
這也就意味著,對于 Pod 里的容器 A 和容器 B 來說:
* 它們可以直接使用 localhost 進行通信;
* 它們看到的網(wǎng)絡(luò)設(shè)備跟 Infra 容器看到的完全一樣;
* 一個 Pod 只有一個 IP 地址,也就是這個 Pod 的 Network Namespace 對應(yīng)的 IP 地址;
* 當(dāng)然,其他的所有網(wǎng)絡(luò)資源,都是一個 Pod 一份,并且被該 Pod中的所有容器共享;
* Pod 的生命周期只跟 Infra 容器一致,而與容器 A 和 B 無關(guān)。
而對于同一個 Pod 里面的所有用戶容器來說,它們的進出流量,也可以認(rèn)為都是通過 Infra 容器完成的。這一點很重要,因為將來如果你要為 Kubernetes 開發(fā)一個網(wǎng)絡(luò)插件時,應(yīng)該重點考慮的是如何配置這個 Pod 的 Network Namespace,而不是每一個用戶容器如何使用你的網(wǎng)絡(luò)配置,這是沒有意義的。
這就意味著,如果你的網(wǎng)絡(luò)插件需要在容器里安裝某些包或者配置才能完成的話,是不可取的:Infra 容器鏡像的 rootfs 里幾乎什么都沒有,沒有你隨意發(fā)揮的空間。當(dāng)然,這同時也意味著你的網(wǎng)絡(luò)插件完全不必關(guān)心用戶容器的啟動與否,而只需要關(guān)注如何配置 Pod,也就是 Infra 容器的 Network Namespace 即可。
有了這個設(shè)計之后,共享 Volume 就簡單多了:Kubernetes項目只要把所有 Volume 的定義都設(shè)計在 Pod 層級即可。
這樣,一個 Volume 對應(yīng)的宿主機目錄對于 Pod 來說就只有一個,Pod 里的容器只要聲明掛載這個Volume,就一定可以共享這個 Volume 對應(yīng)的宿主機目錄。比如下面這個例子:

在這個例子中,debian-container 和nginx-container 都聲明掛載了 shared-data 這個Volume。而 shared-data 是 hostPath 類型。所以,它對應(yīng)在宿主機上的目錄就是:/data。而這個目錄,其實就被同時綁定掛載進了上述兩個容器當(dāng)中。
這就是為什么,nginx-container 可以從它的/usr/share/nginx/html 目錄中,讀取到debian-container 生成的 index.html 文件的原因。
明白了 Pod 的實現(xiàn)原理后,我們再來討論“容器設(shè)計模式”,就容易多了。
Pod 這種“超親密關(guān)系”容器的設(shè)計思想,實際上就是希望,當(dāng)用戶想在一個容器里跑多個功能并不相關(guān)的應(yīng)用時,應(yīng)該優(yōu)先考慮它們是不是更應(yīng)該被描述成一個 Pod 里的多個容器。
為了能夠掌握這種思考方式,你就應(yīng)該盡量嘗試使用它來描述一些用單個容器難以解決的問題。
第一個最典型的例子是:WAR 包與 Web 服務(wù)器。
我們現(xiàn)在有一個 Java Web 應(yīng)用的 WAR 包,它需要被放在 Tomcat 的 webapps 目錄下運行起來。
假如,你現(xiàn)在只能用 Docker 來做這件事情,那該如何處理這個組合關(guān)系呢?
一種方法是,把 WAR 包直接放在 Tomcat 鏡像的 webapps 目錄下,做成一個新的鏡像運行起來??墒?,這時候,如果你要更新 WAR 包的內(nèi)容,或者要升級Tomcat 鏡像,就要重新制作一個新的發(fā)布鏡像,非常麻煩。
另一種方法是,你壓根兒不管 WAR 包,永遠(yuǎn)只發(fā)布一個Tomcat 容器。不過,這個容器的webapps 目錄,就必須聲明一個 hostPath 類型的 Volume,從而把宿主機上的 WAR 包掛載進 Tomcat 容器當(dāng)中運行起來。不過,這樣你就必須要解決一個問題,即:如何讓每一臺宿主機,都預(yù)先準(zhǔn)備好這個存儲有 WAR 包的目錄呢?這樣來看,你只能獨立維護一套分布式存儲系統(tǒng)了。
實際上,有了 Pod 之后,這樣的問題就很容易解決了。我們可以把WAR 包和 Tomcat 分別做成鏡像,然后把它們作為一個 Pod 里的兩個容器“組合”在一起。這個 Pod 的配置文件如下所示:


在這個 Pod 中,我們定義了兩個容器,第一個容器使用的鏡像是geektime/sample:v2,這個鏡像里只有一個 WAR 包(sample.war)放在根目錄下。而第二個容器則使用的是一個標(biāo)準(zhǔn)的Tomcat 鏡像。
不過,你可能已經(jīng)注意到,WAR 包容器的類型不再是一個普通容器,而是一個Init Container類型的容器。
在 Pod 中,所有 Init Container 定義的容器,都會比 spec.containers 定義的用戶容器先啟動。并且,Init Container 容器會按順序逐一啟動,而直到它們都啟動并且退出了,用戶容器才會啟動。
所以,這個 Init Container 類型的 WAR 包容器啟動后,我執(zhí)行了一句"cp /sample.war/app",把應(yīng)用的 WAR 包拷貝到 /app 目錄下,然后退出。
而后這個 /app 目錄,就掛載了一個名叫 app-volume 的 Volume。
接下來就很關(guān)鍵了。Tomcat 容器,同樣聲明了掛載app-volume 到自己的 webapps 目錄下。
所以,等 Tomcat 容器啟動時,它的 webapps 目錄下就一定會存在 sample.war 文件:這個文件正是 WAR 包容器啟動時拷貝到這個 Volume 里面的,而這個 Volume 是被這兩個容器共享的
像這樣,我們就用一種“組合”方式,解決了 WAR 包與Tomcat 容器之間耦合關(guān)系的問題。
實際上,這個所謂的“組合”操作,正是容器設(shè)計模式里最常用的一種模式,它的名字叫:sidecar。
顧名思義,sidecar 指的就是我們可以在一個 Pod 中,啟動一個輔助容器,來完成一些獨立于主進程(主容器)之外的工作。
比如,在我們的這個應(yīng)用 Pod 中,Tomcat 容器是我們要使用的主容器,而 WAR 包容器的存在,只是為了給它提供一個 WAR 包而已。所以,我們用 InitContainer 的方式優(yōu)先運行WAR包容器,扮演了一個 sidecar 的角色。
第二個例子,則是容器的日志收集。
比如,我現(xiàn)在有一個應(yīng)用,需要不斷地把日志文件輸出到容器的 /var/log 目錄中。
這時,我就可以把一個 Pod 里的 Volume 掛載到應(yīng)用容器的 /var/log 目錄上。
然后,我在這個 Pod 里同時運行一個 sidecar 容器,它也聲明掛載同一個 Volume 到自己的/var/log 目錄上。
這樣,接下來 sidecar 容器就只需要做一件事兒,那就是不斷地從自己的 /var/log 目錄里讀取日志文件,轉(zhuǎn)發(fā)到 MongoDB 或者 Elasticsearch中存儲起來。這樣,一個最基本的日志收集工作就完成了。
跟第一個例子一樣,這個例子中的 sidecar 的主要工作也是使用共享的 Volume 來完成對文件的操作。
但不要忘記,Pod 的另一個重要特性是,它的所有容器都共享同一個Network Namespace。這就使得很多與 Pod 網(wǎng)絡(luò)相關(guān)的配置和管理,也都可以交給sidecar 完成,而完全無須干涉用戶容器。這里最典型的例子莫過于 Istio 這個微服務(wù)治理項目了。
Istio 項目使用 sidecar 容器完成微服務(wù)治理的原理,我在后面很快會講解到。
備注:Kubernetes 社區(qū)曾經(jīng)把“容器設(shè)計模式”這個理論,整理成了一篇小論文,你可以點擊鏈接瀏覽。
總結(jié)
在本篇文章中我重點分享了 Kubernetes 項目中 Pod 的實現(xiàn)原理。
Pod 是 Kubernetes 項目與其他單容器項目相比最大的不同,也是一位容器技術(shù)初學(xué)者需要面對的第一個與常規(guī)認(rèn)知不一致的知識點。
事實上,直到現(xiàn)在,仍有很多人把容器跟虛擬機相提并論,他們把容器當(dāng)做性能更好的虛擬機,喜歡討論如何把應(yīng)用從虛擬機無縫地遷移到容器中。
但實際上,無論是從具體的實現(xiàn)原理,還是從使用方法、特性、功能等方面,容器與虛擬機幾乎沒有任何相似的地方;也不存在一種普遍的方法,能夠把虛擬機里的應(yīng)用無縫遷移到容器中。因為,容器的性能優(yōu)勢,必然伴隨著相應(yīng)缺陷,即:它不能像虛擬機那樣,完全模擬本地物理機環(huán)境中的部署方法。
所以,這個“上云”工作的完成,最終還是要靠深入理解容器的本質(zhì),即:進程。
實際上,一個運行在虛擬機里的應(yīng)用,哪怕再簡單,也是被管理在 systemd 或者supervisord之下的一組進程,而不是一個進程。這跟本地物理機上應(yīng)用的運行方式其實是一樣的。這也是為什么,從物理機到虛擬機之間的應(yīng)用遷移,往往并不困難。
可是對于容器來說,一個容器永遠(yuǎn)只能管理一個進程。更確切地說,一個容器,就是一個進程。這是容器技術(shù)的“天性”,不可能被修改。所以,將一個原本運行在虛擬機里的應(yīng)用,“無縫遷移”到容器中的想法,實際上跟容器的本質(zhì)是相悖的。
這也是當(dāng)初 Swarm 項目無法成長起來的重要原因之一:一旦到了真正的生產(chǎn)環(huán)境上,Swarm這種單容器的工作方式,就難以描述真實世界里復(fù)雜的應(yīng)用架構(gòu)了。
所以,你現(xiàn)在可以這么理解 Pod 的本質(zhì):
Pod,實際上是在扮演傳統(tǒng)基礎(chǔ)設(shè)施里“虛擬機”的角色;而容器,則是這個虛擬機里運行的用戶程序。
所以下一次,當(dāng)你需要把一個運行在虛擬機里的應(yīng)用遷移到 Docker 容器中時,一定要仔細(xì)分析到底有哪些進程(組件)運行在這個虛擬機里。
然后,你就可以把整個虛擬機想象成為一個 Pod,把這些進程分別做成容器鏡像,把有順序關(guān)系的容器,定義為 Init Container。這才是更加合理的、松耦合的容器編排訣竅,也是從傳統(tǒng)應(yīng)用架構(gòu),到“微服務(wù)架構(gòu)”最自然的過渡方式。
? ? ? ? 注意:Pod 這個概念,提供的是一種編排思想,而不是具體的技術(shù)方案。所以,如果愿意的話,你完全可以使用虛擬機來作為 Pod 的實現(xiàn),然后把用戶容器都運行在這個虛擬機里。比如,Mirantis 公司的virtlet 項目就在干這個事情。甚至,你可以去實現(xiàn)一個帶有 Init 進程的容器項目,來模擬傳統(tǒng)應(yīng)用的運行方式。這些工作,在 Kubernetes 中都是非常輕松的,也是我們后面講解CRI 時會提到的內(nèi)容。
相反的,如果強行把整個應(yīng)用塞到一個容器里,甚至不惜使用 Docker In Docker 這種在生產(chǎn)環(huán)境中后患無窮的解決方案,恐怕最后往往會得不償失。
思考題
除了 Network Namespace 外,Pod 里的容器還可以共享哪些 Namespace 呢?你能說出共享這些 Namesapce 的具體應(yīng)用場景嗎?
文章回復(fù):
瓜娃子
痛快,每一篇都鞭辟入里。
2018-09-21
段帥民
這文章讀起來像吃脆蘋果,爽,這是我訂閱專欄中寫的最好的,沒有之一
2018-09-21
作者回復(fù)
這是我見過最形象的評論……
2018-09-21
重要理解了這個核心概念,透透透!不但解決了我前幾天war和tomcat做一起,完成鏡像的頻繁打包問題,而且還想到怎么用puppeteer做一個initcontainer,然后注入到nodejs主容器,從而解決chrome headless太大不容易安裝的問題,爽爽爽!
劉榴
好專欄啊,再寫成書繼續(xù)支持
2018-09-21
虎虎?
講的真的用心,水平也高。被圈粉,希望一直能出專欄。您一定有一票粉絲支持和跟隨的!繼續(xù)加油。
2018-09-21
小新是也
war包跟tomcat這個栗子舉得恰到好處啊
2018-09-24
Jeff.W
pod是一個小家庭,它把密不可分的家庭成員(container)聚在一起,Infra container則是家長,掌管家中共通資源,家庭成員通過sidecar方式互幫互助,其樂融融~
2018-09-30
extraterrestrial!!
容器不能管理多進程那塊,能不能每個容器都默認(rèn)搬一套系統(tǒng)的init過去,而不要讓普通應(yīng)用進程做進程1,這樣是不是就可以支持容器里面管理多進程了?
2018-09-21
作者回復(fù)
對。不過我們現(xiàn)在講的古典互聯(lián)網(wǎng)技術(shù)不太建議這么做,這是原始互聯(lián)網(wǎng)時代的思路。
2018-09-21
北卡
看得太爽了。請教一個問題:
war和tamcat這種情況。
如果把war獨立出來做一個鏡像的話,應(yīng)該用什么做基礎(chǔ)鏡像呢?
我現(xiàn)在做鏡像的時候通常都是用debian做基礎(chǔ)鏡像,但如果只是為了復(fù)制這個.war包的話,用debian感覺蠻浪費的。應(yīng)該怎樣做到最小呢,而且要支持cp命令。
2018-09-24
作者回復(fù)
市面上的小鏡像多的很啊,busybox,alpine
2018-09-24
huan
容器與容器是平等的,只是有些容器更加平等。
——超親密關(guān)系
骨湯雞蛋面
張老師,我們公司一直有一個問題: 我們用docker 管理測試環(huán)境,對于springboot 項目,一向是java -jar xx.jar 的方式啟動,但因為是測試環(huán)境,經(jīng)常代碼本身有問題導(dǎo)致java(也就是容器主進程)啟動不起來,進而觸發(fā)健康檢查重新調(diào)度該服務(wù),然后開發(fā)總是抱怨看不到事故現(xiàn)場。我打算自己實現(xiàn)一個程序(我們稱為nile),容器啟動時先啟動nile確保容器可以啟動起來,再由nile啟動java進程。這時還可以讓nile 讀取用戶配置 自定義設(shè)置jvm 參數(shù)、nile向zk匯報一些應(yīng)用情況等。這個做法呢,nile可以算是java 的sidecar,按您文章的說法,nile和java 是拓?fù)潢P(guān)系而不是對等關(guān)系,這個時候我一個pod里分別是nile和java容器是否可能呢?
2018-11-04
作者回復(fù)
如果nile不負(fù)責(zé)管理java進程的話當(dāng)然可以。否則的話就是同一個容器。
2018-11-04
star
對于war包這個例子還有點不明白,war包這個 /app 目錄,就掛載了一個名叫app-volume...那么這個app-volume是對應(yīng)宿主機?還是infra容器?難道可以創(chuàng)建一個沒有任何對應(yīng)的volume么?
2018-10-14
作者回復(fù)
任何volume對應(yīng)的都是宿主機啊
2018-10-15
勇敢的心
讀老師您的文章有種海邊拾寶的感覺,時不時蹦出來個好看的貝殼,讓人興奮不已~
2018-10-13
IOVE.-Minn
請問,sidecar這種用initcontainer的方式和后面講到的statefulset的改變拓?fù)錉顟B(tài),有什么區(qū)別么?
2018-10-11
作者回復(fù)
沒什么聯(lián)系……
2018-10-12
Racoon
k8s.gcr.io/pause
在node節(jié)點上一直看到有這個鏡像,搞不懂是干嘛的如今一看 豁然開朗
薛定諤的指南針
兩個例子都非常經(jīng)典,尤其是tomcat和war包的例子,感覺看完了以后容器技術(shù)立馬漲了一大截,贊
2018-10-09
Eddie LAU
此專欄追到現(xiàn)在,老師用通俗的語言闡述了k8s的原理的同時也極力推崇k8s。我在學(xué)習(xí)使用的過程中也確實體會到了其各種優(yōu)勢。但是反過來想,老師是否可以簡單舉兩個例子說下k8s目前為止依然存在的一些缺陷和不足呢?方便我們在應(yīng)用過程中加以注意。
2018-09-23
作者回復(fù)
不足之處肯定要在具體剖析特性的時候才會講到。另外,這Kubernetes可不是推崇的問題,你會覺得我在推崇Linux嗎?
2018-09-23
fatCat
以前看博客文章,都是哎呀媽呀腦瓜疼腦瓜疼,現(xiàn)在終于不疼了不疼了~~~
2018-09-21
silverhawk
非常好,請教一個問題,你之前說比如PHP和MySQL最好分在不同的pod,很可能就是不同的node上了,那么對于latency非常敏感的比如cache,像redis和一個web server是不是做成不同的container部署在一個pod里面合適呢?
2018-09-21
作者回復(fù)
取決于 1. 高可用考慮 2. 別的pod是不是也要用這個redis?
2018-09-21
風(fēng)軌
剛上網(wǎng)查了,Linux 支持7種namespace:
1. cgroup用于隔離cgroup根目錄;
2. IPC用于隔離系統(tǒng)消息隊列;
3. Network隔離網(wǎng)絡(luò);
4. Mount隔離掛載點;
5. PID隔離進程;
6. User隔離用戶和用戶組;
7. UTS隔離主機名nis域名。
pod里網(wǎng)絡(luò)和文件系統(tǒng)應(yīng)該是用得最多的,其他的應(yīng)用程序基本不用吧?