在Kubernetes中,您可以使用Secret對象來存儲敏感信息,例如密碼、OAuth令牌和ssh密鑰等。但Secret在etcd中以base64編碼格式存儲,base64編碼不等于加密。因此建議用如下方式使用Secret。
嚴格限制Secret權限
通過文件掛載的方式使用Secret時,容器內映射的文件權限默認為0644,建議為其配置更嚴格的權限,例如:
apiversion: v1
kind: Pod
metadata:
name: pod-auth
spec:
containers:
- name: mypod
image: nginx
volumeMounts:
- name: example
mountPath: "/etc/example"
volumes:
- name: example
secret:
secretName: mysecret
defaultMode: 256
其中“defaultMode: 256”,256為10進制,對應八進制的0400權限。
“隱藏”Secret文件
使用文件掛載的方式時,通過配置Secret的文件名實現文件在容器中“隱藏”的效果:
apiVersion: v1
kind: Secret
metadata:
name: mysecret-file
data:
.mysecret-file: dmFsdWUtMg0KDQo=
---
apiVersion: v1
kind: Pod
metadata:
name: mysecret-file-pod
spec:
volumes:
- name: myvolume
secret:
secretName: mysecret-file
containers:
- name: secret-container
image: nginx
command:
- ls
- "-1"
- "/etc/volume"
volumeMounts:
- name: myvolume
readOnly: true
mountPath: "/etc/volume"
這樣.mysecret-file目錄在/etc/volume/路徑下通過“ls -l”查看不到,但可以通過“ls -al”查看到。
加密Secret文件內容
用戶應在創建Secret前自行加密敏感信息,使用時再解密。
避免使用ServcieAccount Secret Token訪問集群
Kubernetes 1.21以前版本的集群中,Pod中獲取token的形式是通過掛載ServiceAccount的Secret來獲取的,這種方式獲得的token是永久的,Pod被刪除后token仍然存在Secret中,一旦泄露可能導致安全風險。該方式在1.21及以上的版本中不再推薦使用,并且根據社區版本迭代策略,在1.25及以上版本的集群中,ServiceAccount將不會自動創建對應的Secret。
Kubernetes 1.21及以上版本的集群中,直接使用TokenRequest API獲得token,并使用投射卷(Projected Volume)掛載到Pod中。使用這種方法獲得的token具有固定的生命周期(默認有效期為1小時),在到達有效期之前,Kubelet會刷新該token,保證Pod始終擁有有效的token,并且當掛載的Pod被刪除時這些token將自動失效。該方式通過Bound ServiceAccount TokenVolume特性實現,能夠提升服務賬號(ServiceAccount)token的安全性,Kubernetes 1.21及以上版本的集群中會默認開啟。
為了幫助用戶平滑過渡,社區默認將Token有效時間延長為1年,1年后token失效,不具備證書reload能力的client將無法訪問APIServer,建議使用低版本client的用戶盡快升級至高版本,否則業務將存在故障風險。
基于Secret的ServiceAccount Token由于token由于具有上述的安全風險。1.23版本以及以上版本云容器引擎集群推薦使用Bound Servcie Account Token,該方式支持設置過期時間,并且和Pod生命周期一致,可減少憑據泄露風險。例如:
apiVersion: apps/v1
kind: Deployment
metadata:
name: token-example
namespace: token-example
spec:
replicas: 1
selector:
matchLabels:
app: token-example
label: token-example
template:
metadata:
labels:
app: token-example
label: token-example
spec:
serviceAccountName: bound-sa-token
containers:
- image: nginx
imagePullPolicy: Always
name: token-example
volumes:
- name: test-security
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3600
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace