草庐IT

【云原生 | Kubernetes 系列】K8s 实战 管理 Secret 详解

半身风雪 2023-05-27 原文

kubectl 管理 Secret


前言

Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。 这样的信息可能会被放在 Pod 规约中或者镜像中。 用户可以创建 Secret,同时系统也创建了一些 Secret。


一、使用 kubectl 管理 Secret

1.1、创建 Secret

一个 Secret 可以包含 Pod 访问数据库所需的用户凭证。 例如,由用户名和密码组成的数据库连接字符串。 你可以在本地计算机上,将用户名存储在文件 ./username.txt 中,将密码存储在文件 ./password.txt 中。

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

在这些命令中,-n 标志确保生成的文件在文本末尾不包含额外的换行符。 这一点很重要,因为当 kubectl 读取文件并将内容编码为 base64 字符串时,多余的换行符也会被编码。

kubectl create secret 命令将这些文件打包成一个 Secret 并在 API 服务器上创建对象。

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

输出类似于:

secret/db-user-pass created

默认密钥名称是文件名。 可以使用 --from-file=[key=]source 来设置密钥名称。

例如:

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

不需要对文件中包含的密码字符串中的特殊字符进行转义。

还可以使用 --from-literal=<key>=<value> 标签提供 Secret 数据。 可以多次使用此标签,提供多个键值对。
需要注意,特殊字符(例如:$,\,*,= 和 !)由你的 shell 解释执行,而且需要转义。

在大多数 shell 中,转义密码最简便的方法是用单引号括起来。 比如,如果你的密码是 S!B\*d$zDsb=, 可以像下面一样执行命令:

$ kubectl create secret generic db-user-pass \
  --from-literal=username=devuser \
  --from-literal=password='S!B\*d$zDsb='

1.2、验证 Secret

检查 secret 是否已创建:

$ kubectl get secrets

输出类似于:

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

你可以查看 Secret 的描述:

$ kubectl describe secrets/db-user-pass

输出类似于:

Name:            db-user-pass
Namespace:       default
Labels:          <none>
Annotations:     <none>

Type:            Opaque

Data
====
password:    12 bytes
username:    5 bytes

kubectl getkubectl describe 命令默认不显示 Secret 的内容。 这是为了防止 Secret 被意外暴露或存储在终端日志中。

1.3、解码 Secret

要查看创建的 Secret 的内容,运行以下命令:

$ kubectl get secret db-user-pass -o jsonpath='{.data}'

这里会输出你的账号和密码,我就不贴了。

现在你可以解码 password 的数据:

# 这是一个用于文档说明的示例。
# 如果你这样做,数据 'MWYyZDFlMmU2N2Rm' 可以存储在你的 shell 历史中。
# 可以进入你电脑的人可以找到那个记住的命令并可以在你不知情的情况下 base-64 解码这个 Secret。
# 通常最好将这些步骤结合起来,如页面后面所示。
echo 'MWYyZDFlMmU2N2Rm' | base64 --decode

输出类似于:

1f2d1e2e67df

为了避免在 shell 历史记录中存储 Secret 的编码值,可以执行如下命令:

$ kubectl get secret db-user-pass -o jsonpath='{.data.password}' | base64 --decode

输出应与上述类似。

1.4、清理

删除创建的 Secret:

$ kubectl delete secret db-user-pass

二、使用配置文件管理 Secret

2.1、创建 Secret

你可以先用 JSON 或 YAML 格式在一个清单文件中定义 Secret 对象,然后创建该对象。 Secret 资源包含 2 个键值对:data 和 stringData。 data 字段用来存储 base64 编码的任意数据。 提供 stringData 字段是为了方便,它允许 Secret 使用未编码的字符串。 data 和 stringData 的键必须由字母、数字、-、_ 或 . 组成。

我来使用 data 字段在 Secret 中存储两个字符串:

  1. 将这些字符串转换为 base64:
echo -n 'admin' | base64
echo -n '1f2d1e2e67df' | base64

输出类似于:

YWRtaW4=
MWYyZDFlMmU2N2Rm
  1. 创建清单:
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

Secret 对象的名称必须是有效的 DNS 子域名。

  1. 使用 kubectl apply 创建 Secret:
$ kubectl apply -f ./secret.yaml

输出类似于:

secret/mysecret created

2.2、创建 Secret 时提供未编码的数据

对于某些场景,你可能希望使用 stringData 字段。 这个字段可以将一个非 base64 编码的字符串直接放入 Secret 中, 当创建或更新该 Secret 时,此字段将被编码。

上述用例的实际场景可能是这样:当你部署应用时,使用 Secret 存储配置文件, 你希望在部署过程中,填入部分内容到该配置文件。

如果你的应用程序使用以下配置文件:

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

你可以使用以下定义将其存储在 Secret 中:

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

当你检索 Secret 数据时,此命令将返回编码的值,并不是你在 stringData 中提供的纯文本值。

运行以下命令:

$ kubectl get secret mysecret -o yaml

输出类似于:

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

2.3、同时指定 data 和 stringData

