Kubernetes 的 secret 并不是真正的 secret(上)

简介: Kubernetes 的 secret 并不是真正的 secret

引言

Kubernetes 已经成为现代软件基础设施中不可或缺的一部分。因此,管理 Kubernetes 上的敏感数据也是现代软件工程的一个重要方面,这样您就可以将安全性重新置于 DevSecOps 中。Kubernetes 提供了一种使用 Secret 对象存储敏感数据的方法。虽然总比没有好,但它并不是真正的加密,因为它只是 base64 编码的字符串,任何有权访问集群或代码的人都可以对其进行解码。

注意:默认情况下,Kubernetes Secrets 未加密存储在 API 服务器的底层数据存储 (etcd) 中。具有 API 访问权限的任何人都可以检索或修改 Secret,任何具有 etcd 访问权限的人也可以。此外,任何有权在命名空间中创建 Pod 的人都可以使用该访问权限来读取该命名空间中的任何 Secret;这包括间接访问,例如创建 Deployment 的能力。— Kubernetes 文档

使用正确的 RBAC 配置和保护 API 服务器可以解决从集群读取 secret 的问题,了解有关 RBAC 和集群 API 安全性的更多信息请查看如何使用最佳实践保护您的 Kubernetes 集群。保护源代码中的的 secret 是更大的问题。每个有权访问包含这些 secret 的存储库的人也可以解码它们。这使得在 Git 中管理 Kubernetes secret 变得非常棘手。

让我们看看如何使用更安全的方式设置 secret :

  • Sealed Secrets
  • External Secrets Operator
  • Secrets Store CSI driver

您需要一个 Kubernetes 集群来运行示例。我使用 k3d 创建了一个本地集群。您也可以使用 kind 或 minikube 。


Sealed Secrets

Sealed Secrets 是一个开源的 Kubernetes 控制器和来自 Bitnami 的客户端 CLI 工具,旨在使用非对称密码加密解决“在 Git 中存储 secret ”问题的一部分。具有 RBAC 配置的 Sealed Secrets 防止非管理员读取 secret 是解决整个问题的绝佳解决方案。

Sealed Secrets

它的工作原理如下:

  1. 使用公钥和 kubeseal CLI 在开发人员机器上加密 secret 。这会将加密的 secret 编码为 Kubernetes 自定义资源定义 (CRD)。
  2. 将 CRD 部署到目标集群。
  3. Sealed Secret 控制器使用目标集群上的私钥对机密进行解密,以生成标准的 Kubernetes secret。

私钥仅供集群上的 Sealed Secrets 控制器使用,公钥可供开发人员使用。这样,只有集群才能解密机密,而开发人员只能对其进行加密。

优点

  • 支持模板定义,以便可以将元数据添加到未加密的 secret 中。例如,您可以使用模板定义为未加密的 secret 添加标签和注释。
  • 未加密的 secret 将由加密的 secret CRD 拥有,并在加密的 secret 更新时更新。
  • 默认情况下,证书每 30 天轮换一次,并且可以自定义。
  • secret 使用每个集群、命名空间和 secret 组合(私钥+命名空间名称+ secret 名称)的唯一密钥进行加密,防止解密中出现任何漏洞。在加密过程中,可以使用 strict, namespace-wide, cluster-wide 来配置范围。
  • 可用于管理集群中的现有 secret。
  • 具有 VSCode 扩展,使其更易于使用。

缺点

  • 由于它将加密的 secret 解密为常规 secret ,如果您有权访问集群和命名空间,您仍然可以解码它们。
  • 需要为每个集群环境重新加密,因为密钥对对于每个集群都是唯一的。

安装

在集群上安装 controller,在本地机器上安装 CLI。

  1. 从 release 页面下载 controller.yaml
  2. 执行 kubectl apply -f controller.yaml 将 controller 部署到集群中。控制器将安装到 kube-system 命名空间下。
  3. 安装 CLI,通过 brew install kubeseal 安装,或者从 release 页面下载。

使用

让我们创建一个 sealed secret 。

  1. 创建一个 secret,通过命令 kubectl create secret 或者编写 yaml 文件,如下所示:
echo -n secretvalue | kubectl create secret generic mysecret \
  --dry-run=client \
  --from-file=foo=/dev/stdin -o yaml > my-secret.yaml

这将产生一个如下所示的 secret 定义;

# my-secret.yaml
apiVersion: v1
data:
  foo: c2VjcmV0dmFsdWU=
kind: Secret
metadata:
  creationTimestamp: null
  name: mysecret
  1. 使用 kubeseal CLI 加密 secret。这将使用从服务器获取的公钥加密 secret 并生成加密的 secret 定义。现在可以丢弃 my-secret.yaml 文件。您也可以下载公钥并在本地离线使用。
kubeseal --format yaml < my-secret.yaml > my-sealed-secret.yaml

