之前做了一个VPA项目的需求,就是需要不重启的方式修改容器的Cgroup的值已达到垂直扩缩容的目的,项目中核心的思路如下

  1. 上游下发要VPA的结果的值写入到容器的Annotation里面
  2. Kubelet 感知到这个 annoation 的变化
  3. 我们本地运行一个 Agent,里面运行一个类似的job监听kubelet的变化,当发现annotation的值改变的时候就去修改对应容器的Cgroup的数值即可

具体步骤如下

Cgroup 是什么

简而言之,对容器技术而言,其实现资源层面上的限制和隔离,依赖于 Linux 内核提供的 Cgroup 和 namespace 技术

cgroup 的主要作用:管理资源的分配和限制;主要限制的资源是CPU、内存、网络和磁盘IO

namespace 的主要作用:封装抽象、限制、隔离,使命名空间内的进程看起来拥有他们自己的全局资源

以一个最简单的例子来校验Cgroup的限制,我们使用docker来创建以下容器

docker run --rm -d --cpus=2 --memory=2g --name=2c2g redis:alpine

查看上述容器的ID

➜ dps | grep -i 2c2g
37ad8252f8de   redis:alpine   "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   6379/tcp   2c2g

找到 /sys/fs/cgroup/system.slice 目录对应的容器
在这里插入图片描述

可看到有很多容器的选项可供查看

查看CPU和内存的Max

➜  docker-37ad8252f8de50694e3321364c9ef5e94ae08f45f50e633e561feb291d1c27e9.scope cat cpu.max
200000 100000
➜  docker-37ad8252f8de50694e3321364c9ef5e94ae08f45f50e633e561feb291d1c27e9.scope cat memory.max
2147483648        # 这里的单位是Byte

我们查看容器的占用
在这里插入图片描述

可以看到这个2G就是我们设定的数值

那尝试直接修改这个cgroup的数值,是不是就能修改容器的内存和CPU的限制从而做到VPA的效果

我们尝试修改内存由原来的2G到现在的1G

echo "1073741824" >> memory.max

再次查看内存的占用比值,可以发现确实修改已经生效

在这里插入图片描述

Kubelet 的接口

首先明确一点,你在管控面 kubelet get 等信息基本都是从边缘端映射过来的,所以单机侧的 kubelet 也能获取到很多信息,比如

/configz     返回 kubelet 的相关配置信息
/metrics     暴露 kubelet 和容器的监控指标,比如 CPU 和内存的使用率,网络流量等
/pods        返回当前节点上的所有 Pod 的信息,包括 Pod 的状态以及容器信息等
/stats/summary    提供节点的资源使用统计信息,包括CPU、内存、网络、磁盘等
/exex/<pod_namespace>/<pod_name>/<container_name>     提供指定容器的日志,支持tail和follow参数
/logs        用于获取正在运行的pods和容器日志

配置服务账号访问kubelet

访问 kubelet 需要使用密钥,我们先配置服务账号访问,直接配置成最大的 clusterrole 权限

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: system:my-agent
subjects:- kind: ServiceAccountname: my-agentnamespace: default
roleRef:kind: ClusterRolename: system:my-agentapiGroup: rbac.authorization.k8s.io
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: system:my-agent
rules:- apiGroups:- ""resources:- nodesverbs:- get- list- watch- apiGroups:- ""resources:- nodesverbs:- proxy- apiGroups:- ""resources:- nodes/log- nodes/metrics- nodes/proxy- nodes/spec- nodes/statsverbs:- '*'
---
apiVersion: v1
kind: ServiceAccount
metadata:name: my-agentnamespace: default

上面的服务账号创建完成之后就能看到下面的密钥了

