Kubernetes 笔记(16)— 集群管理、使用名字空间分隔系统资源、给名字空间设置资源限额、默认资源配额的使用

news2024/12/26 22:47:29

1. 为什么要有名字空间

首先要明白,Kubernetes 的名字空间并不是一个实体对象,只是一个逻辑上的概念。它可以把集群切分成一个个彼此独立的区域,然后我们把对象放到这些区域里,就实现了类似容器技术里 namespace 的隔离效果,应用只能在自己的名字空间里分配资源和运行,不会干扰到其他名字空间里的应用。

你可能要问了:KubernetesMaster/Node 架构已经能很好地管理集群,为什么还要引入名字空间这个东西呢?它的实际意义是什么呢?

我觉得,这恰恰是 Kubernetes面对大规模集群、海量节点时的一种现实考虑。因为集群很大、计算资源充足,会有非常多的用户在 Kubernetes 里创建各式各样的应用,可能会有百万数量级别的 Pod,这就使得资源争抢和命名冲突的概率大大增加了,情形和单机 Linux 系统里是非常相似的。

比如说,现在有一个 Kubernetes 集群,前端组、后端组、测试组都在使用它。这个时候就很容易命名冲突,比如后端组先创建了一个 Pod 叫 “Web”,这个名字就被“占用”了,之后前端组和测试组就只能绞尽脑汁再新起一个不冲突的名字。接着资源争抢也容易出现,比如某一天,测试组不小心部署了有 Bug 的应用,在节点上把资源都给“吃”完了,就会导致其他组的同事根本无法工作。

所以,当多团队、多项目共用 Kubernetes 的时候,为了避免这些问题的出现,我们就需要把集群给适当地“局部化”,为每一类用户创建出只属于它自己的“工作空间”。

如果把 Kubernetes 比做一个大牧场的话,API 对象就是里面的鸡鸭牛羊,而名字空间就是圈养它们的围栏,有了各自合适的活动区域,就能更有效、更安全地利用 Kubernetes

2. 如何使用名字空间

名字空间也是一种 API 对象,使用命令 kubectl api-resources 可以看到它的简称是 ns

namespace

命令 kubectl create 不需要额外的参数,可以很容易地创建一个名字空间,比如:


kubectl create ns test-ns 
kubectl get ns

getns

Kubernetes 初始化集群的时候也会预设 4 个名字空间:defaultkube-systemkube-publickube-node-lease。我们常用的是前两个,

  • default 是用户对象默认的名字空间
  • kube-system 是系统组件所在的名字空间

想要把一个对象放入特定的名字空间,需要在它的 metadata 里添加一个 namespace 字段,比如我们要在 test-ns 里创建一个简单的 Nginx Pod ,就要这样写:

# ngx-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: ngx
  namespace: test-ns

spec:
  containers:
  - image: nginx:alpine
    name: ngx

kubectl apply 创建这个对象之后,我们直接用 kubectl get 是看不到它的,因为默认查看的是default名字空间,想要操作其他名字空间的对象必须要用 -n 参数明确指定:

gettest-ns

因为名字空间里的对象都从属于名字空间,所以在删除名字空间的时候一定要小心,一旦名字空间被删除,它里面的所有对象也都会消失。

你可以执行一下 kubectl delete,试着删除刚才创建的名字空间 test-ns

delete-ns

就会发现删除名字空间后,它里面的 Pod 也会无影无踪了。

3. 什么是资源配额

有了名字空间,我们就可以像管理容器一样,给名字空间设定配额,把整个集群的计算资源分割成不同的大小,按需分配给团队或项目使用。

不过集群和单机不一样,除了限制最基本的 CPU 和内存,还必须限制各种对象的数量,否则对象之间也会互相挤占资源。

名字空间的资源配额需要使用一个专门的 API 对象,叫做 ResourceQuota,简称是 quota
quota

我们可以使用命令 kubectl create 创建一个它的样板文件:


export out="--dry-run=client -o yaml"
kubectl create quota dev-qt $out

因为资源配额对象必须依附在某个名字空间上,所以在它的 metadata 字段里必须明确写出 namespace(否则就会应用到 default 名字空间)。

下面我们先创建一个名字空间 dev-ns ,再创建一个资源配额对象 dev-qt


apiVersion: v1
kind: Namespace
metadata:
  name: dev-ns

