出于增强可移植性的需求,我们应该从容器镜像中解耦的不仅有配置数据,还有默认口令(例如 Redis 或 MySQL 服务的访问口令)、用于 SSL 通信时的数字证书和私钥、用于认证的令牌和 ssh key 等,但这些敏感数据不宜存储于 ConfigMap 资源中,而是要使用另一种称为 Secret 的资源类型。
Secret 对象存储数据的机制及使用方式都类似于 ConfigMap 对象,它们以键值方式存储数据,在 Pod 资源中通过环境变量或存储卷进行数据访问。不同的地方在于,Secret 对象仅会被分发至调用了该对象的 Pod 资源所在的工作节点,且仅支持由节点将其临时存储于内存中。另外,Secret 对象的数据存储及打印格式为 Base64 编码的字符串而非明文字符,用户在创建 Secret 对象时需要事先手动完成数据的格式转换。但在容器中以环境变量或存储卷的方式访问时,它们会被自动解码为明文数据。
Secret 资源主要有两种用途:一是作为存储卷注入 Pod 对象上,供容器应用程序使用;二是用于 kubelet 为 Pod 里的容器拉取镜像时向私有仓库提供认证信息。不过,后面使用 ServiceAccount 资源自建的 Secret 对象是一种更安全的方式。
Secret 对象划分为如下 3 种类别:
generic:基于本地文件、目录或字面量值创建的 Secret,一般用来存储密钥、信息、证书等数据。docker-registry:用于认证到 Docker Registry 的 Secret,以使用私有容器镜像。
tls:基于指定的公钥/私钥对创建 TLS Secret,专用于 TLS 通信中;指定公钥和私钥必须事先存在,公钥证书必须采用 PEM 编码,且应该与指定的私钥相匹配。
通用类型的 Secret 资源用于保存除用于 TLS 通信之外的证书和私钥,以及专用于认证到 Docker 注册表服务之外的敏感信息,包括访问服务的用户名和口令、SSH 密钥、OAuth 令牌、CephX 协议的认证密钥等。
Kubernetes 系统上还有一种专用于保存 ServiceAccount 认证令牌的 Secret 对象,它存储有 Kubernetes 集群的私有 CA 的证书(ca.crt)以及当前 Service 账号的名称空间和认证令牌。该类资源以 kubernetes.io/service-account-token 为类型标识,并附加专用资源注解 kubernetes.io/service-account.name 和 kubernetes.io/service-account.uid 来指定所属的 ServiceAccount 账号名称及 ID 信息。
在 Pod 资源上使用 docker-registry Secret 对象的方法有两种。一种方法是使用 spec.imagePullSecrets 字段直接引用;另一种是将 docker-registry Secret 对象添加到某特定的 ServiceAccount 对象之上,而后配置 Pod 资源通过 spec.serviceAccountName 来引用该服务账号.
Pod 资源以环境变量方式消费 Secret 对象也存在两种途径:① 一对一地将指定键的值传递给指定的环境变量;② 将 Secret 对象上的全部键名和键值一次性全部映射为容器的环境变量。前者在容器上使用 env.valueFrom 字段进行定义,而后者则直接使用 envFrom 字段。
Pod 资源上的 Secret 存储卷插件的使用方式同 ConfigMap 存储卷插件非常相似,除了其类型及引用标识要替换为 secret 及 secretName 之外,几乎完全类似于 ConfigMap 存储卷,包括支持使用挂载整个存储卷、只挂载存储卷中指定键值以及独立挂载存储卷中的键等使用方式。
Downward API 并不会将所有可用的元数据统统注入容器中,而是由用户在配置 Pod 对象自行选择需要注入容器中的元数据。可选择注入的信息包括 Pod 对象的 IP、主机名、标签、注解、UID、请求的 CPU 与内存资源量及其限额,甚至是 Pod 所在的节点名称和节点 IP 等。