zoukankan      html  css  js  c++  java
  • kubernetes对象之secrets

    系列目录

    Secrets是Kubernetes中一种对象类型,用来保存密码、私钥、口令等敏感信息。与直接将敏感信息嵌入image、pod相比,Secrets更安全、更灵活,用户对敏感信息的控制力更强。同Docker对敏感信息的管理类似,首先用户创建Secrets将敏感信息加密后保存在集群中,创建pod时通过volume、环境变量引用Secrets。

    创建Secrets

    假设pod需要访问数据库。首先将用户名保存在文件./username.txt,将密码保存在./password.txt文件:

    # Create files needed for rest of example.
    $ echo -n 'admin' > ./username.txt
    $ echo -n '1f2d1e2e67df' > ./password.txt
    

    将两个文件作为参数运行如下命令创建Secret,此时敏感数据被保存在系统中:

    $ kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
    secret "db-user-pass" created
    

    用Secret名称查看创建Secret:

    $ kubectl get secrets
    NAME                  TYPE                                  DATA      AGE
    db-user-pass          Opaque                                2         51s
    
    $ kubectl describe secrets/db-user-pass
    Name:            db-user-pass
    Namespace:       default
    Labels:          <none>
    Annotations:     <none>
    
    Type:            Opaque
    
    Data
    ====
    password.txt:    12 bytes
    username.txt:    5 bytes
    

    以上通过命令行创建Secret,需要首先将敏感内容保存在文件中,文件名作为Secret中单条条目的key。另外一种创建Secret的方法是声明对象。敏感信息可能包含任何控制字符、不可显示字符等,首先进行base64编码:

    $ echo -n 'admin' | base64
    YWRtaW4=
    $ echo -n '1f2d1e2e67df' | base64
    MWYyZDFlMmU2N2Rm
    

    然后像下边这样声明Secret对象:

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    type: Opaque
    data:
      username: YWRtaW4=
      password: MWYyZDFlMmU2N2Rm
    

    Kubernetes用map存储Secret中的data数据部分,合法的key由字母、数字、’-‘、’_’、’.’组成,value可以是任何值,但要base64编码。运行如下命令创建Secret:

    通过如下方法查看Secret中key所对应的值,首先运行如下命令:

    $ kubectl get secret mysecret -o yaml
    apiVersion: v1
    data:
      username: YWRtaW4=
      password: MWYyZDFlMmU2N2Rm
    kind: Secret
    metadata:
      creationTimestamp: 2016-01-22T18:41:56Z
      name: mysecret
      namespace: default
      resourceVersion: "164619"
      selfLink: /api/v1/namespaces/default/secrets/mysecret
      uid: cfee02d6-c137-11e5-8d73-42010af00002
    type: Opaque
    

    运行如下命令base64解码:

    $ echo 'MWYyZDFlMmU2N2Rm' | base64 --decode
    1f2d1e2e67df
    

    使用Secrets

    Pod使用Secret的两种方法:volume与环境变量。

    通过volume使用Secret基于流程:

    创建或者使用已存Secret,同一Secret可被多个pod引用。
    修改pod定义,在.spec.volumes[]下增加新volume,名称随意。在相应的.spec.volumes[].secret.secretName指定Secret名称。
    为使用Secret的容器添加.spec.containers[].volumeMounts[],同时指定.spec.containers[].volumeMounts[].readOnly = true。指定.spec.containers[].volumeMounts[].mountPath为未使用的目录名称。
    在容器的image中,通过指定的目录与Secret中的key访问敏感内容。

    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: mysecret
    

    如果需要引用多个Secret,需要为每个Secret在.spec.volumes[]添加相应的条目。如果单个容器需要引用多个Secret,则在.spec.containers[].volumeMounts[]中为每个Secret添加Mount。可以将多个文件添加到一个Secret中,或者为每个文件创建Secret。

    默认情况下Secret中的所有key被映射到相同目录下,可以通过 .spec.volumes[].secret.items为key设定映射目录:

    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: mysecret
          items:
          - key: username
            path: my-group/my-username
    

    以上配置导致的结果为username被映射到/etc/foo/my-group/my-username,而非默认的/etc/foo/username,并且password未被映射。 如果不使用.spec.volumes[].secret.items,Secret中所有key被映射到默认目录,如果在.spec.volumes[].secret.items指定了key与特定的映射目录,则只映射列出的key。如果打算使用.spec.volumes[].secret.items并且映射所有Secret的key,那么需要列出Secret中所有key。

    可以在.spec.volumes[].secret.defaultMode中为Secret指定Permission,如果需要进一步在.spec.volumes[].secret.items[].mode为每个key单独指定permission。如果没有指定permission,默认为0644。示例如下:

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
      - name: mypod
        image: redis
        volumeMounts:
        - name: foo
          mountPath: "/etc/foo"
      volumes:
      - name: foo
        secret:
          secretName: mysecret
          defaultMode: 256
    

    上例中的256等于8进制的0400,在jsonyaml配置文件中不可以使用八进制表示数字。单位为key指定permission:

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

    当通过Secret通过volume形式被使用时,其中的key如果发生变更的话,由kubelet自动周期性监控变更并为pod更新,但是注意此特性并非实时,存在延迟。

    通过环境使用Secret流程:

    创建或者使用已存在Secrets,一个Secret可以被多个pod使用。
    修改pod声明中使用Secret的容器配置,为其添加环境变量env[].valueFrom.secretKeyRef,每条key对应一个环境变量。
    在容器的image中通过引用环境变量使用敏感数据。

    示例:

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

    Secrets限制条件

    • 创建Pod时需要对其使用的Secret进行有效性检查,因此Secrets要先于pod创建。

    • Secrets寄居于namespace之下,只有处于同一namespace下的pod可以引用

    • 单个Secret的size不能超过1M,防止Secrets占用太多内存引起apiServer性能恶化。但过多的Secrets仍然会占用大量的内在,关于限制所有Secrets占用内存的特性正在计划中。

    • kubelet在不经过apiServer、控制器创建pod,如–manifest-url、–config时不能使用Secrets。

    • 如果在创建pod时Secret不存在或者key不存在,pod不能启动。通过环境变量引用Secret时,如果envFrom中指定的key的名称不合法,pod仍然能启动但会触发相应错误事件,如:

    $ kubectl get events
    LASTSEEN   FIRSTSEEN   COUNT     NAME            KIND      SUBOBJECT                         TYPE      REASON
    0s         0s          1         dapi-test-pod   Pod                                         Warning   InvalidEnvironmentVariableNames   kubelet, 127.0.0.1      Keys [1badkey, 2alsobad] from the EnvFrom secret default/mysecret were skipped since they are considered invalid environment variable names.
    
  • 相关阅读:
    mysql5.7-Group Replication
    yum安装mariadb-galera同步
    开启tomcat的apr模式,并利用redis做tomcat7的session的共享。
    利用Xtrabackup在不停机的情况下备用数据库迁移
    open-falcon(v0.2)安装grafana部署
    open-falcon(v0.2)部署手册(源码编译)
    阿里云ECS主机自定义进程监控
    Open-Falcon第七步安装报警模块(小米开源互联网企业级监控系统)
    Open-Falcon第六步安装Dashboard(小米开源互联网企业级监控系统)
    Open-Falcon第五步安装Query(小米开源互联网企业级监控系统)
  • 原文地址:https://www.cnblogs.com/tylerzhou/p/10995791.html
Copyright © 2011-2022 走看看