Kuberbetes的Secret

背景

Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 将这些信息放在secret中比放在 Pod 的定义、容器镜像中、相对于ConfigMap说更加安全和灵活。 Secret是标准的k8s资源对象,使用方法和ConfigMap非常类似。同时我们可以对Secret进行访问控制,防止机密数据被访问

概念

Secret有三种类型:

  •     Service Account:Pod中的进程用来访问Kubernetes API的凭证,由Kubernetes自动创建,也可以手动创建。当在资源清单的定义中引用自定义的Service Account,如果没有引用,会使用当前namespace下默认的ServiceAccount,并且会自动挂载到容器的/run/secrets/kubernetes.io/serviceaccount路径下。有关ServiceAccount的详细内容可以查看k8s中的访问控制。
  •     Opaque:base64编码格式的Secert,用来存储密码、密钥等。该数据是key:value类型的。
  •     kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。

创建Secret

命令行的方式创建Secret

查看创建命令

[root@k8s-master01 secret]# kubectl create secret --help
Create a secret using specified subcommand.

Available Commands:
  docker-registry 创建一个给 Docker registry 使用的 secret
  generic         从本地 file, directory 或者 literal value 创建一个 secret 本质上是Opaque类型的Secret
  tls             创建一个 TLS secret

可以创建3中类型的Secret:1. docker拉取镜像的凭证、2. base64加密的密文 、3. ca证书的密文

命令行创建Opaque类型的Secret

使用命令行创建ConfigMap的命令类似。支持从文件夹、单个文件、key=value类型的文件、键值对等方式创建Secret。
解释说明:

    使用--from-file的方式,文件中的数据不用使用base64加密。和ConfigMap类似,如果不指定key的名称,默认使用文件名。
    使用--from-literal。使用key1=value1的方式,value1不用base64加密,但是需要使用’'单引号括起来进行反转义。
    其余和ConfigMap基本一致,这里不再赘述。
案例演示:
我们可以将连接mysql数据库的用户名和密码使用Secret保存起来

# 创建本例中要使用的文件
echo -n 'admin' > ./username.txt
echo -n '1f2d1e2e67df' > ./password.txt

kubectl create secret 命令将这些文件打包到一个 Secret 中并在 API server 中创建了一个对象。

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

查看一下刚才创建的Secret 使用yaml的方式查看kubectl get secret db-user-pass -o yaml

apiVersion: v1
data:
  password.txt: MWYyZDFlMmU2N2Rm
  username.txt: YWRtaW4=
kind: Secret
metadata:
  creationTimestamp: "2020-09-16T09:13:12Z"
  name: db-user-pass
  namespace: default
  resourceVersion: "35680"
  selfLink: /api/v1/namespaces/default/secrets/db-user-pass
  uid: 2ecf89d5-bdaf-4b91-ac45-d568061e8e52
type: Opaque

命令行创建docker registry类型的Secret

kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL

Secret的作用是在kubelet拉取镜像的时候,如果该镜像需要认证,该Secret可以作为拉取镜像的凭证。在pod.spec.imagePullSecrets可以引用创建的Secret

yaml文件的方式创建Secret

创建secret加密数据  编码base64

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type:
  Opaque
data:
  username: YWRtaW4K
  password: YWRtaW4K

使用Secret

两种挂载方式

1、变量形式挂载

Pod.spec.containers下使用env或者是envFromSecret中的数据加载到容器的环境变量中。envenvFrom和引用ConfigMap类似。
使用env方式的资源清单。pod-env.yaml

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: nginx
    image: nginx
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: username
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: username

创建Pod kubectl apply -f pod-env.yaml

查看结果

