使用vault管理Kubernetes Secret

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用vault管理Kubernetes Secret相关的知识,希望对你有一定的参考价值。

参考技术A 我们通过vault的secret(version1 kv)backend来进行管理secret中的key/value,通过我们的 vault-agent 来动态(每隔SECRET_REFRESH_TIME秒来获取这些既定路径的secret,并写到K8S的secret中。
比如我们写入以下key/value

我们的k8s中自动创建出来的secret条目如下所示:

vault-agent基本上可以实现:

我们按照官方的学习文档来启动一个dev vault server,简单的步骤如下:
https://learn.hashicorp.com/vault/getting-started/dev-server

我们的vault访问地址为: http://192.168.31.185:8200

后面我们期待生成的secret名字为 test-app.service-secrets ,里面有 key1=value1 的内容,此secret将默认出现在所有的 namespaces 下。

在 Kubernetes 上部署 Secret 加密系统 Vault

HashiCorp Vault 是一个基于身份的 Secret 和加密管理系统。Secret 是您想要严格控制访问的内容,例如 API 加密密钥、密码或证书。Vault 提供由身份验证和授权方法控制的加密服务。使用 Vault 的 UI、CLI 或 HTTP API,可以安全地存储和管理对机密和其他敏感数据的访问、严格控制和可审计。

目前的系统需要访问大量 Secret:数据库凭据、外部服务的 API 密钥、面向服务的架构通信的凭据等。了解谁在访问哪些机密已经非常困难。如果没有自定义解决方案,几乎不可能安全存储和详细审计。这就是 Vault 的用武之地。

我们可以使用官方 HashiCorp Vault Helm Chart 将 Vault 部署到 Kubernetes 中。https://github.com/hashicorp/Vault-helm

Helm Chart 允许用户以各种配置部署 Vault:

  • Dev:用于测试 Vault 的单个内存 Vault 服务器

  • 独立(默认):单个 Vault 服务器使用文件存储后端持久保存到卷

  • 高可用性 (HA):使用 HA 存储后端(如 Consul)的 Vault 服务器集群(默认)

  • 外部:依赖于外部 Vault 服务器的 Vault Agent Injector 服务器

下面将使用 Helm 部署 Vault,以下是步骤概述:

  • 下载 Vault Helm Chart

  • 修改 values.yaml, 用 Nodeport 暴露 Vault UI Service

  • 安装 Vault

  • 避坑指南

安装

下载 Chart 包

添加仓库:

helm repo add hashicorp https://helm.releases.hashicor

搜索可用的安装包版本:

# helm search repo hashicorp/Vault -l
NAME            CHART VERSION   APP VERSION     DESCRIPTION
hashicorp/Vault 0.19.0          1.9.2           Official HashiCorp Vault Chart
........

拉取最新版本的 Chart 包到本地:

helm fetch hashicorp/Vault
tar -zxf Vault-0.19.0.tgz
cd Vault/

修改 values.yaml

编辑 values.yaml 文件,修改访问 Vault UI 的配置:

  • enable ui

  • activeVaultPodOnly的值设为true

  • serviceType 更改为 NodePort

  • serviceNodePort 端口号改为 30000

# Vault UI
ui:
  # True if you want to create a Service entry for the Vault UI.
  #
  # serviceType can be used to control the type of service created. For
  # example, setting this to "LoadBalancer" will create an external load
  # balancer (for supported K8S installations) to access the UI.
  enabled: true
  publishNotReadyAddresses: true
  # The service should only contain selectors for active Vault pod
  activeVaultPodOnly: true
  serviceType: "NodePort"
  serviceNodePort: 30000
  externalPort: 8200
  targetPort: 8200

执行安装

基于修改后的 values.yaml,执行安装命令:

helm install -f values.yaml Vault --namespace Vault . --create-namespace
或者
helm install -f values.yaml Vault hashicorp/Vault --namespace Vault --version 0.19.0  --create-namespace

检查 pod、svc 是否正常:

# k get pod -n Vault
NAME                                   READY   STATUS    RESTARTS   AGE
Vault-0                                1/1     Running   0          11m
Vault-agent-injector-f96b59db4-4855j   1/1     Running   0          11m

# k get svc -n Vault
NAME                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
Vault                      ClusterIP   10.233.61.235    <none>        8200/TCP,8201/TCP   11m
Vault-agent-injector-svc   ClusterIP   10.233.32.31     <none>        443/TCP             11m
Vault-internal             ClusterIP   None             <none>        8200/TCP,8201/TCP   11m
Vault-ui                   NodePort    10.233.145.124   <none>        8200:30000/TCP      11m

避坑指南

Vault-0 一直 NotReady,通过 get pod 命令进行查看。

$ k get pod -n Vault
NAME                                   READY   STATUS    RESTARTS   AGE
Vault-0                                0/1     Running   0          1m
Vault-agent-injector-f96b59db4-4855j   1/1     Running   0          1m

检查日志:

$ k logs -f Vault-0 -n Vault
│ 2022-05-18T03:37:03.330Z [INFO]  core: security barrier not initialized                                                                                                        │
│ 2022-05-18T03:37:03.330Z [INFO]  core: seal configuration missing, not initialized

describe 看到下面的输出:

............
   Warning  Unhealthy  2m19s (x57 over 6m41s)  kubelet            Readiness probe failed: Key                Value                                                              │
│ ---                -----                                                                                                                                                       │
│ Seal Type          shamir                                                                                                                                                      │
│ Initialized        false                                                                                                                                                       │
│ Sealed             true                                                                                                                                                        │
│ Total Shares       0                                                                                                                                                           │
│ Threshold          0                                                                                                                                                           │
│ Unseal Progress    0/0                                                                                                                                                         │
│ Unseal Nonce       n/a                                                                                                                                                         │
│ Version            1.9.2                                                                                                                                                       │
│ Storage Type       file                                                                                                                                                        │
│ HA Enabled         false

这个问题是:尚未初始化和解封 Vault。自身没有自动初始化机制,需要执行下面的操作。

参见下面的 issue:
https://github.com/hashicorp/Vault-helm/issues/17

初始化 Vault

要解封 Vault,我们需要初始化 Vault,该操作将输出一些将用于解封 Vault 的 Unseal 密钥。保存Unseal KeyInitial Root Token,下面要用到:

$ k exec -ti Vault-0 -n Vault -- Vault operator init
Unseal Key 1: 84EQZ9v8EOsboZ2sakjWkaladYg3Kc6cMSR3SaTXjlnQ
Unseal Key 2: ljJlqqERDSjWkaladIcaNlpBUOELKJtZhb9zDwzV/GiL
Unseal Key 3: Cxi+JEpUs1aDR/XcjWadM/sK+xXbIXlYjck9o/5Bifw9
Unseal Key 4: 291rLn8XMsLIOKjWka6/7dBlzfIad830g0wcgEoOUx7X
Unseal Key 5: TqDLJkpE6NTsIyKVwjaWkaladO5B70LntD8o06x95l7Z

Initial Root Token: s.mCOZiIHkRLopQsMOS1bd5ZJ
............

Vault 初始化为 5 个 Key,密钥阈值为 3。使用上面 Key 解封 Vault,需要达到阈值:

$ k exec -ti Vault-0 -n Vault -- Vault operator unseal
 $ k exec -ti Vault-0 -n Vault -- Vault operator unseal
 $ k exec -ti Vault-0 -n Vault -- Vault operator unseal

在提示符下每次粘贴不同的 Key。下面是解封 Vault 后的输出:

Unseal Key (will be hidden):
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    1/3
Unseal Nonce       9hl41a94-f15f-125d-04e5-edbd026cfc44
Version            1.9.2
Storage Type       file
HA Enabled         false

现在检查 Vault-0,应该为 READY 1/1

$ k get pod -n Vault
NAME                                   READY   STATUS    RESTARTS   AGE
Vault-0                                1/1     Running   0          11m
Vault-agent-injector-f96b59db4-4855j   1/1     Running   0          11m
登录 Vault UI

在 Nodeport 服务中配置的 30000 端口上打开 UI:
http://HostIP:30000/ui/Vault/auth?with=token

使用Token登录,需要使用到上面获得到的Initial Root Token

总结

本文实践了如何在 Kubernetes 中使用 Helm 部署 HashiCorp Vault。下面是一些常用场景:

  • 使用在 Kubernetes 中运行的 Vault 服务的应用程序可以使用不同的 secrets 引擎[1] 和 身份验证方法[2] 从 Vault 访问和存储秘密。

  • 使用在 Kubernetes 中运行的 Vault 服务的应用程序可以利用Transit 秘密引擎[3] 作为“加密即服务”。这允许应用程序在存储静态数据之前将加密需求发送到 Vault。

  • 管理员可以给 Vault 挂载持久卷,该卷可用于存储 审计日志[4]

Vault 可以直接在 Kubernetes 上运行,因此除了 Vault 本身提供的原生集成之外,为 Kubernetes 构建的任何其他工具都可以选择利用 Vault。

  • Vault on Kubernetes Reference Architecture[5]提供了在生产环境 Kubernetes 上运行 Vault 的最佳实践。

  • Vault on Kubernetes Security Considerations[6]提供了特定于在生产 Kubernetes 环境中安全运行 Vault 的建议。

参考资料

[1]

secrets 引擎: https://www.vaultproject.io/docs/secrets

[2]

身份验证方法: https://www.vaultproject.io/docs/auth

[3]

Transit 秘密引擎: https://www.vaultproject.io/docs/secrets/transit

[4]

审计日志: https://www.vaultproject.io/docs/audit

[5]

Vault on Kubernetes Reference Architecture: https://learn.hashicorp.com/tutorials/vault/kubernetes-reference-architecture?in=vault/kubernetes

[6]

Vault on Kubernetes Security Considerations: https://learn.hashicorp.com/tutorials/vault/kubernetes-security-concerns?in=vault/kubernetes

以上是关于使用vault管理Kubernetes Secret的主要内容,如果未能解决你的问题,请参考以下文章

在 Kubernetes 上部署 Secret 加密系统 Vault

运维实战 容器部分 Kubernetes存储

运维实战 容器部分 Kubernetes存储

运维实战 容器部分 Kubernetes存储

运维实战 容器部分 Kubernetes存储

当 vault 部署在专用集群上时,如何从另一个 kubernetes 集群访问 vault secret?