kubectl get secret $(kubectl get serviceaccount my-agent -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 --decode

比如我这个机器上是

➜  ~ k get secret $(kubectl get serviceaccount my-agent -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 --decode
eyJhbGciOiJSUzI1NiIsImtpZCI6IlBQTDNXcGNKenVxNGZ3OHdpam5WQ0Jnd3d3NWpMbVZtSWJETTQ0WW5EZHMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Im15LWFnZW50LXRva2VuLXE0a2hsIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Im15LWFnZW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiY2UyMzQzNGEtMTViYy00YzI1LWIwYTktZGQxM2E3MDllMGRlIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6bXktYWdlbnQifQ.UjNJxEbaLDm_19wVB4OPi-3u6fTG2noCQrLI7e7-PA1DoPc4SQJHzVXmPGwP6Ln4Odv-PrC0jkOpGF4DQQcQx589HsXN0zpmn6z-GJdzTsVxFFaJZpgZlfITGN99zQlr-AkRjgEm_9vUpijjjXOP0dWmPlHlmpxSYqpf3zSohIJsBySpXp1sQKboaeqTHbXU02xwsCjFDHeOyfESQcyVOtKQk9_w0Qvtiz5DcCClAZSCW8WLQPX9X7wie_vZCKlcNKiS5eKYCdymm6ZndXyidqb9Ga027_jhZnjvPO27rzBAL5wiTgonYAUau6tvB9KENfYAFF3pm2rTJZYujjUOfA

那用这个 token 是否可以访问到机器上的 pods 信息呢

我们试着对 /configz 接口发起访问,访问其 kubelet 的配置信息
在这里插入图片描述

可以看到访问成功

实操:部署pod并做VPA操作

手动修改

创建一个 nginx 的 deployment,设定资源限制为2core2G

apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deployment
spec:replicas: 1  # 设置副本数selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:latest  # 使用最新的 Nginx 镜像resources:requests:memory: "2Gi"  # 请求的内存cpu: "2"       # 请求的 CPUlimits:memory: "2Gi"  # 限制的内存cpu: "2"       # 限制的 CPUports:- containerPort: 80  # Nginx 默认监听的端口

创建完成之后到目录 /sys/fs/cgroup/kubepods.slice 下面就能看到我们创建的pod
在这里插入图片描述

这个后缀就是我们pod的uid
在这里插入图片描述

进入到这个目录下面
在这里插入图片描述

可以发现这个pod里面实际运行了两个容器,一个 sandbox 容器用来隔离容器的网络,一个业务自身的容器

分别对应的pod的信息如下
在这里插入图片描述
在这里插入图片描述

我们进入到我们的业务pod里面,修改内存的取值如下

➜  docker-567f43cdcb3c5630ffc17735d92b2895912a65a3e03fd5575262a52709eba00b.scope cat memory.max
2147483648

修改为1G

然后使用 docker stats 查看容器的负载使用情况
在这里插入图片描述

可以看到容器的内存使用上限已经修改为我们期望的1GB,并且是不需要在重启容器的情况下进行的

参考文档

一篇搞懂容器技术的基石: cgroup

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/912653.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/912653.shtml
英文地址,请注明出处:http://en.pswp.cn/news/912653.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

熟悉 PyCharm

界面 我们常用的就这个几个地方&#xff1a; 常用配置 调整字体大小 Ctrl 滚轮调整字体大小 插件推荐 Indent Rainbow 该插件的作用在于能够对于不同层级缩进的空格标注不同的颜色&#xff1a; 快捷键 快捷键的 pdf 下载链接&#xff1a; Windows 版&#xff1a;https:…

pytorch--模型训练的一般流程

文章目录 前言0、数据集准备1、数据集2、dataset3、model4、训练模型 前言 在pytorch中模型训练一般分为以下几个步骤&#xff1a; 0、数据集准备 1、数据集读取&#xff08;dataset模块&#xff09; 2、数据集转换为tensor&#xff08;dataloader模块&#xff09; 3、定义模型…

智能合同管理实战:基于区块链的电子签约技术实现

在数字经济时代,传统纸质合同签署方式已难以满足企业高效、安全、合规的业务需求。智能合同管理(Smart Contract Management)结合区块链技术,正在重塑电子签约流程,实现合同全生命周期的自动化、可追溯和防篡改。本文将深入探讨基于区块链的电子签约技术实现,涵盖核心架构…

设计模式精讲 Day 22:模板方法模式(Template Method Pattern)

【设计模式精讲 Day 22】模板方法模式&#xff08;Template Method Pattern&#xff09; 文章标签 设计模式, 模板方法模式, Java开发, 面向对象设计, 软件架构, 设计模式实战, Java应用开发 文章简述 模板方法模式是一种行为型设计模式&#xff0c;它通过定义一个算法的骨架…

如何在pytorch中使用tqdm:优雅实现训练进度监控

文章目录 为什么需要进度条&#xff1f;tqdm 简介基础用法示例深度学习中的实战应用1. 数据加载进度监控2. 训练循环增强版3. 验证阶段集成 高级技巧与最佳实践1. 自定义进度条样式2. 嵌套进度条&#xff08;多任务&#xff09;3. 分布式训练支持4. 与日志系统集成 性能优化建议…

Linux中的xxd命令详解

xxd 是一个 十六进制转储&#xff08;hex dump&#xff09;工具&#xff0c;通常用于将二进制文件转换为十六进制格式&#xff0c;或者反向转换&#xff08;十六进制→二进制&#xff09;。它是 vim 的一部分&#xff0c;但在大多数 Linux 系统&#xff08;如 Ubuntu&#xff0…

磐维数据库panweidb3.1.0单节点多实例安装

0 说明 业务科室提单需要在某台主机上部署多个单机磐维数据库&#xff0c;用于业务测试。以下内容展示如何在单节点安装多个磐维数据库实例。 1 部署环境准备 1.1 IP 地址及端口 instipport实例1192.168.131.1717700实例2192.168.131.1727700 在131.17上分别安装两个实例&…

转录组分析流程(三):功能富集分析

我们的教程主要是以一个具体的例子作为线索,通过对公共数据库数据bulk-RNA-seq的挖掘,利用生物信息学分析来探索目标基因集作为某种疾病数据预后基因的潜能及其潜在分子机制,同时在单细胞水平分析(对scRNA-seq进行挖掘)预后基因的表达,了解细胞之间的通讯网络,以期为该疾病…

全面掌握 tkinter:Python GUI 编程的入门与实战指南

在自动化、工具开发、数据可视化等领域&#xff0c;图形用户界面&#xff08;GUI&#xff09;往往是提升用户体验的重要方式。作为 Python 官方内置的 GUI 库&#xff0c;tkinter 以其轻量、跨平台、易于学习的特性成为初学者和轻量级应用开发者首选。 本文将以深入浅出的方式…

TDH社区开发版安装教程

&#xff08;注&#xff1a;本文章来源于星环官网安装手册&#xff09; 后面放置了视频和安装手册连接 1、硬件及环境要求 Docker17及以上版本&#xff0c;支持Centos&#xff0c;Ubuntu等系统&#xff08;注&#xff1a;这里我使用CentOS-7版本&#xff0c;最佳版本推荐为7.…

Linux基本命令篇 —— grep命令

grep是Linux/Unix系统中一个非常强大的文本搜索工具&#xff0c;它的名字来源于"Global Regular Expression Print"&#xff08;全局正则表达式打印&#xff09;。grep命令用于在文件中搜索包含特定模式的行&#xff0c;并将匹配的行打印出来。 目录 一、基本语法 二…

苍穹外卖问题系列之 苍穹外卖订单详情前端界面和网课给的不一样

问题 如图&#xff0c;我的前端界面和网课里面给的不一样&#xff0c;没有“申请退款”和一些其他的该有的东西。 原因分析 “合计”这一栏显示undefined说明我们的总金额没有输入进去。可以看看订单提交那块的代码&#xff0c;是否可以正确输出。还有就是订单详细界面展示这…

CppCon 2018 学习:EMULATING THE NINTENDO 3DS

我们来逐个分析一下这个 组件交互模型 和 仿真 & 序列化 的关系&#xff0c;特别是主线程&#xff08;Main Thread&#xff09;与其他系统组件之间的交互。 1. Main Thread — simple (basically memcpy) --> GPU Main Thread&#xff08;主线程&#xff09;负责游戏的…

[Python 基础课程]数字

数字 数字数据类型用于存储数值&#xff0c;比如整数、小数等。数据类型是不允许改变的&#xff0c;这就意味着如果改变数字数据类型的值&#xff0c;将重新分配内存空间。 创建数字类型的变量&#xff1a; var1 1 var2 10创建完变量后&#xff0c;如果想废弃掉这个变量&a…

Linux CentOS环境下Java连接MySQL数据库指南

文章目录 前言一、环境准备1.1 系统更新1.2 Java环境安装1.3 MySQL数据库安装1.4 下载JDBC驱动 二、编写Java程序2.1 代码如下2.2 编译和运行2.3 验证创建结果 三、代码上传至Gitee3.1 安装配置Git3.2 克隆仓库到本地3.3 添加Java项目文件3.4 提交代码到本地仓库3.5 推送到Gite…

LLM面试12

讯飞算法工程师面试题 SVM核函数能否映射到无穷维 可以的&#xff0c;多项式核函数将低维数据映射到高维&#xff08;维度是有限的&#xff09;&#xff0c;而高斯核函数可以映射到无穷维。由 描述下xgb原理&#xff0c;损失函数 首先需要说一说GBDT,它是一种基于boosting增强…

类加载生命周期与内存区域详解

类加载生命周期与内存区域详解 Java 类加载的生命周期包括加载、验证、准备、解析、初始化五个阶段&#xff0c;每个阶段在内存中的存储区域和赋值机制各有不同。以下是详细解析&#xff1a; 一、类加载生命周期阶段 1. 加载&#xff08;Loading&#xff09; 内存区域&…

正交视图三维重建2 笔记 2d线到3d线2 先生成3d线然后判断3d线在不在

应该先连线再判断线在不在 if(fx1tx1&&tx1tx2){ const A[fx1, fy1, ty1];const Ahat[fx1, fy1, ty2];drawlines(A[0], A[1], A[2], Ahat[0], Ahat[1], Ahat[2], lineId, type,2);}if(fx2tx1&&tx1tx2){ const B[fx2, fy2, ty1];const Bhat[fx2, fy2, ty2];drawl…

Hibernate对象生命周期全解析

Hibernate对象生命周期详解 Hibernate作为Java领域主流的ORM框架,其核心机制之一就是对持久化对象生命周期的管理。理解Hibernate对象生命周期对于正确使用Hibernate进行数据持久化操作至关重要。Hibernate将对象分为三种主要状态:瞬时态(Transient)、持久态(Persistent)和游…

MCP 协议使用核心讲解

&#x1f4c4; MCP 协议使用核心讲解 ✅ MCP 协议的核心在于以下几个方面 一、MCP 请求结构&#xff08;MCPRequest&#xff09; {"messages": [{"role": "user","content": "帮我查询一下上海的天气"}],"tools"…