一、Secret

1、定义

  1. Secret 的用途​:

    • 专门用于保存敏感信息

    • 包括:密码、OAuth 令牌、SSH 密钥等

  2. Secret 的优势​:

    • 更安全​:相比直接放在 Pod 定义或容器镜像中

    • 更灵活​:可以独立于应用代码进行管理

  3. 使用特点​:

    • 数据默认以 base64 编码形式存储(非加密)

    • 支持多种类型:Opaque(通用)、docker-registry、tls 等

    • 可以通过卷挂载或环境变量方式提供给 Pod

注意​:虽然 Secret 比明文更安全,但在生产环境中建议结合 RBAC、加密等机制进一步增强安全性。

2、特性

  1. 最小分发原则​:Secret 仅分发给真正需要访问它的 Pod 所在节点

  2. 内存存储​:Secret 数据仅保存在节点内存中,不落盘到物理存储

  3. 加密存储​:自 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
# 输出:MWYyZDFlMmU2N2Rm
apiVersion: 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 更新。

技术要点说明:​

  1. Secret 更新机制​:

    • Secret 更新后,卷中映射的键最终会被更新(最终一致性)

    • kubelet 会周期性地检查挂载的 Secret 是否是最新版本

  2. 缓存行为​:

    • kubelet 使用本地缓存的值作为 Secret 的当前值

    • 这意味着更新不会立即生效,存在一定的延迟

  3. 重要限制​:

    • 使用 ​subPath​ 子路径方式挂载 Secret 的容器无法接收到 Secret 的更新

    • 这是使用子路径挂载时的一个重要注意事项

实际影响​:如果应用需要实时获取最新的 Secret 值,应避免使用子路径挂载方式,或者考虑其他机制来触发 Pod 重启。

8、不可改

核心特性说明:​

  1. 不可变配置​:

    • 通过 immutable: true字段设置

    • 适用于 Secret 和 ConfigMap 两种资源类型

  2. 主要优势​:

    • 防止意外更新​:避免配置变更导致的应用中断

    • 降低 API 负载​:关闭 kube-apiserver 的监视机制,提升集群性能

    • 特别适合​:包含成千上万个不同 Secret/ConfigMap 的大规模集群

  3. 使用注意事项​:

    • 设置为不可变后,无法修改数据内容

    • 如需更新,必须删除后重新创建资源

    • 适合那些部署后不需要频繁变更的配置和密钥

适用场景​:生产环境中那些稳定不变的配置项、证书、密钥等敏感信息。

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 容器

资源清单说明:​

  1. Pod 基本信息​:

    • 名称:downward-api-volume-example

    • 使用 Downward API 通过卷方式暴露 Pod 和容器信息

  2. 容器配置​:

    • 容器名称:my-container

    • 使用镜像:wangyanglinux/myapp:v1.0

    • 资源限制:CPU 1核心,内存 512Mi

    • 资源请求:CPU 0.5核心,内存 256Mi

    • 挂载卷:downward-api-volume/etc/podinfo路径

  3. Downward API 卷配置​:

    • 暴露 Pod 元数据:名称、命名空间、UID、注解、标签

    • 暴露容器资源信息:CPU 和内存的请求与限制值

    • 所有信息将以文件形式存储在 /etc/podinfo目录下

  4. 修正内容​:

    • 修正了 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

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