Kubernetes基于Secret存储敏感数据

1 简介Secret

1.1 用途

  • 用途:Kubernetes的Secret对象与ConfigMap对象类似,只不过ConfigMap一般用于存储普通配置信息,而Secret一般用于存储敏感配置信息(例如密码、OAuth Token、SSH Key等)。通过把敏感配置信息单独存储在Secret对象中,而不是直接存储在Pod中或Docker镜像中,能够更加的安全和灵活。

1.2 类型

  • 类型:Kubernetes中的Secret对象一共有三种类型。

    类型名称说明
    Opaque用于存储Base64编码后的配置信息,这种类型的配置信息可以通过环境变量或挂载的形式传给Pod使用。该类型的信息可以经Base64解码而获得原始数据,因此安全性较低,因此不建议将密码等敏感信息放入到这种类型的Secret中。
    kubernetes.io/dockerconfigjson用于存储Docker Registry的认证信息,K8S集群到Docker镜像仓库拉取镜像时,需要使用这种类型的Secret进行Docker身份认证,只有认证通过后,才能成功拉取镜像。
    kubernetes.io/service-account-token用于被ServiceAccount引用。ServiceAccount创建时,Kubernetes会默认创建对应的Secret,Pod如果使用了ServiceAccount,对应的Secret会自动挂载到Pod的/run/secrets/kubernetes.io/serviceAccount目录中

2 Opaque类型的Secret

2.1 创建Secret

2.1.1 使用命令的方式创建

  • 说明:通过使用命令的方式创建Opaque类型的Secret,需要指定Secret的类型为 generic。
2.1.1.1 通过文字值创建
  • 说明:通过文字值创建Secret时,需要传入密码等敏感配置信息的原始数据,Kubernetes会自动地将这些原始数据通过Base64进行编码,并使用编码后的值来创建Secret。
  • 创建:在Kubelet客户端中通过执行以下命令即可创建一个名称为secret-1的Secret。
    kubectl create secret generic secret-1 --from-literal=username=admin --from-literal=password=123456
    

在这里插入图片描述

  • 查看:上述命令执行成功之后,即可执行以下命令以查看创建成功的Secret,结果截图如下。
    kubectl get secret secret-1 -o yaml
    
    在这里插入图片描述
2.1.1.2 通过目录创建
  • 说明:通过目录创建Secret时,目录下的文件名(包括后缀名)即为Secret中的Key,目录下的文件的内容经Base64编码后的值即为Secret中对应Key的Value。

  • 文件:例如在Kubelet客户端中的当前目录下的secret目录中有如下4个文件,其文件名和内容分别如下所示:

    # secret/username
    admin
    
    # secret/username.txt
    admin
    
    # secret/password
    123456
    
    # secret/password.txt
    123456
    

    在这里插入图片描述

  • 创建:在Kubelet客户端中通过执行以下命令即可创建一个名称为secret-2的Secret。

    kubectl create secret generic secret-2 --from-file=./secret
    

    在这里插入图片描述

  • 查看:上述命令执行成功之后,即可执行以下命令以查看创建成功的Secret,结果截图如下。

    kubectl get secret secret-2 -o yaml
    

    在这里插入图片描述

2.1.1.3 通过文件创建
  • 说明:通过文件创建Secret时,如果不指定生成的Key,则文件名(包括后缀名)即为Secret中的key,文件的内容经Base64编码后的值即为Secret中对应Key的Value。

  • 文件:例如在Kubelet客户端中的当前目录下的secret目录中下有如下2个文件,其文件名和内容分别如下所示:

    # secret/username.txt
    admin
    
    # secret/password.txt
    123456
    

    在这里插入图片描述

  • 创建:在Kubelet客户端中通过执行以下命令即可创建一个名称为secret-3的Secret和创建一个名称为secret-4的Secret。

    # 不指定生成的Key
    kubectl create secret generic secret-3 --from-file=./secret/username.txt --from-file=./secret/password.txt
    
    # 指定生成的Key
    kubectl create secret generic secret-4 --from-file=username=./secret/username.txt --from-file=password=./secret/password.txt
    

    在这里插入图片描述

  • 查看:上述命令执行成功之后,即可执行以下命令以查看创建成功的Secret,结果截图如下。

    kubectl get secret secret-3 -o yaml
    kubectl get secret secret-4 -o yaml
    

    在这里插入图片描述

