从应用访问Pod元数据-DownwardApi的应用
对于某些需要调度之后才能知道的数据,比如 pod 的 ip,主机名,或者 pod 自身的名称等等,k8s 依旧很贴心的提供了 Downward API 的方式来获取此类数据,并且可以通过环境变量或者文件(downwardApi卷中)来传递 pod 的元数据。
可以传递的容器数据包括如下:
- pod的名称,IP,所在命名空间,运行节点的名称,运行所归属的服务账户名称
- 每个容器请求的 CPU 和内存的使用量
- 每个容器可以使用的 CPU 和内存的限制
- pod 的标签
- pod 的注解
通过环境变量暴露元数据
创建一个但容器的 pod
$ vim ./dowanwardapi-learn.yaml apiVersion: v1
kind: Pod
metadata:
name: downward-learn
spec:
containers:
- name: main
image: busybox
command: ["sleep", "999999"]
resources:
requests:
cpu: "15m"
memory: "100Ki"
limits:
cpu: "100m"
memory: "4Mi"
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: CONTAINER_CPU_REQUEST_MILLICORES
valueFrom:
resourceFieldRef:
resource: requests.cpu
divisor: "1m"
- name: CONTAINER_MEMORY_LIMIT_KIBIBYTES
valueFrom:
resourceFieldRef:
resource: limits.memory
divisor: "1Ki"
创建完成后我们可以使用 kubectl exec 命令来查看容器中的所有环境变量,如下:
$ kubectl exec downward-learn env
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=downward-learn
POD_NAME=downward-learn
POD_IP=10.44.0.3
NODE_NAME=node1
CONTAINER_CPU_REQUEST_MILLICORES=15
CONTAINER_MEMORY_LIMIT_KIBIBYTES=4096
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
HOME=/root
但是有一些变量并不能根据环境变量暴露,比如 lables 标签和 annotations 注释等等,但是这些可以使用过 dowanwardApi 卷的方式来进行载入。
通过 downwardAPI 卷来传递元数据
和环境变量一样,通过文件卷的方式也需要显式指定元数据字段来暴露给进程,如下:
apiVersion: v1
kind: Pod
metadata:
name: downward-learn
spec:
containers:
- name: main
image: busybox
command: ["sleep", "999999"]
resources:
requests:
cpu: "15m"
memory: "100Ki"
limits:
cpu: "100m"
memory: "4Mi"
volumeMounts:
- name: downward
mountPath: /etc/downard
volumes:
- name: downward
downwardAPI:
iterms:
- path: "podName"
fileRef:
fieldPath: metadata.name
......
其中声明元数据和配置的方式没什么不同。
但是其中需要注意的是,如果是暴露容器级的元数据时,比如容器可使用的资源限制和资源请求(如使用字段 resourceFieldRef),必须指定引入资源字段的容器名称,比如:
spec:
volumes:
- name: downward
downwardAPI:
items:
- path: "containerCpuRequestMilliCores"
resourceFieldRef:
containerName: main ## 容器名称
resource: requests.cpu
divisor: 1m
这里由于引入了cpu资源限制,所以也贴一下所用到的,在 pod 内查询当前的 cpu 使用进程代码,因为 pod 容器内的查询 cpu 使用和物理机上的还不太一样,在网上找了一些但是都不太适合容器使用,所以自己写了一个
$ vim cpu.go
package handler import (
"fmt"
"os" linuxproc "github.com/c9s/goprocinfo/linux"
) var (
prevUsageUser int64 = 0
prevUsageSystem int64 = 0
cpuNum = 1 // 设置该容器内使用的cpu个数
) func GetCpuCount(stat *linuxproc.Stat) (count float64) {
cfsQuota := getCgoupValueByPath("/sys/fs/cgroup/cpu/cpu.cfs_quota_us")
cfsPeriod := getCgoupValueByPath("/sys/fs/cgroup/cpu/cpu.cfs_period_us") if cfsQuota == -1 {
return float64(len(stat.CPUStats))
} return float64(cfsQuota) / float64(cfsPeriod)
} func CpuCountToString(c float64) string {
if c == float64(int64(c)) {
return fmt.Sprintf("%v", c)
}
return fmt.Sprintf("%0.1f", c)
} // GetCpuUsage should be called every 1 seconds. not quite precise.
func GetCpuUsage(cpus float64) (user, system, idle float64) {
var currentUsageUser, currentUsageSystem int64
currentUsageUser = getCgoupValueByPath("/sys/fs/cgroup/cpuacct/cpuacct.usage_user")
currentUsageSystem = getCgoupValueByPath("/sys/fs/cgroup/cpuacct/cpuacct.usage_sys") if prevUsageUser == 0 && prevUsageSystem == 0 {
prevUsageUser = currentUsageUser
prevUsageSystem = currentUsageSystem
return
} user = float64(currentUsageUser-prevUsageUser) / 10000000 / cpus // / 1000,000,000 * 100 = /10,000,000
system = float64(currentUsageSystem-prevUsageSystem) / 10000000 / cpus // / 1000,000,000 * 100 = /10,000,000
idle = 100 - user - system
if idle < 0 {
idle = 0
} prevUsageUser = currentUsageUser
prevUsageSystem = currentUsageSystem return
} func getCgoupValueByPath(path string) int64 {
data, err := os.ReadFile(path)
if err != nil {
return 0
} var value int64
n, err := fmt.Sscanf(string(data), "%d", &value)
if err != nil || n != 1 {
return 0
}
return value
}
计算出来当前的容器数值换算为:use 80% = 800
这样在容器内就能根据元数据和监控脚本时刻监控容器的 cpu 使用率了。
从应用访问Pod元数据-DownwardApi的应用的更多相关文章
- Kubernetes学习笔记(七):访问Pod元数据与Kubernetes API
Downward API 我们已经了解到,使用ConfigMap和Secret向应用传递配置数据,这对于运行前预设的数据是可行的.但是对于那些不能预先知道的,就需要使用Downward API. Do ...
- kubernets之从应用访问pod元数据以及其他资源
一 downwardAPI的应用 1.1 前面我们介绍了如何通过configmap以及secret将配置传入到pod的容器中,但是传递的这些都是预先能够安排和只晓得,对于那些只有当pod创建起来之 ...
- spark on yarn模式下配置spark-sql访问hive元数据
spark on yarn模式下配置spark-sql访问hive元数据 目的:在spark on yarn模式下,执行spark-sql访问hive的元数据.并对比一下spark-sql 和hive ...
- 第六章 通过Service访问Pod(中)
6.2 Cluster IP 底层实现 Cluster IP 是一个虚拟IP,是由K8s节点上的iptables规则管理的. 使用类似轮询的方法访问Pod. 6.3 DNS 访问Service 在Cl ...
- 第六章 通过Service访问Pod(上)
不应该直接使用Pod的ID地址作为对外提供服务的接口,应为一旦Pod重启,IP地址就变化了,解决方案是使用Service. 6.1 创建Service K8s service从逻辑上代表了一组Pod, ...
- k8s如何访问pod
1. 通过 Service 访问 Pod 我们不应该期望 Kubernetes Pod 是健壮的,而是要假设 Pod 中的容器很可能因为各种原因发生故障而死掉.Deployment 等 control ...
- 如何访问Pod
本章看点: 理清Deployment,ReplicaSet和Pod的关系,以及三者之间的网络关系,ip地址和端口号 通过Pod进入docker容器修改里面的内容 外部网络访问Pod里面的应用 一.通过 ...
- 如何访问pod(6)
一.通过 Service 访问 Pod: 我们不应该期望 Kubernetes Pod 是健壮的,而是要假设 Pod 中的容器很可能因为各种原因发生故障而死掉.Deployment 等 control ...
- kubernetes如何访问pod服务
一.通过 Service 访问 Pod: 我们不应该期望 Kubernetes Pod 是健壮的,而是要假设 Pod 中的容器很可能因为各种原因发生故障而死掉.Deployment 等 control ...
随机推荐
- jdbc 09: preparedStatement实现增删改查
jdbc连接mysql,利用preparedStatement实现增删改查 package com.examples.jdbc.o9_preparedStatement实现增删改; import ja ...
- AtCoder Beginner Contest 247 E - Max Min // 容斥原理
原题链接:E - Max Min (atcoder.jp) 题意: 给定一个数组,求满足最大值为X且最小值为Y的区间个数. 思路:容斥原理 因为必须要包含端点,直接求是不容易的.因此考虑去求不一定包含 ...
- C#委托的最简单入门和理解
委托是.net语言中非常重要的一个概念,初学不太好理解也没有关系的,在一次一次的攻关后会领会到委托的精妙,可以说 .net 没有委托就没有后面更高级的事件,异步多线程等等特性的形成可能.所以一定要 ...
- [NCTF2019]SQLi-1||SQL注入
1.打开之后首先尝试万能密码登录和部分关键词(or.select.=.or.table.#.-等等)登录,显示被检测到了攻击行为并进行了拦截,结果如下: 2.使用dirmap进行目录扫描,发现robo ...
- Linux系列之重定向操作
前言 I/O重定向允许我们将命令的输入和输出重定向到文件中,以及将多个命令连接到一起成为管道.本文就来介绍有关重定向的知识. 标准输入.输出.错误 输出包括两种类型: 程序的结果.被称为标准输出或者s ...
- Apache DolphinScheduler 源码剖析之 Worker 容错处理流程
今天给大家带来的分享是 Apache DolphinScheduler 源码剖析之 Worker 容错处理流程 DolphinScheduler源码剖析之Worker容错处理流程 Worker容错流程 ...
- ASP.NET Core依赖注入系统学习教程:容器对构造函数选择的策略
.NET Core的依赖注入容器之所以能够为应用程序提供服务实例,这都归功于ServiceDescriptor对象提供的服务注册信息.另外,在ServiceDescriptor对象中,还为容器准备了3 ...
- SpringBoot整合Redis实现常用功能
SpringBoot整合Redis实现常用功能 建议大小伙们,在写业务的时候,提前画好流程图,思路会清晰很多. 文末有解决缓存穿透和击穿的通用工具类. 1 登陆功能 我想,登陆功能是每个项目必备的功能 ...
- MySQL源码分析之SQL函数执行
1.MySQL中执行一条SQL的总体流程 2.SQL函数执行过程 1.MySQL中执行一条SQL的总体流程 一条包含函数的SQL语句,在mysql中会经过: 客户端发送,服务器连接,语法解析,语句执行 ...
- 【MIDO】乐理基础 与 python - 从零开始到编写柱式和弦与分解和弦
本篇文章从律学开始,从十二平均律出发,介绍一些基础必要的乐理知识,然后编写python文件,输出和弦音频文件. 乐理知识部分: 一.律学简述(temperament) 1.概论 律学,又称&q ...