pod使用宿主節點的Linux命名空間
pod中的容器通常在分開的Linux命名空間中運行。 這些命名空間將容器中的進程與其他容器中,或者宿主機默認命名空間中的進程隔離開來。
一、在pod中使用宿主節點的網絡命名空間
部分pod(特別是系統pod)需要在宿主節點的默認命名空間中運行,以允許它們看到和操作節點級別的資源和設備。例如,某個pod可能需要使用宿主節點上的網絡適配器,而不是自己的虛擬網絡設備。
在這種情況下,這個pod可以使用宿主節點的網絡接口,而不是擁有自己獨立的網絡。這意味着這個pod沒有自己的IP地址;如果這個pod中的某一進程綁定了某個端口,那么該進程將被綁定到宿主節點的端口上。
配置清單

apiVersion: vl kind: Pod metadata: name: pod-with-host-network spec: hostNetwork: true #使用宿主節點的網絡命名空間 containers - name. dfse image: asdf command : ["/bin/sleep”,1000000”]
通過將pod spec中的hostNetwork設置為true實現。
二、綁定宿主節點上的端口而不使用宿主節點的網絡命名空間
通過配置 pod spec containers ports 字段中某個容器某一端口的 hostPort 屬性來實現。

apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - image: docker.io/nginx name: asdf ports: - containersPorts: 8080 #可以通過pod 的Ip:8080 訪問該pod hostPort: 9000 #也可以通過Pod 所在節點的9000訪問該pod protocol: TCP
三、hostPort pod 和通過 Node Port 服務暴露的 pod 區別
對於使用 hostPort ,到達宿主節點的端口的連接會被直接轉發到 pod 的對應端口上:然而在 Node Port 服務中,到達宿主節點的端口的連接將被轉發到隨機選取的 pod 上(這個 pod 可能在其他節點上)。另外一個區別是,對於使用 hostPort 的pod ,僅有運行了這類 pod 的節點會綁定對應的端口;而 Node Port 類型的服務會在所有的節點上綁定端口,即使這個節點上沒有運行對應的 pod。
View Code
View Code
View Code
View Code
View Code
View Code
View Code
View Code
View Code
View Code
View Code
View Code
View Code
還有一個區別就是 hostPort 的 pod 綁定了宿主節點上的 個特定端口,每個宿主節點只能調度一個這樣的 pod 實例,因為兩個進程不能綁定宿主機上的同一個端口。
Tips:
host Port 功能最初是用於暴露通過 DeamonSet 部署在每個節點上的系統服務。最初,這個功能也用於保證 pod 兩個副本不被調度到同一節點上,但是現在有更好的方法來實現這一需求。
四、使用宿主節點的 PID IPC 命名空間
pod spec 中的 hostPID host IPC 選項與 hostNetwork 相似。當它們被設置為 true 時, pod 中的容器會使用宿主節點的 PID IPC 名空間 ,分別允許它們看到宿主機上的全部進程,或通過 IPC 機制與它們通信

apiVersion: v1 kind: Pod metadata: name: pod-with-host-pid-and-ipc spec: hostPID: true hostIPC: true containers: ... ...
配置節點的安全上下文
除了讓 pod 使用宿主節點的 Linux 命名空間,還可以在 pod 或其所屬容器的描述中通過 security Context 選項配置其他與安全性相關的特性。這個選項可以運用於整個 pod ,或者每個 pod 中單獨的容器
安全上下文中可以配置的內容

指定容器中運行進程的用戶(用戶ID)
阻止容器使用 root 戶運行(容器的默認運行用戶通常在其鏡像中指定,所以可能需要阻止容器 root 用戶運行)
使用特權模式運行容器,使其對宿主節點的內核具有完全的訪問權限
與以上相反,通過添加或禁用內核功能,配置細粒度的內核訪問權限
設置 SELinux (Security Enhaced Linux 安全增強型 Linux )選項,加強對容器的限制。
阻止進程寫入容器的根文件系統
使用指定用戶運行容器
默認情況運行容器的用戶是root ,用戶id 為0

apiVersion: v1 kind: Pod metadata: name· pod-as-user-guest spec· containers: - name: asdf image: wq55/lks command: ["..."] securityContext: runAsUser: 405 #通過指定用戶id 來指定用戶運行
阻止容器以 root 用戶運行
使用 Dockerfile 配置鏡像以root 用戶啟動,如果避免此情況,可以配置pod 如下:

apiVersion: v1 kind: Pod metadata: spec: containers: - name: asdf image: lkjl/sdf command: ["..."] securityContext: runAsNonRoot: true
使用特權模式運行 pod
有時 pod 需要做它們的宿主節點上能夠做的任何事,例如操作被保護的系統設備,或使用其他在通常容器中不能使用的內核功能。

apiVersion: v1 kind: Pod metadata: spec: containers: - name: asdf image: lkjl/sdf command: ["..."] securityContext: privileged : true
為容器單獨添加內核功能
相比於讓容器運行在特權模式下以給予其無限的權限,一個更加安全的做法是只給予它使用真正需要的內核功能的權限。K8s允許為特定的容器添加內核功能,或禁用部分內核功能,以允許對容器進行更加精細的權限控制,限制攻擊者潛在侵入的影響。
例如添加一個能夠修改內核時間的功能

apiVersion: v1 kind: Pod metadata: spec: containers: - name: asdf image: lkjl/sdf command: ["..."] securityContext: capabilities: add - SYS_TIME
注意 Linux內核功能的名稱通常以CAP_開頭。但在podspec中指定內核功能時,必須省略CAP_前綴。提示:: 可以在Linux手冊中查閱Linux內核功能列表。
在容器中禁用內核功能
默認情況下容器擁有CAP_CHOWN權限,允許進程修改文件系統中文件的所有者。為了阻止容 器的此種行為,需要如以下代碼清單所示,在容器的securityContext.capabilities.drop列表中加入此項,以禁用這個修改文件所有者的內核功能。

apiVersion: v1 kind: Pod metadata: spec: containers: - name: asdf image: lkjl/sdf command: ["..."] securityContext: capabilities: drop: - CHOWN
阻止對容器根文件系統的寫入
因為安全原因你可能需要阻止容器中的進程對容器的根文件系統進行寫入,僅允許它們寫入掛載的存儲卷。

apiVersion: v1 kind: Pod metadata: spec: containers: - name: asdf image: lkjl/sdf command: ["..."] securityContext: readOnlyRootFilesystem: true #不允許容器寫入根文件系統 volumeMounts: - name: my-volume mountPath: /volume readOnly: false #允許寫入掛載卷目錄 volumes: - name: my-volume emptyDir:
設置pod級別的安全上下文
以上的例子都是對單獨的容器設置安全上下文。 這些選項中的一部分也可以從pod級別設定(通過pod.spec.securityContext屬性)。 它們會作為pod中每一個容器的默認安全上下文, 但是會被容器級別的安全上下文覆蓋。
下面將會介紹 pod級別安全上下文獨有的內容

Kubemetes 允許為pod 中所有容器指定 supplemental 組,以允許它們無論以哪個用戶ID運行都可以共享文件 。這可以通過以下兩個屬性設置: • fsGroup • supplementalGroups apiVersion: v1 kind: Pod metadata: spec: securityContext: fsGroup: 555 supplementalGroups: [666,777] containers: - name: first image: lkjl/sdf command: ["..."] volumeMounts: - name: my-volume mountPath: /volume readOnly: false - name: second image: lkjl/sdf command: ["..."] volumeMounts: - name: my-volume mountPath: /volume readOnly: false volumes: - name: my-volume emptyDir:
安全上下文中的fsGroup屬性當進程在存儲卷中創建文件時起作用, 而 supplementalGroups屬性定義了某個用戶所關聯的額外的用戶組。
限制pod使用安全相關的特性
以上章節中的例子已經介紹了如何在部署 pod時在任一宿主節點上做任何想做的事。 比如, 部署一個特權模式的 pod 。 很明顯, 需要有一種機制阻止用戶使用其中的部分功能。 集群管理入員可以通過創建 PodSecurityPolicy 資源來限制對以上提到的安全相關的特性的使用。
PodSecurityPolicy資源介紹
PodSecurityPolicy 是一種集群級別(無命名空間)的資源, 它定義了用戶能否在 pod 中使用各種安全相關的特性。 維護 PodSecurityPolicy 資源中配置策略的工作由集成在 API 服務器中的 PodSecurityPolicy 准入控制插件完成
當有人向 API 服務器發送 pod 資源時, PodSecurityPolicy 准入控制插件會將這個 pod 與已經配置的 PodSecurityPolicy 進行校驗。 如果這個 pod 符合集群中已有安策略, 它會被接收並存入 etcd; 否則它會立即被拒絕。 這個插件也會根據安全策略中配置的默認值對 pod 進行修改。
對不同的用戶與組分配不同的 PodSecurityPolicy
PodSecurityPolic 是集群級別的資源,這意味着它不能存儲和應用在某一特定的命名空間上 這是否意味着它總是會應用在所有的命名空間上呢?不是的,因為這樣會使得它們相 當難以應用。畢竟,系統 pod 經常需要允許做一些常規 pod 不應當做的事情
實現機制
對不同用戶分配不同 PodSecurityPolicy 是通過RBAC 機制實現。這個方法是,創建你需要的 PodSecurityPolicy 資源,然后創建 ClusterRole 資源並通過名稱將它指向不同的策略,以此使PodSecurityPoIicy 資源中的策略對不同
的用戶或組生效 通過 ClusterRoleBinding 資源將特定的用戶或組綁定到 ClusterRole上,當 PodSecurityPolicy 訪問 控制ity插件需要決定是否接納 pod 時,它只會考慮 pod 的用戶可以訪問到 PodS ecurityPolicy 中的策略。
實現過程

