• Kubernetes对象——Secret


    1、概述

    应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名密码或者密钥。将这些信息直接保存在容器镜像中显然不妥,Kubernetes 提供的解决方案是 Secret。Secret 会以密文的方式存储数据,避免了直接在配置文件中保存敏感信息。Secret 会以 Volume 的形式被 mount 到 Pod,容器可通过文件的方式使用 Secret 中的敏感数据;此外,容器也可以环境变量的方式使用这些数据。

    要使用 Secret,Pod 需要引用 Secret。 Pod 可以用三种方式之一来使用 Secret:

    • 作为挂载到一个或多个容器上的卷中的文件。
    • 作为容器的环境变量
    • 由 kubelet 在为 Pod 拉取镜像时使用

    Kubernetes 控制平面也使用 Secret; 例如,引导令牌 Secret 是一种帮助自动化节点注册的机制。

    Secret 对象的名称必须是合法的 DNS 子域名。 在为创建 Secret 编写配置文件时,你可以设置 data 与/或 stringData 字段。 data 和 stringData 字段都是可选的。data 字段中所有键值都必须是 base64 编码的字符串。如果不希望执行这种 base64 字符串的转换操作,你可以选择设置 stringData 字段,其中可以使用任何字符串作为其取值。

    2、Secret 的类型

    创建 Secret 时,你可以使用 Secret 资源的 type 字段, 或者与其等价的 kubectl 命令行参数(如果有的话,例如generic、docker-registry)为其设置类型。 Secret 的 type 有助于对不同类型机密数据的编程处理。

    Kubernetes 提供若干种内置的类型,用于一些常见的使用场景。 针对这些类型,Kubernetes 所执行的合法性检查操作以及对其所实施的限制各不相同。

    内置类型用法
    Opaque 用户定义的任意数据,使用base64编码存储信息,可以通过base64 --decode解码获得原始数据,因此安全性弱。
    kubernetes.io/service-account-token 服务账号令牌,用于被 serviceaccount 引用。serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。Pod 如果使用了 serviceaccount,对应的 secret 会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中。
    kubernetes.io/dockercfg ~/.dockercfg 文件的序列化形式
    kubernetes.io/dockerconfigjson ~/.docker/config.json 文件的序列化形式,用于存储docker registry的认证信息。
    kubernetes.io/basic-auth 用于基本身份认证的凭据
    kubernetes.io/ssh-auth 用于 SSH 身份认证的凭据
    kubernetes.io/tls 用于 TLS 客户端或者服务器端的数据
    bootstrap.kubernetes.io/token 启动引导令牌数据

    通过为 Secret 对象的 type 字段设置一个非空的字符串值,你也可以定义并使用自己 Secret 类型。如果 type 值为空字符串,则被视为 Opaque 类型。 Kubernetes 并不对类型的名称作任何限制。不过,如果你要使用内置类型之一, 则你必须满足为该类型所定义的所有要求。

    2.1 Opaque Secret

    当 Secret 配置文件中未作显式设定时,默认的 Secret 类型是 Opaque。 当你使用 kubectl 来创建一个 Secret 时,你会使用 generic 子命令来标明 要创建的是一个 Opaque 类型 Secret。 例如,下面的命令会创建一个空的 Opaque 类型 Secret 对象:

    kubectl create secret generic empty-secret
    kubectl get secret empty-secret

    输出类似于

    NAME           TYPE     DATA   AGE
    empty-secret   Opaque   0      2m6s

    DATA 列显示 Secret 中保存的数据条目个数。 在这个例子种,0 意味着我们刚刚创建了一个空的 Secret。

    2.2 服务账号令牌 Secret 

    类型为 kubernetes.io/service-account-token 的 Secret 用来存放标识某 服务账号的令牌。使用这种 Secret 类型时,你需要确保对象的注解 kubernetes.io/service-account-name 被设置为某个已有的服务账号名称。 某个 Kubernetes 控制器会填写 Secret 的其它字段,例如 kubernetes.io/service-account.uid 注解以及 data 字段中的 token 键值,使之包含实际的令牌内容。

    下面的配置实例声明了一个服务账号令牌 Secret:

    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-sa-sample
      annotations:
        kubernetes.io/service-account.name: "sa-name"
    type: kubernetes.io/service-account-token
    data:
      # 你可以像 Opaque Secret 一样在这里添加额外的键/值偶对
      extra: YmFyCg==

    Kubernetes 在创建 Pod 时会自动创建一个服务账号 Secret 并自动修改你的 Pod 以使用该 Secret。该服务账号令牌 Secret 中包含了访问 Kubernetes API 所需要的凭据。

    如果需要,可以禁止或者重载这种自动创建并使用 API 凭据的操作。 不过,如果你仅仅是希望能够安全地访问 API 服务器,这是建议的工作方式。

    Pod 如果使用了 serviceaccount,对应的 secret 会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中。
    示例:
    $ kubectl run nginx --image nginx
    deployment "nginx" created
    $ kubectl get pods
    NAME                     READY     STATUS    RESTARTS   AGE
    nginx-3137573019-md1u2   1/1       Running   0          13s
    $ kubectl exec nginx-3137573019-md1u2 ls /run/secrets/kubernetes.io/serviceaccount
    ca.crt
    namespace
    token

    2.3 Docker 配置 Secret(kubernetes.io/dockerconfigjson)

    kubernetes.io/dockerconfigjson用于存储docker registry的认证信息,可以直接使用kubectl create secret命令创建:

    kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
    secret "myregistrykey" created.
    

    查看secret的内容: 

    kubectl get secret myregistrykey  -o yaml
    apiVersion: v1
    data:
      .dockerconfigjson: eyJjY3IuY2NzLnRlbmNlbnR5dW4uY29tL3RlbmNlbnR5dW4iOnsidXNlcm5hbWUiOiIzMzIxMzM3OTk0IiwicGFzc3dvcmQiOiIxMjM0NTYuY29tIiwiZW1haWwiOiIzMzIxMzM3OTk0QHFxLmNvbSIsImF1dGgiOiJNek15TVRNek56azVORG94TWpNME5UWXVZMjl0In19
    kind: Secret
    metadata:
      name: myregistrykey
      ......
    type: kubernetes.io/dockerconfigjson

    在创建 Pod 的时候,通过 imagePullSecrets 来引用刚创建的 myregistrykey:

    apiVersion: v1
    kind: Pod
    metadata:
      name: foo
    spec:
      containers:
        - name: foo
          image: janedoe/awesomeapp:v1
      imagePullSecrets:
        - name: myregistrykey

    3、Secret使用 

    Secret 可通过命令行或 YAML 创建。比如希望 Secret 中包含如下信息:

    1. 用户名 zmc

    2. 密码 123456

    3.1 创建 Secret方式

    有四种方法创建 Secret:

    (1)通过 --from-literal

    kubectl create secret generic mysecret --from-literal=username=zmc --from-literal=password=123456

    每个 --from-literal 对应一个信息条目。

    (2)通过 --from-file

    echo -n zmc > ./username
    echo -n 123456 > ./password
    kubectl create secret generic mysecret --from-file=./username --from-file=./password

    每个文件内容对应一个信息条目。

    (3)通过 --from-env-file

    cat << EOF > env.txt
    username=zmc
    password=123456
    EOF
    kubectl create secret generic mysecret --from-env-file=env.txt

    文件 env.txt 中每行 Key=Value 对应一个信息条目。

    (4)通过 YAML 配置文件:

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
      namespace: default
    type: Opaque
    data:
      username: em1j
      password: MTIzNDU2

    文件中的敏感数据必须是通过 base64 编码后的结果。

    [root@master1 ~]# echo -n zmc|base64
    em1j
    [root@master1 ~]# echo -n 123456|base64
    MTIzNDU2

    执行 kubectl apply 创建 Secret:

    [root@master1 ~]# kubectl apply -f mysecret.yaml 
    secret/mysecret created

    3.2 查看secret

    (1)通过 kubectl get secret 查看存在的 secret

    显示有两个数据条目

    (2)通过kubectl describe secret 查看条目的 Key

    [root@master1 ~]# kubectl describe secret  mysecret 
    Name:         mysecret
    Namespace:    default
    Labels:       <none>
    Annotations:  
    Type:         Opaque
    
    Data
    ====
    password:  6 bytes
    username:  3 bytes

    (3)通过kubectl edit secret mysecret 查看vlaue

    apiVersion: v1
    data:
      password: MTIzNDU2
      username: em1j
    kind: Secret
    metadata:
      annotations:
      ......
      name: mysecret
      namespace: default
      resourceVersion: "307042063"
      selfLink: /api/v1/namespaces/default/secrets/mysecret
      uid: 679f748d-cff7-41fa-9bb1-bcee1f00a0fd
    type: Opaque

    (4)通过base64将value反解码

    [root@master1 ~]# echo -n MTIzNDU2|base64 --decode
    123456[root@master1 ~]# echo -n em1j|base64 --decode
    zmc  

    3.3 vloume方式secret的使用

    Pod 可以通过 Volume 或者环境变量的方式使用 Secret,先学习 Volume 方式。

    Pod 的配置文件如下所示(username: admin   password:123456):

    ① 定义 volume foo,来源为 secret mysecret

    ② 将 foo mount 到容器路径 /etc/foo,可指定读写权限为 readOnly

     创建 Pod 并在容器中读取 Secret:

     

    可以看到,Kubernetes 会在指定的路径 /etc/foo 下为每条敏感数据创建一个文件,文件名就是数据条目的 Key,这里是 /etc/foo/username 和 /etc/foo/passwordValue 则以明文存放在文件中。

     我们也可以自定义存放数据的文件名,比如将配置文件改为:

     

    这时数据将分别存放在 /etc/foo/my-group/my-username 和 /etc/foo/my-group/my-password 中。

    以 Volume 方式使用的 Secret 支持动态更新:Secret 更新后,容器中的数据也会更新。

     将 password 更新为 abcdef,base64 编码为 YWJjZGVm

    3.4 环境变量中使用secret

     通过 Volume 使用 Secret,容器必须从文件读取数据会稍显麻烦,Kubernetes 还支持通过环境变量使用 Secret。

     创建 Pod 并读取 Secret。

    通过环境变量 SECRET_USERNAME 和 SECRET_PASSWORD 成功读取到 Secret 的数据。

    需要注意的是,环境变量读取 Secret 很方便,但无法支撑 Secret 动态更新。

    4、并不安全的Secret

    其实目前Secret的实现,就是ConfigMap把value用base64 encode了一下,所以,其实不存在任何安全性,只要decode一下就能出现原来结果,相当于明文存储。base64这玩意儿都不能叫做加密,只能叫做编码,所以我们都不说encrypt,而是encode和decode。

    5、总结

    • Secret 可以为 Pod 提供密码、Token、私钥等敏感数据;对于一些非敏感数据,比如应用的配置信息,则可以用 ConfigMap。 
    • Kubernetes 并不对Secret类型的名称作任何限制。不过,如果你要使用内置类型之一, 则你必须满足为该类型所定义的所有要求。
    • 以 Volume 方式使用的 Secret 支持动态更新:Secret 更新后,容器中的数据也会更新。
    • 环境变量读取 Secret 很方便,但无法支撑 Secret 动态更新。
    • Secret的值在Pod里面都是以明文形式显示。
    • Secret其实不存在任何安全性,只要decode一下就能出现原来结果,相当于明文存储。

    参考:https://kubernetes.io/zh/docs/concepts/configuration/secret/

    参考:https://www.cnblogs.com/benjamin77/p/9960624.html

  • 相关阅读:
    AspNet上传文件的几个控件(downmoon收集)
    简单的iframe无刷新上传带生产缩略图和水印
    js 操作frameset frame 对象
    C#里的三种定时器类型
    Asp.net上传图片同时生成缩略图和水印图后台代码
    .NET调用新浪微博开放平台接口的代码示例
    用 javascript 获取鼠标(光标)的坐标位置 兼容IE/Firefox等浏览器
    IIS Web服务扩展中没有Asp.net 2.0
    asp.net实现form验证登陆
    Asp.net实现在线截图(大图截取为小图)
  • 原文地址:https://www.cnblogs.com/zhangmingcheng/p/15815897.html
Copyright © 2020-2023  润新知