在红旗Linux操作系统上运行Kubernetes集群的企业不在少数,而秘密管理一直是绕不开的难题。如果直接把数据库密码写进Deployment的环境变量,一旦镜像泄露或集群被入侵,所有凭据都会暴露。Kubernetes原生的Secret对象虽然解决了存储问题,但应用需要显式读取,而且Secret本身是静态的,无法配合Vault这类工具实现自动轮转。Vault Agent的Sidecar注入模式正是为了解决这个矛盾而设计:它向Pod中注入一个轻量级Agent容器,由Agent负责与Vault Server通信、完成认证、拉取最新秘密,并把结果渲染到指定文件。业务容器只需要读取本地文件即可,完全无感知。

要理解这套机制,先得明白它在Pod生命周期中的位置。当Kubernetes调度器创建Pod时,准入控制器会根据Pod注解中的Vault配置,自动向Pod定义里添加一个名为vault-agent的容器。这个容器启动后会运行vault agent命令,以指定的认证方式(通常是Kubernetes Service Account)登录Vault Server,然后定期拉取秘密并写入一个emptyDir卷。业务容器和vault-agent容器共享同一个卷,因此业务容器启动时可以直接从卷中读取最新凭据。如果秘密发生轮转,vault-agent会自动更新文件内容,业务容器重新加载即可拿到新凭据。
红旗Linux上部署Vault Server的要点
红旗Linux基于RPM包管理,内核和glibc版本与主流CentOS/RHEL高度兼容,因此HashiCorp官方提供的Linux amd64二进制包可以直接运行。首先要确保系统时间与NTP同步,因为Vault的令牌和租约都依赖时间戳。然后下载Vault二进制文件,解压后放到/usr/local/bin目录,并创建专用的vault用户和组,避免以root身份运行服务端。配置文件通常放在/etc/vault/vault.hcl,数据目录建议使用独立的磁盘分区,例如/var/lib/vault。
下面展示一个最小化的Vault Server配置,监听地址绑定到集群内部网络,存储后端使用本地文件模式(生产环境建议使用Consul或Raft集成存储)。注意配置文件中的路径和IP地址需要根据实际网络调整。
# /etc/vault/vault.hcl
storage "file" {
path = "/var/lib/vault/data"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = "true" # 测试环境关闭TLS,生产请启用并配置证书
}
api_addr = "http://192.168.10.20:8200"
cluster_addr = "http://192.168.10.20:8201"
ui = true
disable_mlock = false
启动服务后,需要执行vault operator init命令初始化,并妥善保存解封密钥和根令牌。红旗Linux的systemd服务单元可以参考如下写法,确保服务崩溃后自动拉起:
[Unit] Description=Vault Server After=network-online.target Wants=network-online.target [Service] User=vault Group=vault ExecStart=/usr/local/bin/vault server -config=/etc/vault/vault.hcl Restart=on-failure LimitMEMLOCK=infinity Environment=GOMAXPROCS=2 [Install] WantedBy=multi-user.target
完成初始化后,需要启用Kubernetes认证方法并创建策略。这一步允许Pod中的Service Account通过JWT令牌向Vault证明身份。在Vault CLI中执行以下命令:
vault auth enable kubernetes
vault write auth/kubernetes/config \
kubernetes_host="https://k8s-api.ipipp.com:6443" \
token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
kubernetes_ca_cert=@/etc/kubernetes/pki/ca.crt
vault policy write myapp-policy - <<EOF
path "secret/data/myapp/*" {
capabilities = ["read"]
}
EOF
这里需要把kubernetes_host替换成红旗Linux集群的API Server地址,token_reviewer_jwt通常是Vault所在节点上ServiceAccount的令牌,如果Vault部署在集群外则需要手动提供。认证配置完成后,Pod中的vault-agent才能通过ServiceAccount的JWT换取Vault令牌。
注入Sidecar的注解与模板配置细节
准备工作就绪后,就可以在业务Deployment的Pod模板上添加Vault Agent的注解。这些注解由vault-k8s注入器识别,它运行在集群中作为一个Mutating Admission Webhook。首先需要在集群中安装vault-k8s注入器,建议使用Helm Chart安装,因为红旗Linux的Kubernetes发行版通常也兼容Helm。安装时注意指定Vault Server地址和注入器镜像的拉取策略,避免镜像仓库不可达。
一个典型的Pod注解配置如下,它告诉注入器使用哪个Vault角色、拉取哪个路径的秘密、以及如何渲染到文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 1
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-inject-status: "update"
vault.hashicorp.com/role: "myapp-role"
vault.hashicorp.com/agent-inject-secret-db-creds: "secret/data/myapp/db"
vault.hashicorp.com/agent-inject-template-db-creds: |
{{- with secret "secret/data/myapp/db" -}}
export DB_USER="{{ .Data.data.username }}"
export DB_PASS="{{ .Data.data.password }}"
{{- end -}}
spec:
serviceAccountName: myapp-sa
containers:
- name: webapp
image: registry.ipipp.com/webapp:1.0
volumeMounts:
- name: vault-secrets
mountPath: /vault/secrets
注解中agent-inject-secret-db-creds定义了要拉取的秘密路径,agent-inject-template-db-creds则定义了渲染模板。模板使用Go Template语法,输出结果会写入/vault/secrets/db-creds文件。业务容器只需要source这个文件即可加载环境变量。注意VolumeMount必须挂载名为vault-secrets的emptyDir卷,否则Agent写入的文件业务容器看不到。
模板渲染支持丰富的函数,例如可以只输出密码字段、格式化JSON、甚至执行条件判断。如果秘密包含多行内容,模板中的with语句能够安全处理数据。实际使用时,强烈建议在模板中明确指定输出格式,避免把整个JSON对象写入文件,这样业务解析更简单,也减少了敏感信息意外泄露的风险。
认证角色与ServiceAccount的映射
Vault Agent注入后,会读取Pod所在的Kubernetes命名空间和ServiceAccount名称,然后根据这些信息在Vault中查找对应的角色。因此需要预先在Vault中创建角色,将ServiceAccount绑定到策略。例如,在default命名空间中运行的应用使用myapp-sa这个ServiceAccount,对应的Vault角色配置如下:
vault write auth/kubernetes/role/myapp-role \
bound_service_account_names=myapp-sa \
bound_service_account_namespaces=default \
policies=myapp-policy \
ttl=1h
这个角色只允许default命名空间下名为myapp-sa的ServiceAccount登录,并且授予的令牌只有读取secret/data/myapp/*路径的权限。如果多个应用需要不同权限,可以创建多个角色和策略。角色配置中的ttl决定令牌有效期,vault-agent会在令牌过期前自动续期,或重新认证获取新令牌,确保业务容器始终能读取最新秘密。
需要注意的是,角色名称必须与Pod注解中的vault.hashicorp.com/role完全一致。如果角色不存在或ServiceAccount不匹配,vault-agent容器会持续报错并重启,导致Pod处于CrashLoopBackOff状态。监控vault-agent容器的日志是排查问题的第一步。
常见问题与排错思路
在实际部署中,红旗Linux环境可能遇到两个典型问题:一是Vault Server地址不可达,二是Kubernetes认证配置错误导致JWT验证失败。对于第一个问题,先检查vault-agent容器日志中是否出现connection refused或timeout,然后确认Vault Server监听的地址是否在集群网络内可达,并且防火墙规则放行了8200端口。红旗Linux默认使用firewalld,需要手动添加端口放行规则。
第二个问题表现为vault-agent报错“permission denied”或“error validating token”。这通常是因为Vault中配置的kubernetes_host、CA证书或token_reviewer_jwt与实际集群不匹配。建议在Vault节点上手动执行一次kubectl命令测试ServiceAccount令牌的有效性,或者直接查看Vault Server的审计日志。另外,vault-k8s注入器版本与Vault Server版本不兼容也可能导致注入失败,应尽量保持版本一致。
如果业务容器启动时读取不到秘密文件,检查共享卷的挂载路径是否一致,以及emptyDir卷的medium是否为Memory。默认emptyDir使用磁盘,vault-agent写入文件后业务容器立即可见。若使用内存卷,需要注意内存压力导致的驱逐。总的来说,Vault Agent Sidecar注入在红旗Linux上运行稳定,只要网络、认证和卷配置正确,就能为业务提供无缝的动态秘密管理。
红旗LinuxVault AgentSidecar注入修改时间:2026-10-07 04:49:01