十一、kubernetes 1.29 之 存储 Secret 和 DownwardAPI
一、Secret
1、定义
Secret 的用途:
专门用于保存敏感信息
包括:密码、OAuth 令牌、SSH 密钥等
Secret 的优势:
更安全:相比直接放在 Pod 定义或容器镜像中
更灵活:可以独立于应用代码进行管理
使用特点:
数据默认以 base64 编码形式存储(非加密)
支持多种类型:Opaque(通用)、docker-registry、tls 等
可以通过卷挂载或环境变量方式提供给 Pod
注意:虽然 Secret 比明文更安全,但在生产环境中建议结合 RBAC、加密等机制进一步增强安全性。
2、特性
最小分发原则:Secret 仅分发给真正需要访问它的 Pod 所在节点
内存存储:Secret 数据仅保存在节点内存中,不落盘到物理存储
加密存储:自 Kubernetes 1.7 起,etcd 中对 Secret 进行加密存储
3、类型

# Kubernetes Secret 内置类型
| 内置类型 | 用途说明 |
|---------|----------|
| **Opaque** | 用户定义的任意数据(通用类型) |
| **kubernetes.io/service-account-token** | 服务账号令牌 |
| **kubernetes.io/dockercfg** | `~/.dockercfg` 文件的序列化形式 | 老
| **kubernetes.io/dockerconfigjson** | `~/.docker/config.json` 文件的序列化形式 | 新
| **kubernetes.io/basic-auth** | 用于基本身份认证的凭据 |
| **kubernetes.io/ssh-auth** | 用于 SSH 身份认证的凭据 |
| **kubernetes.io/tls** | 用于 TLS 客户端或服务器端的数据 |
| **bootstrap.kubernetes.io/token** | 启动引导令牌数据 |
4、Opaque
概念
当 Secret 配置文件中未作显式设定时,默认的 Secret 类型是 Opaque。
当你使用 kubectl 来创建一个 Secret 时,你会使用 generic 子命令来标明要创建的是一个 Opaque 类型 Secret。
创建
opaque的pod在创建的时候,data的 值 会自动解码,如果写资源清单的时候没有编码,就会出现乱码

# 对用户名进行 base64 编码 echo -n 'admin' | base64 # 输出:YWRtaW4= # 对密码进行 base64 编码 echo -n '1f2d1e2e67df' | base64 # 输出:MWYyZDFlMmU2N2RmapiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4= password: MWYyZDFlMmU2N2Rm
创建成功,不显示值

获取值
kubectl get secret 名字 -o yaml

在解码

5、ENV
在运行的时候会显示成明文

apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: opaque-secret-env
name: opaque-secret-env-deploy
spec:
replicas: 5
selector:
matchLabels:
app: op-se-env-pod
template:
metadata:
labels:
app: op-se-env-pod
spec:
containers:
- image: wangyanglinux/myapp:v1
name: myapp-container
ports:
- containerPort: 80
env:
- name: TEST_USER
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: TEST_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
6、Volume
挂载到内部文件
apiVersion: v1 kind: Pod metadata: name: secret-volume-pod labels: app: secret-volume spec: volumes: - name: secret-volume secret: secretName: mysecret containers: - name: myapp-container image: wangyanglinux/myapp:v1.0 volumeMounts: - name: secret-volume mountPath: "/data"
对挂载文件进行权限修改
对某一个键值进行挂载,不支持热更新
7、热更新
当已经存储于卷中被使用的 Secret 被更新时,被映射的键也将终将被更新。 组件 kubelet 在周期性同步时检查被挂载的 Secret 是不是最新的。但是,它会使用其本地缓存的数值作为 Secret 的当前值。 使用 Secret 作为子路径卷挂载的容器不会收到 Secret 更新。技术要点说明:
Secret 更新机制:
Secret 更新后,卷中映射的键最终会被更新(最终一致性)
kubelet 会周期性地检查挂载的 Secret 是否是最新版本
缓存行为:
kubelet 使用本地缓存的值作为 Secret 的当前值
这意味着更新不会立即生效,存在一定的延迟
重要限制:
使用 subPath 子路径方式挂载 Secret 的容器无法接收到 Secret 的更新
这是使用子路径挂载时的一个重要注意事项
实际影响:如果应用需要实时获取最新的 Secret 值,应避免使用子路径挂载方式,或者考虑其他机制来触发 Pod 重启。
8、不可改
核心特性说明:
不可变配置:
通过
immutable: true字段设置适用于 Secret 和 ConfigMap 两种资源类型
主要优势:
防止意外更新:避免配置变更导致的应用中断
降低 API 负载:关闭 kube-apiserver 的监视机制,提升集群性能
特别适合:包含成千上万个不同 Secret/ConfigMap 的大规模集群
使用注意事项:
设置为不可变后,无法修改数据内容
如需更新,必须删除后重新创建资源
适合那些部署后不需要频繁变更的配置和密钥
适用场景:生产环境中那些稳定不变的配置项、证书、密钥等敏感信息。
apiVersion: v1 kind: ConfigMap metadata: name: my-config immutable: true data: log.level: "INFO" app.name: "my-application"
二、Downward API
1、概述
Downward API 是 Kubernetes 中的一个功能,它允许容器在运行时从 Kubernetes API 服务器获取有关它们自身的信息。这些信息可以作为容器内部的环境变量或文件注入到容器中,以便容器可以获取有关其运行环境的各种信息,如 Pod 名称、命名空间、标签等。
主要作用:
提供容器元数据
动态配置
与 Kubernetes 环境集成
2、环境变量案例
功能说明:
此 Pod 配置使用 Kubernetes Downward API 将以下信息注入为环境变量:
Pod 名称 (
metadata.name)命名空间 (
metadata.namespace)Pod IP 地址 (
status.podIP)CPU 请求和限制值
内存请求和限制值
这些环境变量可以在容器内部访问,使应用程序能够感知其运行的 Kubernetes 环境信息。
apiVersion: v1 kind: Pod metadata: name: downward-api-env-example spec: containers: - name: my-container image: wangyanglinux/myapp:v1.0 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: CPU_REQUEST valueFrom: resourceFieldRef: resource: requests.cpu - name: CPU_LIMIT valueFrom: resourceFieldRef: resource: limits.cpu - name: MEMORY_REQUEST valueFrom: resourceFieldRef: resource: requests.memory - name: MEMORY_LIMIT valueFrom: resourceFieldRef: resource: limits.memory restartPolicy: Never被写到pod环境变量
3、volume 卷案例
相较于 env
保持热更新
同一个pod传递 A 容器 的字段给 B 容器
资源清单说明:
Pod 基本信息:
名称:
downward-api-volume-example使用 Downward API 通过卷方式暴露 Pod 和容器信息
容器配置:
容器名称:
my-container使用镜像:
wangyanglinux/myapp:v1.0资源限制:CPU 1核心,内存 512Mi
资源请求:CPU 0.5核心,内存 256Mi
挂载卷:
downward-api-volume到/etc/podinfo路径Downward API 卷配置:
暴露 Pod 元数据:名称、命名空间、UID、注解、标签
暴露容器资源信息:CPU 和内存的请求与限制值
所有信息将以文件形式存储在
/etc/podinfo目录下修正内容:
修正了
apiVersion拼写修正了字段路径的格式(
fieldPath)修正了 YAML 缩进和结构
修正了资源字段引用的容器名称指定方式
使用说明:
此 Pod 启动后,可以在容器内的
/etc/podinfo目录下查看各种 Pod 和容器的元数据信息文件,如:
/etc/podinfo/name:Pod 名称
/etc/podinfo/namespace:命名空间
/etc/podinfo/cpu_request:CPU 请求值等等
apiVersion: v1 kind: Pod metadata: name: downward-api-volume-example spec: containers: - name: my-container image: wangyanglinux/myapp:v1.0 resources: #资源限制 limits: #最大 cpu: "1" memory: "512Mi" requests: #初始 cpu: "0.5" memory: "256Mi" volumeMounts: - name: downward-api-volume mountPath: /etc/podinfo volumes: - name: downward-api-volume downwardAPI: items: - path: "annotations" fieldRef: fieldPath: metadata.annotations - path: "labels" fieldRef: fieldPath: metadata.labels - path: "name" fieldRef: fieldPath: metadata.name - path: "namespace" fieldRef: fieldPath: metadata.namespace - path: "uid" fieldRef: fieldPath: metadata.uid - path: "cpu_request" resourceFieldRef: containerName: my-container resource: requests.cpu - path: "memory_request" resourceFieldRef: containerName: my-container resource: requests.memory - path: "cpu_limit" resourceFieldRef: containerName: my-container resource: limits.cpu - path: "memory_limit" resourceFieldRef: containerName: my-container resource: limits.memory restartPolicy: Never
4、扩展
Downward API 提供了一种简单的方式,将 Pod 和容器的元数据传递给在它们内部运行的进程。但这种方式其实仅仅可以暴露一个 Pod 自身的元数据,而且只可以暴露部分元数据。
关键限制说明:
只能暴露当前 Pod 自身的元数据,无法获取集群中其他 Pod 的信息
只能暴露部分元数据字段,并非所有 Pod 信息都可通过 Downward API 获取
可暴露的典型元数据包括:
Pod 名称(metadata.name)
Pod 命名空间(metadata.namespace)
Pod IP 地址(status.podIP)
节点名称(spec.nodeName)
服务账号名称(spec.serviceAccountName)
资源请求和限制(resources.requests/limits)
换方式
创建rbac文件:授权访问 api service
# 1. RBAC 集群角色绑定资源清单 (1.RBAC.yaml) apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: test-api-cluster-admin-binding subjects: - kind: ServiceAccount name: test-api namespace: default roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io迎合rbac绑定的 sa (subjects:- kind: ServiceAccou)
kubectl create sa test-api创建pod
# 2. Pod 资源清单 (2.pod.yaml) apiVersion: v1 kind: Pod metadata: name: curl spec: serviceAccountName: test-api containers: - name: main image: tutum/curl command: ["sleep", "9999"]# 3. Pod 内部执行的命令序列 # 进入 Pod kubectl exec -it curl -- /bin/sh # 在 Pod 内部执行以下命令: //谁拿到谁就是管理员 TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) //Ca证书 CAPATH="/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" //名字空间 NS=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace) //发起认证 curl -H "Authorization: Bearer $TOKEN" --cacert $CAPATH https://kubernetes/api/v1/namespaces/$NS/pods可以查询“底裤信息”
补充
使用8080访问,不需要携带证书,不需要获得认证
kubectl proxy --port=8080将查询内容保存到文件
curl localhost:8080/openapi/v2>k8s-swagger.json这时候文件很难看,容器化部署一个可视化工具
docker run \ --rm \ -d \ -p 80:8080 \ -e SWAGGER_JSON=/k8s-swagger.json \ -v $(pwd)/k8s-swagger.json:/k8s-swagger.json \ swaggerapi/swagger-ui docker run:启动新容器 --rm:容器退出后自动删除 -d:后台运行模式 -p 80:8080:将主机80端口映射到容器8080端口 -e SWAGGER_JSON=/k8s-swagger.json:设置Swagger JSON文件路径环境变量 -v $(pwd)/k8s-swagger.json:/k8s-swagger.json:挂载当前目录下的k8s-swagger.json文件到容器 swaggerapi/swagger-ui:使用的Docker镜像名称需要和被展示的文件处于同一路径
完成后访问节点的80
更多推荐











所有评论(0)