Skip to main content

Command Palette

Search for a command to run...

在 Kubernetes 读取 Vault 中的机密信息

Updated
3 min read

在 Kubernetes 中,我们通常会使用 Secret 对象来保存密码、证书等机密内容,然而 kubeadm 缺省部署的情况下,Secret 内容是用明文方式存储在 ETCD 数据库中的。能够轻松的用 etcdctl 工具获取到 Secret 的内容。通过修改 --encryption-provider-config 参数可以使用静态加密或者 KMS Server 的方式提高 Secret 数据的安全性,这种方式要求修改 API Server 的参数,在托管环境下可能没有那么方便,Hashicorp Vault 提供了一个变通的方式,用 Sidecar 把 Vault 中的内容加载成为业务容器中的文件。

安装和启动 Vault

官网提供了各种系统中的安装指导,例如 CentOS 中可以用包管理器来安装:

$ yum install -y yum-utils
$ yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
$ yum -y install vault
...

安装结束后,就可以启动一个开发服务器了:

$ vault server -dev -dev-root-token-id root -dev-listen-address [主机地址]:8200
...
WARNING! dev mode is enabled! In this mode, Vault runs entirely in-memory
...
You may need to set the following environment variable:

    $ export VAULT_ADDR='http://9.134.14.252:8200'

The unseal key and root token are displayed below in case you want to
seal/unseal the Vault or re-authenticate.

Unseal Key: rpn1ad4t3B4OeUFRAJWUjcmsCmCcEJFaPFjWLbs0IFM=
Root Token: root
...

上面的命令中,指定了登录 Token 为 root,监听地址为 [主机地址]:8200,返回信息中也有提示,开发服务的内容是保存在内存中的,无法适应生产环境的应用

写入测试数据

首先登陆 Vault:

$ vault login root
Success! You are now authenticated. The token information displayed below
...

然后创建测试数据:

vault kv put secret/devwebapp/config username='giraffe' password='salsa'
Key              Value
---              -----
created_time     2020-08-11T16:59:42.076636Z
deletion_time    n/a
destroyed        false
version          1

在 Kubernetes 中引入 Vault 服务

在 Kubernetes 中可以为 Vault 创建 Endpoint 和 Service,用于为集群内提供服务:

apiVersion: v1
kind: Service
metadata:
  name: external-vault
  namespace: default
spec:
  ports:
  - protocol: TCP
    port: 8200
---
apiVersion: v1
kind: Endpoints
metadata:
  name: external-vault
subsets:
  - addresses:
      - ip: [主机地址]
    ports:
      - port: 8200

这样我们就给外部的 Vault 服务创建了一个集群内的服务端点。接下来创建一个 Deployment 来测试读取数据:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: devwebapp-through-service
  labels:
    app: devwebapp-through-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: devwebapp-through-service
  template:
    metadata:
      labels:
        app: devwebapp-through-service
    spec:
      containers:
      - name: app
        image: burtlo/devwebapp-ruby:k8s
        imagePullPolicy: Always
        env:
        - name: SERVICE_PORT
          value: "8080"
        - name: VAULT_ADDR
          value: "http://external-vault:8200"

这个镜像中会使用我们预先设置的开发 Token 来访问 Vault 服务,例如:

$ kubectl exec \
    $(kubectl get pod --selector='app=devwebapp-through-service' --output='jsonpath={.items[0].metadata.name}') \
    -- curl -s localhost:8080 ; echo
{"password"=>"salsa", "username"=>"giraffe"}

安装 Vault 注入器

使用 Helm 进行安装:

$ helm repo add hashicorp https://helm.releases.hashicorp.com
"hashicorp" has been added to your repositories
$ helm install vault hashicorp/vault \
    --set "injector.externalVaultAddr=http://external-vault:8200"

这个安装器会创建 RBAC 相关内容,MutatingWebhook 以及用于执行注入的 Deployment 和 Service。

对接 Kubernetes 认证

接下来要让 Vault 接收并许可来自 Kubernetes 的请求:

# 获取 ServiceAccount 的 Token
$ VAULT_HELM_SECRET_NAME=$(kubectl get secrets --output=json | jq -r '.items[].metadata | select(.name|startswith("vault-token-")).name')

# 启用认证方式
$ vault auth enable kubernetes
Success! Enabled kubernetes auth method at: kubernetes/

# 获取 Token 内容
$ TOKEN_REVIEW_JWT=$(kubectl get secret $VAULT_HELM_SECRET_NAME --output='go-template={{ .data.token }}' | base64 --decode)

# 获取 Kubectl 的 CA 证书
$ KUBE_CA_CERT=$(kubectl config view --raw --minify --flatten --output='jsonpath={.clusters[].cluster.certificate-authority-data}' | base64 --decode)

# 获取 API Server 的地址
$ KUBE_HOST=$(kubectl config view --raw --minify --flatten --output='jsonpath={.clusters[].cluster.server}')

准备工作完成之后,就可以把这个认证配置写入 Vault:

$ vault write auth/kubernetes/config \
        token_reviewer_jwt="$TOKEN_REVIEW_JWT" \
        kubernetes_host="$KUBE_HOST" \
        kubernetes_ca_cert="$KUBE_CA_CERT"
