k8s管理pod資源對象(上)


一、容器於pod資源對象

現代的容器技術被設計用來運行單個進程時,該進程在容器中pid名稱空間中的進程號為1,可直接接收並處理信號,於是,在此進程終止時,容器即終止退出。若要在一個容器中運行多個進程,則需要為這些進程提供一個類似於linux操作系統init進程的管控類進程,以樹狀結構完成多進程的生命周期管理。絕大多數場景中都應該於一個容器中僅運行一個進程,它將日志信息直接輸出至容器的標准輸出。不過,分別運行於各自容器的進程之間無法實現基於ipc的通信機制,此時,容器間的隔離機制對於依賴於此類通信方式的進程來說卻又成了阻礙。pod資源抽象正是用來解決此類問題的組件。pod對象是一組容器的集合,這些容器共享network、uts及ipc名稱空間,因此具有相同的域名、主機名和網絡接口,並可通過ipc直接通信。為一個pod對象中的各容器提供網絡名稱空間等共享機制的是底層基礎容器pause。

盡管可以將pod類比為物理機或vm,但一個pod內通常僅應該運行一個應用,除非多個進程間有密切關系。不過,有些場景要求必須於同一pod中同時運行多個容器,此時,這些分布式應用必須遵循某些最佳實踐機制或基本准則。事實上,k8s並非期望成為一個管理系統,而是一個支持這些最佳實踐的向開發人員或管理人員提供更高級別服務的系統。分布式系統設計通常包含以下幾種模型:

1、sidecar pattern(邊車模型或挎斗模型):即為pod的主應用容器提供協同的輔助應用容器,每個應用獨立運行,最為典型的代表是將主應用容器中的日志使用agent收集至日志服務器中時,可以將agent運行為輔助容器。

2、ambassador pattern(大使模型):即為遠程服務創建一個本地代理,代理應用運行於容器中,著容器中的應用通過代理容器訪問遠程服務。一個典型的場景是主應用容器中的進程訪問一主多從模型的redis應用時,可在當前pod容器中為redis服務創建一個ambassador container,主應用容器中的進程直接通過localhost接口訪問ambassador container即可。即便是redis主從集群架構發生變動時,也僅需要將ambassador conftainer加以修改即可,主應用容器無須對此做出任何反應。

3、adapter pattern(適配器模型):此種模型一般用於將主應用容器中的內容進行標准化輸出,例如,日志數據或指標數據的輸出,這有助於調用者統一接收數據的接口,另外,某應用滾動升級后的版本不兼容舊的版本時,其報告信息的格式也存在不兼容的可能性,使用adapter container有助於避免那些調用此報告的應用發生錯誤。

k8s系統的pod資源對象用於運行單個容器化應用,此應用稱為pod對象的主容器,同時pod也能容納多個容器,不過額外的容器一般工作為sidecar模型,用於輔助著容器完成工作職能。

二、管理pod對象的容器

一個pod對象中至少要存在一個容器,因此,containers字段是定義pod時其嵌套字段spec中的必選項,用於為pod指定要創建的容器列表。進行容器配置時,name為必選字段,用於指定容器名稱,image字段是可選,以為方便更高級別的管理類資源(如deployment)等能覆蓋此字段,於是自助式的pod並不可省略此字段。

1、鏡像及其獲取策略

各工作節點負責運行pod對象,而pod的核心功用在於運行容器,因此工作節點上必須配置容器運行引擎。k8s系統支持用於自定義鏡像文件的獲取策略,例如在網絡資源較為緊張的時候可以禁止從倉庫中獲取鏡像文件等。容器的“imagesPullPolicy”字段用於為其指定鏡像獲取策略,它的可用值包括:

Always:鏡像標簽為latest或鏡像不存在時總是從鏡像倉庫中獲取鏡像

IfNotPresent:僅當本地鏡像缺失時方才從目標倉庫下載鏡像

Never:禁止從倉庫下載鏡像,即僅使用本地鏡像。

對於標簽為latest的鏡像文件,其默認的鏡像獲取策略為Always,而對於其他標簽的鏡像,其默認策略為IfNotPresent。當使用私有鏡像倉庫中的鏡像時,通常需要由倉庫服務器完成認證后才能進行,認證過程要么需要在相關節點上交互式執行docker login命令來進行,要么就是將認證信息定義為專有的secret資源,並配置pod通過imagePullSecrets字段調用此認證信息完成。