---

apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-qt
  namespace: dev-ns

spec:
  ... ...

ResourceQuota 对象的使用方式比较灵活,既可以限制整个名字空间的配额,也可以只限制某些类型的对象(使用 scopeSelector),今天我们看第一种,它需要在 spec 里使用 hard 字段,意思就是“硬性全局限制”。

ResourceQuota 里可以设置各类资源配额,字段非常多,我简单地归了一下类,你可以课后再去官方文档上查找详细信息:

  • CPU 和内存配额,使用 request.*limits.*,这是和容器资源限制是一样的。
  • 存储容量配额,使 requests.storage 限制的是 PVC 的存储总量,也可以用 persistentvolumeclaims 限制 PVC 的个数。
  • 核心对象配额,使用对象的名字(英语复数形式),比如 podsconfigmapssecretsservices
  • 其他 API 对象配额,使用 count/name.group 的形式,比如 count/jobs.batchcount/deployments.apps。这里的 group 是指kubectl api-resourcesAPIVERSION 列中的内容,比如 deploymentAPIVERSIONapps/v1jobcronjobAPIVERSIONbatch/v1

下面的这个 YAML 就是一个比较完整的资源配额对象:

# dev-quota.yml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-qt
  namespace: dev-ns

spec:
  hard:
    requests.cpu: 10
    requests.memory: 10Gi
    limits.cpu: 10
    limits.memory: 20Gi

    requests.storage: 100Gi
    persistentvolumeclaims: 100

    pods: 100
    configmaps: 100
    secrets: 100
    services: 10

    count/jobs.batch: 1
    count/cronjobs.batch: 1
    count/deployments.apps: 1

解释一下它为名字空间加上的全局资源配额:

  • 所有 Pod 的需求总量最多是 10 个 CPU 和 10GB 的内存,上限总量是 10 个 CPU 和 20GB 的内存。
  • 只能创建 100 个 PVC 对象,使用 100GB 的持久化存储空间。
  • 只能创建 100 个 Pod,100 个 ConfigMap,100 个 Secret,10 个 Service
  • 只能创建 1 个 Job,1 个 CronJob,1 个 Deployment

4. 如何使用资源配额

现在让我们用 kubectl apply 创建这个资源配额对象,然后用 kubectl get 查看,记得要用 -n 指定名字空间:


kubectl apply -f dev-quota.yml
kubectl get quota -n dev-ns

quota-devns

你可以看到输出了 ResourceQuota 的全部信息,但都挤在了一起,看起来很困难,这时可以再用命令 kubectl describe 来查看对象,它会给出一个清晰的表格:


kubectl describe quota -n dev-ns

describe

现在让我们尝试在这个名字空间里运行两个 busybox Job,同样要加上 -n 参数:


kubectl create job echo1 -n dev-ns --image=busybox -- echo hello
kubectl create job echo2 -n dev-ns --image=busybox -- echo hello

joblimit
ResourceQuota 限制了名字空间里最多只能有一个 Job,所以创建第二个 Job 对象时会失败,提示超出了资源配额。

再用命令 kubectl describe 来查看,也会发现 Job 资源已经到达了上限:

job-describe

不过,只要我们删除刚才的 Job,就又可以运行一个新的离线业务了:

recreate-job

同样的,这个 dev-ns里也只能创建一个 CronJob 和一个 Deployment

5. 默认资源配额

学到这里估计你也发现了,在名字空间加上了资源配额限制之后,它会有一个合理但比较“烦人”的约束:要求所有在里面运行的 Pod 都必须用字段 resources 声明资源需求,否则就无法创建。

比如说,现在我们想用命令 kubectl run 创建一个 Pod


kubectl run ngx --image=nginx:alpine -n dev-ns

forbidden
发现给出了一个 Forbidden的错误提示,说不满足配额要求。

Kubernetes 这样做的原因也很好理解,上一讲里我们说过,如果 Pod 里没有 resources 字段,就可以无限制地使用 CPU 和内存,这显然与名字空间的资源配额相冲突。为了保证名字空间的资源总量可管可控,Kubernetes 就只能拒绝创建这样的 Pod 了。

这个约束对于集群管理来说是好事,但对于普通用户来说却带来了一点麻烦,本来 YAML 文件就已经够大够复杂的了,现在还要再增加几个字段,再费心估算它的资源配额。如果有很多小应用、临时 Pod 要运行的话,这样做的人力成本就比较高,不是太划算。

那么能不能让 Kubernetes 自动为 Pod 加上资源限制呢?也就是说给个默认值,这样就可以省去反复设置配额的烦心事。

这个时候就要用到一个很小但很有用的辅助对象了—— LimitRange,简称是 limits,它能为 API 对象添加默认的资源配额限制。
limitrange
你可以用命令 kubectl explain limits 来查看它的 YAML 字段详细说明,这里说几个要点:

  • spec.limits 是它的核心属性,描述了默认的资源限制。
  • type 是要限制的对象类型,可以是 ContainerPodPersistentVolumeClaim
  • default 是默认的资源上限,对应容器里的 resources.limits,只适用于 Container
  • defaultRequest 默认申请的资源,对应容器里的 resources.requests,同样也只适用于 Container
  • maxmin 是对象能使用的资源的最大最小值。

explain-limits

这个 YAML 就示范了一个 LimitRange 对象:

# dev-limits.yml

apiVersion: v1
kind: LimitRange
metadata:
  name: dev-limits
  namespace: dev-ns

spec:
  limits:
  - type: Container
    defaultRequest:
      cpu: 200m
      memory: 50Mi
    default:
      cpu: 500m
      memory: 100Mi
  - type: Pod
    max:
      cpu: 800m
      memory: 200Mi

它设置了每个容器默认申请 0.2 的 CPU 和 50MB 内存,容器的资源上限是 0.5 的 CPU 和 100MB 内存,每个 Pod 的最大使用量是 0.8 的 CPU 和 200MB 内存。

使用 kubectl apply 创建 LimitRange 之后,再用 kubectl describe 就可以看到它的状态:


kubectl describe limitranges -n dev-ns

limitsrange

现在我们就可以不用编写 resources 字段直接创建 Pod 了,再运行之前的 kubectl run 命令:


kubectl run ngx --image=nginx:alpine -n dev-ns

有了这个默认的资源配额作为“保底”,这次就没有报错,Pod 顺利创建成功,用 kubectl describe 查看 Pod 的状态,也可以看到 LimitRange 为它自动加上的资源配额:

describe-pod

6. 总结

在我们的实验环境里,因为只有一个用户(也就是你自己),可以独占全部资源,所以使用名字空间的意义不大。

但是在生产环境里会有很多用户共同使用 Kubernetes,必然会有对资源的竞争,为了公平起见,避免某些用户过度消耗资源,就非常有必要用名字空间做好集群的资源规划了。

  1. 名字空间是一个逻辑概念,没有实体,它的目标是为资源和对象划分出一个逻辑边界,避免冲突。
  2. ResourceQuota 对象可以为名字空间添加资源配额,限制全局的 CPU、内存和 API 对象数量。
  3. LimitRange 对象可以为容器或者 Pod 添加默认的资源配额,简化对象的创建工作。
  • 不是所有的 API 对象都可以划分进名字空间管理的,比如 Node, PV 等这样的全局资源就不属于任何名字空间。

  • 因为 ResourceQuota 可以使用 scopeSelector 字段限制不同类型的对象,所以我们还可以在名字空间里设置多个不同策略的配额对象,更精细地控制资源。

  • LimitRange 对象里设置 max 字段可以有效地防止创建意外申请超量资源的对象。

  • 不同 namespaceservicepod 可以通信吗?—— 当然是可以的,像 apiservier就在 kube-system

7. 问答

  1. 如果你是 Kubernetes 系统管理员,你会如何使用名字空间来管理生产集群呢?

namespace属于逻辑隔离,生产上体现可以划分为基础中间件命名空间,其余按照业务系统划分。

  1. 你觉得设置资源配额应该遵循什么样的基本原则?

按照目前实施一些经验,机器通常会采用 cpu与内存形成一个固定比例,例如 8core,16G, 16core,32G, 然后会建议应用软件采用这个比例去配置 request,``limited, 同时要求,request尽可能小些,可以容纳下更多应用,超过一些限额后,集群具备自动化弹性扩容,形成“超卖”。同理,资源配额也是建议这样的比例。

  • limitrangeContainer 的限制是指在容器级别限制资源,不是 Pod 级别。
  • 不同 namespace 的对象 ,可能运行在同一 Node 上吧?—— 当然了,node 不归 namespace 管理。

文中“容器的资源上限是 0.5 的 CPU 和 100MB 内存,每个 Pod 的最大使用量是 0.8 的 CPU 和 200MB 内存。”, 前面部分是上限,后面部分是最大值,后边的大于前面的啊,不矛盾吗?
—— 一个 Pod 可以包含多个容器。

k8snamespace 和容器的 namespace 有什么区别?
—— Kubernetesnamespace 是一个逻辑管理的概念,而容器的 namespace 是一个实打实的隔离技术。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MATLAB符号运算(七) 更新中...

目录 1、实验目的: 2、实验内容: 1、实验目的: 1)掌握定义符号对象和创建符号表达式的方法; 2)掌握符号运算基本命令和规则; 3)掌握符号表达式的运算法则以及符号矩阵运算&#xf…

93、Dehazing-NeRF: Neural Radiance Fields from Hazy Images

简介 论文:https://arxiv.org/pdf/2304.11448.pdf 从模糊图像输入中恢复清晰NeRF 使用大气散射模型模拟有雾图像的物理成像过程,联合学习大气散射模型和干净的NeRF模型,用于图像去雾和新视图合成 通过将NeRF 3D场景的深度估计与大气散射模…

【牛客刷题专栏】23:JZ22 链表中倒数最后k个结点(C语言编程题)

前言 个人推荐在牛客网刷题(点击可以跳转),它登陆后会保存刷题记录进度,重新登录时写过的题目代码不会丢失。个人刷题练习系列专栏:个人CSDN牛客刷题专栏。 题目来自:牛客/题库 / 在线编程 / 剑指offer: 目录 前言问…

LeetCode-344. 反转字符串