[root@test yaml]# kubectl apply -f secret-var.yaml
pod/mypod created
[root@test yaml]# kubectl get pods
NAME                   READY   STATUS      RESTARTS   AGE
ds-test-gs6z5          1/1     Running     0          8h
ds-test-xfjgt          1/1     Running     0          8h
mypod                  1/1     Running     0          3m20s
pi-pdwmx               0/1     Completed   0          5h12m
web-586db47859-6vpfr   1/1     Running     0          32h
web-586db47859-8hmxs   1/1     Running     0          32h
web-586db47859-wspl7   1/1     Running     0          32h
[root@test yaml]# kubectl exec -it mypod bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@mypod:/# ls
bin  boot  dev    docker-entrypoint.d  docker-entrypoint.sh  etc    home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@mypod:/# echo $SECRET_USERNAME
admin
root@mypod:/# echo $SECRET_PASSWORD
admin
root@mypod:/# exit
exit

2、将Secret挂在到Volume下,且键名映射到特定路径

在 Pod 中使用存放在卷中的 Secret:

    创建一个 Secret 或者使用已有的 Secret。多个 Pod 可以引用同一个 Secret。
    将 spec.containers[].volumeMounts[] 加到需要用到该 Secret 的容器中。 指定 spec.containers[].volumeMounts[].readOnly = true 和 spec.containers[].volumeMounts[].mountPath 为你想要该 Secret 出现的尚未使用的目录。
    修改你的 Pod 定义,在 spec.volumes[] 下增加一个卷。可以给这个卷随意命名, 它的spec.volumes[].secret.secretName 必须是 Secret 对象的名字。
    修改你的镜像并且/或者命令行,让程序从该目录下寻找文件。 Secret 的 data 映射中的每一个键都对应 mountPath 下的一个文件名。
    如果想要使用Secret中的某些key,且想要映射到特定路径下,类似于ConfigMap使用items

案例演示:
资源清单 pod-secret-volume.yaml

apiVersion: v1
kind: Pod
metadata:
  name: mypod1
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
      - name: foo
        mountPath: "/etc/foo"
        readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret

创建Secret。kubectl apply -f pod-secret-volume.yaml
查看Pod里面的容器的文件的数据。kubectl exec pod1 cat /etc/foo/my-group/my-username => admin
可以看到Secret里面的数据被加载到/etc/foo/my-group/my-username文件下。/etc/foo/是挂载的路径,my-group/my-username是定义的子路径和文件名。文件的内容已经base64解密过了。

查看结果

[root@test yaml]# kubectl apply -f secret-volume.yaml 
pod/mypod1 created
[root@test yaml]# kubectl get pods
NAME                   READY   STATUS      RESTARTS   AGE
ds-test-gs6z5          1/1     Running     0          8h
ds-test-xfjgt          1/1     Running     0          8h
mypod                  1/1     Running     0          9m41s
mypod1                 1/1     Running     0          7s
pi-pdwmx               0/1     Completed   0          5h19m
web-586db47859-6vpfr   1/1     Running     0          32h
web-586db47859-8hmxs   1/1     Running     0          32h
web-586db47859-wspl7   1/1     Running     0          32h
[root@test yaml]# kubectl exec -it mypod1 bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@mypod1:/# cat /etc/f  
fonts/ foo/   fstab  
root@mypod1:/# cat /etc/foo/
..2020_12_11_12_17_56.196281452/ ..data/                          password                         username
root@mypod1:/# cat /etc/foo/password 
admin
root@mypod1:/# cat /etc/foo/username 
admin
root@mypod1:/# exit
exit

 Secret和ConfigMap对比

相同点:
    key/value的形式
    属于某个特定的namespace
    可以导出到环境变量
    可以通过目录/文件形式挂载(支持挂载所有key和部分key)
不同点:
    Secret可以被ServerAccount关联(使用)
    Secret可以存储register的鉴权信息,用在ImagePullSecret参数中,用于拉取私有仓库的镜像
    Secret支持Base64加密
    Secret分为kubernetes.io/Service Account,kubernetes.io/dockerconfigjson,Opaque三种类型,Configmap不区分类型
    Secret文件存储在tmpfs文件系统中,Pod删除后Secret文件也会对应的删除。这里删除的是Secret的副本

posted @ 2020-12-11 20:39  fat_girl_spring  阅读(141)  评论(0编辑  收藏  举报