Kubernetes 1.21以前版本的集群中,Pod中獲取Token的形式是通過掛載ServiceAccount的Secret來獲取Token,這種方式獲得的Token是永久的。該方式在1.21及以上的版本中不再推薦使用,并且根據社區版本迭代策略,在1.25及以上版本的集群中,ServiceAccount將不會自動創建對應的Secret。
Kubernetes 1.21及以上版本的集群中,直接使用 API獲得Token,并使用投射卷(Projected Volume)掛載到Pod中。使用這種方法獲得的Token具有固定的生命周期(默認有效期為1小時),在到達有效期之前,Kubelet會刷新該Token,保證Pod始終擁有有效的Token,并且當掛載的Pod被刪除時這些Token將自動失效。該方式通過特性實現,能夠提升服務賬號(ServiceAccount)Token的安全性,Kubernetes 1.21及以上版本的集群中會默認開啟。
為了幫助用戶平滑過渡,社區默認將Token有效時間延長為1年,1年后Token失效,不具備證書reload能力的client將無法訪問APIServer,建議使用低版本Client的用戶盡快升級至高版本,否則業務將存在故障風險。
如果用戶使用版本過低的Kubernetes客戶端(Client),由于低版本Client并不具備證書輪轉能力,會存在證書輪轉失效的風險。K8s社區默認具有證書輪轉能力的Client版本如下:
- Go: >= v0.15.7
- Python: >= v12.0.0
- Java: >= v9.0.0
- Javascript: >= v0.10.3
- Ruby: master branch
- Haskell: v0.3.0.0
- C#: >= 7.0.5
官方說明請參見:
說明
如果您在業務中需要一個永不過期的Token,您也可以選擇手動管理ServiceAccount的Secret。盡管存在手動創建永久ServiceAccount Token的機制,但還是推薦使用TokenRequest的方式使用短期的Token,以提高安全性。
排查方案
CCE提供以下排查方式供用戶參考(CCE 1.21及以上版本的集群均涉及):
排查集群中使用的插件版本。
- 若用戶集群中有使用2.23.34及以下版本Prometheus 插件,則需升級至2.23.34以上版本。
- 若用戶集群中有使用1.15.0及以下版本npd插件,則需升級至最新版本。
通過kubectl連接集群,并通過kubectl get --raw "/metrics" | grep stale查詢,可以看到一個名為serviceaccount_stale_tokens_total的指標。
如果該值大于0,則表示當前集群可能存在某些負載正在使用過低的client-go版本情況,此時請您排查自己部署的應用中是否有該情況出現。如果存在,則盡快將client-go版本升級至社區指定的版本之上(至少不低于CCE集群的兩個大版本,如部署在1.23集群上的應用需要使用1.19版本以上的Kubernetes依賴庫)。

