【K8S in Action】第八章 从应用访问pod元数据

news/2025/1/15 18:44:31/

通过环境变量或者configMap和secret卷向应用传递配置数据。这对于pod调度、 运行前预设的数据是可行的。
对于那些不能预先知道的数据, 比如pod的IP、 主机名或者是pod自身的名称。经在别处定义的数据, 比如pod的标签和注解。不想在多个地方重
复保留同样的数据。

通过Downward API传递元数据

1 了解可用的元数据

Downward API 允许我们通过环境变量或者文件(在downwardA釭卷中)的传递pod的元数据。这种方式主要是将在pod的定义和状态中取得的数据作为环境变量和文件的值, 如图所示
在这里插入图片描述
• pod的名称
• pod的IP
• pod所在的命名空间
• pod运行节点的名称
• pod运行所归属的服务账户的名称
• 每个容器请求的CPU和内存的使用量
• 每个容器可以使用的CPU和内存的限制
• pod的标签
• pod的注解

2 通过环境变量暴露元数据

通过环境变量的方式将pod和容器的元数据传递到容器中。

pod的名称 、IP和命名空间可以通过POD_NAME、 POD_IP和POD_NAMESPACE 这几个环境变量分别暴露。

apiVersion: vl 
kind: Pod 
metadata: name: downward 
spec: containers: - name: main image: busybox command: ["sleep", "9999999") resources:requests: cpu: 15m memory: lOOKi limitS:cpu: 100m memory: 4Mi env: - name: POD_NAMEvalueFrom:fieldRef: fieldPath: metadata.name     引用pod manifest中的元数据名称字段 - name: POD_NAMESPACEvalueFrom: fieldRef: fieldPath: metadata.namespace- name: POD IP valueFrom:fieldRef: fieldPath: status.podIP - name: NODE NAMEvalueFrom:fieldRef: fieldPath: spec.nodeName - name: SERVICE ACCOUNTvalueFrom: fieldRef: fieldPath: spec.serviceAccountName- name: CONTAINER CPU REQUEST MILLICORESvalueFrom:resourceFieldRef:            容器请求的内存和CPU 是 resourceFieldRef 字段resource: requests.cpu divisor: lm               资源相关的字段,基数单位- name: CONTAINER MEMORY LIMIT KIBIBYTESvalueFrom:resourceFieldRef: resource: limits.memorydi visor: lKi看看容器中出环境变量
kubect1 exec downward env

3 通过downwardAPI卷来传递元数据

如果更倾向于使用文件的方式而不是环境变量的方式暴露元数据,可以定义一个downwardAPI卷并挂载到容器中。必须使用downwardAPI卷来暴露pod标签或注解。

apiVersion: vl 
kind: Pod 
metadata:name: downward labels: foo: bar annotations:keyl: valuel key2: |      通过downwardAPI卷来暴露这些标签和注解multiline value 
spec: containers: - name: mainimage: busyboxcommand: ["sleep", "9999999"]resources:requests: cpu: 15m memory: lOOKi limitS:cpu: 100m memory: 4Mi volumeMountS:                     在/etc/downward 目录下挂载这个dowanward卷- name: downwardmountPath: /etc/downwardvolumes: - name: downward          通过将卷的名字设定为downward来定义—个dowanwardAPI卷downwardAPI:items: - path: "podName"       pod的名称(来自manifest文件中 的metadate.name字段)将被写入fieldRef:fieldPath: metadata.name - path: "podNamespace"fieldRef:fieldPath: metadata.namespace- path: "labels"                  pod的标签将被保存到/etc/dowanward/labels文件中 fieldRef:fieldPath: metadata.labels- path:"annotations"            pod的注解将被保存到/etc/dowanward/annotations 文件中fieldRef:fieldPath: metadata.annotations - path: "containerCpuRequestMilliCores"resourceFieldRef:containerName: main resource: requests.cpu divisor: lm - path: "containerMemoryLimitBytes"resourceFieldRef: containerName: main resource: limits.memorydivisor: 1	$ kubectl exec downward cat /etc/downward/labels 
foo="bar"
  • 可以在pod运行时修改标签和注解。如我们所愿,当标签和注解被修改后,Kubemetes会更新存有相关信息的文件,从而使pod可以获取最新的数据。
  • 在环境变量方式下,一旦标签和注解被修改,新的值将无法暴露。

