Secret

概述

Kubernetes Secret 对象可以用来储存敏感信息,例如:密码、OAuth token、ssh 密钥等。如果不使用 Secret,此类信息可能被放置在 Pod 定义中或者容器镜像中。将此类敏感信息存储到 Secret 中,可以更好地:

  • 控制其使用
  • 降低信息泄露的风险

用户可以直接创建 Secret,Kubernetes 系统也会创建一些 Secret。

Secret有如下几种使用方式:

  • 作为 Pod 的数据卷挂载
  • 作为 Pod 的环境变量
  • kubelet 在抓取容器镜像时,作为 docker 镜像仓库的用户名密码

内建Secret

Service Account 将自动创建 Secret

Kubernetes 自动创建包含访问 Kubernetes APIServer 身份信息的 Secret,并自动修改 Pod 使其引用这类 Secret。

如果需要,可以禁用或者自定义自动创建并使用 Kubernetes APIServer 身份信息的特性。然而,如果您期望安全地访问 Kubernetes APIServer,您应该使用默认的 Secret 创建使用过程。

如需了解更多细节,参考 Configure Service Accounts for Pods

解码和编辑

Kubenetes 中,Secret 使用 base64 编码存储,您可以将其 解码 获得对应信息的原文,创建 Secret 之后,您也可以再次 编辑 Secret

创建Secret(使用kubectl)

假设某个 Pod 需要访问数据库。在您执行 kubectl 命令所在机器的当前目录,创建文件 ./username.txt 文件和 ./password.txt 暂存数据库的用户名和密码,后续我们根据这两个文件配置 kubernetes secrets。

echo -n 'admin' > ./username.txt
echo -n '1f2d1e2e67df' > ./password.txt

执行命令 kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt 在 Kubernetes APIServer 中创建 Secret 对象,并将这两个文件中的内容存储到该 Secret 对象中,输出结果如下所示:

secret "db-user-pass" created

TIP

  • 上述命令的执行效果与此命令执行效果相同: kubectl create secret generic db-user-pass –from-literal=username=admin –from-literal=password=1f2d1e2e67df
  • 如果您的密码中包含特殊字符需要转码(例如 $*\!),请使用 \ 进行转码。例如:实际密码为 S!B\*d$zDsb,kubectl 命令应该写成 kubectl create secret generic dev-db-secret –from-literal=username=devuser –from-literal=password=S\!B\\*d\$zDsb。如果通过文件创建(--from-file),则无需对文件中的密码进行转码。

执行命令 kubectl get secrets,检查 Secret 的创建结果,输出信息如下所示:

NAME               TYPE                                 DATA      AGE
db-user-pass Opaque 2 51s

执行命令 kubectl describe secrets/db-user-pass,查看 Secret 详情,输出信息如下所示:

Name:            db-user-pass
Namespace: default
Labels: <none>
Annotations: <none> Type: Opaque Data
====
password.txt: 12 bytes
username.txt: 5 bytes

TIP

默认情况下,kubectl getkubectl describe 命令都避免展示 Secret 的内容。这种做法可以避免密码被偷窥,或者被存储到终端的日志中

创建Secret(手动)

和创建其他类型的 API 对象(Pod、Deployment、StatefulSet、ConfigMap 等)一样,您也可以先在 yaml 文件中定义好 Secret,然后通过 kubectl apply -f 命令创建。此时,您可以通过如下两种方式在 yaml 文件中定义 Secret:

  • data:使用 data 字段时,取值的内容必须是 base64 编码的
  • stringData:使用 stringData 时,更为方便,您可以直接将取值以明文的方式写在 yaml 文件中

在 yaml 中定义 data

  • 假设您要保存 username=adminpassword=1f2d1e2e67df 到 Secret 中,请先将数据的值转化为 base64 编码,执行如下命令:
echo -n 'admin' | base64
YWRtaW4=
echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm

创建 secret.yaml 文件,内容如下所示:

apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm

执行命令 kubectl apply -f ./secret.yaml

secret "mysecret" created
  • 此时 Secret 创建成功

在 yaml 中定义 stringData

有时,您并不想先将用户名和密码转换为 base64 编码之后再创建 Secret,则您可以通过定义 stringData 来达成,此时 stringData 中的取值部分将被 apiserver 自动进行 base64 编码之后再保存。

  • 创建文件 secret.yaml,内容如下所示:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
