目录贴:Kubernetes学习系列

1、资源模型

  虛拟化技术是云计算平台的基础,其目标是对计算资源进行整合或划分,这是云计算管理平台中的关键技术。虚拟化技术为云计算管理乎台的资源管理提供了资源调配上的灵活性,从而使得云计算管理平台可以通过虚拟化层整合或划分计算资源。

  相比于虚拟机,新出现的容器技术使用了一系列的系统级别的机制,诸如利用Linux Namespace进行空间隔离,通过文件系统的挂载点决定容器可以访问哪些文件,通过Cgroup确定每个容器可以利用多少资源。此外,容器之间共享同一个系统内核,这样当同一个内核被多个容器使用时,内存的使用效率会得到提升。

  容器和虛拟机两大虛拟化技术,虽然实现方式完全不同,但是它们的资源需求和模型其实是类似的。容器像虛拟机一样需要内存、CPU、硬盘空间和网络带宽,宿主机系统可以将虛拟机和容器都视作一个整体,为这个整体分配其所需的资源,并进行管理。当然, 虚拟机提供了专用操作系统的安全性和更牢固的逻辑边界,而容器在资源边界上比较松散,这带来了灵活性以及不确定性。

  Kubernetes是一个容器集群管理平台,Kubernetes需要统计整体平台的资源使用情况,合理地将资源分配给容器使用,并且要保证容器生命周期内有足够的资源来保证其运行。 更进一步,如果资源发放是独占的,即资源已发放给了个容器,同样的资源不会发放给另外一个容器,对于空闲的容器来说占用着没有使用的资源比如CPU是非常浪费的,Kubernetes需要考虑如何在优先度和公平性的前提下提高资源的利用率。

2、资源请求与限制

  创建Pod的时候,可以指定计算资源(目前支持的资源类型有CPU和内存),即指定每个容器的资源请求(Request)和资源限制(Limit),资源请求是容器所需的最小资源需求,资源限制则是容器不能超过的资源上限。它们的大小关系是:

0<=request<=limit<=infinity

  Pod的资源请求就是Pod中容器资源请求之和。Kubernetes在调度Pod时,会根据Node中的资源总量(通过cAdvisor接口获得),以及该Node上已使用的计算资源,来判断该Node是否满足需求。

  资源请求能够保证Pod有足够的资源来运行,而资源限制则是防止某个Pod无限制地使用资源,导致其他Pod崩溃。特别是在公有云场景,往往会有恶意软件通过抢占内存来攻击平台。

  原理:Docker 通过使用Linux Cgroup来实现对容器资源的控制,具体到启动参数上是--memory和--cpu-shares。Kubernetes中是通过控制这两个参数来实现对容器资源的控制。

以下给出某个Pod申请内存及CPU的示例:

[root@k8s-master demon2]# cat test-limit.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
name: test-limit
role: master
name: test-limit
spec:
containers:
- name: test-limit
image: registry:/back_demon:1.0
resources:
requests:
memory: "256Mi"
cpu: "500m"
limits:
memory: "512Mi"
cpu: "1000m"
command:
- /run.sh

待Pod调度到具体某个机器上之后,在该机器上查询对应容器的详情,如下:

[root@k8s-node- home]# docker inspect 1fdbd6f1b39b
[
{
"Id": "1fdbd6f1b39b561d09084adafb382b721959e5edd0ee9538472313ed0a39162a",
"Created": "2017-03-20T05:40:30.756006226Z",
"Path": "/run.sh",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": ,
"ExitCode": ,
"Error": "",
"StartedAt": "2017-03-20T05:40:31.113657323Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:9369911131d30b12759074e5b72356345446996bf6044950c2def787471e9b4c",
"ResolvConfPath": "/var/lib/docker/containers/8fdb38a4d0074b07ff2f07e21fd8602fdbf4267eafc76179e931d4f5d9265940/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/8fdb38a4d0074b07ff2f07e21fd8602fdbf4267eafc76179e931d4f5d9265940/hostname",
"HostsPath": "/var/lib/kubelet/pods/ba75e7a9-0d2f-11e7-b3d5-fa163ebba51b/etc-hosts",
"LogPath": "/var/lib/docker/containers/1fdbd6f1b39b561d09084adafb382b721959e5edd0ee9538472313ed0a39162a/1fdbd6f1b39b561d09084adafb382b721959e5edd0ee9538472313ed0a39162a-json.log",
"Name": "/k8s_test-limit.79cbd53f_test-limit_default_ba75e7a9-0d2f-11e7-b3d5-fa163ebba51b_efc94078",
"RestartCount": ,
"Driver": "devicemapper",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": [
"/var/lib/kubelet/pods/ba75e7a9-0d2f-11e7-b3d5-fa163ebba51b/etc-hosts:/etc/hosts:Z",
"/var/lib/kubelet/pods/ba75e7a9-0d2f-11e7-b3d5-fa163ebba51b/containers/test-limit/efc94078:/dev/termination-log:Z"
],
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "container:8fdb38a4d0074b07ff2f07e21fd8602fdbf4267eafc76179e931d4f5d9265940",
"PortBindings": null,
"RestartPolicy": {
"Name": "",
"MaximumRetryCount":
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": null,
"DnsOptions": null,
"DnsSearch": null,
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "container:8fdb38a4d0074b07ff2f07e21fd8602fdbf4267eafc76179e931d4f5d9265940",
"Cgroup": "",
"Links": null,
"OomScoreAdj": ,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": [
"seccomp=unconfined"
],
"UTSMode": "",
"UsernsMode": "",
"ShmSize": ,
"Runtime": "docker-runc",
"ConsoleSize": [
, ],
"Isolation": "",
"CpuShares": ,
"Memory": ,
"CgroupParent": "",
"BlkioWeight": ,
"BlkioWeightDevice": null,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": ,
"CpuQuota": ,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DiskQuota": ,
"KernelMemory": ,
"MemoryReservation": ,
"MemorySwap": -,
"MemorySwappiness": -,
"OomKillDisable": false,
"PidsLimit": ,
"Ulimits": null,
"CpuCount": ,
"CpuPercent": ,
"IOMaximumIOps": ,
"IOMaximumBandwidth":
},
"GraphDriver": {
"Name": "devicemapper",
"Data": {
"DeviceId": "",
"DeviceName": "docker-253:0-100693626-cb08877222f483f043fc45c5c4b024de8da9c393c3c06c6252d3c59d330dd4d4",
"DeviceSize": ""
}
},
"Mounts": [
{
"Source": "/var/lib/kubelet/pods/ba75e7a9-0d2f-11e7-b3d5-fa163ebba51b/etc-hosts",
"Destination": "/etc/hosts",
"Mode": "Z",
"RW": true,
"Propagation": "rprivate"
},
{
"Source": "/var/lib/kubelet/pods/ba75e7a9-0d2f-11e7-b3d5-fa163ebba51b/containers/test-limit/efc94078",
"Destination": "/dev/termination-log",
"Mode": "Z",
"RW": true,
"Propagation": "rprivate"
}
],
"Config": {
"Hostname": "test-limit",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"222/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"KUBERNETES_PORT_443_TCP_PROTO=tcp",
"KUBERNETES_PORT_443_TCP_PORT=443",
"FRONTEND_SERVICE_PORT=tcp://10.254.232.119:8080",
"REDIS_SERVICE_SERVICE_PORT=6379",
"REDIS_SERVICE_PORT_6379_TCP_ADDR=10.254.71.136",
"KUBERNETES_SERVICE_PORT_HTTPS=443",
"KUBERNETES_SERVICE_HOST=10.254.0.1",
"KUBERNETES_PORT_443_TCP=tcp://10.254.0.1:443",
"BACK_SERVICE_PORT_8080_TCP_PORT=8080",
"FRONTEND_SERVICE_PORT_8080_TCP=tcp://10.254.232.119:8080",
"FRONTEND_SERVICE_PORT_8080_TCP_ADDR=10.254.232.119",
"REDIS_SERVICE_PORT_6379_TCP=tcp://10.254.71.136:6379",
"REDIS_MASTER_PORT_6379_TCP_PORT=6379",
"FRONTEND_PORT_80_TCP_PORT=80",
"REDIS_MASTER_PORT_6379_TCP_ADDR=10.254.132.210",
"REDIS_SLAVE_PORT_6379_TCP=tcp://10.254.104.23:6379",
"REDIS_SLAVE_PORT_6379_TCP_PORT=6379",
"BACK_SERVICE_SERVICE_HOST=10.254.246.51",
"BACK_SERVICE_PORT=tcp://10.254.246.51:8080",
"BACK_SERVICE_PORT_8080_TCP_PROTO=tcp",
"FRONTEND_PORT=tcp://10.254.93.91:80",
"REDIS_MASTER_SERVICE_HOST=10.254.132.210",
"REDIS_MASTER_PORT_6379_TCP_PROTO=tcp",
"KUBERNETES_SERVICE_PORT=443",
"FRONTEND_SERVICE_PORT_8080_TCP_PROTO=tcp",
"REDIS_MASTER_SERVICE_PORT=6379",
"REDIS_SLAVE_SERVICE_HOST=10.254.104.23",
"REDIS_SLAVE_PORT=tcp://10.254.104.23:6379",
"REDIS_SERVICE_PORT_6379_TCP_PROTO=tcp",
"REDIS_MASTER_PORT=tcp://10.254.132.210:6379",
"KUBERNETES_PORT_443_TCP_ADDR=10.254.0.1",
"BACK_SERVICE_SERVICE_PORT=8080",
"FRONTEND_SERVICE_HOST=10.254.93.91",
"FRONTEND_SERVICE_SERVICE_PORT=8080",
"REDIS_SERVICE_SERVICE_HOST=10.254.71.136",
"REDIS_SERVICE_PORT=tcp://10.254.71.136:6379",
"BACK_SERVICE_PORT_8080_TCP=tcp://10.254.246.51:8080",
"REDIS_SLAVE_SERVICE_PORT=6379",
"REDIS_SLAVE_PORT_6379_TCP_PROTO=tcp",
"REDIS_SLAVE_PORT_6379_TCP_ADDR=10.254.104.23",
"KUBERNETES_PORT=tcp://10.254.0.1:443",
"BACK_SERVICE_PORT_8080_TCP_ADDR=10.254.246.51",
"FRONTEND_PORT_80_TCP=tcp://10.254.93.91:80",
"FRONTEND_PORT_80_TCP_ADDR=10.254.93.91",
"FRONTEND_SERVICE_PORT_8080_TCP_PORT=8080",
"REDIS_MASTER_PORT_6379_TCP=tcp://10.254.132.210:6379",
"FRONTEND_PORT_80_TCP_PROTO=tcp",
"FRONTEND_SERVICE_SERVICE_HOST=10.254.232.119",
"REDIS_SERVICE_PORT_6379_TCP_PORT=6379"
],
"Cmd": null,
"Image": "registry:5000/back_demon:1.0",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/run.sh"
],
"OnBuild": null,
"Labels": {
"io.kubernetes.container.hash": "79cbd53f",
"io.kubernetes.container.name": "test-limit",
"io.kubernetes.container.restartCount": "",
"io.kubernetes.container.terminationMessagePath": "/dev/termination-log",
"io.kubernetes.pod.name": "test-limit",
"io.kubernetes.pod.namespace": "default",
"io.kubernetes.pod.terminationGracePeriod": "",
"io.kubernetes.pod.uid": "ba75e7a9-0d2f-11e7-b3d5-fa163ebba51b"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": ,
"Ports": null,
"SandboxKey": "",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": ,
"IPAddress": "",
"IPPrefixLen": ,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": null
}
}
]

3、LimitRange

  LimitRange设计的初衷是为了满足以下场景:

    能够约束租户的资源需求。

    能够约束容器的资源请求范围。

    能够约束Pod的资源请求范围。

    能够指定容器的默认资源限制。

    能够指定Pod的默认资源限制。

    能够约束资源请求和限制之间的比例。

4、Resource Quota

  Kubernetes是一个多租户架构,当多用户或者团队共享一个Kubernetes系统的时候,系统管理员需要防止租户的资源抢占,定义好资源分配策略。比如Kubernetes系统共有20 核CPU和32GB内存,分配给A租户5核CPU和16GB,分配给B租户5核CPU 和8GB,预留10核CPU和8GB内存。这样,租户中所使用的CPU和内存的总和不能超过指定的资源配额,促使其更合理地使用资源。

  Kubernetes提供API对象Resource Quota(资源配额)来实现资源配额,Resource Quota不仅可以作用于CPU和內存,另外还可以限制比如创建Pod的总数目、Service总数目、RC总数目等。

  默认情况下,Namespace是没有Resource Quota的,需要另外创建Resource Quota。一旦Namespace中有了Resource Quota,那么创建Pod的时候就必须制定资源请求,否则Pod就会创建失败。

Kubernetes资源管理的更多相关文章

  1. kubernetes 资源管理

    前言 在kubernetes环境下,无论集群再大,对应的集群资源(cpu.memory.storage)总是有上限的.而默认情况下,我们启动的pod.以及pod中运行的容器,对应的资源是不加限制的.理 ...

  2. [Kubernetes]资源模型与资源管理

    作为 Kubernetes 的资源管理与调度部分的基础,需要从它的资源模型说起. 资源管理模型的设计 我们知道,在 Kubernetes 里面, Pod 是最小的原子调度单位,这就意味着,所有和调度和 ...

  3. Kubernetes学习系列

    这段时间项目组内想要引入Kubernetes,作为第二代容器调度引擎,故最近在系统的学习Kubernetes.整理了一些学习笔记,心得,放到博客中,一来记录自己的学习经过,二来看能否帮到有需要的同学. ...

  4. Kubernetes 资源对象

    概述 我将它们简单的分类为以下几种资源对象: 类别 名称 资源对象 Pod.ReplicaSet.ReplicationController.Deployment.StatefulSet.Daemon ...

  5. Kubernetes 多集群在开源项目 KubeSphere 的应用

    Kubernetes 多集群使用场景 随着容器的普及和 Kubernetes 的日渐成熟,企业内部运行多个 Kubernetes 集群已变得颇为常见.概括起来,多个集群的使用场景主要有以下几种. 多集 ...

  6. Apache Spark 3.0 将内置支持 GPU 调度

    如今大数据和机器学习已经有了很大的结合,在机器学习里面,因为计算迭代的时间可能会很长,开发人员一般会选择使用 GPU.FPGA 或 TPU 来加速计算.在 Apache Hadoop 3.1 版本里面 ...

  7. Spark(一)Spark简介

    一.官网介绍 1 什么是Spark 官网地址:http://spark.apache.org/ Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎.Spark是UC Berkel ...

  8. Kubernetes-运维指南

    Node隔离与恢复 cat unschedule_node.yaml apiVersion: kind: Node metadata: name: k8s-node-1 labels: kuberne ...

  9. Apache Spark 3.0 预览版正式发布,多项重大功能发布

    2019年11月08日 数砖的 Xingbo Jiang 大佬给社区发了一封邮件,宣布 Apache Spark 3.0 预览版正式发布,这个版本主要是为了对即将发布的 Apache Spark 3. ...

随机推荐

  1. 恒生UFX接口引用计数心得

    本文介绍在基于恒生T2SDK基础上开发对接UFX柜台时,有关引用计数的一些心得体会. 下面以配置接口和连接接口为例子来介绍,下面是文档介绍: 创建配置接口说明: 3.1.2 创建配置接口(NewCon ...

  2. [hadoop] kettle spoon 基础使用 (txt 内容抽取到excel中)

    spoon.bat 启动kettle. 测试数据 1. 新建转换 输入中选择文本文件输入 双击设置文本输入 字符集.分隔符设置 获取对应的字段,预览记录. 拖入 excel输出,设置转换关系 设置输出 ...

  3. 21备忘录模式Memento

    一.什么是备忘录模式 Memento模式也叫备忘录模式,是行为模式之 一,它的作用是保存对象的内部状态,并在需要 的时候(undo/rollback)恢复对象以前的状态. 二.备忘录模式的应用场景 如 ...

  4. OpenGL step by step 38 : Skeletal Animation with Assimp

    一般骨架模型由两部分组成: Rigging(bone):相当于骨架,可以用来控制模型的动作 Mesh(skin):相当于表面皮肤 骨架模型一般是层级结构的,比如上面 背骨是root,他的孩子包括胳膊. ...

  5. Linux系统(本例以Ubuntu18.04为例)安装GCC编译器

    Linux(本例以Ubuntu18.04为例)安装GCC编译器 一.安装 安装命令:sudo apt-get  build-dep  gcc 遇到 您希望继续执行吗? [Y/n] y 直接输入y回车即 ...

  6. 使用PsExec获取shell执行命令

    PsExec PsExec是pstools工具组套件的一部分,确成为了渗透利器,下载地址:点击这里下载 连接shell 我的Windows Server 2012默认打开域网络防火墙的时候,是不能连接 ...

  7. Spark JDBC To MySQL

    mysql jdbc driver下载地址https://dev.mysql.com/downloads/connector/j/ 在spark中使用jdbc1.在 spark-env.sh 文件中加 ...

  8. 我的C语言编程风格

    前几天看别人的代码,真是的看的头昏脑涨,基本没有注释.乱起的变量名字,还要费尽心思去解读作者的意思.突然感觉高效的程序注释说明和良好的编程风格是多么的重要. 为了不让别人在看到我的代码时在背后骂我,也 ...

  9. 【1】public

    [面向对象] 李坤是不是人?(人类) 飞飞是不是人?(人类) 扎心是不是人?(人类) 是:特指某一个事物 属于:同一的类型 什么是对象: 就是特指的某一个东西,万物皆对象 什么是类: 具有一批相同属性 ...

  10. python 中的 list dict 与 set 的关系

    转自: http://www.cnblogs.com/soaringEveryday/p/5044007.html list arraylist 实现(数组) List 通过内置的 append()方 ...