• 小白学k8s(11)-k8s中Secret理解


    理解Secret

    什么是Secret

    Secret对象类型用来保存敏感信息,例如密码、OAuth令牌和 SSH 密钥。 将这些信息放在secret中比放在Pod的定义或者 容器镜像中来说更加安全和灵活。

    Secret是一种包含少量敏感信息例如密码、令牌或密钥的对象。 这样的信息可能会被放在Pod 规约中或者镜像中。 用户可以创建Secret,同时系统也创建了一些Secret

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

    • 作为挂载到一个或多个容器上的卷中的文件。

    • 作为容器的环境变量

    • 由kubelet在为Pod拉取镜像时使用

    Secret的类型

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

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

    Opaque Secret

    Opaque类型的数据是一个map类型,要求valuebase64编码格式:

    创建我们需要的两个base64账号信息

    $ echo -n "root" | base64
      cm9vdA==
    $ echo -n "123456" | base64
      MTIzNDU2
    

    secrets.yml

    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-test
    type: Opaque
    data:
      password: MTIzNDU2
      username: cm9vdA==
    

    创建 secret:kubectl create -f secrets.yml

    $ kubectl get secret
      NAME                         TYPE                                  DATA   AGE
      secret-test                  Opaque                                2      8s
    

    可以看到我们刚刚创建的secret

    Opaque Secret的使用

    创建好secret之后,有两种方式来使用它:

    • 以 Volume 方式

    • 以环境变量方式

    将Secret挂载到Volume中

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
      - name: mypod
        image: redis
        volumeMounts:
        - name: foo
          mountPath: "/etc/foo"
          readOnly: true
      volumes:
      - name: foo
        secret:
          secretName: secret-test
          items:
          - key: username
            path: my-group/my-username
    

    成功运行之后,进入到pod中

    root@mypod:/etc/foo/my-group# ls
    my-username
    
    root@mypod:/etc/foo/my-group# cat my-username 
    root
    

    可以看到我们之前定义的secret的username已经被当前的pod引用,并成功挂载

    挂载的Secret会被自动更新

    当已经存储于卷中被使用的Secret被更新时,被映射的键也将终将被更新。 组件kubelet在周期性同步时检查被挂载的Secret是不是最新的。 但是,它会使用其本地缓存的数值作为Secret的当前值。

    不过,使用Secret作为子路径卷挂载的容器 不会收到Secret更新。

    将Secret导出到环境变量中

    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-env-pod
    spec:
      containers:
      - name: mycontainer
        image: redis
        env:
          - name: SECRET_USERNAME
            valueFrom:
              secretKeyRef:
                name: secret-test
                key: username
          - name: SECRET_PASSWORD
            valueFrom:
              secretKeyRef:
                name: secret-test
                key: password
      restartPolicy: Never
    

    启动pod,之后进入pod

    root@secret-env-pod:/data# echo $SECRET_USERNAME
    root
    root@secret-env-pod:/data# echo $SECRET_PASSWORD
    123456
    

    可以看到secret的值已经成功写入到环境变量中了

    Secret更新之后对应的环境变量不会被更新

    如果某个容器已经在通过环境变量使用某Secret,对该Secret的更新不会被 容器马上看见,除非容器被重启。有一些第三方的解决方案能够在Secret发生变化时触发容器重启。

    kubernetes.io/dockerconfigjson

    类型kubernetes.io/dockerconfigjson被设计用来保存JSON数据的序列化形式, 该 JSON 也遵从~/.docker/config.json文件的格式规则,而后者是~/.dockercfg的新版本格式。 使用此Secret类型时,Secret对象的 data 字段必须包含.dockerconfigjson键,其键值为base64编码的字符串包含~/.docker/config.json文件的内容。

    下面是一个kubernetes.io/dockercfg类型Secret的示例:

    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-dockercfg
    type: kubernetes.io/dockercfg
    data:
      .dockercfg: |
            "<base64 encoded ~/.dockercfg file>"
    

    kubernetes.io/service-account-token

    kubernetes.io/service-account-token: 用于被serviceaccount引用。serviceaccout创建时Kubernetes会默认创建对应的secret。Pod如果使用了serviceaccount,对应的 secret 会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中。

    $ kubectl run nginx --image nginx
      pod/nginx created
    $ kubectl get pods
      NAME             READY   STATUS              RESTARTS   AGE
      nginx            0/1     ContainerCreating   0          26s
    $ kubectl exec nginx ls /run/secrets/kubernetes.io/serviceaccount
      ca.crt
      namespace
      token
    

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

    不可更改的Secret

    Kubernetes对于SecretConfigMap提供了一种不可变更的配置选择,对于大量使用Secret的集群(至少有成千上万各不相同的SecretPod挂载), 禁止变更它们的数据有下列好处:

    • 防止意外(或非预期的)更新导致应用程序中断

    • 通过将 Secret 标记为不可变来关闭 kube-apiserver 对其的监视,从而显著降低 kube-apiserver 的负载,提升集群性能。

    Secretimmutable字段设置为true创建不可更改的Secret

    apiVersion: v1
    kind: Secret
    metadata:
      ...
    data:
      ...
    immutable: true
    

    1、当一个secret设置成不可更改,如果想要更改secret中的内容,就需要删除并且重新创建这个secret

    2、对于引用老的secret的pod,需要删除并且重新创建

    Secret与Pod生命周期的关系

    通过API创建Pod时,不会检查引用的Secret是否存在。一旦Pod被调度,kubelet就会尝试获取该Secret的值。如果获取不到该Secret,或者暂时无法与API服务器建立连接,kubelet将会定期重试。kubelet将会报告关于 Pod 的事件,并解释它无法启动的原因。 一旦获取到Secret,kubelet将创建并挂载一个包含它的卷。在Pod的所有卷被挂载之前,Pod中的容器不会启动。

    Secret与ConfigMap对比

    相同点:

    • key/value 的形式

    • 属于某个特定的 namespace

    • 可以导出到环境变量

    • 可以通过目录 / 文件形式挂载 (支持挂载所有 key 和部分 key)

    不同点:

    • Secret 可以被 ServerAccount 关联 (使用)

    • Secret 可以存储 register 的鉴权信息,用在 ImagePullSecret 参数中,用于拉取私有仓库的镜像

    • Secret 支持 Base64 加密

    • Secret 文件存储在 tmpfs 文件系统中,Pod 删除后 Secret 文件也会对应的删除。

    参考

    【Secret】https://feisky.gitbooks.io/kubernetes/content/concepts/secret.html
    【k8s官方对Secret的描述】https://kubernetes.io/zh/docs/concepts/configuration/secret/

  • 相关阅读:
    【题解】[USACO07OPEN]Dining G
    【学习笔记】拉格朗日插值
    【题解】简单的数学题
    docker-compose编排参数详解
    Harbor搭建企业级docker仓库
    centos7制作U盘启动盘
    c语言输入矩阵的对角线之和
    搭建rsync+inotify实现实时备份
    CentOS7添加自定义脚本服务
    Linux搭建NFS服务
  • 原文地址:https://www.cnblogs.com/ricklz/p/14946232.html
Copyright © 2020-2023  润新知