• K8S Secrete详解2


    k8s通过secret管理敏感信息

     

    应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名密码或者秘钥。将这些信息直接保存在容器镜像中显然不妥,Kubernetes 提供的解决方案是 Secret。

    Secret 会以密文的方式存储数据,避免了直接在配置文件中保存敏感信息。Secret 会以 Volume 的形式被 mount 到 Pod,容器可通过文件的方式使用 Secret 中的敏感数据;此外,容器也可以环境变量的方式使用这些数据。

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

    1. 用户名 admin

    2. 密码 123456

    1.创建 Secret方式

    有四种方法创建 Secret:

    1.1 通过 --from-literal

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

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

    1.2 通过 --from-file

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

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

    1.3通过 --from-env-file

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

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

    1.4通过 YAML 配置文件:

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

     

    执行 kubectl apply 创建 Secret:

    2.查看secret

    2.1通过 kubectl get secret 查看存在的 secret

    显示有两个数据条目

    2.2通过kubectl describe secret 查看条目的 Key

    2.3通过kubectl edit secret mysecret 查看vlaue

    2.4通过base64将value反解码

    3.vloume方式secret的使用

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

    Pod 的配置文件如下所示:

    ① 定义 volume foo,来源为 secret mysecret

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

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

     

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

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

     

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

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

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

    4.环境变量中使用secret

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

     创建 Pod 并读取 Secret。

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

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

    Secret 可以为 Pod 提供密码、Token、私钥等敏感数据;对于一些非敏感数据,比如应用的配置信息,则可以用 ConfigMap

     
     

    一、启动应用安全信息的保护:

    Secret介绍:

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

     

    创建 Secret

    四种方法创建 Secret:
     

    1. 通过 --from-literal

    kubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=123
    kubectl get secret
    [root@cicd ~]# kubectl get secret
    NAME                  TYPE                                  DATA      AGE
    default-token-g44kp   kubernetes.io/service-account-token   3         3d
    mysecret              Opaque                            2         9s
    每个 --from-literal 对应一个信息条目。
     

     

    2. 通过 --from-file

    echo -n admin > ./username
    echo -n 123 > ./password
    kubectl create secret generic yoursecret --from-file=./username --from-file=./password
    每个文件内容对应一个信息条目。
    [root@cicd yml]# cat username 
    admin[root@cicd yml]# cat password 
    123[root@cicd yml]#
     

    3. 通过 --from-env-file

    cat << EOF > env.txt
    username=admin
    password=123456
    EOF
     
    kubectl create secret generic mysecret --from-env-file=env.txt
    文件 env.txt 中每行 Key=Value 对应一个信息条目。

    4. 通过 YAML 配置文件:

     
    文件中的敏感数据必须是通过 base64 编码后的结果。
    复制代码
    echo -n admin | base64
    
     YWRtaW4=

    echo -n 123 | base64

    YWJj
    复制代码
    复制代码
     然后编写以下文件,添加关键参数。

    [root@cicd yml]# cat secret.yml apiVersion: v1 kind: Secret metadata: name: yoursecret data: username: YWRtaW4= password: YWJj
    复制代码

     data的数据以key:value的形式写入。

    执行 kubectl apply 创建 Secret
     
     

    然后通过 base64 将 Value 反编码:
    [root@cicd yml]# echo -n YWRtaW4=|  base64 --decode      #-n 不换行
    admin[root@cicd yml]# echo -n YWJj |  base64 --decode
    abc[root@cicd yml]#

     

    二、secret在pod中的应用:

    volume 方式使用 Secret

    Pod 可以通过 Volume 或者环境变量的方式使用 Secret,先学习 Volume 方式。
    (1)Pod 的配置文件如下所示:
      cat pod2.yml
     
     
    ① 定义 volume foo,来源为 yoursecret
    ② 将 foo mount 到容器路径 /etc/foo,可指定读写权限为 readOnly
     3.定义pod名称
     4. 挂载的目录名与宿主机映射的目录同名。
     

     

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

    [root@cicd yml]# kubectl get pod
    NAME       READY     STATUS              RESTARTS   AGE
    mypod-c3   1/1       Running             3          2h
    mypod-c4   1/1       Running             2          1h
    mypod3     0/1       ContainerCreating   0          42s

    可以看到mypod3正在创建,这一状态的原因有2;

    一是因为延迟,等会就行

    二是因为报错,执行

    [root@cicd yml]# kubectl describe pod mypod3
    进入mypod3查看详细状态信息,如果报错根据报错做出反应。

    创建完后,我们进入mypod3验证:

    [root@cicd yml]# kubectl exec -it mypod3 sh

    可以看到,Kubernetes 会在指定的路径 /etc/foo 下为每条敏感数据创建一个文件文件名就是数据条目的 Key,这里是 /etc/foo/username 和 /etc/foo/password,Value 则以明文存放在文件中。
     
     
     
    (2)我们也可以自定义存放数据的文件名,比如将配置文件改为:
    这时数据将分别存放在 /etc/foo/my-group/my-username 和 /etc/foo/my-group/my-password 中。
     执行创建mypod4:
    [root@cicd yml]# kubectl exec -it mypod4 sh
    error: unable to upgrade connection: container not found ("mypod")
    如果报此错,则是因为创建的pod不成功,即error或者正在创建中。
     
    创建完毕后,我们进入mypod4的/etc/foo路径查看。
     Volume 方式使用的 Secret 支持动态更新:Secret 更新后,容器中的数据也会更新。
     
    将 password 更新为 mdzz,base64 编码为 YWJjZGVm
    [root@cicd yml]# echo -n mdzz | base64
    bWR6eg==
     
    更新 Secret。

    重新执行secret.yml文件

    几秒钟后出现此报错:
    cat: can't open 'my-password': No such file or directory
    sh: getcwd: No such file or directory

    这是因为改变的密码正在生效,重新进入/etc/foo发现新的 password 已经同步好了。
     
    /etc/foo/..2019_06_24_09_42_04.419998613/my-group # cat my-password 
    mdzz/etc/foo/..2019_06_24_09_42_04.419998613/my-group # 
     

     

    环境变量方式使用 Secret

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

    注意上图里的key:username和key:password是对应secret.yml文件里的

    所以一定要注意书写,不然是无法通过环境变量方式使用secret的。

    然后创建 Pod。
    [root@cicd yml]# kubectl apply -f pod4.yml
    pod "mypod5" created

    通过环境变量 SECRET_USERNAME 和 SECRET_PASSWORD 成功读取到 Secret 的数据。
    复制代码
    [root@cicd yml]# kubectl get pod
    NAME      READY     STATUS    RESTARTS   AGE
    mypod5    1/1       Running   0          56s
    [root@cicd yml]# kubectl exec-it mypod5 sh
    / # echo $SECRET_USERNAME
    admin
    / # echo $SECRET_PASSWORD
    mdzz
    复制代码
    需要注意的是,环境变量读取 Secret 很方便,但无法支撑 Secret 动态更新
    Secret 可以为 Pod 提供密码、Token、私钥等敏感数据
     
     

                  k8s

                   docker

    108、如何使用 Secret? (Swarm15)

     
     
    我们经常要想容器传递敏感信息,最常见的就是密码。比如:
     
    docker run -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql
     
    在启动 Mysql 容器时,我们通过环境变量 MYSQL_ROOT_PASSWORD 设置 mysql 的管理员密码。不过密码是以明文的形式写在了 docker run 命令中,有潜在的安全隐患。
     
    为了解决这个问题, docker swarm 提供了secret 机制,允许将敏感信息加密后保存到secret 中,用户可以指定哪些容器可以使用此 secret。
     
    如果使用 secret 启动 Mysql 容器,方法是:
     
    root@host03:~# echo 'my-secret-pw' | docker secret create my_secret_data1 -    #    创建一个secret
    z04oyb43x6brtvpdel6bqc7rv
     
    root@host03:~# docker secret ls    #    查看 secret 列表
    ID                          NAME                DRIVER              CREATED             UPDATED
    z04oyb43x6brtvpdel6bqc7rv   my_secret_data1                         7 seconds ago       7 seconds ago
     
    root@host03:~# docker secret inspect my_secret_data1    #    查看 secret详细信息
    [
        {
            "ID": "z04oyb43x6brtvpdel6bqc7rv",
            "Version": {
                "Index": 13493
            },
            "CreatedAt": "2019-05-16T02:05:11.083477558Z",
            "UpdatedAt": "2019-05-16T02:05:11.083477558Z",
            "Spec": {
                "Name": "my_secret_data1",
                "Labels": {}
            }
        }
    ]
     
    root@host03:~# docker service create --name mysql --secret source=my_secret_data1,target=mysql_root_password -e MYSQL_ROOT_PASSWORD_FILE="/run/secrets/mysql_root_password" mysql
    4epm4b3arpzetqra3vuveqgq5
    overall progress: 1 out of 1 tasks
    1/1: running   [==================================================>]
    verify: Service converged
     
    root@host03:~# docker service ps mysql
    ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
    8icyti1vg03n        mysql.1             mysql:latest        host02              Running             Running 5 minutes ago                       
     
    root@host02:~# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
    74ae17815637        mysql:latest        "docker-entrypoint.s…"   57 seconds ago      Up 56 seconds       3306/tcp, 33060/tcp   mysql.1.8icyti1vg03nlmp87zna0vw4g
     
    root@host02:~# docker exec mysql.1.8icyti1vg03nlmp87zna0vw4g cat /run/secrets/mysql_root_password    #    在容器中可以看到未加密的密码
    my-secret-pw
     
     
     
    docker service create --name mysql
    --secret source=my_secret_data1,target=mysql_root_password                     #    source指定容器使用secret后,secret会被解密并存放到容器中 /run/secret/<filename>,其中filename由tatget指定
    -e MYSQL_ROOT_PASSWORD_FILE="/run/secrets/mysql_root_password"     #    环境变量 MYSQL_ROOT_PASSWORD_FILE 从容器中指定的文件 /run/secret/<filename> 中获得(明文)
    mysql
     
    这里可能会有两个问题:
     
    1、在第一步创建secret时,不是也使用明文了吗?这跟在环境变量中直接指定密码有什么不同?
     
        在我们的例子中创建secret和使用secret是分开完成的,其好处是将密码和容器解耦。secret可以有专人(比如管理员)负责,而运行容器的用户只需要使用secret但并不需要知道secret的内容。也就是说例子中的两个步骤可以由不同的人在不同的时间完成。
     
    2、secret是以文件形式mount到容器中,容器怎么知道去哪里读取呢?
     
        这需要image的支持,如果image希望他部署出来的容器能够从secret中读取数据,那么此image就应该提供一种方式,让用户能够制定secret的位置。最常用的方法就是通过环境变量,Docker的很多官方image都采用这种方式,比如Mysql镜像同事提供了MYSQL_ROOT_PASSWORD 和 MYSQL_ROOT_PASSWORD_FILE 两个环境变量。
  • 相关阅读:
    BZOJ 1724: [Usaco2006 Nov]Fence Repair 切割木板 贪心 + 堆 + 反向思考
    BZOJ 1715: [Usaco2006 Dec]Wormholes 虫洞 DFS版SPFA判负环
    qqq
    爬虫的盗亦有道Robots协议
    Requests库
    常用的re模块的正则匹配的表达式
    python -服务器与客户端断电续传程序详细介绍
    模拟ssh远程执行命令,粘包问题,基于socketserver实现并发的socket
    python大佬养成计划----基于flask_sqlalchemy的网页显示数据库信息
    python实战----Todo清单续写
  • 原文地址:https://www.cnblogs.com/panpanwelcome/p/13633209.html
Copyright © 2020-2023  润新知