stringData:
username: admin
password: 1f2d1e2e67df

执行命令 kubectl apply -f ./secret.yaml 输出结果如下所示:

secret "mysecret" created

此时 Secret 创建成功

执行命令 kubectl get -f ./secret.yaml -o yaml 输出结果如下所示:

apiVersion: v1
data:
password: MWYyZDFlMmU2N2Rm
username: YWRtaW4=
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"mysecret","namespace":"default"},"stringData":{"password":"1f2d1e2e67df","username":"admin"},"type":"Opaque"}
creationTimestamp: "2019-09-23T14:16:56Z"
name: mysecret
namespace: default
resourceVersion: "10318365"
selfLink: /api/v1/namespaces/default/secrets/mysecret
uid: 24602031-e18d-467a-b7fe-0962af8ec8b8
type: Opaque
  • 注意
  • 此时 annotation 中可以看到 password 的明文,这也许并不是您所期望的
  • 输出的 Secret 对象中,stringData 字段不再出现

同时定义了 data 和 stringData

TIP

如果您同时定义了 data 和 stringData,对于两个对象中 key 重复的字段,最终将采纳 stringData 中的 value

  • 创建文件 secret.yaml,该文件同时定义了 data 和 stringData,内容如下所示:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
stringData:
username: administrator

执行命令 kubectl apply -f ./secret.yaml 输出结果如下所示:

secret "mysecret" created

此时 Secret 创建成功

执行命令 kubectl get -f ./secret.yaml -o yaml 输出结果如下所示:

apiVersion: v1
kind: Secret
metadata:
creationTimestamp: 2018-11-15T20:46:46Z
name: mysecret
namespace: default
resourceVersion: "7579"
uid: 91460ecb-e917-11e8-98f2-025000000001
type: Opaque
data:
username: YWRtaW5pc3RyYXRvcg==

TIP

此处 YWRtaW5pc3RyYXRvcg== 解码后的值是 administrator

将配置文件存入 Secret

假设您的某个应用程序需要从一个配置文件中读取敏感信息,此时,您可以将该文件的内容存入 Secret,再通过数据卷的形式挂载到容器。[挂载方式未完待续]

例如,您的应用程序需要读取如下配置文件内容:

apiUrl: "https://my.api.com/api/v1"
username: user
password: password

您可以使用下面的 secret.yaml 创建 Secret

apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
stringData:
config.yaml: |-
apiUrl: "https://my.api.com/api/v1"
username: user
password: password

执行命令 kubectl apply -f ./secret.yaml 输出结果如下所示:

secret "mysecret" created

此时 Secret 创建成功

执行命令 kubectl get -f ./secret.yaml -o yaml 输出结果如下所示:

apiVersion: v1
kind: Secret
metadata:
creationTimestamp: 2018-11-15T20:40:59Z
name: mysecret
namespace: default
resourceVersion: "7225"
uid: c280ad2e-e916-11e8-98f2-025000000001
type: Opaque
data:
config.yaml: YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IHt7dXNlcm5hbWV9fQpwYXNzd29yZDoge3twYXNzd29yZH19

创建Secret(使用Generator)

从 kubernetes v1.14 开始,kubectl 集成了 Kustomize。通过 Kustomize,您可以使用 generator(Kustomize 的概念)创建 Secret,并保存到 API Server。Generator 必须在 kustomization.yaml 文件中指定。

TIP

需要结合 Kustomize 一起使用,在您决定采纳 Kustomize 之前,可以暂时不看这篇文章的内容

从文件生成 Secret

例如,如果想从 ./username.txt./password.txt 文件生成(generate)一个 Secret,则可以:

  • 执行如下指令创建 kustomization.yaml 文件
# Create a kustomization.yaml file with SecretGenerator
cat <<EOF >./kustomization.yaml
secretGenerator:
- name: db-user-pass
files:
- username.txt
- password.txt
EOF

执行指令 kubectl apply -k . 以创建 Secret 对象,输出结果如下所示:

secret/db-user-pass-96mffmfh4k created

执行指令 kubectl get secrets 以检查创建结果,输出结果如下所示:

NAME                      TYPE                                  DATA      AGE
db-user-pass-96mffmfh4k Opaque 2 51s

执行指令 kubectl describe secrets/db-user-pass-96mffmfh4k 以查看 Secret 详情(请使用您自己的 Secret 名字),输出结果如下所示:

