K8S Secret 一文详解, 全面覆盖 Secret 使用场景 | 全家桶

K8S Secret 一文详解, 全面覆盖 Secret 使用场景 | 全家桶_第1张图片

博客原文

文章目录

    • Secret介绍
    • Secret 类型
      • kubectl 创建类型
    • Secret 使用
      • Opaque 类型 Secret 的使用
        • 创建
          • 1. kubectl create
          • 2. yaml
        • 挂载
          • 1. 作为环境变量
          • 2. 作为文件挂载及设置 POSIX 权限
      • Secret 绑定 serviceAccount
        • 查看 secret
      • TLS Secret
        • yaml 方式创建
        • kubectl 创建
      • Docker 镜像仓库 Secret
        • yaml 方式创建
        • kubectl 方式创建
      • ssh 类型 secret
        • 通过文件创建
        • pod 挂载 ssh secret
    • 参考

Secret介绍

k8s secrets用于存储和管理一些敏感数据,比如密码,token,密钥等敏感信息。它把 Pod 想要访问的加密数据存放到 Etcd 中。然后用户就可以通过在 Pod 的容器里挂载 Volume 的方式或者环境变量的方式访问到这些 Secret 里保存的信息了。

Secret 类似于 ConfigMap 但专门用于保存机密数据。

Secret 类型

内置类型 用法
Opaque 用户定义的任意数据
kubernetes.io/service-account-tokensymotion 服务账号令牌
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 启动引导令牌数据

kubectl 创建类型

$ kubectl create secret dotfile -h
Create a secret with specified type.

 A docker-registry type secret is for accessing a container registry.

 A generic type secret indicate an Opaque secret type.

 A tls type secret holds TLS certificate and its associated key.

Available Commands:
  docker-registry   Create a secret for use with a Docker registry
  generic           Create a secret from a local file, directory, or literal value
  tls               Create a TLS secret
  • docker-registry: 连接私有镜像仓库的凭证
  • generic: 常见 secret, 该类型 secret 与 configmap 使用相同
  • tls: 提供 tls 证书, 在 service mesh 中自动挂载

Secret 使用

使用场景:

  • 设置容器的环境变量。
  • 向 Pod 提供 SSH 密钥或密码等凭据。
  • 允许 kubelet 从私有镜像仓库中拉取镜像。

Opaque 类型 Secret 的使用

创建
1. kubectl create
$ kubectl create secret generic dotfile --from-literal=username=admin --from-literal=password=123456

$ kubectl get secret dotfile -oyaml
apiVersion: v1
data:
  password: MTIzNDU2
  username: YWRtaW4=
kind: Secret
metadata:
  creationTimestamp: "2024-01-09T07:45:19Z"
  name: dotfile
  namespace: default
  resourceVersion: "621858"
  uid: ce3a3332-5b97-4af0-8312-ced355786e64
type: Opaque

$ echo -n "YWRtaW4=" | base64 -d
admin
2. yaml

以 yaml 方式创建需要你提前进行 base64

$ echo -n "admin" | base64
YWRtaW4=
$ echo -n "123456" | base64
MTIzNDU2
apiVersion: v1
kind: Secret
metadata:
  name: dotfile
  namespace: default
type: Opaque
data:
  password: MTIzNDU2
  username: YWRtaW4=
immutable: true

你可以通过将 Secret 的 immutable 字段设置为 true 创建不可更改的 Secret。

创建

$ kubectl create -f dotfile-secret.yaml
挂载
1. 作为环境变量

创建 pod

apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  containers:
  - image: busybox
    name: busybox
    command: ["/bin/sh","-c","echo $username && env"]
    env:
    - name: username
      valueFrom:
        secretKeyRef:
          key: username
          name: dotfile    # secret 名称

获取容器日志

# 创建
$ kubectl create -f pod1.yaml

$ kubectl logs pod1
admin
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=pod1
SHLVL=1
username=admin
HOME=/root
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
2. 作为文件挂载及设置 POSIX 权限

对于 volume 挂载, 推荐 configmap 总结 k8s 中 volume 挂载的种种情况, 及最佳实践

创建 pod

apiVersion: v1
kind: Pod
metadata:
  name: pod2
spec:
  volumes:
  - name: sec
    secret:
      secretName: dotfile
      defaultMode: 0400  # 设置文件权限
  containers:
  - image: busybox
    name: busybox
    command: ["sleep", "24h"]
    volumeMounts:
    - mountPath: /etc/config
      name: sec

注意: secret 挂载到容器后自动 base64 解码

$ kubectl exec pod2 -- ls -l /etc/config/
total 0
lrwxrwxrwx    1 root     root            15 Jan  9 08:00 password -> ..data/password
lrwxrwxrwx    1 root     root            15 Jan  9 08:00 username -> ..data/username

