

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

# 数据加密和机密管理
<a name="data-encryption-and-secrets-management"></a>

## 静态加密
<a name="_encryption_at_rest"></a>

[https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEFS.html](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEFS.html)所有三者都使用服务托管式密钥或客户主密钥（CMK）进行静态加密。对于 EBS，您可以使用树内存储驱动程序或 [EBS](https://github.com/kubernetes-sigs/aws-ebs-csi-driver) CSI 驱动程序。两者都包含用于加密卷和提供 CMK 的参数。对于 EFS，您可以使用 [EFS CSI 驱动程序](https://github.com/kubernetes-sigs/aws-efs-csi-driver)，但是，与 EBS 不同，EFS CSI 驱动程序不支持动态配置。如果要将 EFS 与 EKS 配合使用，则需要在创建 PV 之前为文件系统配置和配置静态加密。有关 EFS 文件加密的更多信息，请参阅[加密静态数据](https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html)。除了提供静态加密外，EFS 和 f FSx or Lustre 还包括对传输中的数据进行加密的选项。 FSx for Lustre 默认会这样做。对于 EFS，您可以通过在 PV `mountOptions` 中添加`tls`参数来添加传输加密，如以下示例所示：

```
apiVersion: v1
kind: PersistentVolume
metadata:
  name: efs-pv
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: efs-sc
  mountOptions:
    - tls
  csi:
    driver: efs.csi.aws.com
    volumeHandle: <file_system_id>
```

[FSx CSI 驱动程序](https://github.com/kubernetes-sigs/aws-fsx-csi-driver)支持 Lustre 文件系统的动态配置。默认情况下，它使用服务托管密钥对数据进行加密，但可以选择提供您自己的 CMK，如以下示例所示：

```
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: fsx-sc
provisioner: fsx.csi.aws.com
parameters:
  subnetId: subnet-056da83524edbe641
  securityGroupIds: sg-086f61ea73388fb6b
  deploymentType: PERSISTENT_1
  kmsKeyId: <kms_arn>
```

**重要**  
自 2020 年 5 月 28 日起，写入 EKS Fargate 容器中临时卷的所有数据都默认使用行业标准的 AES-256 加密算法进行加密。由于加密和解密由该服务无缝处理，因此无需对应用程序进行任何修改。

### 加密静态数据
<a name="_encrypt_data_at_rest"></a>

加密静态数据被认为是一种最佳做法。如果您不确定是否需要加密，请加密您的数据。

### CMKs 定期轮换
<a name="_rotate_your_cmks_periodically"></a>

将 KMS 配置为自动轮换 CMKs。这将每年轮换一次您的密钥，同时无限期地保存旧密钥，这样您的数据仍然可以被解密。有关更多信息，请参阅[轮换客户主密钥](https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html) 

### 使用 EFS 接入点简化对共享数据集的访问
<a name="_use_efs_access_points_to_simplify_access_to_shared_datasets"></a>

如果您共享了具有不同 POSIX 文件权限的数据集，或者想要通过创建不同的挂载点来限制对部分共享文件系统的访问，请考虑使用 EFS 接入点。要了解有关使用接入点的更多信息，请参阅 https://docs.aws.amazon.com/efs/ latest/ug/efs-access-points.html。如今，如果您想使用接入点 (AP)，则需要在 PV 的`volumeHandle`参数中引用 AP。

**重要**  
自 2021 年 3 月 23 日起，EFS CSI 驱动程序支持动态配置 EFS 接入点。接入点是 EFS 文件系统中特定于应用程序的入口点，可以更轻松地在多个 pod 之间共享文件系统。每个 EFS 文件系统最多可以有 120 个 PVs。有关更多信息，请参阅 [Amazon EFS CSI 动态配置简介](https://aws.amazon.com/blogs/containers/introducing-efs-csi-dynamic-provisioning/)。

## 密钥管理
<a name="_secrets_management"></a>

Kubernetes 密钥用于存储敏感信息，例如用户证书、密码或 API 密钥。它们作为 base64 编码的字符串保存在 etcd 中。在 EKS 上，etcd 节点的 EBS 卷使用 [E](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html) BS 加密进行加密。Pod 可以通过引用中的密钥来检索 Kubernetes 机密对象。`podSpec`这些密钥可以映射到环境变量，也可以作为卷挂载。有关创建密钥的更多信息，请参阅 https://kubernetes。 io/docs/concepts/configuration/secret/。

**警告**  
特定命名空间中的密钥可以被该密钥命名空间中的所有 pod 引用。

**警告**  
节点授权器允许 Kubelet 读取挂载到节点上的所有密钥。

### 使用 AWS KMS 对 Kubernetes 机密进行信封加密
<a name="_use_aws_kms_for_envelope_encryption_of_kubernetes_secrets"></a>

这允许您使用唯一的数据加密密钥 (DEK) 加密您的机密。然后，使用来自 AWS KMS 的密钥加密密钥 (KEK) 对 DEK 进行加密，该密钥可以定期自动轮换。使用适用于 Kubernetes 的 KMS 插件，所有 Kubernetes 机密都以密文而不是纯文本形式存储在 etcd 中，并且只能由 Kubernetes API 服务器解密。有关更多详细信息，请参阅[使用 EKS 加密提供商支持进行深入防御](https://aws.amazon.com/blogs/containers/using-eks-encryption-provider-support-for-defense-in-depth/) 

### 审计 Kubernetes 密钥的使用情况
<a name="_audit_the_use_of_kubernetes_secrets"></a>

在 EKS 上，打开审核日志并创建 CloudWatch 指标筛选器和警报，以便在使用密钥时提醒您（可选）。以下是 Kubernetes 审计日志的指标筛选器的示例。`{($.verb="get") && ($.objectRef.resource="secret")}`您还可以在 CloudWatch Log Insights 中使用以下查询：

```
fields @timestamp, @message
| sort @timestamp desc
| limit 100
| stats count(*) by objectRef.name as secret
| filter verb="get" and objectRef.resource="secrets"
```

上面的查询将显示在特定时间范围内访问密钥的次数。

```
fields @timestamp, @message
| sort @timestamp desc
| limit 100
| filter verb="get" and objectRef.resource="secrets"
| display objectRef.namespace, objectRef.name, user.username, responseStatus.code
```

此查询将显示密钥，以及尝试访问该密钥的用户的命名空间和用户名以及响应代码。

### 定期轮换你的秘密
<a name="_rotate_your_secrets_periodically"></a>

Kubernetes 不会自动轮换密钥。如果您必须轮换密钥，请考虑使用外部密钥存储库，例如 Vault 或 AWS Secrets Manager。

### 使用单独的命名空间来隔离来自不同应用程序的机密
<a name="_use_separate_namespaces_as_a_way_to_isolate_secrets_from_different_applications"></a>

如果您的密钥无法在命名空间中的应用程序之间共享，请为这些应用程序创建一个单独的命名空间。

### 使用卷装载而不是环境变量
<a name="_use_volume_mounts_instead_of_environment_variables"></a>

环境变量的值可能会无意中出现在日志中。作为卷挂载的密钥会被实例化为 tmpfs 卷（支持 RAM 的文件系统），这些卷将在删除 Pod 时自动从节点中删除。

### 使用外部密钥提供者
<a name="_use_an_external_secrets_provider"></a>

[除了使用 Kubernetes 机密之外，还有几种可行的替代方案，包括 [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) 和 Hashicorp 的 Vault。](https://www.hashicorp.com/blog/injecting-vault-secrets-into-kubernetes-pods-via-a-sidecar/)这些服务提供了 Kubernetes Secrets 所不具备的精细访问控制、强加密和自动轮换机密等功能。Bitnami的[密封机密](https://github.com/bitnami-labs/sealed-secrets)是另一种使用非对称加密来创建 “密封机密” 的方法。公钥用于加密密钥，而用于解密密密钥的私钥则保存在集群中，这样您就可以将密封的机密安全地存储在源代码控制系统（如 Git）中。有关更多信息，请参阅[使用密封密钥在 Kubernetes 中管理密钥部署](https://aws.amazon.com/blogs/opensource/managing-secrets-deployment-in-kubernetes-using-sealed-secrets/)。

随着外部密钥存储库的使用越来越多，将它们与 Kubernetes 集成的需求也随之增加。S [ecret Store CSI 驱动程序](https://github.com/kubernetes-sigs/secrets-store-csi-driver)是一个社区项目，它使用 CSI 驱动程序模型从外部秘密存储库中获取机密。目前，该驱动程序支持 [AWS Secrets Manager](https://github.com/aws/secrets-store-csi-driver-provider-aws)、Azure、Vault 和 GCP。AWS 提供商同时支持 AWS Secrets Manager **和** AWS Parameter Store。它还可以配置为在密钥过期时轮换密钥，并且可以将 AWS Secrets Manager 密钥同步到 Kubernetes 密钥。当您需要将密钥作为环境变量引用而不是从卷中读取密钥时，同步密钥会很有用。

**注意**  
当密钥存储库 CSI 驱动程序必须获取密钥时，它会假设分配给引用密钥的 pod 的 IRSA 角色。此操作的代码可以[在这里](https://github.com/aws/secrets-store-csi-driver-provider-aws/blob/main/auth/auth.go)找到。

有关 AWS 机密和配置提供商 (ASCP) 的更多信息，请参阅以下资源：
+  [如何将 AWS 密钥配置提供程序与 Kubernetes 密钥存储 CSI 驱动程序配合使用](https://aws.amazon.com/blogs/security/how-to-use-aws-secrets-configuration-provider-with-kubernetes-secrets-store-csi-driver/) 
+  [将 Secrets Manager 机密与 Kubernetes 密钥商店 CSI 驱动程序集成](https://docs.aws.amazon.com/secretsmanager/latest/userguide/integrating_csi_driver.html) 

 [外部机密](https://github.com/external-secrets/external-secrets)是在 Kubernetes 中使用外部密钥存储的另一种方式。与 CSI 驱动程序一样，外部机密适用于各种不同的后端，包括 AWS Secrets Manager。不同之处在于，外部机密不是从外部密钥存储中检索机密，而是将这些后端的机密作为机密复制到 Kubernetes。这使您可以使用首选的密钥存储库管理密钥，并以 Kubernetes 原生方式与密钥进行交互。

## 工具和资源
<a name="_tools_and_resources"></a>
+  [Amazon EKS 安全沉浸式研讨会-数据加密和机密管理](https://catalog.workshops.aws/eks-security-immersionday/en-US/13-data-encryption-and-secret-management) 