目录
Kubernetes 中的 Secret 是一种用于存储敏感信息(如密码、令牌、密钥等)的资源对象。与直接将敏感信息写入 Pod 的配置文件中相比,Secret 提供了一种更加安全和灵活的方式来管理这些信息。官网地址:Secrets | Kubernetes
一、Secret 的用途
-
存储敏感信息:
-
用于存储应用程序需要的敏感信息,例如数据库密码、API 密钥、TLS 证书等。
-
-
提高安全性:
-
避免将敏感信息硬编码在 Pod 的定义中。
-
可以限制 Secret 的访问权限(结合 RBAC 使用)。
-
-
支持动态更新:
-
如果 Secret 被更新,挂载到 Pod 的数据也可以动态更新(适用于挂载为文件的情况)。
-
-
支持不同类型的敏感信息:
-
Kubernetes 提供了多种内置 Secret 类型,如
Opaque
、kubernetes.io/tls
、kubernetes.io/dockerconfigjson
等。
-
二、Secret 的类型
Kubernetes 支持以下几种内置的 Secret 类型:
-
Opaque(默认类型)
-
用于存储任意键值对(如密码、配置信息等)。
-
-
kubernetes.io/service-account-token
-
用于自动为 Pod 提供访问 Kubernetes API 的凭据(与 ServiceAccount 相关)。
-
-
kubernetes.io/dockerconfigjson
-
用于存储 Docker 注册表的认证信息(
~/.docker/config.json
文件的内容)。
-
-
kubernetes.io/tls
-
用于存储 TLS 证书,包括
tls.crt
和tls.key
两部分。
-
三、Secret 的创建
1. 通过 YAML 文件创建
以下是创建一个 Opaque 类型 Secret 的 YAML 示例:
apiVersion: v1 kind: Secret metadata: name: my-secret type: Opaque data: username: YWRtaW4= # Base64 编码的 "admin" password: cGFzc3dvcmQ= # Base64 编码的 "password"
将其应用到集群中:
kubectl apply -f secret.yaml
2. 通过命令行创建
使用 kubectl create secret
命令快速创建:
kubectl create secret generic my-secret \ --from-literal=username=admin \ --from-literal=password=password
查看创建的 Secret:
kubectl get secrets my-secret -o yaml
四、Secret 的使用方式
1. 挂载为环境变量
可以将 Secret 中的键值对以环境变量的形式传递给容器。
示例 Pod 定义:
apiVersion: v1 kind: Pod metadata: name: secret-env-pod spec: containers: - name: app image: busybox command: ["/bin/sh", "-c", "echo $USERNAME && echo $PASSWORD"] env: - name: USERNAME valueFrom: secretKeyRef: name: my-secret key: username - name: PASSWORD valueFrom: secretKeyRef: name: my-secret key: password
2. 挂载为文件
也可以将 Secret 挂载到容器的文件系统中。
示例 Pod 定义:
apiVersion: v1 kind: Pod metadata: name: secret-volume-pod spec: containers: - name: app image: busybox command: ["/bin/sh", "-c", "ls /etc/secret-volume && cat /etc/secret-volume/username"] volumeMounts: - name: secret-volume mountPath: /etc/secret-volume readOnly: true volumes: - name: secret-volume secret: secretName: my-secret
挂载后的文件结构:
-
/etc/secret-volume/username
:包含admin
-
/etc/secret-volume/password
:包含password
3. 使用 Docker 注册表的 Secret
创建一个用于 Docker 注册表的 Secret:
kubectl create secret docker-registry my-docker-secret \ --docker-username=<username> \ --docker-password=<password> \ --docker-server=<registry-url> \ --docker-email=<email>
在 Pod 中引用该 Secret 以拉取私有镜像:
apiVersion: v1 kind: Pod metadata: name: private-reg-pod spec: containers: - name: private-app image: <private-image> imagePullSecrets: - name: my-docker-secret
4. 用于 TLS
创建一个 TLS 类型的 Secret:
kubectl create secret tls my-tls-secret \ --cert=path/to/tls.crt \ --key=path/to/tls.key
在 Ingress 中使用:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tls-example spec: tls: - secretName: my-tls-secret rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: my-service port: number: 80
五、RBAC 与 Secret 的权限管理
使用 RBAC 控制对 Secret 的访问权限,确保只有授权的 Pod 或用户可以访问敏感信息。
示例 Role 定义:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: secret-reader rules: - apiGroups: [""] resources: ["secrets"] resourceNames: ["my-secret"] verbs: ["get"]
绑定到 ServiceAccount:
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-my-secret roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: secret-reader subjects: - kind: ServiceAccount name: my-service-account namespace: default
六、注意事项
-
Base64 编码:Secret 的数据必须是 Base64 编码的。
-
Secret数据没有进行加密,建议对敏感数据先进行对称加密然后再base64加密,之后在对应的容器中进行base64解密
-
对单个secret限制的大小为1M以内,因为过大的secret会导致kubelet内存消耗过大,同时可以通过资源限制的方式来限制过多的secret的key,导致内存过大问题