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

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 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 管理器一起使用。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
2月前
|
Kubernetes 关系型数据库 MySQL
|
4月前
|
运维 Kubernetes 容器
【Azure K8S】演示修复因AKS密钥过期而导致创建服务不成功的问题(The provided client secret keys for app ****** are expired)
【Azure K8S】演示修复因AKS密钥过期而导致创建服务不成功的问题(The provided client secret keys for app ****** are expired)
【Azure K8S】演示修复因AKS密钥过期而导致创建服务不成功的问题(The provided client secret keys for app ****** are expired)
|
2月前
|
存储 Kubernetes 数据安全/隐私保护
k8s学习--Secret详细解释与应用
Secret 支持四种类型: - **Opaque Secrets**:存储任意类型机密数据,需自行加密。 - **Service Account Token Secrets**:自动管理 API 访问令牌。 - **Docker Registry Secrets**:存储 Docker 私有仓库认证信息。 - **TLS Secrets**:存储 TLS 证书和私钥,用于加密通信。
240 0
|
4月前
|
存储 Kubernetes 数据安全/隐私保护
k8s学习笔记之ConfigMap和Secret
k8s学习笔记之ConfigMap和Secret
|
4月前
|
存储 Kubernetes 安全
在k8S中,Secret 有哪些使用方式?
在k8S中,Secret 有哪些使用方式?
|
4月前
|
Kubernetes 数据安全/隐私保护 容器
Kubernetes(K8S) 配置管理 Secret 介绍
Kubernetes(K8S) 配置管理 Secret 介绍
55 1
|
4月前
|
Prometheus Kubernetes 数据安全/隐私保护
使用kubeseal加密和管理k8s集群的secret
使用kubeseal加密和管理k8s集群的secret
76 2
|
4月前
|
Kubernetes 容器 Perl
在K8S中,请问harbor的secret创建能否直接创建资源清单?
在K8S中,请问harbor的secret创建能否直接创建资源清单?
|
4月前
|
存储 Kubernetes 安全
在k8S中,Kubernetes Secret 作用是什么?
在k8S中,Kubernetes Secret 作用是什么?
|
7月前
|
存储 Kubernetes 数据安全/隐私保护
Kubernetes的ConfigMap和Secret
Kubernetes的ConfigMap和Secret
137 0