当前位置: 技术文章>> 如何在生产环境中将 Vault 与 Kubernetes 的外部密钥一起使用?

文章标题:如何在生产环境中将 Vault 与 Kubernetes 的外部密钥一起使用?
  • 文章分类: 后端
  • 19235 阅读

今天,我们将讨论如何优化 Kubernetes 中存储机密的流程,并学习授权我们的开发人员查看/修改部署在 Kubernetes 集群中的机密。我们还将根据开发人员所属的 GitHub 团队将访问权限委托给他们。

因此,让我问你一个基本问题,如何在 K8s 集群中存储密钥?

如果您回答说您使用的是普通的 base64 编码清单文件并手动管理它们,则:

当前方法中的问题

不容易可见 - 没有 GUI 来轻松管理机密

无版本控制

如果您想与开发人员共享,则需要将 K8s 凭据公开给他们。(不过,您可以为它们创建和设置适当的 RBAC 权限,但在某些用例中不能使用)

不支持任何第三方身份验证,例如 - 使用 GitHub Team/Org 授予开发人员预定义的访问级别。

简单解决方案 - 将 Vault 与外部机密一起使用

是的,你没听错,一旦设置好了,将访问权限委派给用户将是一件轻而易举的:)

第1季第3集 GIF by BET Plus

我们的行动项目

安装 External Secrets Operator

安装保管库

将 Vault 配置为允许使用 GitHub PAT 登录

为外部密钥配置保管库身份验证

配置外部密钥以从保管库创建密钥

在 Vault 中创建一个示例密钥,并查看该密钥是在 K8s 中创建的

安装 External Secrets Operator

https://external-secrets.io/latest/introduction/overview/

它有三个组件 - 外部机密控制器、Webhook 和证书控制器

您可以使用 Helm 快速安装外部机密!

https://external-secrets.io/latest/introduction/getting-started/

values.yaml

#? count of the controller pods for HA

replicaCount: 3

#? enable/disable the leader election - at any time, only one active controller is recommended

leaderElect: true

#? how many secrets to update concurrently

concurrent: 3

#? PDB configuration - helpful when doing maintenance tasks

podDisruptionBudget:

  enabled: true

  minAvailable: 1

#? Recommended - Exposes metrics!

serviceMonitor:

  enabled: true

webhook:

  serviceMonitor:

    enabled: true

certController:

  serviceMonitor:

    enabled: true

helm repo add external-secrets https://charts.external-secrets.io

helm upgrade --install external-secrets external-secrets/external-secrets -f values.yaml -n external-secrets --create-namespace

部署后,它将如下所示:

注 - 您可以看到三个部署,但由于我们启用了其中只有一个将处于活动状态并保留租约,其他副本将等待主副本关闭,然后其中一个备用副本将成为领导者。是不是很酷?external-secretsleaderElect

奖金!- 更多关于K8s领导人选举的信息:https://carlosbecker.com/posts/k8s-leader-election/

安装保管库

加工

Vault的内部工作非常有趣,用几句话总结起来有点复杂,我们需要另一个博客来更详细地解释它。如果您完全一无所知,那么您可以在此处阅读有关此内容的更多信息:

https://developer.hashicorp.com/vault/docs/what-is-vault#what-is-vault-1

https://developer.hashicorp.com/vault/docs/internals/architecture

要安装 Vault,我们将使用 Banzaicloud 的 Vault Operator,又名 Bank Vaults!

为了在 Kubernetes 环境中部署任何东西并确保其可靠性和可用性,Operator 正在成为事实上的标准。

您知道吗:Kubernetes Operator 是一个特定于应用程序的控制器,它扩展了 Kubernetes API 的功能,以代表 Kubernetes 用户创建、配置和管理复杂应用程序的实例。

在这里查看更多: https://operatorframework.io/what/

使用 Helm 安装 vault-operator

helm repo add banzaicloud-stable https://kubernetes-charts.banzaicloud.com

helm repo update