$ kubectl exec pod2 -- cat /etc/config/username
admin

Secret 绑定 serviceAccount

k8s 中 pod 会挂载 serviceAccount

  • 挂载路径: /var/run/secrets/kubernetes.io/serviceaccount
  • 挂载内容该 serviceAccount 的: ca.crt , namespace , token

secret:

apiVersion: v1
kind: Secret
metadata:
  name: sa-secret
  annotations:
    kubernetes.io/service-account.name: "tdd"
type: kubernetes.io/service-account-token
data:
  password: MTIzNDU2
  username: YWRtaW4=

我们为 secret 添加了 kubernetes.io/service-account.name字段, 为其指定的 serviceAccount, 创建了 Secret 之后,等待 Kubernetes 在 data 字段中填充 token 主键。

查看 secret
$ kubectl get secrets sa-secret -oyaml
apiVersion: v1
data:
  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJWVB2VXI2cG02NFF3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TXpFeU16QXdPVE16TVRkYUZ3MHpNekV5TWpjd09UTTRNVGRhTUJVeApFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLCkFvSUJBUUM0M1JFazZPZ0VFMGVWN1JHbmc1YnRONEdHaE5uUFNjbUZuYy9LKzhlSEZESVlPRkRKblZlZ0tOUmQKblVOSEFUL2h3T3RaWFZUTHhieWRGTVNqd0xSeDVPNTg5bUlVM3M2SlVZZjFvajFCUjFsWlkreXA5eVRGdXFYYQphbzc3WTVPbkVpT3BOQXUxek1WWUFRK0V2bzJtbmY2b0p6WDd3SFc2TkxZd0V0TVA2cklhclNaaU11MTllRnBWCnpmNU5RMGFGUU4vbkJyQUpHQm15eHF1cGhNRFpYOXlyK1c3emY4Q296NkxuTHRCMCtIaEtHYm9kUGVyaWk0bjgKczJlc2tLdmZ6NmdJK0dhR3ROYWtNU3gwbVZXV0MycTBDbndrOVJEOTNhd1JWRHd2VnZRczljR1B0R0I3WVdIcApDOXBLeTdaOEgybjdDZndza2FqZTMzWnhuUzJaQWdNQkFBR2pXVEJYTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJRU1oxaVlWKzlQNTRiNHB3UU9QVkI0TklXYndEQVYKQmdOVkhSRUVEakFNZ2dwcmRXSmxjbTVsZEdWek1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQkdNRzMvN3dSZwp0ZkxDMkNHTGtRcUdaQmNtTlBzR0lwbmRqSnpTSzVjMXJMSVUrNjNHN3ZnWEJENHVuZ3B5RDFRVE5VSWp1ZVRXCkMxM1lZb1ZjK09zZkIvWFlVRkFvZ1JiWWtvZjV2TTBUeFVzdXN1VVUvT0Q2NDc0cE5xajlzQStrejRiMUliMzAKOVFmUG5mM2ZieVZyVmh0dlYxQmxsNVMwMmVDa2xaazM1SjAzczFLdytOWHovSjQzTDF6UlJjNytCa3M1UVpvbAp2ZnhJYW1BaXdqWGFUMDBhVVB3WjZ4S215KzcvUkZuRjB4aExlanhKRTBrOUU0YWR3NGhWSkNWMUp2aWdzcEpDCmNQL3BJMC9hSlVKeHVKNWZVeENuRVRVOXRpNi9aTGloeDg4Uk1vdmRFS0R4RDZJYlpKSWkxYVJwajhVeGdnL0UKcm1ONU5YTnN3Sk9XCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
  namespace: ZGVmYXVsdA==
  password: MTIzNDU2
  token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNkluZHBiR05VZVVwd1pUbEpRbEJpV0ZReGFFeHFaamh5WlROWE4wOHdXRXBtU1Y4eGJtODRWblp0UlVFaWZRLmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXVZVzFsYzNCaFkyVWlPaUprWldaaGRXeDBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5elpXTnlaWFF1Ym1GdFpTSTZJbk5oTFhObFkzSmxkQ0lzSW10MVltVnlibVYwWlhNdWFXOHZjMlZ5ZG1salpXRmpZMjkxYm5RdmMyVnlkbWxqWlMxaFkyTnZkVzUwTG01aGJXVWlPaUowWkdRaUxDSnJkV0psY201bGRHVnpMbWx2TDNObGNuWnBZMlZoWTJOdmRXNTBMM05sY25acFkyVXRZV05qYjNWdWRDNTFhV1FpT2lKbVpEWTRZelkwTVMwMU1qSXpMVFJsTUdRdFlqRXlaQzFpWkdKbE5ETXlOMlpsT0dZaUxDSnpkV0lpT2lKemVYTjBaVzA2YzJWeWRtbGpaV0ZqWTI5MWJuUTZaR1ZtWVhWc2REcDBaR1FpZlEuY09UZXoyM2w3VFl2TjFFN1FYcW4xVkN4dUxhbEJCN0JOMTVyU05IWFZndk5waEY4ZTd3ZkY4R3VheXFaSmZtdXB3ZE5HVzV2SFVRbE8yQVQtX3pGZkEta0hSbEN6OVZzZUVnTV82S0lrZ3FiZlNKNGw2WDRQOWFwaEdvYUhBaEdJUGdibTVGU1UwTWR6NlhzNW9fSnVvVjZfWkxxN3BZRVlGU0Y3REF1U0VyZHljSjdBZFFidWl6cHhuOE5lb3JhZ3Y5OWNDWjFlQjVJS0lGQW05SjBld1dlZEJBOUJhM0haN2RXQWozNE9uLW9mTWVKOWtQcmhvZWlUb2dtSkk5SE9NYWd4Ynh4YmF5cVpYdW9TQWJBSkNqVkRoUVZxdUJZRnJ5T09lWFowSnlXaWkyeVdVQWVvdVNDSEtRWUFXd2pmU2dwaGtKdzFQUkE4M3pFQWFmc3hn
  username: YWRtaW4=
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: tdd
    kubernetes.io/service-account.uid: fd68c641-5223-4e0d-b12d-bdbe4327fe8f
  creationTimestamp: "2024-01-09T08:49:30Z"
  name: sa-secret
  namespace: default
  resourceVersion: "630499"
  uid: c41bc253-c2c4-4d2f-a5d9-0a4fe8b0d8da
