12-敏感的资料怎么存在K8S-Secret

前言

今天的学习笔记将介绍Kubernetes另一个组件secret。secret协助开发者将一些敏感信息,像是数据库账密、访问其它server的access token、ssh key,用非明文的方式(opaque)存放在Kubernetes中。今天的学习笔记内容如下:

  • 什么是secret

  • 实操:Kubernetes中如何创建secret对象

  • 实操:如何挂载secret对象到pod中

小提醒:今天的源码可以在demo-secret中找到。

什么是secret

正如前言提及的,secret是Kubernetes提供给开发者一种存放敏感信息的方式。Kubernetes本身也使用相同的机制(secret mechanism)存放access token,限制API的存取权限,确保不会有外部服务随意操作Kubernetes API。

在Kubernetes存取敏感资料(sensitive data)有以下几种常见的使用方式:

  • 将secret当成环境变量(environment variable)使用;

  • 将secret file挂载(mount)在pod某个文件路径下使用;

  • 将这些sensitive data统一存放在某一个docker image中,并将这个image存放在私有的image registry中,通过image pull下载到Kubernetes cluster中,让其它pod存取。

今天实操的部分,将针对上述提到的前两点进行介绍。

实操:Kubernetes中如何创建secret对象

在Kubernetes中,创建secret对象又一下几种方法:

  1. 从文件导入sensitive data

    我们可以先将sensitive data存在某一个文件中,通过kubectl create命令产生一个secret对象。

    以账号密码为例,我们先将账号、密码分别存入两个不同的文件,

    $ echo -n "root" > ./username.txt
    $ echo -n "rootpass" > ./password.txt

    接着使用kubectl create secret generic命令创建一个secret对象,

    $ kubectl create secret generic demo-secret-from-file \
    --from-file=./username.txt \
    --from-file=./password.txt
    secret "demo-secret-from-file" created

    用kubectl describe命令查看demo-secret-from-file对象,

     

    若用kubectl get查看所有的secret,

    $ kubectl get secrets
    NAME                    TYPE                                  DATA      AGE
    default-token-cljjb     kubernetes.io/service-account-token   3         4m
    demo-secret-from-file   Opaque                                2         3m

    会发现除了刚刚创建好的demo-secret-from-file,还有一组default-token-cljjb对象,这是Kubernetes内部帮我们创建好的对象。里面存放着一个token,开发者可以通过这组access token来操控Kubernetes API。

  2. 从命令输入sensitive data

    我们也可以通过kubectl create命令搭配--from-literal直接在命令后面输入信息,以上述的账密为例,

    $ kubectl create secret generic demo-secret-from-literal \
    > --from-literal=username=root \
    > --from-literal=password=rootpass
    ​
    secret "hello-secret-literal" created

    用kubectl describe查看demo-secret-from-literal详情,

     

  3. 通过yaml创建secret对象

    我们也可以通过配置文件创建一个secret对象。

    首先,需将账号密码用 base64 编码,以username=root,password=rootpaas为例,

    $ echo -n "root" | base64
    cm9vdA==
    ​
    $ echo -n "rootpass" | base64
    cm9vdHBhc3M=

    并将编码过的资料写入my-secret.yaml中,

    apiVersion: v1
    kind: Secret
    metadata:
      name: demo-secret-from-yaml
    type: Opaque
    data:
      username: cm9vdA==
      password: cm9vdHBhc3M=

    通过kubectl create创建一个新对象,

    $ kubectl create -f ./my-secret.yaml
    secret "demo-secret-from-yaml" created

    最后可以使用kubectl get secret查看今天创建的3个secret对象,

    $ kubectl get secrets
    NAME                TYPE                            DATA    AGE
    default-token-cljjb kubernetes.io/service-account-token 3   8m
    demo-secret-from-file           Opaque  2   7m
    demo-secret-from-literal        Opaque  2   2m
    demo-secret-from-yaml           Opaque  2   16s

    下个章节将通过这些我们创建好的secret对象,介绍如何将这些secret对象挂载到pod使用。

    如何挂载secret对象到pod中

    1. 将secret当成环境变量(environment variable)使用

      以my-pod.yaml为例,

      apiVersion: v1
      kind: Pod
      metadata:
        name: my-pod
        labels:
          app: webserver
      spec:
        containers:
        - name: demo-pod
          image: zxcvbnius/docker-demo
          ports:
          - containerPort: 3000
          env:
          - name: SECRET_USERNAME
            valueFrom:
              secretKeyRef:
                name: demo-secret-from-yaml
                key: username
          - name: SECRET_PASSWORD
            valueFrom:
              secretKeyRef:
                name: demo-secret-from-yaml
                key: password

      在my-pod.yaml中,我们设置env会从指定的secret对象找出对应的值。值得一提的是,如果该secret对象是从--from-file创建,那么Kubernetes会把文件名称当成key、文件内容当成value。

      使用kubectl create创建my-pod,命令如下,

      $ kubectl create -f ./my-pod.yaml
      pod "my-pod" created

      当my-pod创建完毕后,

      $ kubectl get pods my-pod
      NAME	READY	STATUS	RESTARTS	AGE
      my-pod	1/1		Running	0			5m

      我们可以通过kubectl exec进入到my-pod中,

      $ kubectl exec -it my-pod -- /bin/bash

      查看SECRET_USERNAME/SECRET_PASSWORD,如我们在demo-secret-from-yaml设置一致,

      $ kubectl exec -it my-pod -- /bin/bash
      root@my-pod:/app#echo $SECRET_USERNAME
      root
      root@my-pod:/app#echo $SECRET_PASSWORD
      rootpaas
    2. 将secret file挂载(mount)在pod某个文件路径下使用

      我们也可以将secret挂载到,pod底下的某个路径文件,以my-pod-with-mounting-secret.yaml为例,

      apiVersion: v1
      kind: Pod
      metadata:
        name: my-pod-with-mounting-secret
        labels:
          app: webserver
      spec:
        containers:
        - name: demo-pod
          image: zxcvbnius/docker-demo
          ports:
          - containerPort: 3000
          volumeMounts:
          - name: secret-volume
            mountPath: /etc/creds
            readOnly: true
        volumes:
        - name: secret-volume
          secret:
            secretName: demo-secret-from-yaml

      如同创建my-pod.yaml一样,使用kubectl create命令创建一个新的pod对象,

      $ kubectl create -f ./my-pod-with-mounting-secret.yaml
      pod "my-pod-with-mounting-secret" created

      通过kubectl exec进入my-pod-with-mounting-secret这个对象,且可以在我们指定挂载的/etc/creds找到存在 demo-secret-from-yaml中的材料,

      $ kubectl exec -it my-pod-with-mounting-secret -- /bin/bash
      root@my-pod-with-mounting-secret:/app# ls /etc/creds
      root@my-pod-with-mounting-secret:/app# echo "$(cat /etc/creds/username)"
      root@my-pod-with-mounting-secret:/app# echo "$(cat /etc/creds/password)"

      通过以上两种方式,我们便能再pod中存取secret对象。

      总结

      当我们有些敏感信息需要传入Kubernetes时,使用secret是个不错的选择。然而,需要留意的是,一旦建立secret对象,其他人也可以在Kubernetes cluster上存取secret中的敏感信息。因此,我们需要搭配 Service Account 来限制其他人的存取权限,在之后28-如何在K8S管理不同的项目-namespace也会与大家分享如何设置。

      Q&A

      依然欢迎大家给予建议与回复, 如果能够一键三连 点个赞给些鼓励也是很开心的 :)

      参考链接

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