Name:            db-user-pass
Namespace: default
Labels: <none>
Annotations: <none> Type: Opaque Data
====
password.txt: 12 bytes
username.txt: 5 bytes

TIP

生成的 Secret 的名字包含一个 hash 值(Secret 内容的 hash)做为后缀,这种做法可以确保每次修改 Secret 的内容时,都将产生新的 Secret 对象

从明文生成 Secret

例如,如果要从明文 username=adminpassword=secret,您可以:

  • 通过如下指令创建 secret generator 的 kustomization.yaml 文件:
# Create a kustomization.yaml file with SecretGenerator
cat <<EOF >./kustomization.yaml
secretGenerator:
- name: db-user-pass
literals:
- username=admin
- password=secret
EOF

然后执行指令 kubectl apply -k . 创建 Secret 对象,输出结果如下所示:

secret/db-user-pass-dddghtt9b5 created

创建Secret(使用Kuboard)

Kubernetes Secret 必须从属于某一个名称空间,进入 Kuboard 名称空间界面,在菜单中导航到 配置中心 / 密 文,点击 创建 Secret 按钮,可显示 Secret 的创建界面

  • 可以创建的 Secret 类型有:

    • docker 仓库密码
    • Opaque (可自定义 key / value)
    • TLS (可存放 HTTPS 证书等)
  • 可以显示的 Secret 类型有:
    • Service Account Token (通常由系统创建)
    • Bootstrap Token (通常由系统创建)

解码和编辑Secret

解码Secret

Secret 中的信息可以通过 kubectl get secret 命令获取。例如,执行命令 kubectl get secret mysecret -o yaml 可获取前面章节中所创建的 Secret,输出信息如下:

apiVersion: v1
kind: Secret
metadata:
creationTimestamp: 2016-01-22T18:41:56Z
name: mysecret
namespace: default
resourceVersion: "164619"
uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm

执行命令 echo 'MWYyZDFlMmU2N2Rm' | base64 --decode 可解码密码字段,输出结果如下:

1f2d1e2e67df

执行命令 echo 'YWRtaW4=' | base64 --decode 可解码用户名字段,输出结果如下:

admin

编辑Secret

执行命令 kubectl edit secrets mysecret 可以编辑已经创建的 Secret,该命令将打开一个类似于 vi 的文本编辑器,您可以直接编辑已经进行 base64 编码的字段,如下所示:

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: { ... }
creationTimestamp: 2016-01-22T18:41:56Z
name: mysecret
namespace: default
resourceVersion: "164619"
uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque

使用Secret存储Ingress TLS证书

创建证书

如果您为自己的测试域名购买证书,可到阿里云 SSL证书产品页申请免费证书。在下载证书时,请选择 nginx 证书下载,解压缩下载到的 zip 文件后,您将获得一个 .key 私钥文件和一个 .pem 公钥文件

创建Secret

在 Kuboard 界面中进入 配置中心 / 密 文 ,点击 创建 Secret 按钮,填写表单,如下图所示:

  • 选择类型为 TLS
  • 将 .key 文件中的内容填入 tls.key 字段
  • 将 .pem 文件中的内容填入 tls.crt 字段

在Ingress中引用Secret

在 Kuboard 界面中,点击要激活 HTTPS 的工作负载,进入编辑页面,在 应用路由 区域,勾选 HTTPS,并选择刚才创建好的 Secret

申请证书时,所填写的域名必须与Ingress配置的域名一致。