helm upgrade --install vault-operator banzaicloud-stable/vault-operator -n vault-operator

设置 RBAC

rbac.yaml- 需要应用它来为我们的设置提供所需的 RBAC 访问权限。

 kubectl apply -f vault/rbac.yml -n vault-operator

解释-在这里,我们正在创建一个 Secret vault-sa-token-manual,它将保存名为 vault 的 ServiceAccount 的 Kubernetes 访问令牌(在 Kubernetes v1.24 之前,我们不必手动创建密钥,请参阅 - stackoverflow.com/a/72258300)。此 ServiceAccount 有权读取/更新 Pod 以及对机密的所有访问权限。

注 - 您还可以通过仅添加必需的谓词/资源名称/命名空间来微调访问。

另外,您是否注意到我们正在绑定一个名为 ServiceAccount 的默认值?来自官方文档 - 允许委派身份验证和授权检查。ClusterRole 具有调用 Token Review API 的权限。ClusterRolesystem:auth-delegatorVaultsystem:auth-delegator

Christian Bale GIF by PeacockTV

使用 CRD 部署 Vault

现在,由于我们已经使用 Vault Operator 为集群提供支持,因此我们可以使用简单的 YAML 文件部署 Vault。

vault-deploy.yaml

身份验证和授权

在这里,我们使用 GitHub 身份验证后端对用户进行身份验证。他们的访问级别由他们所属的 GitHub 团队定义。

例如,我的帐户 (k4kratik) 被分配了 admin policy 。同样,我在我的组织中创建了一个 GitHub 团队,该团队将授予其成员在策略中定义的访问权限,并且还为开发人员创建了一个团队,我只想为其配置只读访问权限,该团队将被分配 .vault_adminDEVS_RWrw_access_policyDEVS_ROro_access_policy

以上可视化如下:

配置文件说明:

#1 行到 #102 行,我认为这几乎是不言自明的。让我们从第 #106 行开始。(externalConfig 开始的位置)

externalConfig.policies

就像任何其他设置一样,我们在这里定义 IAM 策略,这些策略将分配给用户/团队。

ro_access_policy:仅权限。read

rw_access_policy:RW 权限。[“读取”, “列表”, “更新”]

vault_admin:仅使用动词定义并不能授予所有权限。因此,我们已显式定义了所有管理员级别的访问权限。*

为什么?: 更多信息 : https://discuss.hashicorp.com/t/vault-admin-policy/39803/2

管理员所需的访问权限:https://developer.hashicorp.com/vault/tutorials/policies/policies#write-a-policy

externalConfig.auth:kubernetes

type:当我们将其设置为在 Kubernetes 上运行时,它的值应该是external-secretskubernetes

path:保管库中此身份验证条目的标识符。

config

token_reviewer_jwt:ServiceAccount 的 JWT Token,因为它具有角色,可以帮助我们使用 K8s 的 API 来验证其他 JWT。若要获取其值,请运行以下命令,如博客前面部分所示,我们已经设置了所需的 RBAC。vaultsystem:auth-delegatorTokenReview

命令(此命令并替换为TOKEN_REVIEWER_JWT_TOKEN_HERE )

  kubectl get secret vault-sa-token-manual -n vault-operator -o go-template='{{.data.token}}' | base64 --decode

kubernetes_ca_cert:PEM 编码的 CA 证书,供用于与 Kubernetes API 通信的 TLS 客户端使用。

命令

  kubectl get secret vault-sa-token-manual -n vault-operator -o go-template='{{index .data "ca.crt"}}' | base64 --decode

kubernetes_host:的端点。确保可从 Vault Pod 访问它。Kubernetes API server

  kubectl config view --minify --output jsonpath="{.clusters[*].cluster.server}"

disable_issuer_verification: - 禁用颁发者验证。true

roles - 定义附加到此身份验证机制的角色

name:角色的名称

bound_service_account_names: - 我们只想允许外部机密 SA,所以只添加它。["external-secrets"]