当暴露容器级的元数据时,如容器可使用的资源限制或者资源请求(使用字段 resourceFieldRef), 必须指定引用资源字段对应的容器名称。因为我们对千卷的定义是基于 pod级的,而不是容器级的。

spec: volumes: - name: downwarddownwardAPI:items: - path: "containCpuRequestMilliCores"resourceFieldRef: containerName: main          必须指定容器名称resource: requests.cpu divisor: lm

二、 与Kubernetes API服务器交互

通过服务相关的环境变量或者 DNS 来获取服务和 pod的信息, 但如果应用需要获取其他资源的信息或者获取最新的信息, 就需要直接与API 服务器进行交互。

2.1 Kubernetes REST API

可以通过运行kubectl cluster-info 命令来得到服务器的 URL。kubectl proxy命令启动了一个代理服务来接收来自你本机的 HTTP 连接并转发至 API 服务器, 同时处理身份认证。

$ kubect1 cluster-info
Kubernetes master is running at https://192.168.99.100:8443$ kubect1 proxy 
Starting to serve on 127.0.0.1:8001curl http://localhost:8001/apis/batchcurl http://localhost:8001/apis/batch/vl通过名称恢复一个指定命名空间下的资源 (name:my-job;namespace:dfault)
curl http://localhost:8001/apis/batch/vl/namespaces/default/jobs/my-job 
与这个Job资源的完整的 JSON 定义信息一致
kubetcl get job my-job -o json

通过在 /apis/batch/vl/jobs路径运行一个GET请求,列举集群中所有的Job实例。

2.2 从pod内部与API服务器进行交互

apiVersion: vl 
kind: Pod 
metadata:name: curl 
spec: containers: - name: main image: tutum/curlcommand: ["sleep", "9999999"]在完成pod的创建后,在容器中运行kubectl exec来启动一个bashshell
kubectl exec -it curl bash
  • 确定API 服务器的位置
  • 确保是与 API 服务器进行交互,而不是一个冒名者
  • 通过服务器的认证,否则将不能查看任何内容以及进行任何操作
确定API 服务器的位置

Kubemetes API服务器的 IP 地址和端口:名为kubernetes的服务在默认的命名空间被自动暴露。每个服务都被配置了对应的环境变量, 在容器内通过查询KUBERNETES_SERVICE_HOST 和 KUBERNETES_SERVICE_PORT 这两个环境变量就可以获取 API 服务器的 IP 地址和端口。

同样, 每个服务都可以获得一个 DNS 入口,curl 指向 https://kubemetes

kubectl get SVC 
NAME      CLUSTER-IP EXTERNAL-IP  PORT(S)   AGE 
kubernetes 10.0.0.1   <none>    443/TCP     46dcurl https://kubernetes
验证服务器身份

在讨论 Secret 时, 我们看到一个名为 defalut-token-xyz的 Secret 被自动创建,并挂载到每个容器的 /var/run/secrets/kubemetes.io/serviceaccount
目录下。curl允许使用-cacert选项来指定CA 证书。

在容器内执行
curl --cacert /var/run/secrets/kubernetes.io/serviceaccountca.ert https://kubernetes
Unauthorized 设置CURL_CA_BUNDLE环境变量来简化操作,不用每次指定 cacert export CURL_CA_BUNDLE=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
获得API服务器授权

凭证可以使用之前提到的default-token Secret来产生, 同时凭证可以被存放在secret卷的token文件中。

TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
Authorization字段向 API 服务器传递了凭证
curl -H "Authorization: Bearer $TOKEN"  https://kubernetessecret卷中命名空间的文件,可以读取这个文件来获得命名空间信息
NS=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace) 
curl -H "Authorization: Bearer $TOKEN"  https://kubernetes/api/vl/namespaces/$NS/pods