...

编写读取策略:

$ vault policy write devwebapp - <<EOF
path "secret/data/devwebapp/config" {
  capabilities = ["read"]
}
EOF

为 Kubernetes 创建授权角色:

$ vault write auth/kubernetes/role/devweb-app \
        bound_service_account_names=internal-app \
        bound_service_account_namespaces=default \
        policies=devwebapp \
        ttl=24h

注入 Sidecar

在测试 Deployment 中加入注解:

...
spec:
  template:
    metadata:
      annotations:
        vault.hashicorp.com/agent-inject: "true"
        vault.hashicorp.com/role: "devweb-app"
        vault.hashicorp.com/agent-inject-secret-credentials.txt: "secret/data/devwebapp/config"
...

上面的注解表明,使用 devweb-app 角色,读取 secret/data/devwebapp/config 中的数据,保存到 /vault/secrets 目录的 credentials.txt 文件之中。

修改之后,等新的 Pod 启动成功。验证一下:

$ kubectl exec -it \
    $(kubectl get pod --selector='app=devwebapp' --output='jsonpath={.items[0].metadata.name}') \
    -c app -- cat /vault/secrets/credentials.txt
data: map[password:salsa username:giraffe]
metadata: map[created_time:2019-12-20T18:17:50.930264759Z deletion_time: destroyed:false version:2]

后记

这实际上是官方案例的一个翻译,另外 Vault 也提供了基于 secrets-store-csi-driver 的挂载方案供选用。

More from this blog

龙虾恐慌:AIOps 又要改名了?

ChatGPT 开始,把 AI 拉近到普罗大众的面前,让无数人感受到 AI 的亲民魅力。而龙虾,则把大模型驱动的自动化能力,突然间变得水灵灵、活泼泼地走进千家万户。它不只是“风口上的猪”,而是风口本身。热度高到让 Mac mini 一度断货,不知道这在不在库克的预料之内。 每代人都有每代人的鸡蛋,春节期间,我就领了我的鸡蛋。翻出古老的 MacBook Air M1,充值各种大模型。当然了,这个工具

Mar 9, 20261 min read

再见 2025

我猜不少人以为这个号废了吧?并没有,只是今年变化有点大,一直有种抄起键盘,无从说起的感觉,所以一直偷懒到今天,2025 的最后一天。 今年是我的第四个本命年,去年末一期播客里,大内说本命年不是灾年,是变化年,有危也有机。可是讲真啊,只看到危,没看到机。 各种因缘际会,从鹅厂跳槽到前东家,已经接近四年,第一个合同期已经进入尾声。除了前两年还在云原生领域嗷嗷叫,后两年基本都是些鸡零狗碎的东西了,用老东家的术语说是——偏离主航道,可谓是前景暗淡了。 一旦确定要滚蛋,反倒心思轻松起来,每天骑着我的小红车...

Jan 5, 20261 min read

辅助编程?dora 说:我知道你很急可是请你别急

从 OpenGPT 把大模型的火烧旺了之后,这三年来,相信很多组织或摩拳擦掌、或躬身入局,希望借助聪明能干的大模型,或想偿还技术宅,或想降本增效,或想弯道超车。一时间,沉寂许久的 AIxx 又活过来了,LLM Ops、Vibe Coding、中医大模型、GPT 算命等等,全都老树发新芽,焕发了勃勃生机。那么视角拉回从业者最关注的饭碗相关的领域之一——AI 辅助开发,产生了什么触动,应该如何拥抱呢? DORA 的年度报告中给出了很有意思的结论——强者恒强。 执行摘要部分总结了几个有趣的点: 问题...

Oct 6, 20251 min read

[译]dora:ai 辅助软件开发状态报告

执行摘要 在 2025 年,科技领导者面临的核心问题已不再是“是否要采用 AI”,而是“如何实现其价值”。 DORA 的研究基于超过 100 小时的定性访谈和来自全球近 5,000 名技术专业人士的问卷调查。研究揭示了一个关键事实:AI 在软件开发中的主要角色是“放大器”。它会放大高效能组织的优势,也会凸显组织的缺陷。 关键结论:AI 是放大器 AI 投资的最大回报并非来自工具本身,而是来自组织底层系统的战略性建设: 高质量的内部平台 清晰的工作流 团队的协同能力 缺少这些基础,AI ...

Oct 2, 202514 min read

僭越了,有人在用 Rust 写 Kubernetes

一个新语言问世,最爱做的事情之一,就是重写存量软件了。 云原生喝酒 SIG 重点扶持项目——rk8s(https://github.com/rk8s-dev/rk8s) 也可以归在这个范畴里,只不过这个项目重写的东西比较大,是 Kubernetes。 从 2025 年 1 月第一个 Commit 开始,到现在有了 200 多次 Commit,十几万行代码。当然距离 Kubernetes 的几百万行代码还差得远——老马就是喜欢整这种大无畏项目。 另外该项目也是国内第一个脱离 Cargo 转向使用 ...

Sep 27, 20253 min read

【伪】架构师

342 posts