2、暴露端口

k8s系統的網絡模型中,各pod的IP地址處於同一網絡平面,無論是否為容器指定了暴露的端口,都不會影響集群中其他節點之上的pod客戶端對其進行訪問,這就意味着,任何監聽在非lo接口上的端口都可以通過pod網絡直接被請求,從這個角度來說,容器端口只是信息性數據,它只是為集群用戶提供一個快速了解相關pod對象的可訪問端口的途徑,而且顯式指定容器端口,還能為其賦予一個名稱以方便調用。

容器的ports字段的值是一個列表,由一個到多個端口對象組成,它的常用嵌套字段包括:

containerPort:必選字段,指定在pod對象的IP地址上暴露的容器端口。

name:當前端口的名稱,在當前pod內必須是唯一;此端口名可被service資源調用。

protocol:端口協議,默認tcp

然而,pod對象的IP地址僅在當前集群內可達,它們無法直接接收來自集群外部的客戶端請求流量。可通過其所在的工作節點的IP和端口將其暴露到集群外部:

hostPort:主機端口,它將接收到的請求通過nat機制轉發至由containerPort字段指定的容器端口

hostIP:主機端口要綁定的主機IP,默認0.0.0.0,即主機之上所有可用的IP地址;考慮到pod對象是由調度器調度運行的,工作節點的IP地址難以明確指定,因此此字段通常使用默認值。

hostPort和NodePort類型的Service對象暴露端口的方式不同,NodePort是通過所有節點暴露容器服務,而hostPort則是經由pod對象所在的節點IP地址來進行。

3、自定義運行的容器化應用

容器的command字段能夠指定不同於鏡像默認運行的應用程序,並且可以同時使用args字段進行參數傳遞,它們將覆蓋鏡像中的默認定義。不過,如果僅為容器定義了args字段,那么它將作為參數傳遞給鏡像中默認指定運行的應用程序;如果僅為容器定義了command字段,那么它將覆蓋鏡像中定義的程序及參數,並以無參數方式運行應用程序。自定義args,也是向容器中的應用程序傳遞配置信息的常用方式之一,對於非雲原生的應用程序,這幾乎也是最簡單的配置方式。另一個常用的方式是使用環境變量。

4、環境變量

向pod對象中的容器環境變量傳遞數據的方法有兩種:env和envFrom,通過環境變量配置容器化應用時,需要在容器配置段中嵌套使用env字段,它的值是一個由環境變量構成的列表。環境變量通常由name和value字段構成。

name:環境變量的名稱,必選字段

value:傳遞給環境變量的值,通過$(VAAR_NAME)引用,逃逸格式為$$(VAR_NAME),默認為空。

5、共享節點的網絡名稱空間

同一個pod對象的各容器均運行於一個獨立的、隔離的network名稱空間中,共享同一個網絡協議棧及相關的網絡設備。也有一些特殊的pod對象需要運行於所在節點的名稱空間中,執行系統級的管理任務,例如查看和操作節點的網絡資源甚至是網絡設備等。

通常,以k8s部署的k8s集群中的kube-apiserver、kube-controller-manager、kube-scheduler,以及kube-proxy和kube-flannel等通常都是第二種類型的pod對象。事實上,僅需要設置spec.hostNetwork的屬性為true即可創建共享節點網絡名稱空間的pod對象。另外,在創建pod對象時,還可以使用spec.hostPid和spec.hostIPC來共享工作節點的pid和ipc名稱空間。

6、設置pod對象的安全上下文

pod對象的安全上下文用於設定pod容器的權限和訪問控制功能,其支持設置的常用屬性包括:

1、基於用戶id和組id控制訪問對象時的權限。

2、以特權或非特權的方式運行。

3、通過Linux Capabilities為其提供部分特權。

4、基於Seccomp過濾進行的系統調用。

5、基於SELinux的安全標簽

6、是否能夠進行權限升級。

pod對象的安全上下文定義在spec.securityContext字段中,而容器的安全上下文則定義在spec.containers[].securityContext字段中,且二者可嵌套使用的字段還有所不同。

另外,可設置的安全上下文屬性還有fsGroup、seLinuxOptions、supplementalGroups、sysctls、capabilities和privileged等。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM