

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Pod 安全性
<a name="pod-security"></a>

**提示**  
 透過 Amazon EKS 研討會[探索](https://aws-experience.com/emea/smb/events/series/get-hands-on-with-amazon-eks?trk=4a9b4147-2490-4c63-bc9f-f8a84b122c8c&sc_channel=el)最佳實務。

Pod 規格包含各種不同的屬性，可強化或削弱您的整體安全狀態。身為 Kubernetes 從業人員，您的首要考量應該是防止容器中執行的程序逸出容器執行時間的隔離界限，並取得基礎主機的存取權。

## Linux 功能
<a name="_linux_capabilities"></a>

根據預設，在容器內執行的程序會在 【Linux】 根使用者的內容下執行。雖然容器內根的動作部分受限於容器執行時間指派給容器的一組 Linux 功能，但這些預設權限可能允許攻擊者提升其權限和/或存取繫結至主機的敏感資訊，包括 Secrets 和 ConfigMaps。以下是指派給容器的預設功能清單。如需每個功能的詳細資訊，請參閱 https：//http://man7.org/linux/man-pages/man7/capabilities.7.html。

 `CAP_AUDIT_WRITE, CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_MKNOD, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SETGID, CAP_SETUID, CAP_SETFCAP, CAP_SETPCAP, CAP_SYS_CHROOT` 

**Example**  
EC2 和 Fargate Pod 預設會獲指派上述功能。此外，Linux 功能只能從 Fargate Pod 中捨棄。

以特殊權限執行的 Pod，會繼承與主機根相關聯的*所有* Linux 功能。如果可能，應該避免這種情況。

### 節點授權
<a name="_node_authorization"></a>

所有 Kubernetes 工作者節點都使用稱為 [Node Authorization ](https://kubernetes.io/docs/reference/access-authn-authz/node/)的授權模式。節點授權會授權來自 kubelet 的所有 API 請求，並允許節點執行下列動作：

讀取操作：
+ services
+ 端點
+ 節點
+ Pod
+ 與綁定至 kubelet 節點的 Pod 相關的秘密、組態映射、持久性磁碟區宣告和持久性磁碟區

寫入操作：
+ 節點和節點狀態 （啟用`NodeRestriction`許可外掛程式以限制 kubelet 修改自己的節點）
+ Pod 和 Pod 狀態 （啟用`NodeRestriction`許可外掛程式以限制 kubelet 修改綁定至其本身的 Pod)
+ events

驗證相關操作：
+ TLS 引導的 CertificateSigningRequest (CSR) API 讀取/寫入存取權
+ 為委派的身分驗證/授權檢查建立 TokenReview 和 SubjectAccessReview 的能力

EKS 使用[節點限制許可控制器](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction)，僅允許節點修改綁定至節點的一組有限節點屬性和 Pod 物件。不過，管理 以存取主機的攻擊者仍然可以從 Kubernetes API 收集環境的敏感資訊，讓他們可以在叢集內橫向移動。

## Pod 安全解決方案
<a name="_pod_security_solutions"></a>

### Pod 安全政策 (PSP)
<a name="_pod_security_policy_psp"></a>

在過去，[Pod 安全政策 (PSP)](https://kubernetes.io/docs/concepts/policy/pod-security-policy/) 資源用於指定一組 Pod 在建立之前必須符合的要求。自 Kubernetes 1.21 版起，PSP 已棄用。它們排定在 Kubernetes 1.25 版中移除。

**重要**  
 Kubernetes 1.21 版已[棄用 PSPs](https://kubernetes.io/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/)。直到 1.25 版或大約 2 年，您都可以轉換到替代版本。[本文件](https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/2579-psp-replacement/README.md#motivation)說明此棄用的動機。

### 遷移至新的 Pod 安全解決方案
<a name="_migrating_to_a_new_pod_security_solution"></a>

由於 PSPs已從 Kubernetes v1.25 移除，叢集管理員和運算子必須取代這些安全控制。有兩種解決方案可以滿足此需求：
+ Kubernetes 生態系統中的Policy-as-code(PAC) 解決方案
+ Kubernetes [Pod 安全標準 (PSS)](https://kubernetes.io/docs/concepts/security/pod-security-standards/) 

PAC 和 PSS 解決方案都可以與 PSP 共存；它們可以在移除 PSP 之前用於叢集。這可簡化從 PSP 遷移時的採用。在考慮從 PSP 遷移到 PSS 時，請參閱[本文件](https://kubernetes.io/docs/tasks/configure-pod-container/migrate-from-psp/)。

以下概述的 PAC 解決方案之一 Kyverno 在從 PSPs 遷移至其解決方案時，有[部落格文章](https://kyverno.io/blog/2023/05/24/podsecuritypolicy-migration-with-kyverno/)中概述的特定指引，包括類似政策、功能比較和遷移程序。有關遷移至 Kyverno 有關 Pod 安全許可 (PSA) 的其他資訊和指導已發佈於[此處](https://aws.amazon.com/blogs/containers/managing-pod-security-on-amazon-eks-with-kyverno/)的 AWS 部落格。

### Policy-as-code(PAC)
<a name="_policy_as_code_pac"></a>

Policy-as-code(PAC) 解決方案提供護欄，透過規定和自動化控制來引導叢集使用者，並防止不必要的行為。PAC 使用 [Kubernetes 動態許可控制器](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/)透過 Webhook 呼叫攔截 Kubernetes API 伺服器請求流程，並根據撰寫並儲存為程式碼的政策來變更和驗證請求承載。變更和驗證會在 API 伺服器請求導致叢集變更之前發生。PAC 解決方案使用政策來比對 API 伺服器請求承載，並根據分類和值採取行動。

有多種開放原始碼 PAC 解決方案可供 Kubernetes 使用。這些解決方案不屬於 Kubernetes 專案；它們來自 Kubernetes 生態系統。以下列出一些 PAC 解決方案。
+  [OPA/Gatekeeper](https://open-policy-agent.github.io/gatekeeper/website/docs/) 
+  [開啟政策代理程式 (OPA)](https://www.openpolicyagent.org/) 
+  [基佛諾](https://kyverno.io/) 
+  [Kubewarden](https://www.kubewarden.io/) 
+  [jsPolicy](https://www.jspolicy.com/) 

如需 PAC 解決方案以及如何協助您選擇適合您需求的解決方案的詳細資訊，請參閱以下連結。
+  [Kubernetes 的政策型對策 – 第 1 部分](https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-1/) 
+  [Kubernetes 的政策型對策 – 第 2 部分](https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-2/) 

### Pod 安全標準 (PSS) 和 Pod 安全許可 (PSA)
<a name="_pod_security_standards_pss_and_pod_security_admission_psa"></a>

為了回應 PSP 棄用，以及持續需要透過內建的 Kubernetes 解決方案立即控制 Pod 安全 out-of-the-box ，Kubernetes [Auth Special Interest Group](https://github.com/kubernetes/community/tree/master/sig-auth) 建立了 [Pod 安全標準 (PSS)](https://kubernetes.io/docs/concepts/security/pod-security-standards/) 和 [Pod 安全許可 (PSA)](https://kubernetes.io/docs/concepts/security/pod-security-admission/)。PSA 工作包含[許可控制器 Webhook 專案](https://github.com/kubernetes/pod-security-admission#pod-security-admission)，可實作 PSS 中定義的控制項。此許可控制器方法類似於 PAC 解決方案中使用的 。

根據 Kubernetes 文件，PUS *"`define three different policies to broad cover the security spectrum。這些政策是累積的，範圍從高度寬鬆到高度限制。`"*

這些政策的定義如下：
+  **特殊權限：**不受限制 （不安全） 政策，提供最廣泛的許可層級。此政策允許已知的權限提升。這是缺少政策。這適用於記錄代理程式、CNIs、儲存驅動程式等應用程式，以及其他需要特殊存取權限的應用程式。
+  **基準：**可避免已知權限提升的最小限制政策。允許預設 （最低指定） Pod 組態。基準政策禁止使用 hostNetwork、hostPID、hostIPC、hostPath、hostPort、無法新增 Linux 功能，以及其他幾項限制。
+  **限制：**嚴格限制政策，遵循目前的 Pod 強化最佳實務。此政策繼承自基準，並新增進一步的限制，例如無法以根或根群組身分執行。限制政策可能會影響應用程式運作的能力。它們主要以執行安全關鍵應用程式為目標。

這些政策會定義 [Pod 執行的設定檔](https://kubernetes.io/docs/concepts/security/pod-security-standards/#profile-details)，並分為三個層級的特權與 限制存取。

若要實作 PSS 定義的控制項，PSA 會以三種模式運作：
+  **強制執行：**違反政策會導致 Pod 遭到拒絕。
+  **稽核：**政策違規將觸發將稽核註釋新增至稽核日誌中記錄的事件，但在其他情況下是允許的。
+  **警告：**違反政策將觸發面向使用者的警告，但在其他情況下是允許的。

這些模式和設定檔 （限制） 層級是在 Kubernetes 命名空間層級使用標籤設定，如下列範例所示。

```
apiVersion: v1
kind: Namespace
metadata:
  name: policy-test
  labels:
    pod-security.kubernetes.io/enforce: restricted
```

獨立使用時，這些操作模式會有不同的回應，進而產生不同的使用者體驗。如果個別 PodSpecs 違反設定的限制層級，*強制執行*模式將阻止建立 Pod。 podSpecs 不過，在此模式中，即使其中的 podSpec 違反套用的 PSS，也不會阻止建立 Pod 的非 Pod Kubernetes 物件，例如部署。在這種情況下，部署將套用，而 Pod (s) 將無法套用。

這是一個困難的使用者體驗，因為沒有立即指出成功套用的部署物件是失敗的 Pod 建立。違規的 podSpecs 不會建立 Pod。使用 檢查部署資源`kubectl get deploy <DEPLOYMENT_NAME> -oyaml`會公開來自失敗 Pod (s) `.status.conditions`元素的訊息，如下所示。

```
...
status:
  conditions:
    - lastTransitionTime: "2022-01-20T01:02:08Z"
      lastUpdateTime: "2022-01-20T01:02:08Z"
      message: 'pods "test-688f68dc87-tw587" is forbidden: violates PodSecurity "restricted:latest":
        allowPrivilegeEscalation != false (container "test" must set securityContext.allowPrivilegeEscalation=false),
        unrestricted capabilities (container "test" must set securityContext.capabilities.drop=["ALL"]),
        runAsNonRoot != true (pod or container "test" must set securityContext.runAsNonRoot=true),
        seccompProfile (pod or container "test" must set securityContext.seccompProfile.type
        to "RuntimeDefault" or "Localhost")'
      reason: FailedCreate
      status: "True"
      type: ReplicaFailure
...
```

在*稽核*和*警告*模式中，Pod 限制不會防止建立和啟動違反 Pod。不過，在這些模式中，當 Pod 以及建立 Pod 的物件包含違規的 podSpecs 時，會分別觸發 API 伺服器稽核日誌事件和警告上的稽核註釋，例如 *kubectl*。警告`kubectl`**訊息如下所示。

```
Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "test" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "test" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "test" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "test" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
deployment.apps/test created
```

引進 PSS 時，PSA *稽核*和*警告*模式非常有用，而不會對叢集操作造成負面影響。

PSA 操作模式並非互斥，可以累積方式使用。如下所示，您可以在單一命名空間中設定多個模式。

```
apiVersion: v1
kind: Namespace
metadata:
  name: policy-test
  labels:
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/warn: restricted
```

在上述範例中，套用部署時會提供易於使用的警告和稽核註釋，而強制執行違規也會在 Pod 層級提供。事實上，多個 PSA 標籤可以使用不同的設定檔層級，如下所示。

```
apiVersion: v1
kind: Namespace
metadata:
  name: policy-test
  labels:
    pod-security.kubernetes.io/enforce: baseline
    pod-security.kubernetes.io/warn: restricted
```

在上述範例中，PSA 設定為允許建立符合*基準*設定檔層級的所有 Pod，然後在違反*受限*設定檔層級的 Pod （以及建立 Pod 的物件） 上*發出警告*。這是一個有用的方法，用於判斷從*基準*變更為*受限*設定檔時可能的影響。

#### 現有 Pod
<a name="_existing_pods"></a>

如果修改具有現有 Pod 的命名空間以使用更嚴格的 PSS 設定檔，則*稽核*和*警告*模式會產生適當的訊息；不過，*強制*模式不會刪除 Pod。警告訊息如下所示。

```
Warning: existing pods in namespace "policy-test" violate the new PodSecurity enforce level "restricted:latest"
Warning: test-688f68dc87-htm8x: allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile
namespace/policy-test configured
```

#### 豁免
<a name="_exemptions"></a>

PSA 使用*豁免*來排除對原本應套用之 Pod 的違規強制執行。這些豁免列於下方。
+  **使用者名稱：**忽略具有豁免身分驗證 （或模擬） 使用者名稱之使用者的請求。
+  **RuntimeClassNames：**會忽略指定豁免執行時間類別名稱的 Pod 和工作負載資源。
+  **命名空間：**忽略豁免命名空間中的 Pod 和工作負載資源。

這些豁免會在 [PSA 許可控制器組態](https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/#configure-the-admission-controller)中靜態套用，做為 API 伺服器組態的一部分。

在*驗證 Webhook* 實作中，可以在 Kubernetes [ConfigMap](https://github.com/kubernetes/pod-security-admission/blob/master/webhook/manifests/20-configmap.yaml) 資源中設定豁免，該資源會掛載為 [pod-security-webhook](https://github.com/kubernetes/pod-security-admission/blob/master/webhook/manifests/50-deployment.yaml) 容器的磁碟區。

```
apiVersion: v1
kind: ConfigMap
metadata:
  name: pod-security-webhook
  namespace: pod-security-webhook
data:
  podsecurityconfiguration.yaml: |
    apiVersion: pod-security.admission.config.k8s.io/v1
    kind: PodSecurityConfiguration
    defaults:
      enforce: "restricted"
      enforce-version: "latest"
      audit: "restricted"
      audit-version: "latest"
      warn: "restricted"
      warn-version: "latest"
    exemptions:
      # Array of authenticated usernames to exempt.
      usernames: []
      # Array of runtime class names to exempt.
      runtimeClasses: []
      # Array of namespaces to exempt.
      namespaces: ["kube-system","policy-test1"]
```

如上述 ConfigMap YAML 所示，整個叢集的預設 PSS 層級已設定為*限制*所有 PSA 模式、*稽核*、*強制執行*和*警告*。這會影響所有命名空間，但不包括豁免的命名空間：`namespaces: ["kube-system","policy-test1"]`。此外，在如下所示的 *ValidatingWebhookConfiguration* 資源中，*pod-security-webhook* 命名空間也會從設定的 PSS 中排除。

```
...
webhooks:
  # Audit annotations will be prefixed with this name
  - name: "pod-security-webhook.kubernetes.io"
    # Fail-closed admission webhooks can present operational challenges.
    # You may want to consider using a failure policy of Ignore, but should
    # consider the security tradeoffs.
    failurePolicy: Fail
    namespaceSelector:
      # Exempt the webhook itself to avoid a circular dependency.
      matchExpressions:
        - key: kubernetes.io/metadata.name
          operator: NotIn
          values: ["pod-security-webhook"]
...
```

**重要**  
Pod 安全許可在 Kubernetes 1.25 版中進入穩定狀態。如果您想要在預設啟用 Pod 安全許可功能之前使用此功能，則需要安裝動態許可控制器 （變動 Webhook)。您可以在[此處](https://github.com/kubernetes/pod-security-admission/tree/master/webhook)找到安裝和設定 Webhook 的說明。

### 在policy-as-code和 Pod 安全標準之間進行選擇
<a name="_choosing_between_policy_as_code_and_pod_security_standards"></a>

Pod 安全標準 (PSS) 旨在取代 Pod 安全政策 (PSP)，方法是提供內建於 Kubernetes 且不需要 Kubernetes 生態系統解決方案的解決方案。也就是說，policy-as-code(PAC) 解決方案更加靈活。

下列 Pros 和 Cons 清單旨在協助您更明智地決定 Pod 安全解決方案。

#### Policy-as-code（與 Pod 安全標準相比）
<a name="_policy_as_code_as_compared_to_pod_security_standards"></a>

優點：
+ 更靈活、更精細 （視需要縮減至資源的屬性）
+ 不僅專注於 Pod，還可以用於不同的資源和動作
+ 不僅適用於命名空間層級
+ 比 Pod 安全標準更成熟
+ 決策可以根據 API 伺服器請求承載中的任何內容，以及現有的叢集資源和外部資料 （取決於解決方案）
+ 支援在驗證之前變更 API 伺服器請求 （取決於解決方案）
+ 可以產生互補政策和 Kubernetes 資源 （取決於解決方案 - 從 Pod 政策中，Kyverno 可以[自動產生](https://kyverno.io/docs/writing-policies/autogen/)高階控制器的政策，例如部署。 Kyverno 也可以使用[產生規則](https://kyverno.io/docs/writing-policies/generate/)產生額外的 Kubernetes 資源*「建立新資源時或更新來源時`」*。)
+ 在呼叫 Kubernetes API 伺服器 （依解決方案而定） 之前，可用來向左移動至 CICD 管道
+ 可用於實作不一定與安全相關的行為，例如最佳實務、組織標準等。
+ 可用於非 Kubernetes 使用案例 （取決於解決方案）
+ 由於靈活性，使用者體驗可以根據使用者的需求進行調整

缺點：
+ 未內建於 Kubernetes
+ 更複雜的學習、設定和支援
+ 政策撰寫可能需要新的skills/languages/capabilities

#### Pod 安全許可 （與policy-as-code相比）
<a name="_pod_security_admission_as_compared_to_policy_as_code"></a>

優點：
+ 內建於 Kubernetes
+ 設定更簡單
+ 沒有要使用的新語言或編寫的政策
+ 如果叢集預設許可層級設定為*特殊權限*，則可以使用命名空間標籤將命名空間選擇為 Pod 安全性設定檔。

缺點：
+ 不像policy-as-code一樣靈活或精細
+ 只有 3 個層級的限制
+ 主要專注於 Pod

#### 摘要
<a name="_summary"></a>

如果您目前沒有 PSP 以外的 Pod 安全解決方案，且所需的 Pod 安全狀態符合 Pod 安全標準 (PSS) 中定義的模型，則更簡單的路徑可能是採用 PSS，而不是policy-as-code解決方案。不過，如果您的 Pod 安全狀態不符合 PSS 模型，或者您設想新增超出 PSS 定義的其他控制項，則policy-as-code解決方案似乎更合適。

## 建議
<a name="_recommendations"></a>

### 使用多個 Pod 安全許可 (PSA) 模式，以獲得更好的使用者體驗
<a name="_use_multiple_pod_security_admission_psa_modes_for_a_better_user_experience"></a>

如前所述，PSA *強制執行*模式可防止套用具有 PSS 違規的 Pod，但不會停止更高層級的控制器，例如部署。事實上，部署將成功套用，而不會指出 Pod 無法套用。雖然您可以使用 *kubectl* 來檢查部署物件，並從 PSA 探索失敗的 Pod 訊息，但使用者體驗可能會更好。為了改善使用者體驗，應使用多個 PSA 模式 （稽核、強制執行、警告）。

```
apiVersion: v1
kind: Namespace
metadata:
  name: policy-test
  labels:
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/warn: restricted
```

在上述範例中，在定義*強制執行*模式的情況下，當嘗試將個別 podSpec 中具有 PSS 違規的部署資訊清單套用至 Kubernetes API 伺服器時，部署將成功套用，但 Pod 不會。此外，由於*稽核*和*警告*模式也已啟用，API 伺服器用戶端會收到警告訊息，API 伺服器稽核日誌事件也會以訊息標註。

### 限制可做為特殊權限執行的容器
<a name="_restrict_the_containers_that_can_run_as_privileged"></a>

如前所述，以特殊權限身分執行的容器會繼承指派給主機根目錄的所有 Linux 功能。容器很少需要這些類型的權限才能正常運作。有多種方法可用來限制容器的許可和功能。

**重要**  
Fargate 是一種啟動類型，可讓您執行「無伺服器」容器 （在 AWS 管理的基礎設施上執行 Pod 的容器）。使用 Fargate，您無法執行特權容器或將 Pod 設定為使用 hostNetwork 或 hostPort。

### 請勿在容器中執行程序做為根目錄
<a name="_do_not_run_processes_in_containers_as_root"></a>

根據預設，所有容器都會以根身分執行。如果攻擊者能夠利用應用程式中的漏洞，並取得執行中容器的 shell 存取，則這可能有問題。您可以用各種方式降低此風險。首先，從容器映像中移除 Shell。其次，將 USER 指令新增至 Dockerfile，或以非根使用者身分在 Pod 中執行容器。Kubernetes podSpec 包含一組欄位，位於 下`spec.securityContext`，可讓您指定要在其中執行應用程式的使用者和/或群組。這些欄位`runAsGroup`分別為 `runAsUser`和 。

若要在 Kubernetes podSpec 中強制使用 `spec.securityContext`及其相關聯的元素，可以將policy-as-code或 Pod 安全標準新增至叢集。這些解決方案可讓您撰寫和/或使用可驗證傳入 Kubernetes API 伺服器請求承載的政策或設定檔，然後再保留到 等。此外，policy-as-code解決方案可以改變傳入請求，在某些情況下，會產生新的請求。

### 切勿在 Docker 中執行 Docker 或在容器中掛載通訊端
<a name="_never_run_docker_in_docker_or_mount_the_socket_in_the_container"></a>

雖然這可讓您在 Docker 容器中建置/執行映像，但您基本上會放棄節點對容器中執行程序的完整控制。如果您需要在 Kubernetes 上建置容器映像，請改用 [Kaniko](https://github.com/GoogleContainerTools/kaniko)、[buildah](https://github.com/containers/buildah) 或像是 [CodeBuild](https://docs.aws.amazon.com/codebuild/latest/userguide/welcome.html) 的建置服務。

**注意**  
用於 CICD 處理的 Kubernetes 叢集，例如建置容器映像，應與執行更廣泛工作負載的叢集隔離。

### 限制 hostPath 的使用，或者如果需要 hostPath 限制哪些字首可以使用，並將磁碟區設定為唯讀
<a name="_restrict_the_use_of_hostpath_or_if_hostpath_is_necessary_restrict_which_prefixes_can_be_used_and_configure_the_volume_as_read_only"></a>

 `hostPath` 是將目錄從主機直接掛載到容器的磁碟區。在極少數情況下，Pod 會需要這種類型的存取，但如果他們需要，您需要注意風險。根據預設，以根身分執行的 Pod 將具有 hostPath 公開之檔案系統的寫入存取權。這可能會允許攻擊者修改 kubelet 設定、建立未由 hostPath 直接公開的目錄或檔案的符號連結，例如 /etc/shadow、安裝 ssh 金鑰、掛載到主機的讀取秘密，以及其他惡意物件。若要降低 hostPath 的風險，請將 設定為 `spec.containers.volumeMounts` `readOnly`，例如：

```
volumeMounts:
- name: hostPath-volume
    readOnly: true
    mountPath: /host-path
```

您也應該使用policy-as-code解決方案來限制可供磁碟`hostPath`區使用的目錄，或完全防止`hostPath`使用。您可以使用 Pod 安全標準*基準*或*受限制*政策來防止使用 `hostPath`。

如需特殊權限提升危險的進一步資訊，請參閱 Seth Art 的部落格[錯誤 Pod：Kubernetes Pod 特殊權限提升](https://labs.bishopfox.com/tech-blog/bad-pods-kubernetes-pod-privilege-escalation)。

### 為每個容器設定請求和限制，以避免資源爭用和 DoS 攻擊
<a name="_set_requests_and_limits_for_each_container_to_avoid_resource_contention_and_dos_attacks"></a>

沒有請求或限制的 Pod 理論上可以使用主機上所有可用的資源。當其他 Pod 排程到節點時，節點可能會遇到 CPU 或記憶體壓力，這可能會導致 Kubelet 從節點終止或移出 Pod。雖然您無法防止這種情況一起發生，但設定請求和限制將有助於最大限度地減少資源爭用，並降低因寫入不良的應用程式消耗過多資源的風險。

`podSpec` 可讓您指定 CPU 和記憶體的請求和限制。CPU 被視為可壓縮資源，因為它可能會過度訂閱。記憶體無法壓縮，即 無法在多個容器之間共用。

當您指定 CPU 或記憶體的*請求*時，基本上就是指定容器保證取得的*記憶體*量。Kubernetes 會彙總 Pod 中所有容器的請求，以決定要排程 Pod 的節點。如果容器超過請求的記憶體數量，如果節點上有記憶體壓力，則可能會終止。

 *限制*是允許容器使用並直接對應至為容器建立之 cgroup `memory.limit_in_bytes`值的 CPU 和記憶體資源數量上限。超過記憶體限制的容器將被刪除。如果容器超過其 CPU 限制，則會對其進行調節。

**注意**  
使用容器時`resources.limits`，強烈建議容器資源使用量 （即資源足跡） 根據負載測試以資料驅動且準確。如果沒有準確且受信任的資源使用量，`resources.limits`可以填充容器。例如， `resources.limits.memory`可能填充比可觀測的最大值高 20-30%，以考慮潛在的記憶體資源限制不正確。

Kubernetes 使用三種服務品質 (QoS) 類別來排定節點上執行工作負載的優先順序。其中包含：
+ 保證
+ 爆量
+ 最佳努力

如果未設定限制和請求，Pod 會設定為*盡力* （最低優先順序）。當記憶體不足時，最努力的 Pod 是第一個被終止的 Pod。如果 Pod 內*的所有*容器都設定了限制，或者如果請求和限制設定為相同的值但不等於 0，則 Pod 會設定為*保證* （最高優先順序）。除非保證的 Pod 超過其設定的記憶體限制，否則不會被終止。如果限制和請求設定了不同的值，但不等於 0，或 Pod 中的一個容器設定了限制，而其他容器未針對不同的資源設定限制，則 Pod 會設定為*爆量* （中等優先順序）。這些 Pod 有一些資源保證，但一旦超過其請求的記憶體，就會遭到刪除。

**重要**  
請求不會影響容器 cgroup `memory_limit_in_bytes`的值；cgroup 限制會設定為主機上可用的記憶體量。不過，如果將請求值設定為過低，可能會導致 Pod 在節點發生記憶體壓力時被 kubelet 終止。


| 類別 | Priority | 條件 | 刪除條件 | 
| --- | --- | --- | --- | 
|  保證  |  最高  |  limit = 請求 ！= 0  |  僅超過記憶體限制  | 
|  爆量  |  中型  |  限制 ！= 請求 ！= 0  |  如果超過請求記憶體，則可以終止  | 
|  盡最大努力  |  最低  |  限制和請求未設定  |  記憶體不足時首先被終止  | 

如需資源 QoS 的其他資訊，請參閱 [Kubernetes 文件](https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/)。

您可以在命名空間上設定[資源配額](https://kubernetes.io/docs/concepts/policy/resource-quotas/)或建立限制[範圍，強制使用請求和限制](https://kubernetes.io/docs/concepts/policy/limit-range/)。資源配額可讓您指定配置給命名空間的資源總量，例如 CPU 和 RAM。套用到命名空間時，它會強制您指定部署到該命名空間中所有容器的請求和限制。相反地，限制範圍可讓您更精細地控制資源的配置。透過限制範圍，您可以為每個 Pod 或命名空間內每個容器的 CPU 和記憶體資源最小/最大。如果未提供任何請求/限制值，您也可以使用它們來設定預設請求/限制值。

Policy-as-code解決方案可用於強制執行請求和限制。 或 甚至在建立命名空間時建立資源配額和限制範圍。

### 不允許特殊權限呈報
<a name="_do_not_allow_privileged_escalation"></a>

特殊權限提升允許程序變更其執行所在的安全內容。Sudo 是很好的範例，因為 是具有 SUID 或 SGID 位元的二進位檔。特殊權限呈報基本上是使用者執行具有其他使用者或群組許可的檔案的一種方式。您可以在 `securityContext.allowPrivilegeEscalation`中實作設定為 `allowPrivilegeEscalation``false`或 policy-as-code變更政策，以防止容器使用特殊權限升級`podSpec`。如果偵測到不正確的設定，Policy-as-code政策也可用來防止 API 伺服器請求成功。Pod 安全標準也可以用來防止 Pod 使用權限提升。

### 停用 ServiceAccount 字符掛載
<a name="_disable_serviceaccount_token_mounts"></a>

對於不需要存取 Kubernetes API 的 Pod，您可以停用 ServiceAccount 字符在 Pod 規格上的自動掛載，或使用特定 ServiceAccount 的所有 Pod。

**Example**  

```
apiVersion: v1
kind: Pod
metadata:
  name: pod-no-automount
spec:
  automountServiceAccountToken: false
```

```
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sa-no-automount
automountServiceAccountToken: false
```

### 停用服務探索
<a name="_disable_service_discovery"></a>

對於不需要查詢或呼叫叢集內服務的 Pod，您可以減少提供給 Pod 的資訊量。您可以將 Pod 的 DNS 政策設定為不使用 CoreDNS，且不得將 Pod 命名空間中的服務公開為環境變數。如需服務連結的詳細資訊，請參閱[環境變數上的 Kubernetes 文件](https://kubernetes.io/docs/concepts/services-networking/service/#environment-variables)。Pod 的 DNS 政策預設值為「ClusterFirst」，其使用叢集內 DNS，而非預設值「Default」則使用基礎節點的 DNS 解析。如需詳細資訊，請參閱 [Pod DNS 政策上的 Kubernetes 文件](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy)。

**Example**  

```
apiVersion: v1
kind: Pod
metadata:
  name: pod-no-service-info
spec:
    dnsPolicy: Default # "Default" is not the true default value
    enableServiceLinks: false
```

### 使用唯讀根檔案系統設定映像
<a name="_configure_your_images_with_read_only_root_file_system"></a>

使用唯讀根檔案系統設定映像，可防止攻擊者覆寫應用程式使用的檔案系統上的二進位檔案。如果您的應用程式必須寫入檔案系統，請考慮寫入暫存目錄或連接並掛載磁碟區。您可以透過設定 Pod 的 SecurityContext 來強制執行此操作，如下所示：

```
...
securityContext:
  readOnlyRootFilesystem: true
...
```

Policy-as-code和 Pod 安全標準可用來強制執行此行為。

**Example**  
根據 [Kubernetes 中的 Windows 容器](https://kubernetes.io/docs/concepts/windows/intro/)，`securityContext.readOnlyRootFilesystem`無法在 Windows 上執行`true`的容器設定為 ，因為需要寫入存取權，登錄檔和系統程序才能在容器內執行。

## 工具和資源
<a name="_tools_and_resources"></a>
+  [Amazon EKS 安全浸入研討會 - Pod 安全](https://catalog.workshops.aws/eks-security-immersionday/en-US/3-pod-security) 
+  [open-policy-agent/gatekeeper-library：OPA Gatekeeper 政策程式](https://github.com/open-policy-agent/gatekeeper-library)庫 OPA/Gatekeeper 政策程式庫，可用來取代 PSPs。
+  [Kyverno 政策程式庫](https://kyverno.io/policies/) 
+ EKS 的常見 OPA 和 Kyverno [政策](https://github.com/aws/aws-eks-best-practices/tree/master/policies)集合。
+  [政策型對策：第 1 部分](https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-1/) 
+  [政策型對策：第 2 部分](https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-2/) 
+  [Pod 安全政策 Migrator](https://appvia.github.io/psp-migration/) 將 PSPs 轉換為 OPA/Gatekeeper、KubeWarden 或 Kyverno 政策的工具
+  [NeuVector by SUSE](https://www.suse.com/neuvector/) 開放原始碼、零信任容器安全平台，提供程序和檔案系統政策以及許可控制規則。