题目链接 LeetCode-344. 反转字符串 题目描述 题解 题解一(Java) 作者:仲景 直接双指针前后一直交换即可 class Solution {public void reverseString(char[] s) {if (s.length 1)return;// 双指针int lp 0, rp s.length - 1;while (lp…

【百度智能云】基于http3的xcdn 开放直播方案设计与实践

大神:柯老师 现有的融合CDN 0 需要集成sdksdk 是集成在端侧缺点 sdk 对端侧有影响多云模式下,sdk不互通、 XCDN 设计目标 :保持现有cdn的优势 承载各种业务:直播点播让各家的cdn互通cdn 厂家屏蔽了差异性,集成起来比较简单,对接简单开发的互联网生态。使用统一的http3标…

理解缓冲区

文章目录 一.缓冲区1.什么是缓冲区2.缓冲区的意义3.缓冲区的刷新策略4.我们目前谈论的缓冲区在哪里5.仿写FILE5.1myStdio.h5.2myStdio.c 6.操作系统的缓冲区 一.缓冲区 int main() {printf("hello linux");sleep(2);return 0; }对于这样的代码,首先可以肯…

C++11 unique_ptr智能指针

#include<iostream> using namespace std;class test { public:test() {cout << "调用构造函数" << endl;}~test() {cout << "调用析构函数" << endl;} };int main(void) {//1.构造函数unique_ptr<test>t1;unique_ptr…

数据结构之KMP算法:彻底搞懂kmp算法

数据结构的学习&#xff0c;kmp匹配算法困扰我许久&#xff0c;此处来一个总结&#xff08;仅供自己复习了解参考使用&#xff09;&#xff0c;如果有不对的地方请多多指点。好了废话不多说我们直接开始好吧。 目录 关于暴力匹配原理的讲解&#xff1a; kmp算法&#xff1a; …

ChatGPT - 如何高效的调教ChatGPT (指令建构模型-LACES问题模型)

文章目录 定义1. Limitation&#xff08;限定条件&#xff09;2. Assignment&#xff08;分配角色&#xff09;3. Context&#xff08;背景或上下文&#xff09;4. Example&#xff08;示例&#xff09;5. Step by Step&#xff08;拆分任务&#xff09; 小Demo 定义 LACES问题…

尚硅谷大数据技术Spark教程-笔记04【SparkCore(核心编程,RDD-行动算子-序列化-依赖关系-持久化-分区器-文件读取与保存)】

视频地址&#xff1a;尚硅谷大数据Spark教程从入门到精通_哔哩哔哩_bilibili 尚硅谷大数据技术Spark教程-笔记01【Spark&#xff08;概述、快速上手、运行环境、运行架构&#xff09;】尚硅谷大数据技术Spark教程-笔记02【SparkCore&#xff08;核心编程&#xff0c;RDD-核心属…

加强人工智能共性技术研发与产业化协同发展

央视网消息&#xff1a;“以5G为代表的新一代信息技术与制造业、交通、旅游等实体经济重要领域深度融合。”4月20日下午&#xff0c;国新办举行一季度工业和信息化发展情况新闻发布会&#xff0c;相关部门负责人在答问时表示&#xff0c;将用好融合应用这把金钥匙&#xff0c;开…

ReactHook学习(第一篇-N)

文章目录 Hook简介概述class组件的不足什么是 Hook?Hook 使用规则 state的研究&#xff08;useState&#xff09;State&#xff1a;组件的记忆&#xff08;响应式数据&#xff09;当普通的变量无法满足时添加一个 state 变量遇见你的第一个 Hook剖析 useState 赋予一个组件多个…

【C++】面向对象

文章目录 3.1 类与对象3.1.1 类成员的访问控制3.1.2 类的成员函数对象的访问方式成员函数的实现内联成员函数 3.1.3 构造函数复制构造函数调用复制构造函数的三种情况深复制与浅复制&#xff1f; 析构函数类的组合 3.1.4 前向引用声明3.1.5 结构体与类对比3.1.6 UML类图属性表示…

IMX6ULL裸机篇之按键消抖实验

一. 按键消抖 在之前的 按键中断实验时&#xff0c;我们讲了如何使用中断的方式驱动按键或GPIO。如果通过中断的方式处理按键的话&#xff0c;按键是需要消抖处理的。 而在之前 按键中断实验中&#xff0c;在中断处理函数中对按键进行消抖&#xff0c;调用了 delay 延时函数。…

剑指 Offer 32 - II. 从上到下打印二叉树 II

目录 题目思路BFS 题目来源 剑指 Offer 32 - II. 从上到下打印二叉树 II 题目思路 I. 按层打印&#xff1a; 题目要求的二叉树的 从上至下 打印&#xff08;即按层打印&#xff09;&#xff0c;又称为二叉树的 广度优先搜索&#xff08;BFS&#xff09;。BFS 通常借助 队列 的…

Midjourney v4 | 如何结合参考图像来生成AI艺术图

网址&#xff1a;midjourney.com 首页展示 首页如下图&#xff1a; 第一步&#xff1a;进入社群 点击首页右下角“Join the Beta”&#xff0c;进入如下页面&#xff1a; 点击“接受邀请”&#xff0c;验证之后进入 可以点击认证账号&#xff0c;进行注册&#xff1a; 应该不…

Redis三种集群模式

一、引言 Redis有三种集群模式&#xff0c;第一个就是主从模式&#xff0c;第二种“哨兵”模式&#xff0c;第三种是Cluster集群模式&#xff0c;第三种的集群模式是在Redis 3.x以后的版本才增加进来的&#xff0c;我们今天就来说一下Redis第一种集群模式&#xff1a;主从集群模…

【英语】100个句子记完7000个托福单词

其实主要的7000词其实是在主题归纳里面&#xff0c;不过过一遍100个句子也挺好的&#xff0c;反正也不多。 文章目录 Sentence 01Sentence 02Sentence 03Sentence 04Sentence 05Sentence 06Sentence 07Sentence 08Sentence 09Sentence 10Sentence 11Sentence 12Sentence 13Sent…

Redis的底层数据结构

Redis的底层数据结构 Redis的底层数据类型&#xff08;对比&#xff09;Redis的底层数据结构Redis数据类型和底层数据结构的对应关系Redis的使用 Redis的底层数据类型&#xff08;对比&#xff09; String&#xff08;字符串&#xff09;List&#xff08;列表&#xff09;Hash…

CRE66365 应用资料

CRE66365是一款高度集成的电流模式PWM控制IC&#xff0c;为高性能、低待机功耗和低成本的隔离型反激转换器。在正常负载条件下&#xff0c;AC输入高电压下工作在QR模式。为了最大限度地减少开关损耗&#xff0c;QR 模式下的最大开关频率被内部限制为 77kHz。当负载较低时&#…