2.1.1.4 通过配置文件创建
  • 说明:通过Porperties配置文件创建Secret时,Properties文件中的Key即为Secret中的Key,Properties文件中的Value经Base64编码后的值即为Secret中对应Key的Value。

  • 文件:例如在Kubelet客户端中的当前目录下有如下1个Properties配置文件,其内容如下所示

    # secret.properties
    username=admin
    password=123456
    

    在这里插入图片描述

  • 创建:在Kubelet客户端中通过执行以下命令即可创建一个名称为secret-5的Secret。

    kubectl create secret generic secret-5 --from-env-file=./secret.properties
    

    在这里插入图片描述

  • 查看:上述命令执行成功之后,即可执行以下命令以查看创建成功的Secret,结果截图如下。

    kubectl get secret secret-5 -o yaml
    

    在这里插入图片描述

2.1.2 使用声明的方式创建

  • 说明:通过使用声明的方式创建Opaque类型的Secret,需要指定Secret的类型为 Opaque,并且需要传入密码等敏感信息的原始数据经由Base64编码后的值,而不是密码等敏感信息的原始数据。

  • 编码:在Shell命令行中执行以下命令,即可生成username和password的值经由Base64编码后的值。

    echo -n 'admin' | base64
    echo -n '123456' | base64
    

    在这里插入图片描述

  • yaml:在Kubelet客户端中的当前目录下创建一个名称为secret.yaml的文件,其内容如下所示。

    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-6
    type: Opaque
    data:
      username: YWRtaW4=
      password: MWYyZDFlMmU2N2Rm
    
  • 创建:在Kubelet客户端中通过执行以下命令即可使用上述yaml文件创建一个名称为secret-6的Opaque类型的Secret。

    kubectl apply -f ./secret.yaml
    

    在这里插入图片描述

  • 查看:上述命令执行成功之后,即可执行以下命令以查看创建成功的Secret,结果截图如下。

    kubectl get secret secret-6 -o yaml
    

    在这里插入图片描述

2.2 使用Secret

2.2.1 通过环境变量的方式使用

  • 说明:Kubernetes中的Secret对象中的配置项,可以通过环境变量的方式传给Pod使用,然后再在Pod中使用这些环境变量,这种方式要求指定Secret中的各个Key传给Pod中的哪个环境变量,而Secret中各个Key对应的Value经Base64解码后的值即为传给Pod的环境变量的值。

  • yaml:在Kubelet客户端中的当前目录下创建一个名称为secret-env-pod.yml文件,其内容如下所示。

    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-env-pod
    spec:
      containers:
      - name: busybox
        image: busybox:latest
        command: [ "/bin/sh", "-c", "echo $SECRET_USERNAME; echo $SECRET_PASSWORD" ]
        env:
          - name: SECRET_USERNAME
            valueFrom:
              secretKeyRef:
                name: secret-1
                key: username
          - name: SECRET_PASSWORD
            valueFrom:
              secretKeyRef:
                name: secret-1
                key: password
      restartPolicy: Never
    
  • 创建:在Kubelet客户端中通过执行以下命令即可使用上述yaml文件创建一个名称为secret-env-pod的Pod,在该Pod中会使用在2.1.1.1小节中创建的名称为secret-1的Secret,在该Pod中会打印出名称为SECRET_USERNAME和SECRET_PASSWORD这两个环境变量的值。

    kubectl apply -f secret-env-pod.yml
    

    在这里插入图片描述

  • 查看:上述命令执行成功之后,即可执行以下命令以查看创建的Pod的运行日志,从中可以看出成功打印出了Secret中的username和password的值,结果截图如下

    kubectl logs -f secret-env-pod
    

    在这里插入图片描述

2.2.2 通过挂载的方式使用

  • 说明:Kubernetes中的Secret对象中的配置项,可以通过挂载的方式挂载到Pod中的指定路径下的文件中,然后再在Pod使用这些文件,挂载的时候可以指定Secret中每个Key挂载的文件名,也可以不指定Secret中每个Key挂载的文件名。
2.2.2.1 不指定Key挂载的文件名
  • 说明:如果在挂载的时候没有指定Secret中每个Key要挂载的文件名,则Secret中的Key即为挂载后的文件名,而Secret中对应Key的Value经Base64解码后的值即为挂载后的文件的内容。这种情况下,Secret中所有的Key都会挂载到指定目录中。

  • yaml:在Kubelet客户端中的当前目录下创建一个名称为secret-mount-pod.yml文件,其内容如下所示。

    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-mount-pod
    spec:
      containers:
      - name: busybox
        image: busybox:latest
        command: [ "/bin/sh", "-c", "ls /etc/secret; cat /etc/secret/username; cat /etc/secret/password" ]
        volumeMounts:
        - name: secret
          mountPath: "/etc/secret"
          readOnly: true
      volumes:
      - name: secret
        secret:
          secretName: secret-2
      restartPolicy: Never
    
  • 创建:在Kubelet客户端中通过执行以下命令即可使用上述yaml文件创建一个名称为secret-mount-pod的Pod,在该Pod中会使用在2.1.1.2小节中创建的名称为secret-2的Secret,在该Pod中会展示出/etc/secret目录下的所有文件名称,并打印出该目录下的名称为username和password的文件中的内容。

    kubectl apply -f secret-mount-pod.yml
    

    在这里插入图片描述

  • 查看:上述命令执行成功之后,即可执行以下命令以查看创建的Pod的运行日志,从中可以看出/etc/secret目录下存在4个文件,这些文件的名称(包括后缀名)即为Secret中的Key,该目录下的名称为username的文件中的内容即为Secret中名称为username的Key的Value经由Base64解码后的值,结果截图如下。

    kubectl logs -f secret-mount-pod
    

    在这里插入图片描述

