(十五)Kubernetes系列之存储(配置存储-Downward API)

本文详细介绍了如何在Kubernetes中使用DownwardAPI将Pod或容器的元数据通过环境变量或存储卷方式挂载到Nginx容器,包括创建模板、应用模板以及验证操作的步骤。

使用Downward API可以把pod或者容器的某些元数据挂载到容器内,供容器内应用使用。

1.环境变量的方式

1.1创建模板

vi nginxdeploymentdownwardapi.yml

内容如下:

图片

1.2.根据模板创建deployment

kubectl apply -f  nginxdeploymentdownwardapi.yml

图片

1.3查看

1.3.1查看pod

kubectl get pods

图片

1.3.2查看容器输出

kubectl logs nginxdeploymentdownwardapi

图片

2.存储卷的方式

2.1创建模板

vi nginxdeploymentdownwardapi1.yml

内容如下

图片

2.2根据模板创建deployment

kubectl apply -f nginxdeploymentdownwardapi1.yml

图片

2.3查看

2.3.1查看deployment创建的pod

kubectl get pods

图片

2.3.2进入容器

kubectl exec -ti inginxdeploymentdownwardapi1-6b59b6d6d9-bmgkq -- /bin/sh

图片

执行命令

cat /config/'"metadataName"'/metadataName

图片