这将产生一个加密的 secret 定义,my-sealed-secret.yaml,如下所示;

# my-sealed-secret.yaml
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  creationTimestamp: null
  name: mysecret
  namespace: default
spec:
  encryptedData:
    foo: AgA6a4AGzd7qzR8mTPqTPFNor8tTtT5...==
  template:
    metadata:
      creationTimestamp: null
      name: mysecret
      namespace: default

此文件可以安全地提交到 Git 或与其他开发人员共享。

  1. 最后,您可以将其部署到要解封的集群中。
kubectl apply -f my-sealed-secret.yaml
  1. 现在,您可以在集群中看到未加密的 secret 。
kubectl describe secret mysecret

您可以像使用任何其他 Kubernetes 密钥一样在部署中使用此密钥。


External Secrets Operator

Sealed Secrets 是保护 secret 的方式之一,但除此之外还有更好的方法。使用 External Secrets Operator (ESO) 和外部 secret 管理系统,如 HashiCorp Vault、AWS Secrets Manager、Google Secrets Manager 或 Azure Key Vault。虽然设置起来有点复杂,但如果您使用云提供商来托管您的 Kubernetes 集群,这是一种更好的方法。ESO 支持许多这样的 secret 管理器并监视外部 secret 存储的变化,并使 Kubernetes secret 保持同步。

ESO

ESO 提供了四个 CRD 来管理 secret。ExternalSecretClusterExternalSecret CRD 定义需要获取哪些数据以及如何转换这些数据。SecretStoreClusterSecretStore CRD 定义了与外部 secret 存储的连接细节。Cluster 前缀的 CRD 表示作用范围是集群。

它的工作原理如下;

  1. 创建 SecretStoreCRD 以定义与外部机密存储的连接详细信息。
  2. 在外部 secret 存储中创建 secret 。
  3. 创建一个 ExternalSecretCRD 来定义需要从外部 secret 存储中获取的数据。
  4. 将 CRD 部署到目标集群。
  5. ESO 控制器将从外部 secret 存储中获取数据并创建 Kubernetes secret 。

优点

  • secret 存储在安全的外部 secret 管理器中,而不是代码存储库中。
  • 使 secret 与外部 secret 管理器保持同步。
  • 与许多外部 secret 管理者合作。
  • 可以在同一个集群中使用多个 secret 存储。
  • 提供用于监控的 Prometheus 指标。

缺点

  • 需要精心设置才能使用。
  • 创建一个 Kubernetes secret 对象,如果您有权访问集群和命名空间,则可以对其进行解码。
  • 依靠外部 secret 管理器及其访问策略来确保安全。

安装

可以使用以下命令通过 Helm 安装 ESO :

helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets \
  external-secrets/external-secrets \
  --namespace external-secrets \
  --create-namespace

如果您想在 Helm release 中包含 ESO,请将 --set installCRDs=true 标志添加到上述命令中。

让我们看看如何将 ESO 与不同的 secret 管理器一起使用。

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
目录
相关文章
|
11天前
|
存储 Kubernetes 数据安全/隐私保护
k8s学习-Secret(创建、使用、更新、删除等)
k8s学习-Secret(创建、使用、更新、删除等)
227 0
|
11天前
|
存储 Kubernetes 数据安全/隐私保护
Kubernetes的ConfigMap和Secret
Kubernetes的ConfigMap和Secret
45 0
|
9月前
|
存储 Kubernetes 数据安全/隐私保护
k8s--配置存储 ConfigMap、Secret
k8s--配置存储 ConfigMap、Secret
|
11天前
|
Kubernetes 数据安全/隐私保护 Docker
云原生|kubernetes|关于secret的一些使用
云原生|kubernetes|关于secret的一些使用
76 0
|
11天前
|
Kubernetes 容器
k8s学习-CKS真题-secret创建、使用
k8s学习-CKS真题-secret创建、使用
52 0
|
8月前
|
存储 Kubernetes API
Kubernetes 的 secret 并不是真正的 secret(下)
Kubernetes 的 secret 并不是真正的 secret
92 0
|
10月前
|
存储 Kubernetes 安全
【k8s 系列】k8s 学习二十三-2,ConfigMap 补充 和 Secret
对于上一篇文章我们分享了为什么要使用 ConfigMap ,我们创建 ConfigMap 的时候可以传入单个或者多个键值对,也可以传入文件,还分享了如何简单的传入 ConfigMap 里面的数据作为环境变量
|
存储 JSON 缓存
kubernetes secret使用详解(2)
kubernetes secret使用详解(2)
|
Kubernetes Shell API
kubernetes secret使用详解(1)
kubernetes secret使用详解(1)
kubernetes secret使用详解(1)
|
Kubernetes Cloud Native 应用服务中间件
云原生|kubernetes|关于secret的一些使用(二)
云原生|kubernetes|关于secret的一些使用
118 0