2.2.2.2 指定Key挂载的文件名
  • 说明:在挂载的时候还可以指定Secret中每个Key要挂载的文件名,则Secret中对应Key的Value经Base64解码后的值即为挂载后的文件的内容。这种情况下,只有指定的Secret中的Key才会挂载到指定目录中,而没有指定的Secret中的Key则不会挂载到指定目录中。

  • yaml:在Kubelet客户端中的当前目录下创建一个名称为secret-mount-pod-spec.yml文件,其内容如下所示。

    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-mount-pod-spec
    spec:
      containers:
      - name: busybox
        image: busybox:latest
        command: [ "/bin/sh", "-c", "ls /etc/secret; ls /etc/secret/auth; cat /etc/secret/auth/login_username; cat /etc/secret/auth/login_password" ]
        volumeMounts:
        - name: secret
          mountPath: "/etc/secret"
          readOnly: true
      volumes:
      - name: secret
        secret:
          secretName: secret-2
          items:
          - key: username.txt
            path: auth/login_username
          - key: password.txt
            path: auth/login_password
      restartPolicy: Never
    
  • 创建:在Kubelet客户端中通过执行以下命令即可使用上述yaml文件创建一个名称为secret-mount-pod-spec的Pod,在该Pod中会使用在2.1.1.2小节中创建的名称为secret-2的Secret,在该Pod中会展示出/etc/secret目录及/etc/secret/auth目录下的所有文件名称,并打印出该/etc/secret/auth目录下的名称为login_username和login_password的文件中的内容。

    kubectl apply -f secret-mount-pod-spec.yml
    

    在这里插入图片描述

  • 查看:上述命令执行成功之后,即可执行以下命令以查看创建的Pod的运行日志,从中可以看出/etc/secret目录只有auth子目录,而/etc/secret/auth目录下也只有2个文件,而/etc/secret/auth目录下的名称为login_username的文件中的内容即为Secret中名称为username.txt的Key的Value经由Base64解码后的值,结果截图如下。

    kubectl logs -f secret-mount-pod-spec
    

    在这里插入图片描述

3 DockerConfigJson类型的Secret

3.1 创建Secret

3.1.1 使用命令的方式创建

  • 说明:通过使用命令的方式创建DockerConfigJson类型的Secret,需要指定Secret的类型为 docker-registry。需要指定Docker仓库的域名地址、登录名、登录密码等敏感配置信息的原始数据,Kubernetes会自动地将这些原始数据通过Base64进行编码,并使用编码后的值来创建Secret。

  • 创建:在Kubelet客户端中通过执行以下命令即可创建一个名称为docker-secret-1的DockerConfigJson类型的Secret。

    kubectl create secret docker-registry docker-secret-1 --docker-server=registry.k8s.com --docker-username=admin --docker-password=Harbor12345
    

    在这里插入图片描述

  • 查看:上述命令执行成功之后,即可执行以下命令以查看创建成功的Secret,结果截图如下。

    kubectl get secret docker-secret-1 -o yaml
    

    在这里插入图片描述

  • 解码:从上面的输出结果可知,Docker认证信息经过Base64编码生成了一个字符串,并放在了.dockerconfigjson字段中,为了弄清楚是如何使用docker认证信息构造Base64编码的字符串,把生成的Base64编码的字符串复制出来,并通过在Shell命令行中执行以下命令进行解码,其结果如下所示。

    echo eyJhdXRocyI6eyJyZWdpc3RyeS5rOHMuY29tIjp7InVzZXJuYW1lIjoiYWRtaW4iLCJwYXNzd29yZCI6IkhhcmJvcjEyMzQ1IiwiYXV0aCI6IllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSJ9fX0= | base64 -d
    

    在这里插入图片描述

  • 进一步解码:从上图中可知,解码出来的结果是一个JSON对象,且JSON对象中的auth字段的值仍然是一个Base64编码的字符串,把auth字段的值复制出来,并通过在Shell命令行中执行以下命令进一步解码,其结果如下所示:

     echo YWRtaW46SGFyYm9yMTIzNDU= | base64 -d
    

    在这里插入图片描述

  • 结果:通过上述的两次解码后,可以发现,在使用命令的方式生成DockerConfigJson类型的Secret时,是通过以下的JSON格式组织Docker认证信息,并把JSON对象作为字符串进行Base64解码。

    Base64({"auths":{"域名地址":{"username":"登录名","password":"登录密码","auth":"Base64(登录名:登录密码)"}}})
    

