在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