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:?truepublishNotReadyAddresses:?true#?The?service?should?only?contain?selectors?for?active?Vault?podactiveVaultPodOnly:?trueserviceType:?"NodePort"serviceNodePort:?30000externalPort:?8200targetPort:?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 Key
和Initial 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:?TqDLJkpE6NTsIyKVwjaWkaladO5B70LntD8o06x95l7ZInitial?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