3.1.2 使用声明的方式创建

  • 说明:通过使用声明的方式创建DockerConfigJson类型的Secret,需要指定Secret的类型为 kubernetes.io/dockerconfigjson。通过3.1.1小节可知,Docker认证信息需要经过两次Base64编码才能被DockerConfigJson类型的Secret使用,并且还需要使用以下的JSON格式组织Docker认证信息。

    Base64({"auths":{"域名地址":{"username":"登录名","password":"登录密码","auth":"Base64(登录名:登录密码)"}}})
    
  • 编码:在Shell命令行中通过执行以下命令对Docker的认证信息进行第一次编码。

     echo 'admin:Harbor12345' | base64
    

    在这里插入图片描述

  • 进一步编码:上一步编码完成之后,使用上一步编码生成的结果以及Docker认证的信息再一次进行编码,在Shell命令行中通过执行以下命令对Docker的认证信息进行第二次编码,第二次编码生成的结果即为可用于生成DockerConfigJson类型的Secret的值。注意:第二次编码的结果可能会有多行,需要拼接在一起进行使用。

    echo '{"auths":{"registry.k8s.com":{"username":"admin","password":"Harbor12345","auth":"YWRtaW46SGFyYm9yMTIzNDUK"}}}' | base64
    

    在这里插入图片描述

  • yaml:在Kubelet客户端中的当前目录下创建一个名称为docker-secret.yml文件,并使用上一步中生成的Docker认证信息的Base64编码格式的值作为.dockerconfigjson字段的值,其内容如下所示。

    apiVersion: v1
    kind: Secret
    metadata:
      name: docker-secret-2
    type: kubernetes.io/dockerconfigjson
    data:
      .dockerconfigjson: eyJhdXRocyI6eyJyZWdpc3RyeS5rOHMuY29tIjp7InVzZXJuYW1lIjoiYWRtaW4iLCJwYXNzd29yZCI6IkhhcmJvcjEyMzQ1IiwiYXV0aCI6IllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVSyJ9fX0K
    
  • 创建:在Kubelet客户端中通过执行以下命令即可使用上述yaml文件创建一个名称为docker-secret-2的DockerConfigJson类型的Secret。

    kubectl apply -f docker-secret.yml
    

    在这里插入图片描述

  • 查看:上述命令执行成功之后,即可执行以下命令以查看创建成功的Secret,结果截图如下。

    kubectl get secret docker-secret-2 -o yaml
    

    在这里插入图片描述

3.2 使用Secret

  • 说明:DockerConfigJson类型的Secret用于K8S集群从Docker镜像仓库拉取镜像时进行认证使用,因此,需要在创建Pod的yaml中指定用于K8S集群从Docker镜像仓库中拉取镜像的Docker认证信息,即要指定DockerConfigJson类型的Secret。
  • yaml:在Kubelet客户端中的当前目录下创建一个名称为docker-secret-pod.yml文件,并指定K8S集群从Docker镜像仓库中拉取registry.k8s.com/k8s/busybox:latest镜像时,使用3.1.1小节中生成的名称为docker-secret-1的DockerConfigJson类型的Secret进行Docker认证,其内容如下所示。
    apiVersion: v1
    kind: Pod
    metadata:
      name: docker-secret-pod
    spec:
      containers:
        - name: busybox
          image: registry.k8s.com/k8s/busybox:latest
          command: [ "/bin/sh", "-c", "echo hello world" ]
      imagePullSecrets:
        - name: docker-secret-1
      restartPolicy: Never
    
  • 创建:在Kubelet客户端中通过执行以下命令即可使用上述yaml文件创建一个名称为docker-secret-pod的Pod,该Pod中会打印一句 “hello world”。
    kubectl apply -f docker-secret-pod.yml
    
    在这里插入图片描述
  • 查看:上述命令执行成功之后,即可执行以下命令以查看Pod是否创建成功,以及查看Pod的运行日志,从中可以看出Pod创建成功,且Pod成功的向日志中打印出了"hello world"这句话,结果截图如下。
    kubectl get pods
    
    kubectl logs -f docker-secret-pod
    
    在这里插入图片描述
  • 补充:如果在上述docker-secret-pod.yml中没有指定imagePullSecrets字段,则使用该yml文件创建Pod时,由于K8S从Docker镜像仓库拉取镜像时没有Docker认证信息,因此会拉取失败,从而看到的结果如下图所示。
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值