avatar🌌
TangentTangent Blog

技术博客 | Go & Kubernetes & Linux

技术博客 | Go & Kubernetes & Linux

Kubernetes Secret 详解

什么是 Secret ​

Secret 是 Kubernetes 中用于存储和管理敏感信息的对象,如密码、OAuth 令牌、SSH 密钥等。与 ConfigMap 不同,Secret 专门设计用于处理机密数据,提供了额外的安全保护。

Secret 的主要特性 ​

1. 安全性 ​

  • Base64 编码:数据以 Base64 编码存储(注意:这不是加密)
  • 内存存储:在节点上以 tmpfs 形式存储,不写入磁盘
  • 访问控制:通过 RBAC 控制访问权限
  • 静态加密:支持 etcd 静态数据加密

2. 大小限制 ​

  • 单个 Secret 最大 1MB
  • 建议保持较小的 Secret 大小以提高性能

3. 作用域 ​

  • 命名空间级别的资源
  • 只能在同一命名空间内的 Pod 中使用

Secret 的分类 ​

1. Opaque(通用 Secret) ​

最常用的 Secret 类型,用于存储任意的用户定义数据。

yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=     # admin 的 base64 编码
  password: MWYyZDFlMmU2N2Rm  # 1f2d1e2e67df 的 base64 编码

可以通过Linux的 base64 命令进行编码:

bash
echo -n "admin" | base64
echo -n "1f2d1e2e67df" | base64

2. kubernetes.io/service-account-token ​

用于 ServiceAccount 的身份验证令牌。

yaml
apiVersion: v1
kind: Secret
metadata:
  name: sa-token
  annotations:
    kubernetes.io/service-account.name: my-service-account
type: kubernetes.io/service-account-token
data:
  token: <base64-encoded-token>
  ca.crt: <base64-encoded-ca-certificate>

3. kubernetes.io/dockercfg 和 kubernetes.io/dockerconfigjson ​

用于存储 Docker 仓库的认证信息。

yaml
apiVersion: v1
kind: Secret
metadata:
  name: docker-secret
type: kubernetes.io/dockercfg
data:
  .dockercfg: <base64-encoded-dockercfg>

apiVersion: v1
kind: Secret
metadata:
  name: docker-secret
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: <base64-encoded-docker-config>

4. kubernetes.io/basic-auth ​

用于基本身份验证。

yaml
apiVersion: v1
kind: Secret
metadata:
  name: basic-auth-secret
type: kubernetes.io/basic-auth
data:
  username: YWRtaW4=
  password: dGVzdA==

5. kubernetes.io/ssh-auth ​

用于 SSH 身份验证。

yaml
apiVersion: v1
kind: Secret
metadata:
  name: ssh-secret
type: kubernetes.io/ssh-auth
data:
  ssh-privatekey: <base64-encoded-ssh-private-key>

6. kubernetes.io/tls ​

用于存储 TLS 证书和私钥。

yaml
apiVersion: v1
kind: Secret
metadata:
  name: tls-secret
type: kubernetes.io/tls
data:
  tls.crt: <base64-encoded-certificate>
  tls.key: <base64-encoded-private-key>

7. bootstrap.kubernetes.io/token ​

用于节点引导过程中的令牌。

yaml
apiVersion: v1
kind: Secret
metadata:
  name: bootstrap-token
type: bootstrap.kubernetes.io/token
data:
  token-id: <base64-encoded-token-id>
  token-secret: <base64-encoded-token-secret>

创建 Secret 的方法 ​

1. 通过命令行创建 ​

创建通用 Secret ​

bash
kubectl create secret generic my-secret --from-literal=username=admin --from-literal=password=123456

从文件创建 ​

bash
kubectl create secret generic my-secret --from-file=username.txt --from-file=password.txt

创建 Docker 仓库 Secret ​

bash
kubectl create secret docker-registry my-registry-secret \
  --docker-server=myregistry.com \
  --docker-username=admin \
  --docker-password=mypassword \
  --docker-email=admin@example.com

创建 TLS Secret ​

bash
kubectl create secret tls my-tls-secret --cert=path/to/cert.crt --key=path/to/key.key

2. 通过 YAML 文件创建 ​

yaml
apiVersion: v1
kind: Secret
metadata:
  name: app-secret
  namespace: default
type: Opaque
data:
  database_url: cG9zdGdyZXNxbDovL3VzZXI6cGFzc3dvcmRAaG9zdDpwb3J0L2RiX25hbWU=
  api_key: bXktc2VjcmV0LWFwaS1rZXk=
stringData:  # 使用 stringData 可以直接提供明文,系统会自动编码
  debug_mode: "true"
  log_level: "info"

在 Pod 中使用 Secret ​

1. 作为环境变量 ​

yaml
apiVersion: v1
kind: Pod
metadata:
  name: secret-env-pod
spec:
  containers:
  - name: myapp
    image: nginx
    env:
    - name: DB_USERNAME
      valueFrom:
        secretKeyRef:
          name: app-secret
          key: username
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: app-secret
          key: password
  restartPolicy: Never

2. 导入所有环境变量 ​

yaml
apiVersion: v1
kind: Pod
metadata:
  name: secret-envfrom-pod
spec:
  containers:
  - name: myapp
    image: nginx
    envFrom:
    - secretRef:
        name: app-secret
  restartPolicy: Never

3. 作为挂载卷 ​

yaml
apiVersion: v1
kind: Pod
metadata:
  name: secret-volume-pod
spec:
  containers:
  - name: myapp
    image: nginx
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secrets
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: app-secret
  restartPolicy: Never

4. 指定特定文件和权限 ​

yaml
apiVersion: v1
kind: Pod
metadata:
  name: secret-volume-specific
spec:
  containers:
  - name: myapp
    image: nginx
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secrets
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: app-secret
      defaultMode: 0400  # 只读权限
      items:
      - key: username
        path: db-username
        mode: 0444
      - key: password
        path: db-password
        mode: 0400
  restartPolicy: Never

Secret 管理命令 ​

查看 Secret ​

bash
kubectl get secrets

kubectl describe secret my-secret

kubectl get secret my-secret -o yaml

kubectl get secret my-secret -o jsonpath='{.data.username}' | base64 -d

更新 Secret ​

bash
kubectl edit secret my-secret

kubectl patch secret my-secret -p='{"data":{"password":"bmV3LXBhc3N3b3Jk"}}'

kubectl create secret generic my-secret --from-literal=username=admin --from-literal=password=newpass --dry-run=client -o yaml | kubectl apply -f -

删除 Secret ​

bash
kubectl delete secret my-secret

Secret 与 ConfigMap 的对比 ​

特性SecretConfigMap
用途敏感数据非敏感配置
存储方式Base64 编码明文
节点存储tmpfs(内存)普通文件系统
大小限制1MB1MB
安全性高(支持加密)一般
访问控制严格的 RBAC相对宽松

总结 ​

Secret 是 Kubernetes 中处理敏感数据的核心机制,提供了多种类型来满足不同的使用场景。正确使用 Secret 可以提高应用的安全性,但需要注意其限制和最佳实践,特别是在生产环境中要启用适当的访问控制和加密措施。

PV(PersistentVolume)与 PVC(PersistentVolumeClaim)详解
Go 语言泛型使用教程
由 Valaxy v1.2.2 驱动|主题-Yunv1.2.2