Kubernetes之Secret私密凭据

原创
半兽人 发表于: 2018-11-08   最后更新时间: 2020-10-23 17:37:40  
{{totalSubscript}} 订阅, 5,296 游览

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-1value-2

一旦Secret被创建,可以通过以下三个方式使用它:

  1. 在创建Pod时,通过为Pod指定ServiceAccount来自动使用该Seret;
  2. 通过挂载该Secret到Pod来使用它;
  3. 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
kindSecret
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是一样的。

更新于 2020-10-23

查看kubernetes更多相关的文章或提一个关于kubernetes的问题,也可以与我们一起分享文章