type: kubernetes.io/service-account-token

可以看到 kubernetes 控制器自动为其填充了 namespace, token, ca

TLS Secret

创建方式

yaml 方式创建
apiVersion: v1
kind: Secret
metadata:
  name: secret-tls
type: kubernetes.io/tls
data:
  # 值为 base64 编码,这样会掩盖它们,但不会提供任何有用的机密性级别
  tls.crt: |
    LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVakNDQWJzQ0FnMytNQTBHQ1NxR1NJYjNE
    UUVCQlFVQU1JR2JNUXN3Q1FZRFZRUUdFd0pLVURFT01Bd0cKQTFVRUNCTUZWRzlyZVc4eEVEQU9C
    ......
  # 在这个例子中,密钥数据不是真正的 PEM 编码的私钥
  tls.key: |
    RXhhbXBsZSBkYXRhIGZvciB0aGUgVExTIGNydCBmaWVsZA==    
kubectl 创建
$ kubectl create secret tls my-tls-secret \
  --cert=path/to/cert/file \
  --key=path/to/key/file

Docker 镜像仓库 Secret

yaml 方式创建
apiVersion: v1
kind: Secret
metadata:
  name: secret-dockercfg
type: kubernetes.io/dockercfg
data:
  .dockercfg: |
    eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUvdjEvIjp7ImF1dGgiOiJvcGVuc2VzYW1lIn19fQo=    
kubectl 方式创建
$ kubectl create secret docker-registry secret-tiger-docker \
  --docker-email=[email protected] \
  --docker-username=tiger \
  --docker-password=pass1234 \
  --docker-server=my-registry.example:5000

$ kubectl get secret secret-tiger-docker -o jsonpath='{.data.*}' | base64 -d

输出等价于以下 JSON 文档(这也是一个有效的 Docker 配置文件):

{
  "auths": {
    "my-registry.example:5000": {
      "username": "tiger",
      "password": "pass1234",
      "email": "[email protected]",
      "auth": "dGlnZXI6cGFzczEyMzQ="
    }
  }
}

ssh 类型 secret

通过文件创建
$ kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/path/to/.ssh/id_rsa --from-file=ssh-publickey=/path/to/.ssh/id_rsa.pub
pod 挂载 ssh secret
apiVersion: v1
kind: Pod
metadata:
  name: secret-test-pod
  labels:
    name: secret-test
spec:
  volumes:
  - name: secret-volume
    secret:
      secretName: ssh-key-secret
  containers:
  - name: ssh-test-container
    image: mySshImage
    volumeMounts:
    - name: secret-volume
      readOnly: true
      mountPath: "/etc/secret-volume"

容器命令执行时,秘钥的数据可以在下面的位置访问到:

/etc/secret-volume/ssh-publickey
/etc/secret-volume/ssh-privatekey

容器就可以随便使用 Secret 数据来建立 SSH 连接。

参考

  1. https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/#service-account-token-secrets
  2. https://kubernetes.io/zh-cn/docs/tasks/inject-data-application/distribute-credentials-secure/#provide-prod-test-creds
  3. https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/pull-image-private-registry/

你可能感兴趣的:(kubernetes,kubernetes,容器,云原生,运维,linux)