Secret主要作用是保管私密数据,比如密码、OAuth Tokens、SSH Keys等信息。将这些私密信息放在Secret对象中比直接放在Pod或Docker Image中要更安全,也便于使用和分发。
下面的例子用于创建一个Secret,命名为secret.yaml:
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  password: dmfsdWUtMg0k
  username: dmfsdWUtMg0k
创建:
kubectl create -f secret.yaml
在上面的data域中的各子域的值必须为BASE64编码值,其中password域和username域BASE64编码前的值分别为value-1和value-2。
一旦Secret被创建,可以通过以下三个方式使用它:
- 在创建Pod时,通过为Pod指定ServiceAccount来自动使用该Seret;
- 通过挂载该Secret到Pod来使用它;
- Docker镜像下载时使用,通过指定Pod的spec.ImagePullSecrets来引用它;
第一种方式主要用在 API Server 鉴权方面;下面的例子展示了第二种使用方式:将一个Secret通过挂载的方式添加到Pod的Volume中。
apiVersion:v1
kind:Pod
metadata:
    name:mypod
    namespace:myns
spec:
    containers:
    - name:mycontainer
      image:redis
      volumeMounts:
      - name:foo
        mountPath:“/etc/foo”
        readOnly:true
volumes:
- name:foo
  secret:
      secretName:mysecret
第三种使用方式的使用流程如下:
(1)执行login命令,登录私有Registry
#docker login localhost:5000(输入账户及密码,如果是第1次登录则会创建新用户,并把相关信息写入~/.dockercfg文件中)
(2)用BASE64编码dockercfg的内容
#cat ~/.dockercfg|base64
(3)将上一步命令的输出结果作为Secret的“data.dockercfg”域的内容,由此来创建一个Secret
image-pull-secret.yaml:
apiVersion:v1
kind:Secret
metadata:
    name:myregistrykey
data:
    .dockercfg:oiu09joiu09ujlih8hkjh98...
type:kubernetes.io/dockercfg
# kubectl create -f image-pull-secret.yaml
(4)在创建Pod的时候引用该Secret
pods.yaml
apiVersion:v1
kind:Pod
metadata:
  name:mypod2
spec:
  containers:
    - name:foo
    image:janedoe/awexomeapp:v1
  imagePullSecrets:
    - name:myregistrykey
# kubectl create -f pods.yaml
每个单独的Secret大小不能超过1M,Kubernetes不鼓励创建大尺寸的Secret,因为如果使用大尺寸的Secret,则将大量占用API Server和kubelet的内存。当然创建许多小的Secret也能耗尽API Server和kubelet的内存。
在使用Mount方式挂载Secret时,Container中Secret的“data”域的各个域的key值作为目录中的文件,Value值被BASE64编码后存储在相应的文件中。前面的例子中创建的Secret,被挂载到一个叫做mycontainer的container中。
在该container中可以通过命令查看所生产的文件和文件中的内容:
# ls /etc/foo
username
password
# cat /etc/foo/username
value-1
# cat /etc/foo/password
value-2
关于Secret的一些知识点:
- 我们可以通过Secret保管其他系统的敏感信息(比如数据库用户名和密码),并以Mount的方式将Secret挂载到Container中,然后通过访问目录中的文件的方式获取该敏感信息。 
- 当Pod被API Server创建时,API Server不会校验该Pod引用的Secret是否存在。 
- 一旦这个Pod被调度,则Kubelet将试着获取Secret的值。如果Secret不存在或暂时无法连接到API Server,则kubelet将按一定的时间间隔定期重试获取该Secret,并发送一个Event来解释Pod没有启动的原因。一旦Secret被Pod获取,则Kubelet将创建并Mount包含Secret的Volume。 
- 只有所有的Volume被Mount后,Pod中的Container才会被启动。 
- 在kubelet启动Pod中container后,Container中和Secret相关的Volume将不会被改变,即使Secret本身被修改了。 
- 为了使用更新后的Secret,必须删除旧的Pod,并重新创建一个新的Pod,因此更新Secret的流程和部署一个新的Image是一样的。 
 
                             
        