bound_service_account_namespaces ["external-secrets"]- 我们只想允许外部机密命名空间,所以只添加它。

token_policies:-重要!- 要附加的策略的名称,我们的外部密钥只需要读取访问权限即可读取密钥。ro_access_policy

token_max_ttl:令牌到期时间。

外部配置.auth:github

type:由于我们正在通过 GitHub 设置身份验证,因此其值应为github

path:保管库中此身份验证条目的标识符。

config

organization:您的 GitHub 组织的名称。(用这个替换GITHUB_ORGANIZATION_NAME_HERE)

注意!- 您必须是此组织的一员,否则您将无法登录,并且您将收到以下错误:Configuration is not set!

token_ttl:生成的令牌的生存期。

map(GitHub 的映射)

teams(映射具有保管库策略的 GitHub Teams)

格式:

TEAM_NAME : POLICY_NAME

例如

DEV_RW:rw_access_policy

DEV_RO:ro_access_policy

users(使用 Vault 策略的 GitHub 用户的映射)

例如:k4kratikvault_admin

externalConfig.secrets

path: - Vault 将挂载此秘密引擎的路径。secret

type: - 秘密引擎类型:键/值kv

options:

version: 2 (推荐)

startupSecrets(启动密钥)

测试密钥,将在启动时创建。

审计

审核设备是保险柜中的组件,它们共同保留对保险柜的所有请求的详细日志。

文件审计设备将审计日志写入文件。https://developer.hashicorp.com/vault/docs/audit/file#configuration

部署 Vault

kubectl apply -f vault/vault-deploy.yml

它将部署 Pod,如下所示:

登录到 Vault UI

让我们公开用于登录的Vault UI

  kubectl port-forward svc/vault -n vault-operator 8200:8200

您将受到以下屏幕的欢迎:

使用 GitHub PAT(个人访问令牌)登录

生成至少具有权限的 GitHub PAT(指南在这里read:org)

我们将使用该 PAT 登录 Vault

注意 - 记住我们创建的身份验证策略,根据我们的 GitHub 用户名、组织或团队,我们将获得相关访问权限。

检查引擎,你会发现我们的测试秘诀:secretTEST_PROJECT_ONE/test

使用 Root Token 登录 [不推荐]

获取根令牌

  kubectl get secrets vault-unseal-keys -o jsonpath={.data.vault-root} | base64 --decode

使用此令牌登录,如下所示

检查我们配置的内容:

检查我们定义的身份验证 - 'github''k8s-one'

让我们检查一下 auth 方法,我们的角色是否存在k8s-onek8s-one-external-secrets-role

这总结了基本的保管库身份验证和授权设置 + 外部机密。

Jimmy Fallon GIF by The Tonight Show Starring Jimmy Fallon

但要抱住你的马!我们仍然需要使用外部密钥从 Vault 创建密钥。如果博客看起来太长,我们深表歉意,但相信我,最终这一切都是值得的。

Season 1 GIF by Showtime

设置外部机密

外部机密有两种重要的对象类型

SecretStore(或) - 它定义如何访问外部 API 密钥提供程序。(例如 Vault、AWS Secrets Manager)ClusterSecretStore

ExternalSecret(or ) - 它描述了应该获取哪些数据,应该如何转换数据并将其保存为 K8s 。ClusterExternalSecretSecret

让我们创建一个群集范围的密钥存储,以将其与保管库连接。

  kubectl apply -f external-secrets/secret-store.yml

它如下所示

在创建 之前,让我们在 Vault 中创建一些测试密钥ExternalSecret

现在,让我们创建一个 to use our 并使用它创建一个 k8s 密钥。ExternalSecretClusterSecretStore

sample-external-secret.yaml (GitHub的)

  k apply -f external-secrets/sample-external-secret.yaml

让我们通过检查密钥来验证它

瞧!我们可以看到我们的秘密被创建了,我们也可以看到我们在 Vault 中的值经历了


推荐文章