<think>好的,我现在需要解释用户提供的这个Pod中的`volumes`配置,特别是`serviceAccountToken`部分以及它的来源。用户之前已经问过关于`kube-root-ca.crt` ConfigMap的问题,现在他们希望了解这个projected volume里的serviceAccountToken和相关配置。 首先,我需要理解这个YAML片段的结构。这个volumes部分定义了一个名为`kube-api-access-959z4`的projected volume,里面有三个来源:serviceAccountToken、configMap和downwardAPI。用户特别关注serviceAccountToken以及它的来源。 接下来,我需要回忆Kubernetes中Service Account的相关知识。每个Pod都会关联一个Service Account,默认是default。当创建Service Account时,Kubernetes会自动生成一个对应的Secret,里面包含token、ca.crt和namespace等信息。但在较新的版本中,Kubernetes使用TokenRequest API动态生成token,而不是依赖于Secret,这样更安全,因为token是临时的并且可以自动轮换。 然后,这个projected volume的作用是将这些信息(token、ca.crt、namespace)自动挂载到Pod中,以便Pod内的应用可以与kube-apiserver安全通信。serviceAccountToken部分指定了token的路径和有效期,这里expirationSeconds是3607秒,大约1小时,path是token。这个token是由kube-apiserver生成的,当Pod创建时,控制平面会处理这个请求,生成一个临时的、有时间限制的token,并将其挂载到Pod的指定路径。 接下来,我需要确认这个token的来源。用户问“他是哪里来的”,也就是这个serviceAccountToken是如何生成的。根据Kubernetes的机制,当Pod使用某个Service Account时,kube-apiserver会使用TokenRequest API为这个Pod生成一个专有的token。这个token与传统的基于Secret的token不同,它更安全,具有明确的过期时间,并且与Pod的生命周期绑定。当Pod被删除时,这个token也会失效。 然后,我需要解释为什么使用projected volume。Projected volume允许将多个来源的数据合并挂载到同一个目录下。在这里,token来自Service Account,ca.crt来自之前提到的kube-root-ca.crt ConfigMap,namespace则是通过downwardAPI从Pod的metadata中获取的。这些信息组合在一起,使得Pod内的应用可以方便地获取访问kube-apiserver所需的所有凭证和配置。 此外,需要注意默认的挂载路径。通常这个projected volume会被挂载到`/var/run/secrets/kubernetes.io/serviceaccount`,里面包含token、ca.crt和namespace文件。应用可以使用这些文件来构造kubeconfig,或者直接使用它们进行TLS认证。 最后,我需要总结这个机制的优势,比如自动管理、动态更新、安全性高等,并提醒用户不要手动修改这些自动生成的token,因为它们由Kubernetes控制平面管理,手动修改可能导致不可预知的问题。</think>以下是对该 `volumes` 配置中 `serviceAccountToken` 的详细解析: --- ### 一、**Projected Volume 结构总览** ```yaml volumes: - name: kube-api-access-959z4 projected: sources: - serviceAccountToken: ... # 身份凭证 - configMap: ... # CA 证书(kube-root-ca.crt) - downwardAPI: ... # 命名空间信息 ``` - **核心作用**:将多个来源的数据合并挂载到 Pod 的同一目录,为容器提供访问 Kubernetes API 所需的**三要素**: 1. **身份凭证**(ServiceAccount Token) 2. **CA 证书**(用于验证 API Server 的 TLS 证书) 3. **命名空间信息**(当前 Pod 所在的 Namespace) --- ### 二、**ServiceAccountToken 深度解析** #### 1. **核心特性** ```yaml - serviceAccountToken: expirationSeconds: 3607 # 约 1 小时 path: token # 挂载路径下的文件名 ``` - **动态生成**:由 Kubernetes 控制平面(kube-apiserver)**自动创建**,**无需手动管理** - **临时性**:具有明确的过期时间(默认根据集群配置,通常 1 小时),到期后自动轮换 - **绑定关系**:此 Token **专属于当前 Pod**,与 Pod 生命周期绑定(删除 Pod 后 Token 失效) #### 2. **Token 来源** - **生成机制**: - 当 Pod 使用 ServiceAccount 时(默认为 `default`),kube-apiserver 通过 `TokenRequest` API 动态生成 - 与传统 ServiceAccount Secret(如 `default-token-xxxxx`)不同,**不依赖静态 Secret 存储** - **安全增强**: ```bash # 对比传统 Secret 型 Token(已废弃) kubectl get secret default-token-abcde -o jsonpath='{.data.token}' | base64 -d # 输出:永不过期的静态 Token(存在安全风险) # 当前动态 Token(更安全) kubectl exec <pod> -- cat /var/run/secrets/token # 输出:有过期时间的临时 Token ``` #### 3. **技术原理** - **签发流程**: 1. Pod 创建时,kubelet 向 kube-apiserver 发起 `TokenRequest` 2. kube-apiserver 校验 Pod 的 ServiceAccount 权限后签发 Token 3. Token 通过 Projected Volume 挂载到 Pod - **JWT 结构**: ```text Header: {"alg":"RS256","kid":"...") Payload: { "iss": "kubernetes/serviceaccount", "sub": "system:serviceaccount:default:my-sa", # 身份标识 "exp": 1735683067, # 过期时间 "pod": {"name": "my-pod", "uid": "..."} # 绑定到特定 Pod } ``` --- ### 三、**完整挂载示例** 假设 Pod 中配置了以下挂载: ```yaml volumeMounts: - name: kube-api-access-959z4 mountPath: /var/run/secrets/kubernetes.io/serviceaccount ``` 最终生成的文件结构为: ```text /var/run/secrets/kubernetes.io/serviceaccount/ ├── token # ServiceAccount Token(身份凭证) ├── ca.crt # 根证书(来自 kube-root-ca.crt) └── namespace # 当前命名空间(来自 downwardAPI) ``` --- ### 四、**关键安全设计** #### 1. **最小权限原则** - Token 的权限由关联的 ServiceAccount 的 RBAC 规则控制 - 可通过 `automountServiceAccountToken: false` 关闭自动挂载 #### 2. **防御措施** ```bash # 尝试在容器内修改 Token 文件(将被禁止) echo "hack" > /var/run/secrets/token # 错误:Read-only file system ``` #### 3. **审计追踪** - Token 中携带 Pod 的 UID 和名称,所有 API 请求均可追溯来源 ```bash kubectl get --raw /api/v1/namespaces/default/pods/my-pod | jq '.spec.volumes' ``` --- ### 五、**与旧版机制的对比** | **特性** | **传统 Secret Token** | **Projected ServiceAccountToken** | |--------------------|-------------------------------------|----------------------------------------| | 存储方式 | 静态 Secret | 动态生成,无持久化存储 | | 生命周期 | 永久有效(除非手动轮换) | 临时 Token(默认 1 小时) | | 安全风险 | 泄露后长期有效 | 过期自动失效 | | 绑定粒度 | 关联 ServiceAccount | 关联特定 Pod | | 更新机制 | 需手动删除 Secret | 自动轮换(由 kubelet 管理) | --- ### 六、**实践建议** 1. **避免硬编码**: ```go // 正确方式:使用自动挂载的 Token tokenPath := "/var/run/secrets/kubernetes.io/serviceaccount/token" token, _ := os.ReadFile(tokenPath) // 错误方式:硬编码 Token token := "eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9..." ``` 2. **监控 Token 过期**: ```bash # 检查 Token 过期时间 kubectl exec <pod> -- cat /var/run/secrets/token | jq -R 'split(".")[1] | @base64d | fromjson.exp' ``` 3. **自定义配置**: ```yaml # 调整 Token 过期时间(需集群开启 BoundServiceAccountTokenVolume 特性门控) - serviceAccountToken: expirationSeconds: 86400 # 24 小时 ``` --- ### 总结 该 `serviceAccountToken` 是 Kubernetes 安全模型的核心组件之一,通过动态签发、临时有效、绑定 Pod 等设计,显著提升了集群安全性。它与 `kube-root-ca.crt` 和 `downwardAPI` 共同构成了 Pod 与 kube-apiserver 安全通信的基础设施。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

调试大师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值