如果在 data 和 stringData 中设置了同一个字段,则使用来自 stringData 中的值。

可以定义以下 Secret:

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
stringData:
  username: administrator

所创建的 Secret 对象如下:

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

2.4、清理

删除你创建的 Secret:

$ kubectl delete secret mysecret

三、使用 Kustomize 管理 Secret

从 kubernetes v1.14 开始,kubectl 支持使用 Kustomize 管理对象。 Kustomize 提供了资源生成器(Generators)来创建 Secret 和 ConfigMap。 Kustomize 生成器应该在某个目录的 kustomization.yaml 文件中指定。 生成 Secret 后,你可以使用 kubectl apply 在 API 服务器上创建该 Secret。

3.1、创建 Kustomization 文件

你可以在 kustomization.yaml 中定义 secreteGenerator 字段,并在定义中引用其它本地文件生成 Secret。 例如:下面的 kustomization 文件 引用了 ./username.txt./password.txt 文件:

secretGenerator:
- name: db-user-pass
  files:
  - username.txt
  - password.txt

你也可以在 kustomization.yaml 文件中指定一些字面量定义 secretGenerator 字段。 例如:下面的 kustomization.yaml 文件中包含了 username 和 password 两个字面量:

secretGenerator:
- name: db-user-pass
  literals:
  - username=admin
  - password=1f2d1e2e67df

你也可以使用 .env 文件在 kustomization.yaml 中定义 secretGenerator。 例如:下面的 kustomization.yaml 文件从 .env.secret 文件获取数据。

secretGenerator:
- name: db-user-pass
  envs:
  - .env.secret

注意,上面两种情况,你都不需要使用 base64 编码。

3.2、创建 Secret

在包含 kustomization.yaml 文件的目录下使用 kubectl apply 命令创建 Secret。

$ kubectl apply -k .

输出类似于:

secret/db-user-pass-96mffmfh4k created

请注意,生成 Secret 时,Secret 的名称最终是由 name 字段和数据的哈希值拼接而成。 这将保证每次修改数据时生成一个新的 Secret。

3.3、检查创建的 Secret

你可以检查刚才创建的 Secret:

$ kubectl get secrets

输出类似于:

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

你可以看到 Secret 的描述:

$ kubectl describe secrets/db-user-pass-96mffmfh4k

输出类似于:

Name:            db-user-pass-96mffmfh4k
Namespace:       default
Labels:          <none>
Annotations:     <none>

Type:            Opaque

Data
====
password.txt:    12 bytes
username.txt:    5 bytes

kubectl getkubectl describe 命令默认不显示 Secret 的内容。 这是为了防止 Secret 被意外暴露给旁观者或存储在终端日志中。

3.5、清理

删除你创建的 Secret:

$ kubectl delete secret db-user-pass-96mffmfh4k

总结

通过 API 创建的 Pod 时,不会检查应用的 secret 是否存在。一旦 Pod 被调度,kubelet 就会尝试获取该 secret 的值。如果获取不到该 secret,或者暂时无法与 API server 建立连接,kubelet 将会定期重试。Kubelet 将会报告关于 pod 的事件,并解释它无法启动的原因。一旦获取的 secret,kubelet将创建并装载一个包含它的卷。在安装所有pod的卷之前,都不会启动 pod 的容器。

有关【云原生 | Kubernetes 系列】K8s 实战 管理 Secret 详解的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  3. ruby-on-rails - 使用一系列等级计算字母等级 - 2

    这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,

  4. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  5. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  6. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  7. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  8. 阿里云RDS——产品系列概述 - 2

    基础版云数据库RDS的产品系列包括基础版、高可用版、集群版、三节点企业版,本文介绍基础版实例的相关信息。RDS基础版实例也称为单机版实例,只有单个数据库节点,计算与存储分离,性价比超高。说明RDS基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于

  9. ruby - (Ruby || Python) 窗口管理器 - 2

    我想用这两种语言中的任何一种(最好是ruby​​)制作一个窗口管理器。老实说,除了我需要加载某种X模块外,我不知道从哪里开始。因此,如果有人有线索,如果您能指出正确的方向,那就太好了。谢谢 最佳答案 XCB,X的下一代API使用XML格式定义X协议(protocol),并使用脚本生成特定语言绑定(bind)。它在概念上与SWIG类似,只是它描述的不是CAPI,而是X协议(protocol)。目前,C和Python存在绑定(bind)。理论上,Ruby端口只是编写一个从XML协议(protocol)定义语言到Ruby的翻译器的问题。生

  10. ruby-on-rails - 事件管理员和自定义方法 - 2

    这是我在ActiveAdmin中的自定义页面ActiveAdmin.register_page"Settings"doaction_itemdolink_to('Importprojects','settings/importprojects')endcontentdopara"Text"endcontrollerdodefimportprojectssystem"rakedataspider:import_projects_ninja"para"OK"endendend我想做的是,当我单击“导入项目”按钮时,我想在Controller中执行rake任务。但是我无法访问该方法。可能是什

随机推荐