

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 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] root 用户的上下文中运行。尽管容器内的 root 操作受到容器运行时分配给容器的一组 Linux 功能的部分限制，但这些默认权限可能允许攻击者升级其权限and/or gain access to sensitive information bound to the host, including Secrets and ConfigMaps. Below is a list of the default capabilities assigned to containers. For additional information about each capability, see 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 容器分配上述功能。此外，只能从 Fargate 吊舱中删除 Linux 功能。

以特权身份运行的 Pod 会继承主机上与 root 相关的*所有* Linux 功能。如果可能，应避免这种情况。

### 节点授权
<a name="_node_authorization"></a>

[所有 Kubernetes 工作节点都使用一种名为 “节点授权” 的授权模式。](https://kubernetes.io/docs/reference/access-authn-authz/node/)节点授权授权所有源自 kubelet 的 API 请求，并允许节点执行以下操作：

读取操作：
+ 务
+ 端点
+ 节点
+ 容器组（pod）
+ 与绑定到 kubelet 节点的 pod 相关的机密、配置映射、永久卷声明和永久卷

写入操作：
+ 节点和节点状态（启用`NodeRestriction`准入插件以限制 kubelet 修改自己的节点）
+ pod 和 pod 状态（启用`NodeRestriction`准入插件以限制 kubelet 修改绑定到自身的 pod）
+ events

与身份验证相关的操作：
+ 对用于 TLS 引导的 CertificateSigningRequest (CSR) API 的读/写访问权限
+ 能够创建 TokenReview 和 authentication/authorization 执行委托 SubjectAccessReview 支票

EKS 使用[节点限制准入控制器，该控制器](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction)仅允许节点修改绑定到该节点的一组有限的节点属性和容器对象。尽管如此，设法访问主机的攻击者仍然能够从 Kubernetes API 中收集有关环境的敏感信息，从而允许他们在集群内横向移动。

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

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

过去，[Pod 安全策略 (PSP)](https://kubernetes.io/docs/concepts/policy/pod-security-policy/) 资源用于指定 Pod 在创建 Pod 之前必须满足的一组要求。从 Kubernetes 1.21 版本开始，PSP 已被弃用。它们计划在 Kubernetes 版本 1.25 中移除。

**重要**  
 [PSPs 在 Kubernetes 版本 1.21 中已被弃用](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>

由于从 Kubernetes v1.25 起 PSPs 已被移除，因此集群管理员和操作员必须更换这些安全控件。有两种解决方案可以满足这一需求：
+ Policy-as-code 来自 Kubernetes 生态系统的 (PAC) 解决方案
+ Kubernetes [Pod 安全标准](https://kubernetes.io/docs/concepts/security/pod-security-standards/) (PSS) 

PAC 和 PSS 解决方案都可以与 PSP 共存；它们可以在移除 PSP 之前在集群中使用。这样可以简化从 PSP 迁移时的采用。在考虑从 PSP 迁移到 PSS 时，请参阅此[文档](https://kubernetes.io/docs/tasks/configure-pod-container/migrate-from-psp/)。

Kyverno是下文概述的PAC解决方案之一，它在从其解决方案迁移 PSPs 到其解决方案时在[博客文章](https://kyverno.io/blog/2023/05/24/podsecuritypolicy-migration-with-kyverno/)中概述了具体的指导，包括类似的策略、功能比较和迁移程序。[有关 Pod 安全准入 (PSA) 的迁移到 Kyverno 的其他信息和指南已在此处的 AWS 博客上发布。](https://aws.amazon.com/blogs/containers/managing-pod-security-on-amazon-eks-with-kyverno/)

### 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 服务器请求有效载荷进行匹配和操作。

Kubernetes 有几种开源 PAC 解决方案可供选择。这些解决方案不是 Kubernetes 项目的一部分；它们来自 Kubernetes 生态系统。下面列出了一些 PAC 解决方案。
+  [OPA/看门人](https://open-policy-agent.github.io/gatekeeper/website/docs/) 
+  [开放策略代理 (OPA)](https://www.openpolicyagent.org/) 
+  [Kyverno](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/) 

### 吊舱安全标准 (PSS) 和吊舱安全准入 (PSA)
<a name="_pod_security_standards_pss_and_pod_security_admission_psa"></a>

[为了回应 PSP 的弃用以及控制容器安全的 out-of-the-box持续需求，Kubernetes [Auth 特别兴趣小组](https://github.com/kubernetes/community/tree/master/sig-auth)通过内置的 Kubernetes 解决方案创建了 P [od 安全标准 (PSS) 和 Pod 安全准入 (PSA)](https://kubernetes.io/docs/concepts/security/pod-security-standards/)。](https://kubernetes.io/docs/concepts/security/pod-security-admission/)PSA 的工作包括一个[准入控制器 webhook 项目，该项目](https://github.com/kubernetes/pod-security-admission#pod-security-admission)实现了 PSS 中定义的控制措施。这种准入控制器方法类似于 PAC 解决方案中使用的方法。

根据Kubernetes的文档，PSS *“`定义了三种不同的策略来广泛涵盖安全领域。这些策略是累积性的，范围从高度允许到高度限制。 `”* 

这些策略定义为：
+  Privileged**：不受限制（不安全）的策略，提供尽可能广泛的权限**级别。此策略允许已知的权限升级。这是政策的缺失。这对于日志代理 CNIs、存储驱动程序等应用程序以及其他需要特权访问权限的系统范围的应用程序非常有用。
+  **基准：**限制性最低的策略，可防止已知的权限升级。允许默认（最低限度指定）Pod 配置。基准政策禁止使用 HostNetwork、HostPid、HostPid、HostPort、HostPort、无法添加 Linux 功能以及其他一些限制。
+  **限制：**严格限制政策，遵循当前 Pod 强化最佳实践。此策略继承了基准，并增加了更多限制，例如无法以 root 用户或根组的身份运行。受限的策略可能会影响应用程序的运行能力。它们主要针对运行安全关键型应用程序。

这些策略定义了 [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。但是，在这种模式下，即使其中的 PodSpec 违反了所应用的 PSS，也不会阻止创建容器的非 Pod Kubernetes 对象（例如 Deploymentes）应用于集群。在这种情况下，将应用部署，而将阻止应用 pod。

这是一种困难的用户体验，因为没有立即迹象表明成功应用的 Deployment 对象掩盖了 pod 创建失败。违规的 PodSpecs 不会创建 pod。使用检查部署资源`kubectl get deploy <DEPLOYMENT_NAME> -oyaml`将显示来自失败的 pod `.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 的对象包含违规的 PodSp *ecs 时，会分别触发 API 服务器审核日志事件的审计注释和向 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
```

PSA *审计*和*警告*模式在引入 PSS 时非常有用，不会对群集操作产生负面影响。

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
```

在上面的示例中，在应用 Deployments 时提供了用户友好的警告和审计注释，同时还在 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 和工作负载资源将被忽略。

作为 API 服务器配置的一部分，这些豁免在 [PSA 准入控制器配置](https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/#configure-the-admission-controller)中静态应用。

在*验证 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"]
...
```

**重要**  
在 Kubernetes v1.25 中，Pod Security 招生已升级到稳定版。如果您想在默认启用 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）解决方案要灵活得多。

以下优点和缺点列表旨在帮助您对 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 还可以使用生成规则生成额外的 Kubernetes 资源 *“当创建新资源或更新源代码时*”。）](https://kyverno.io/docs/writing-policies/generate/)
+ 可用于在调用 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 中
+ 配置更简单
+ 没有新的语言可供使用，也没有政策可供创作
+ 如果集群的默认准入级别配置为*特权*，则可以使用命名空间标签将命名空间选择到容器安全配置文件中。

缺点：
+ 不如灵活或精细 policy-as-code
+ 只有 3 个级别的限制
+ 主要集中在吊舱上

#### Summary
<a name="_summary"></a>

如果你目前除了 PSP 之外还没有 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* 来检查 Deployment 对象，并从 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>

如前所述，以特权身份运行的容器会继承主机上分配给 root 的所有 Linux 功能。容器很少需要这些类型的权限才能正常运行。有多种方法可用于限制容器的权限和功能。

**重要**  
Fargate 是一种启动类型，可让您运行 “无服务器” 容器，其中 Pod 的容器在 AWS 管理的基础设施上运行。使用 Fargate，你无法运行特权容器，也无法将你的容器配置为使用 HostNetwork 或 HostPort。

### 不要以 root 用户身份在容器中运行进程
<a name="_do_not_run_processes_in_containers_as_root"></a>

默认情况下，所有容器都以 root 身份运行。如果攻击者能够利用应用程序中的漏洞并获得 shell 访问正在运行的容器的权限，则可能会出现问题。您可以通过多种方式降低这种风险。首先，从容器镜像中移除 shell。其次，将 USER 指令添加到你的 Dockerfile 中，或者以非 root 用户身份运行容器中的容器。Kubernetes PodSpec 在下面包含一组字段`spec.securityContext`，允许您指定运行应用程序的用户 and/or 组。这些字段`runAsGroup`分别是`runAsUser`和。

为了强制使用及其相关元素`spec.securityContext`，可以将 Kubernetes PodSpec policy-as-code 或 Pod 安全标准添加到集群中。这些解决方案允许您编写和/或使用可以验证入站 Kubernetes API 服务器请求有效负载的策略或配置文件，然后再将其保存到 etcd 中。此外， policy-as-code解决方案可以改变入站请求，在某些情况下，还会生成新的请求。

### 切勿在 Docker 中运行 Docker 或将套接字安装到容器中
<a name="_never_run_docker_in_docker_or_mount_the_socket_in_the_container"></a>

虽然这可以方便地在 Docker 容器中查看 build/run 镜像，但你基本上是将对节点的完全控制权交给容器中运行的进程。如果你需要在 Kubernetes 上构建容器镜像，可以改用 [Kaniko](https://github.com/GoogleContainerTools/kaniko)、builda [h 或类似的构建](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 很少需要这种访问权限，但如果需要，则需要注意风险。默认情况下，以 root 身份运行的 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`。

有关特权升级危险的更多信息，请阅读塞思·阿特的博客 Ba [d Pods：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 调度到哪个节点上。如果容器超过请求的内存量，则如果节点上存在内存压力，则该容器可能会被终止。

 *限制*是容器允许消耗的最大 CPU 和内存资源量，直接对应于为容器创建的 cgroup 的`memory.limit_in_bytes`值。超过内存限制的容器将被OOM杀死。如果容器超出其 CPU 限制，它将受到限制。

**注意**  
使用容器时`resources.limits`，强烈建议容器资源使用量（又名资源足迹）以数据为导向，并根据负载测试进行准确。如果没有准确且值得信赖的资源占用空间，则`resources.limits`可以填充容器。例如，`resources.limits.memory`可以比可观察的最大值高 20-30%，以考虑潜在的内存资源限制不准确性。

Kubernetes 使用三个服务质量 (QoS) 类别来确定节点上运行的工作负载的优先级。这些方法包括：
+ 保证
+ 可爆发
+ 尽力而为

如果未设置限制和请求，则将 Pod 配置为*尽力而为*（最低优先级）。当内存不足时，尽力而为的 pod 是第一个被杀死的。如果对 Pod 中的*所有*容器设置了限制，或者将请求和限制设置为相同的值而不等于 0，则该 Pod 将被配置为*保证*（最高优先级）。除非超过配置的内存限制，否则保证的 pod 不会被杀死。如果限制和请求配置为不同的值且不等于 0，或者容器中的一个容器设置了限制，而其他容器没有或对不同的资源设置了限制，则这些 Pod 将被配置为可*突发性*（中等优先级）。这些 pod 有一些资源保证，但是一旦它们超过了请求的内存，它们就会被杀死。

**重要**  
请求不会影响容器的 cgroup 的`memory_limit_in_bytes`值；cgroup 限制设置为主机上的可用内存量。尽管如此，如果节点承受内存压力，将请求值设置得太低可能会导致 kubelet 将 pod 作为终止的目标。


| 类 | 优先级 | 条件 | 击杀条件 | 
| --- | --- | --- | --- | 
|  能保证  |  最高  |  限制 = 请求！ = 0  |  仅超过内存限制  | 
|  可突增  |  medium  |  极限！ = 请求！ = 0  |  如果超过请求内存，则可能被杀死  | 
|  尽力而为  |  最低  |  限制和请求未设置  |  第一个在内存不足时被杀死  | 

有关资源 QoS 的更多信息，请参阅 [Kub](https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/) ernetes 文档。

您可以通过在命名空间上设置[资源配额](https://kubernetes.io/docs/concepts/policy/resource-quotas/)或创建[限制范围来强制使用请求和限制](https://kubernetes.io/docs/concepts/policy/limit-range/)。资源配额允许您指定分配给命名空间的资源总量，例如 CPU 和 RAM。将其应用于命名空间时，它会强制您为部署到该命名空间中的所有容器指定请求和限制。相比之下，限制范围使您可以更精细地控制资源分配。通过限制范围，您可以 min/max 限制命名空间内每个 pod 或每个容器的 CPU 和内存资源。如果未提供任何默认请求/限制值，您也可以使用它们来设置默认请求/限制值。

Policy-as-code 解决方案可以用来强制执行请求和限制。甚至可以在创建命名空间时创建资源配额和限制范围。

### 不允许权限升级
<a name="_do_not_allow_privileged_escalation"></a>

特权升级允许进程更改其运行所处的安全环境。Sudo 就是一个很好的例子，带有 SUID 或 SGID 位的二进制文件也是如此。权限升级基本上是用户以其他用户或组的权限执行文件的一种方式。您可以通过实施设置为`false`或在中设置`securityContext.allowPrivilegeEscalation`的 policy-as-code变更策略来防止容器使用特权升级。`allowPrivilegeEscalation` `podSpec` Policy-as-code 如果检测到设置不正确，也可以使用策略来防止 API 服务器请求成功。Pod 安全标准还可用于防止 Pod 使用权限升级。

### 禁用 ServiceAccount 令牌挂载
<a name="_disable_serviceaccount_token_mounts"></a>

对于不需要访问 Kubernetes API 的 Pod，你可以禁用在容器规范上自动挂载 ServiceAccount 令牌，也可以禁用所有使用特定的 Pod 的自动挂载令牌。 ServiceAccount

**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，而非默认值 “默认” 使用底层节点的 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>

使用只读根文件系统配置图像可防止攻击者覆盖应用程序使用的文件系统上的二进制文件。如果您的应用程序必须写入文件系统，请考虑写入临时目录或连接并装入一个卷。你可以通过按 SecurityContext 如下方式设置 pod 来强制执行此操作：

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

Policy-as-code 并且 Pod 安全标准可用于强制执行此行为。

**Example**  
根据 [Windows规定，`true`对于在Windows上运行的容器，Kubernetes](https://kubernetes.io/docs/concepts/windows/intro/) 中的容器`securityContext.readOnlyRootFilesystem`不能设置为，因为注册表和系统进程需要写入权限才能在容器内运行。

## 工具和资源
<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 Security Policy Migrator 是一种转换为 PSPs OPA/Gatekeeper 或 Kyverno 策略](https://appvia.github.io/psp-migration/)的工具 KubeWarden
+  [NeuVector 由 SUSE](https://www.suse.com/neuvector/) 开源提供的零信任容器安全平台提供进程和文件系统策略以及准入控制规则。