Secret概述的更多相关文章

  1. 034.Kubernetes集群安全-Secret

    一 secret概述 1.1 secret作用 Secret对象,主要作用是保管私密数据,比如密码.OAuth Tokens.SSH Keys等信息.将这些私密信息放在Secret对象中比直接放在Po ...

  2. Kubernetes K8S之存储Secret详解

    K8S之存储Secret概述与类型说明,并详解常用Secret示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 ...

  3. Apache Shiro系列之五,概述 —— 配置

    Shiro设计的初衷就是可以运行于任何环境:无论是简单的命令行应用程序还是复杂的企业集群应用.由于运行环境的多样性,所以有多种配置机制可用于配置,本节我们将介绍Shiro内核支持的这几种配置机制.   ...

  4. CCNA网络工程师学习进程(1)网络的基本概述

        在互联网快速发展的今天,了解互联网成为一项必须的技能,因此在学习编程之余学习如何配置网络还是很有必要的. 本系列博客计划分为三个部分,包括思科CCNA.CCNP和华为的网络工程师认证有关的知识 ...

  5. 【翻译】WhatsApp 加密概述(技术白皮书)

    目录      简介      术语      客户端注册      会话初始化设置      接收会话设置      交换信息      传输媒体和附件      群组消息      通话设置   ...

  6. 微信小程序开发-概述

    微信小程序开发-概述 一.小程序申请&APPID 登录微信平台申请成为小程序开发者,小程序不可直接使用服务号或订阅号的AppID,需要登录微信公众平台管理后台,在网站的"设置&quo ...

  7. 大数据入门第五天——离线计算之hadoop(上)概述与集群安装

    一.概述 根据之前的凡技术必登其官网的原则,我们当然先得找到它的官网:http://hadoop.apache.org/ 1.什么是hadoop 先看官网介绍: The Apache™ Hadoop® ...

  8. Kubernetes集群安全概述

    API的访问安全性 API Server的端口和地址 在默认情况下,API Server通过本地端口和安全端口两个不同的HTTP端口,对外提供API服务,其中本地端口是基于HTTP协议的,用于在本机( ...

  9. SSL/TLS协议运行机制的概述_转

    转自:SSL/TLS协议运行机制的概述 作者: 阮一峰 日期: 2014年2月 5日 互联网的通信安全,建立在SSL/TLS协议之上. 本文简要介绍SSL/TLS协议的运行机制.文章的重点是设计思想和 ...

随机推荐

  1. shell脚本处理二进制数据

    正确处理二进制数据 正确处理二进制数据必须保证以下三个环节是二进制安全(Binary Safe)的: 从文件读取至内存: 处理数据过程中: 内存写入至文件. 那么二进制安全是什么?通俗来说就是不会特殊 ...

  2. Java开发学习(十四)----Spring整合Mybatis及Junit

    一.Spring整合Mybatis思路分析 1.1 环境准备 步骤1:准备数据库表 Mybatis是来操作数据库表,所以先创建一个数据库及表 create database spring_db cha ...

  3. Netty源码解读(一)-前置准备

    前置条件 源码版本netty4.1 了解Java NIO.Reactor模型和Netty的基本使用. 解释一下: Java NIO:了解BIO和NIO的区别以及Java NIO基础API的使用 Rea ...

  4. 基于二进制安装Cloudera Manager集群

    一.环境准备 参考链接:https://www.cnblogs.com/zhangzhide/p/11108472.html 二.安装jdk(三台主机都要做) 下载jdk安装包并解压:tar xvf ...

  5. mysql 跨库事务XA

    前一段时间在工作中遇到了跨库事务问题,后来在网上查询了一下,现在做一下整理和总结. 1.首先要确保mysql开启XA事务支持 SHOW VARIABLES LIKE '%XA%' 如果innodb_s ...

  6. MySQL主从复制之并行复制说明

    传统单线程复制说明 众所周知,MySQL在5.6版本之前,主从复制的从节点上有两个线程,分别是I/O线程和SQL线程. I/O线程负责接收二进制日志的Event写入Relay Log. SQL线程读取 ...

  7. 【转载】一封面向社会,关于对近日来 CCF 不当行为之抗议的公开信

    原文链接:https://101001011.github.io/2022/06/11/zhi-ccf-de-yi-feng-gong-kai-xin/ 原文作者:CCA(CCA's Blog) 前天 ...

  8. 活动回顾丨ALC Beijing 首场 Meetup:《开源到底有多难?》

    8月16日,ALC Beijing 的首次线下沙龙活动 -- <开源到底有多难?>在微软大厦如期举行.本次沙龙主要是分享开源开发经验.探讨如何让开源项目更加茁壮成长,以及分享 ASF 管理 ...

  9. 原生js也可以自定义组件

    Web Components 是一套不同的技术,允许您创建可重用的定制元素(它们的功能封装在您的代码之外)并且在您的web应用中使用它们. 它由三项主要技术组成,它们可以一起使用来创建封装功能的定制元 ...

  10. 基于EasyExcel实现的分页数据下载封装

    功能概述 主要实现的功能: 1.分页查询,避免一次性查询全部数据加载到内存引起频繁FULL GC甚至OOM 2.当数据量超过单个工作簿最大行数(1048575)时,自动将数据写入新的工作簿 3.支持百 ...