K8S(Kubernetes)中的Secret是一种用于保存敏感信息的资源对象,如密码、OAuth令牌、SSH密钥等。这些信息通常不应该直接暴露在Pod的规范(Spec)或镜像中,因为这样做会增加数据泄露的风险。Secret提供了一种更安全的方式来管理这些敏感信息,并允许Pod以受控的方式访问它们。
Kubernetes支持多种Secret类型,每种类型都有其特定的用途和限制。以下是一些常见的Secret类型:
Pod可以通过以下方式使用Secret:
为了安全地使用 Secret,请至少执行以下步骤:
- 为 Secret 启用静态加密。
- 以最小特权访问 Secret 并启用或配置 RBAC 规则。
- 限制 Secret 对特定容器的访问。
- 考虑使用外部 Secret 存储驱动。
通过定义以句点(.)开头的主键,你可以“隐藏”你的数据。 这些主键代表的是以句点开头的文件或“隐藏”文件。 例如,当以下 Secret 被挂载到 secret-volume 卷上时,该卷中会包含一个名为 .secret-file 的文件,并且容器 dotfile-test-container 中此文件位于路径 /etc/secret-volume/.secret-file 处。
样例:
apiVersion: v1
kind: Secret
metadata:
name: dotfile-secret
data:
.secret-file: dmFsdWUtMg0KDQo=
---
apiVersion: v1
kind: Pod
metadata:
name: secret-dotfiles-pod
spec:
volumes:
- name: secret-volume
secret:
secretName: dotfile-secret
containers:
- name: dotfile-test-container
image: registry.k8s.io/busybox
command:
- ls
- "-l"
- "/etc/secret-volume"
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
在Kubernetes(K8S)中,直接实现Secret仅对Pod中一个容器可见的功能并不是原生支持的,因为一旦Secret被挂载到Pod的某个卷上,Pod内的所有容器都可以访问这个卷。不过,我们可以通过一些设计模式和策略来模拟这种效果,尽管它们并不能完全阻止其他容器访问Secret数据(因为容器通常可以以root身份运行并访问Pod内的任何文件)。
样例:
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: YWRtaW4= # admin的base64编码
password: bXlzZWNyZXQwc3N3b3Jk= # mysecretpassword的base64编码
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: container-with-secret
image: myimage
env:
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
- name: container-without-secret
image: anotherimage
# 这个容器没有配置环境变量来访问Secret
Kubernetes 提供若干种内置的类型,用于一些常见的使用场景。 针对这些类型,Kubernetes 所执行的合法性检查操作以及对其所实施的限制各不相同。
内置类型 | 用法 |
---|---|
Opaque | 用户定义的任意数据 |
kubernetes.io/service-account-token | 服务账号令牌 |
kubernetes.io/dockercfg | ~/.dockercfg 文件的序列化形式 |
kubernetes.io/dockerconfigjson | ~/.docker/config.json 文件的序列化形式 |
kubernetes.io/basic-auth | 用于基本身份认证的凭据 |
kubernetes.io/ssh-auth | 用于 SSH 身份认证的凭据 |
kubernetes.io/tls | 用于 TLS 客户端或者服务器端的数据 |
bootstrap.kubernetes.io/token | 启动引导令牌数据 |
场景描述:
在Kubernetes集群中部署的应用程序需要访问数据库,而数据库密码是敏感信息,不应明文存储在配置文件中。
应用步骤:
kubectl create secret generic db-secret --from-literal=username=admin --from-literal=password=mysecretpassword
或者,使用YAML文件:
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: YWRtaW4= # admin的base64编码
password: bXlzZWNyZXQwc3N3b3Jk= # mysecretpassword的base64编码
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mycontainer
image: myimage
env:
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
卷挂载方式(不推荐用于密码,但可用于证书等文件):
apiVersion: v1
kind: Pod
metadata:
name: mypod-volume
spec:
containers:
- name: mycontainer
image: myimage
volumeMounts:
- name: db-secret-volume
mountPath: "/etc/secrets"
readOnly: true
volumes:
- name: db-secret-volume
secret:
secretName: db-secret
场景描述:
需要从私有Docker Registry拉取镜像到Kubernetes集群中,而Registry需要认证信息。
应用步骤:
kubectl create secret docker-registry my-registry \
--docker-server=https://index.docker.io/v1/ \
--docker-username=myusername \
--docker-password=mypassword \
--docker-[email protected]
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mycontainer
image: myprivateimage
imagePullSecrets:
- name: my-registry
场景描述:
Pod之间的通信需要加密,因此需要TLS证书和私钥。
应用步骤:
kubectl create secret tls my-tls-secret \
--cert=path/to/tls.crt \
--key=path/to/tls.key
或者,使用YAML文件:
apiVersion: v1
kind: Secret
metadata:
name: my-tls-secret
type: kubernetes.io/tls
data:
tls.crt: >
tls.key: >