Kubernetes Deployment无法获取重建ServiceAccount令牌的解决方法咨询
问题根源
当你删除并重建ServiceAccount时,Kubernetes会生成一个全新的关联Secret(包含认证token、CA证书等)。而现有Pod挂载的还是旧ServiceAccount对应的Secret,里面的凭证已经失效,所以调用K8s API时会抛出the server has asked for the client to provide credentials错误。
无需重建Deployment的解决办法
方法1:手动更新Pod的Secret挂载
获取新的ServiceAccount Secret名称
执行命令筛选出目标ServiceAccount对应的最新Secret:kubectl get secrets | grep <你的ServiceAccount名称>输出里的名称就是新生成的Secret(通常格式是
sa名称-token-xxxx)。编辑Pod更新挂载的Secret
直接编辑运行中的Pod,替换旧的Secret引用:kubectl edit pod <目标Pod名称>在编辑界面找到
spec.volumes下对应ServiceAccount的条目,把secretName的值改成刚获取的新Secret名称,保存退出。重启Pod内的应用进程
因为应用可能已经缓存了旧凭证,需要重启进程让它读取新的挂载文件:kubectl exec -it <目标Pod名称> -- <应用重启命令>比如Python应用可以用
pkill python,Java应用可以用kill -15 <进程ID>,具体根据你的应用类型调整。
方法2:直接替换Pod内的凭证文件
如果你不想修改Pod的挂载配置,可以直接把新Secret里的凭证复制到Pod的默认目录:
导出新Secret的凭证内容
分别导出token和CA证书:# 导出token并解码 kubectl get secret <新Secret名称> -o jsonpath='{.data.token}' | base64 -d > new-token # 导出CA证书并解码 kubectl get secret <新Secret名称> -o jsonpath='{.data.ca\.crt}' | base64 -d > new-ca.crt复制凭证到Pod内
把文件复制到Pod的默认ServiceAccount凭证目录:kubectl cp new-token <目标Pod名称>:/var/run/secrets/kubernetes.io/serviceaccount/token kubectl cp new-ca.crt <目标Pod名称>:/var/run/secrets/kubernetes.io/serviceaccount/ca.crt重启应用进程
同样执行应用重启命令,让应用加载新的凭证。
注意事项
- 以上两种方法都不需要重建Deployment或Pod,只是更新凭证并重启应用进程。
- 如果你的应用是无状态且可以短暂中断,也可以考虑滚动更新Deployment(但这会重建Pod,不符合你“无需重建Deployment”的要求)。
内容的提问来源于stack exchange,提问作者Sam Reynolds

