如何从Pod内部修改OpenShift环境变量自动更新Bearer token
OpenShift Pod内自动更新Bearer Token环境变量落地方案
首先明确核心误区:不要尝试直接修改运行中Pod的环境变量。运行态Pod的环境变量属于不可变字段,你在容器内执行export修改仅对当前shell会话生效,容器1号主进程读不到新值,Pod重启后所有修改全部清零,完全不满足批量、长期自动更新的需求。
前置准备
- 给运行自动更新脚本的Pod绑定专属ServiceAccount,不要用default SA。给这个SA授予目标命名空间下Deployment、DeploymentConfig资源的list、patch权限,遵循最小权限原则即可,不要直接绑定cluster-admin。
- 进Pod执行
oc auth can-i patch deployments.apps -n <你的业务命名空间>,返回yes即为权限配置正确。
方案选型
方案1:用OpenShift原生自动轮换Token(零维护成本,优先选)
OpenShift默认会给每个Pod的关联ServiceAccount自动挂载短有效期、自动轮换的Bearer Token,固定挂载路径为/var/run/secrets/kubernetes.io/serviceaccount/token,kubelet会在Token临近过期时自动更新文件内容,完全不需要人工或者脚本干预。
- 如果业务代码可以调整:直接把原来读环境变量取Token的逻辑,改成读取上述路径的文件内容即可,从根源上解决Token过期要更新的问题。
- 如果业务强制要求从环境变量读Token:在容器启动命令最前面加一行注入逻辑,服务启动前自动把最新Token读入环境变量即可,示例启动脚本:
#!/bin/bash # 注入最新Token到环境变量 export BEARER_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) # 执行业务原有启动命令 exec /path/to/your/app/start
方案2:批量更新工作负载环境变量(适配改不了业务代码、必须用固定环境变量传Token的场景)
逻辑是定时脚本从SA挂载路径拿到最新有效Token,批量patch上层工作负载(Deployment/DeploymentConfig)的环境变量模板,OpenShift会自动触发滚动更新,新拉起的Pod会自动携带最新的Token环境变量,全程无需人工介入。
脚本示例,放到容器内加cron定时每天执行一次即可:
#!/bin/bash # 按需修改配置项 TARGET_NS="your-business-namespace" # 支持deployment、deploymentconfig两种工作负载类型 WORKLOAD_KIND="deployment" TOKEN_ENV_NAME="BEARER_TOKEN" # 读取当前最新有效Token NEW_TOKEN_VALUE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) # 可通过标签筛选需要更新的工作负载,比如加-l app-tier=backend只更新后端服务 ALL_WORKLOADS=$(oc get $WORKLOAD_KIND -n $TARGET_NS -o name) for item in $ALL_WORKLOADS; do oc set env $item -n $TARGET_NS $TOKEN_ENV_NAME=$NEW_TOKEN_VALUE done
定时任务配置示例,每天凌晨1点自动执行更新:
0 1 * * * /opt/auto-update-token.sh >> /var/log/token-update.log 2>&1
常见踩坑
- 不要直接patch运行中Pod对象的env字段:OpenShift API会直接拒绝该操作,运行态Pod的env字段不支持修改,只能通过更新上层工作负载模板的方式让新Pod生效。
- 不要生成长期不失效的静态Token存到环境变量:违反OpenShift安全基线,Token泄露风险极高,优先用原生自动轮换的SA Token。
- 如果脚本执行报403权限错误,优先检查ServiceAccount绑定的Role、RoleBinding是否配置了对应资源的操作权限,不要跳过权限排查直接给过高权限。
内容的提问来源于stack exchange,提问作者Mou Sam Dahal
相关产品推荐
相关产品推荐