創建一個 PodSecurityPolicy apiVersion: extensions/vlbetal kind: PodSecurityPolicy spec: volumes : - emptyDir - configMap - secret - downwardAPI - persistentVolumeClaim kubectl get psp #查看已經創建得podSecrityPolicy 使用 RBAC 將不同的 PodSecurityPolicy 分配給不同用戶 創建Clusterrole kubectl create clusterrole psp-defaul t --verb=use --resource=podsecuritypolicies --resource-name=default 注意: 你使用的動詞是 use ,而非 get list watch 或類似動詞 創建 ClusterRoleBinding 資源而非 (有命名空間的)RoleBinding,綁定Clusterrole 到用戶上 kubectl create clusterrolebinding psp-bob --clusterrole=psp-privileged --user=bob 為kubectl 創建用戶 $ kubectl config set-credentials bob --username=bob --password=password 因為你使用了用戶名和密碼作為憑據 kubectl將對這兩個用戶使用基礎 HTTP 認證進行認證(其他的認證方法包括 oken 客戶端證書等) 使用不同用戶創建 pod kubectl --user bob create -f pod-privileged.yaml
PodSecurityPolicy 可以做的事

• 是否允許 pod 使用宿主節點的 PID、 IPC、 網絡命名空間
• pod 允許綁定的宿主節點端口
• 容器運行時允許使用的用戶 ID
• 是否允許擁有特權模式容器的 pod
• 允許添加哪些內核功能, 默認添加哪些內核功能, 總是禁用哪些內核功能
• 允許容器使用哪些 SELinux 選項 • 容器是否允許使用可寫的根文件系統
• 允許容器在哪些文件系統組下運行
• 允許 pod 使用哪些類型的存儲卷
一個 PodSecurityPolicy 樣例

apiVersion: extensions/vlbetal kind: PodSecurityPolicy metadata: name: default spec: hostIPC: false hostPID: false hostPorts: - min: 10000 max: 11000 - min: 13000 max: 14000 privileged: false readOnlyRootFilesystem: true runAsUser: rule: RunAsAny fsGroup: rule: RunAsAny supplementalGroups: rule: RunAsAny seLinux: rule: RunAsAny volumes: - '*'
了解 runAsUser、 fsGroup 和 supplementalGroup 策略
如果需要限制容器可以使用的用戶和用戶組ID, 可以將規則改為MustRunAs, 並指定允許使用的ID范圍。

runAsUser: rule: MustRunAs ranges: - min: 2 max: 2 fsGroup: rule: MustRunAs ranges: - min: 2 max: 10 - min: 20 max: 30 supplementalGroups: rule: MustRunAs ranges: - min: 2 max: 10 - min: 20 max: 30
如果pod spec試圖將其中的任一字段設置為該范圍之外的值,這個pod將不會被API服務器接收。
Notice:
View Code
View Code
View Code
修改策略對已經存在的pod無效,因為PodSecurityPolicy資原僅在創建和升級pod 時生效
部署鏡像中用戶 ID 在指定范圍之外的 pod
與之前不同, API 服務器接收了這 pod, kube et 也運行了這個容器。PodSecurityPolicy 可以將硬編碼覆蓋到鏡像中的用戶 ID
runAsUser 字段中使用 mustRunAsNonRoot 規則
runAsUs er 宇段 中還可以 使用另-科 規則: mustRunAsNonRoot 。正名,它將阻止用戶部署以 root 用戶運行的容器。在此種情況下, spec 容器中必須指定 runAsUser 宇段,並且不能為 root 用戶的 ID ),或者容器的鏡像本身指
定了用一個非 的用戶 ID 運行。這種做法的好處己經在之前介紹過。
配置允許、默認添加、禁止使用的內核功能
以下 個字段會影響容器可以使用的內核功能:

• allowedCapabilities
• defaultAddCapabilities
•requiredDropCapabilities
示例

apiVersion: extensions/vlbetal kind: PodSecurityPolicy spec: allowedCapabilities: - SYS_TIME #允許容器添 SYS_TIME功能 defaultAddCapabilities - CHOWN #為每個容器自動添CHOWN功能 requiredDropCapabilites - SYS_ADMIN #要求容器禁用SYS_ADMIN和SYS_MODULE功能 - SYS_MODULE 注:SYS_ADMIN 功能允許使用一系列的管理操作; SYS_MODULE 功能允許加載或卸載 inux 核模塊
限制 pod 可以使用的存儲卷類型

kind: PodSecurityPolicy spec: volumes : - emptyDir - configMap - secret - downwardAPI - persistentVolumeClaim
如果有多個 PodSecurityPolicy 資源, pod 可以使用 PodSecurityPolicy 中允許使用的任何一個存儲卷類型(實際生效的是所有 volume 列表的並集〉。