三、通过 ambassador 容器简化与 API 服务器的交互

可以在主容器运行的同时, 启动一个ambassador容器,并在其中运行kubecctl proxy命令, 通过它来实现与API服务器的交互。保证安全性的前提下有办法简化通信的方式。

apiVersion: vl 
kind: Pod 
metadata:name: curl 
spec: containers: - name: main image: tutum/curlcommand: ["sleep", "9999999"]- name: ambassador image: luksa/kubectl-proxy:l.6.2pod包含两个容器,使用-c main选项指定kubectl exec -it curl-with-ambassador -c main bashcurl localhost:8001成功了

curl向在ambassador容器内运行的代理发送普通的 HTTP 请求(不包含任何授权相关的标头), 然后代理向 API 服务器发送 HTTPS 请求, 通过发送凭证来对客户端授权, 同时通过验证证书来识别服务器的身份。

四 使用客户端库与API服务器交互

可以使用一个标准的客户端库来执行简单的 HTTP 请求。


http://www.ppmy.cn/news/1329399.html

相关文章

C# 获取QQ会话聊天信息

目录 利用UIAutomation获取QQ会话聊天信息 效果 代码 目前遇到一个问题 其他解决办法 利用UIAutomation获取QQ会话聊天信息 效果 代码 AutomationElement window AutomationElement.FromHandle(get.WindowHwnd); AutomationElement QQMsgList window.FindFirst(Tr…

业务逻辑漏洞—验证码绕过

验证码绕过第一关&#xff1a; 前端验证码绕过&#xff1a; 打开pikachu靶场&#xff1a; 输入错误的验证码时会出现弹窗&#xff08;alert&#xff09;此时我们猜测这可能存在着前端限制 如果验证码有前端限制&#xff08;只在前端有作用&#xff09;&#xff0c;不影响后…

为什么两个向量的内积等于模长乘夹角?

为什么两个向量的内积等于模长乘夹角? 已知两个向量 a = [ a 1 , a 2 ] a=[a_1,a_2] a=[a1​,a2​]和 b = [ b 1 , b 2 ] b=[b_1,b_2] b=[b1​,b2​],他们的内积为 a b = a 1 b 1 + a 2 b 2 ab=a_1b_1+a_2b_2 ab=a1​b1​+a2​b2​,看书上的定义该内积的值是一个标量,并且等…

SpringMVC获取参数与页面跳转

获取参数 第一种 直接当成方法的参数&#xff0c;需要与前台的name一致 相当于Request.getAttribute("username") Controller 第二种 使用对象接收 页面的name也要和对象的字段一致 创建一个对应的实体类 Controller 将参数更换为User对象就行 SpringMVC获取到…

Python如何在0和1之间取随机数

在Python中&#xff0c;你可以使用random模块来生成0和1之间的随机数。下面是一个简单的例子&#xff1a; python复制代码 import random # 生成一个0和1之间的随机浮点数 random_number random.random() print(random_number) random.random()函数返回一个0.0到1.0之间的随…

【极数系列】Flink环境搭建(02)

【极数系列】Flink环境搭建&#xff08;02&#xff09; 引言 1.linux 直接在linux上使用jdk11flink1.18.0版本部署 2.docker 使用容器部署比较方便&#xff0c;一键启动停止&#xff0c;方便参数调整 3.windows 搭建Flink 1.18.0版本需要使用Cygwin或wsl工具模拟unix环境…

优化用户体验测试应用领域:提升产品质量与用户满意度

在当今数字化时代&#xff0c;用户体验测试应用已经成为确保产品质量、提升用户满意度的关键工具。随着技术的不断发展&#xff0c;用户的期望也在不断演变&#xff0c;因此&#xff0c;为了保持竞争力&#xff0c;企业必须将用户体验置于产品开发的核心位置。本文将探讨用户体…