Secret 介绍

secret 它是用于管理敏感信息的 api 对象。就类似于程序中的配置文件,在写项目时,对于数据库的用户名和密码都是存放在配置文件中,而不是直接写死在代码中。

secret 把 pod 想要访问的加密数据存放到 etcd 中。然后用户就可以通过在 Pod 的容器里挂载 Volume 的方式或者环境变量的方式访问到这些 Secret 里保存的信息了。

Secret 目前有八种类型,但常用的有以下三种:

  • Opaque:base64 编码格式的 Secret,用来存储密码、密钥等;但数据是可以通过base64–decode 解码得到原始数据,所以加密性很弱。
  • kubernetes.io/service-account-token:用来存放标识某 serviceAccount 的令牌凭据。当创建 serviceAccount 账户时会自动创建;也可以自己手动创建,但前提是必须先创建了 serviceAccount 对象。
  • kubernetes.io/dockerconfigjson: 用来存储私有 docker registry 的认证信息。

Opaque 类型

Opaque 类型的数据是一个 map 类型,要求value是base64编码。

base64加密
$ echo -n 'admin' | base64
YWRtaW4=

$ echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm


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

这里需要注意的是,像这样创建的 Secret 对象,它里面的内容仅仅是经过了转码,而并没有被加密。在真正的生产环境中,你需要在 Kubernetes 中开启 Secret 的加密插件,增强数据的安全性。

kubernetes.io/service-account-token 类型

Service Account 对象的作用,就是 Kubernetes 系统内置的一种“服务账户”,它是 Kubernetes 进行权限分配的对象。比如, Service Account A,可以只被允许对 Kubernetes API 进行 GET 操作,而 Service Account B,则可以有 Kubernetes API 的所有操作权限。

 

Secret 用来存放标识某 serviceAccount 的令牌凭据。

 

使用这种 Secret 类型时,应该先创建 ServiceAccount 对象,然后将 serviceAccount 的name 放到该 secret 注解 kubernetes.io/service-account-name 中。

 

如果不知道什么是 serviceAccount ,那就说明这个东西对目前的我们没用,之后会介绍到。

kubernetes.io/dockerconfigjson 类型

用来创建用户 docker registry 认证的 Secret,直接使用 kubectl create 命令创建即可,如下:

kubectl create secret docker-registry myregistry --docker-server=DOCKER_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL

如果我们需要拉取私有仓库中的docker镜像的话就需要使用到上面的myregistry这个Secret

apiVersion: v1
kind: Pod
metadata:
  name: foo
spec:
  containers:
  - name: foo
    image: 192.168.1.100:5000/test:v1
  imagePullSecrets:
  - name: myregistry

Secret 创建

kubectl create secret 命令

username.txt和password.txt文件内容如下:

$ cat ./username.txt

admin

$ cat ./password.txt

1f2d1e2e67df

generic子命令可以通过本地文件、目录或者literal(键值对)

$ kubectl create secret generic user --from-file=./username.txt

$ kubectl create secret generic pass --from-file=./password.txt

 默认情况下key为文件名

或者直接通过键值对创建

$ kubectl create secret generic user --from-literal=username=admin

$ kubectl create secret generic pass --from-literal=password=1f2d1e2e67df

 

通过 yaml 文件创建

#secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data: 
  user: YWRtaW4= 
  pass: MWYyZDFlMmU2N2Rm

kubectl create -f secret.yaml

secret使用

通过Volume挂载的方式

# test-projected-volume.yaml

 
apiVersion: v1
kind: Pod
metadata:
  name: test-projected-volume
spec:
  containers:
  - name: test-secret-volume
    image: busybox
    args:
    - sleep
    - "86400"
    volumeMounts:
    - name: mysql-cred
      mountPath: "/projected-volume"
      readOnly: true
  volumes:
  - name: mysql-cred
    projected:
      sources:
      - secret:
          name: user
      - secret:
          name: pass

创建pod对象

kubectl create -f test-projected-volume.yaml
 

当 Pod 变成 Running 状态之后,我们再验证一下这些 Secret 对象是不是已经在容器里了: 

$ kubectl exec -it test-projected-volume -- /bin/sh

$ ls /projected-volume/
user
pass

$ cat /projected-volume/user
admin

$ cat /projected-volume/pass
1f2d1e2e67df

通过环境变量

#pod-secret-env.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret-env
spec:
  containers:
  - name: myapp
    image: busybox
    args:
    - sleep
    - "86400"
    env:
    - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: user
    - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: pass
    restartPolicy: Never
 

volume 挂载 和 环境变量的区别

通过Volume挂载到容器内部时,当该Secret的值发生变化时,容器内部具备自动更新的能力;

但是通过环境变量设置到容器内部该值不具备自动更新的能力。所以一般推荐使用Volume挂载的方式使用Secret。

 

Secret 与 ConfigMap 对比

相同点:

key/value 的形式

属于某个特定的 namespace

可以导出到环境变量

可以通过目录/文件形式挂载

通过 volume 挂载的配置信息均可热更新

不同点:

Secret 可以被 ServerAccount 关联

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

Secret 支持 Base64 加密

Secret 分为 kubernetes.io/service-account-token、kubernetes.io/dockerconfigjson、Opaque 三种类型,而 Configmap 不区分类型

secret volume 用于将敏感信息(密码)传递给 pod。可以将 secrets 存储在 k8s API 中,使用的时候以文件的形式挂载到 pod 中,而不用连接 api。

secret 最典型的场景,莫过于存放数据库的 Credential 信息,如:

apiVersion: v1
kind: Pod
metadata:
name: test-projected-volume
spec:
containers
- name: test-secret-volume
   image: busybox
   args:
   - sleep
   - "86400"
  volumeMounts:
  - name: mysql-cred
    mountPath: "/projected-volume"
    readOnly: true
volumes:
- name: mysql-cred
  projected:
    sources:
    - secret:
        name: user
    - secret:
        name: pass

在这个 Pod 中,它声明挂载的 Volume 是 projected 类型。而这个 Volume 的数据来源(sources),则是名为 user 和 pass 的 Secret 对象,分别对应的是数据库的用户名和密码。

这里用到的数据库的用户名、密码,正是以 Secret 对象的方式交给 Kubernetes 保存的。完成这个操作的指令,如下所示:

$ cat ./username.txt
admin

$ cat ./password.txt
c1oudc0w!


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

其中,username.txt 和 password.txt 文件里,存放的就是用户名和密码;而 user 和 pass,是 Secret 对象指定的名字。

查看 Secret 对象的话,执行 kubectl get 命令:

$ kubectl get secrets
NAME           TYPE                                DATA      AGE
user          Opaque                                1         51s
pass          Opaque                                1         51s

除了使用 kubectl create secret 指令外,也可以直接通过编写 YAML 文件的方式来创建这个 Secret 对象,比如:

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  user: YWRtaW4=
  pass: MWYyZDFlMmU2N2Rm

END 

Logo

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

更多推荐