理论+实操:K8S中的pod 资源限制

前言:
学习参考kubernetes官方文档,以kubernetes为准

pod是容器的集合,容器中的隐患(cpu、IO、MEM),在k8s中依然存在

官方文档:https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/

云计算 两大块虚拟化

OpenStack ——创建虚拟硬件资源池——创建虚拟机实例

比如:vdisk 虚拟磁盘

容器—》容器编排—容器群集管理 例如:docker—docker-compose-----kubernetes虚拟硬件 ---- 资源限制

一:pod和container的资源请求和限制

spec.containers[].resources.limits.cpu //cpu上限

spec.containers[].resources.limits.memory //内存上限

spec.containers[].resources.requests.cpu //创建时分配的基本CPU资源

spec.containers[].resources.requests.memory //创建时分配的基本内存资源

一种是最大上限,一种是基本分配

尽管只能在个别容器上指定请求和限制,但是我们可以方便地计算出 Pod 资源请求和限制。特定资源类型的Pod 资源请求/限制是 Pod 中每个容器的该类型的资源请求/限制的总和。

1.1 cpu的含义

CPU 资源的限制和请求以 cpu 为单位。

Kubernetes 中的一个 cpu 等于:

  • 1 AWS vCPU
  • 1 GCP Core
  • 1 Azure vCore
  • 1 Hyperthread 在带有超线程的裸机 Intel 处理器上

允许浮点数请求。具有 spec.containers[].resources.requests.cpu 为 0.5 的容器保证了一半 CPU 要求 1 CPU的一半。表达式 0.1 等价于表达式 100m,可以看作 “100 millicpu”。有些人说成是“一百毫 cpu”,其实说的是同样的事情。具有小数点(如 0.1)的请求由 API 转换为100m,精度不超过 1m。因此,可能会优先选择 100m 的形式。

CPU 总是要用绝对数量,不可以使用相对数量;0.1 的 CPU 在单核、双核、48核的机器中的意义是一样的。

1.2 内存的含义

内存的限制和请求以字节为单位。您可以使用以下后缀之一作为平均整数或定点整数表示内存:E,P,T,G,M,K。您还可以使用两个字母的等效的幂数:Ei,Pi,Ti ,Gi,Mi,Ki。例如,以下代表大致相同的值:

128974848, 129e6, 129M, 123Mi

1.3 举例验证

以下 Pod 有两个容器。每个容器的请求为 0.25 cpu 和 64MiB(226 字节)内存,每个容器的限制为 0.5 cpu 和 128MiB 内存。您可以说该 Pod 请求 0.5 cpu 和 128 MiB 的内存,限制为 1 cpu 和 256MiB 的内存。

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: db
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "password"
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: wp
    image: wordpress
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

1.4 具有资源请求的pod如何调度

当您创建一个 Pod 时,Kubernetes 调度程序将为 Pod 选择一个节点。

每个节点具有每种资源类型的最大容量:可为 Pod 提供的 CPU 和内存量。

调度程序确保对于每种资源类型,调度的容器的资源请求的总和小于节点的容量。

注意,尽管节点上的实际内存或 CPU 资源使用量非常低,但如果容量检查失败,则调度程序仍然拒绝在该节点上放置 Pod。

当资源使用量稍后增加时,例如在请求率的每日峰值期间,这便可以防止节点上的资源短缺。

1.5 具有资源限制的pod如何运行

当 kubelet 启动一个 Pod 的容器时,它会将 CPU 和内存限制传递到容器运行时。

当使用 Docker 时:

  • spec.containers[].resources.requests.cpu 的值将转换成 millicore 值,这是个浮点数,并乘以 1024,这个数字中的较大者或 2 用作 docker run 命令中的 --cpu-shares 标志的值。
  • spec.containers[].resources.limits.cpu 被转换成 millicore 值。被乘以 100000 然后 除以 1000。这个数字用作 docker run 命令中的 --cpu-quota 标志的值。[--cpu-quota ] 标志被设置成了 100000,表示测量配额使用的默认100ms 周期。如果 [--cpu-cfs-quota] 标志设置为 true,则 kubelet 会强制执行 cpu 限制。从 Kubernetes 1.2 版本起,此标志默认为 true。

注意: 默认配额限制为 100 毫秒。 CPU配额的最小单位为 1 毫秒。

如果容器超过其内存限制,则可能会被终止。如果可重新启动,则与所有其他类型的运行时故障一样,kubelet 将重新启动它。

如果一个容器超过其内存请求,那么当节点内存不足时,它的 Pod 可能被逐出。

容器可能被允许也可能不被允许超过其 CPU 限制时间。但是,由于 CPU 使用率过高,不会被杀死。

1.6 pod处于pending状态且时间显示failedscheduling

如果调度器找不到任何该 Pod 可以匹配的节点,则该 Pod 将保持不可调度状态,直到找到一个可以被调度到的位置。每当调度器找不到 Pod 可以调度的地方时,会产生一个事件,如下所示:

kubectl describe pod frontend | grep -A 3 Events
Events:
  FirstSeen LastSeen   Count  From          Subobject   PathReason      Message
  36s   5s     6      {scheduler }              FailedScheduling  Failed for reason PodExceedsFreeCPU and possibly others

上述示例中,由于节点上的 CPU 资源不足,名为 “frontend” 的 Pod 将无法调度。由于内存不足(PodExceedsFreeMemory),类似的错误消息也可能会导致失败。一般来说,如果有这种类型的消息而处于 pending 状态,可以尝试如下几件事情:

  • 向集群添加更多节点。
  • 终止不需要的 Pod,为待处理的 Pod 腾出空间。
  • 检查 Pod 所需的资源是否大于所有节点的资源。 例如,如果全部节点的容量为cpu:1,那么一个请求为 cpu:1.1的 Pod 永远不会被调度。

1.7 kubectl describe nodes 检查节点容量分配和分配的数量

kubectl describe nodes e2e-test-node-pool-4lw4
Name:            e2e-test-node-pool-4lw4
[ ... lines removed for clarity ...]
Capacity:
 cpu:                               2
 memory:                            7679792Ki
 pods:                              110
Allocatable:
 cpu:                               1800m
 memory:                            7474992Ki
 pods:                              110
[ ... lines removed for clarity ...]
Non-terminated Pods:        (5 in total)
  Namespace    Name                                  CPU Requests  CPU Limits  Memory Requests  Memory Limits
  ---------    ----                                  ------------  ----------  ---------------  -------------
  kube-system  fluentd-gcp-v1.38-28bv1               100m (5%)     0 (0%)      200Mi (2%)       200Mi (2%)
  kube-system  kube-dns-3297075139-61lj3             260m (13%)    0 (0%)      100Mi (1%)       170Mi (2%)
  kube-system  kube-proxy-e2e-test-...               100m (5%)     0 (0%)      0 (0%)           0 (0%)
  kube-system  monitoring-influxdb-grafana-v4-z1m12  200m (10%)    200m (10%)  600Mi (8%)       600Mi (8%)
  kube-system  node-problem-detector-v0.1-fj7m3      20m (1%)      200m (10%)  20Mi (0%)        100Mi (1%)
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  CPU Requests    CPU Limits    Memory Requests    Memory Limits
  ------------    ----------    ---------------    -------------
  680m (34%)      400m (20%)    920Mi (12%)        1070Mi (14%)

在上面的输出中,您可以看到如果 Pod 请求超过 1120m CPU 或者 6.23Gi 内存,节点将无法满足。

通过查看 Pods 部分,您将看到哪些 Pod 占用的节点上的资源。

Pod 可用的资源量小于节点容量,因为系统守护程序使用一部分可用资源。 NodeStatusallocatable 字段给出了可用于 Pod 的资源量。 有关更多信息,请参阅官方文档 节点可分配资源

可以将 资源配额 功能配置为限制可以使用的资源总量。如果与 namespace 配合一起使用,就可以防止一个团队占用所有资源

1.8 容器被终止

容器可能因为资源枯竭而被终止了。要查看容器是否因为遇到资源限制而被杀死,请在相关的 Pod 上调用 kubectl describe pod

kubectl describe pod simmemleak-hra99
Name:                           simmemleak-hra99
Namespace:                      default
Image(s):                       saadali/simmemleak
Node:                           kubernetes-node-tf0f/10.240.216.66
Labels:                         name=simmemleak
Status:                         Running
Reason:
Message:
IP:                             10.244.2.75
Replication Controllers:        simmemleak (1/1 replicas created)
Containers:
  simmemleak:
    Image:  saadali/simmemleak
    Limits:
      cpu:                      100m
      memory:                   50Mi
    State:                      Running
      Started:                  Tue, 07 Jul 2015 12:54:41 -0700
    Last Termination State:     Terminated
      Exit Code:                1
      Started:                  Fri, 07 Jul 2015 12:54:30 -0700
      Finished:                 Fri, 07 Jul 2015 12:54:33 -0700
    Ready:                      False
    Restart Count:              5
Conditions:
  Type      Status
  Ready     False
Events:
  FirstSeen                         LastSeen                         Count  From                              SubobjectPath                       Reason      Message
  Tue, 07 Jul 2015 12:53:51 -0700   Tue, 07 Jul 2015 12:53:51 -0700  1      {scheduler }                                                          scheduled   Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f
  Tue, 07 Jul 2015 12:53:51 -0700   Tue, 07 Jul 2015 12:53:51 -0700  1      {kubelet kubernetes-node-tf0f}    implicitly required container POD   pulled      Pod container image "k8s.gcr.io/pause:0.8.0" already present on machine
  Tue, 07 Jul 2015 12:53:51 -0700   Tue, 07 Jul 2015 12:53:51 -0700  1      {kubelet kubernetes-node-tf0f}    implicitly required container POD   created     Created with docker id 6a41280f516d
  Tue, 07 Jul 2015 12:53:51 -0700   Tue, 07 Jul 2015 12:53:51 -0700  1      {kubelet kubernetes-node-tf0f}    implicitly required container POD   started     Started with docker id 6a41280f516d
  Tue, 07 Jul 2015 12:53:51 -0700   Tue, 07 Jul 2015 12:53:51 -0700  1      {kubelet kubernetes-node-tf0f}    spec.containers{simmemleak}         created     Created with docker id 87348f12526a

Restart Count: 5 意味着 Pod 中的 simmemleak 容器被终止并重启了五次。

可以使用 kubectl get pod 命令加上 -o go-template=... 选项来获取之前终止容器的状态。

kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}'  simmemleak-hra99
Container Name: simmemleak
LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-07T20:58:43Z finishedAt:2015-07-07T20:58:43Z containerID:docker://0e4095bba1feccdfe7ef9fb6ebffe972b4b14285d5acdec6f0d3ae8a22fad8b2]]

可以看到容器因为 reason:OOM killed 被终止,OOM 表示 Out Of Memory。

二:演示

2.1 编写yaml文件

[root@master1 ~]# vim pod2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers: 
  #两个容器,分别是名为db的mysql,名为wp的wordpress
  - name: db
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "password"
    resources: 
    #资源管理
      requests:
      #请求资源
        memory: "64Mi"
        cpu: "250m"
      limits:
      #限制资源
        memory: "128Mi"
        cpu: "500m"
  - name: wp
    image: wordpress
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

2.2 创建资源

[root@master1 ~]# kubectl apply -f pod2.yaml
pod/frontend created

2.3 查看pod具体事件

[root@master1 ~]# kubectl get pods
NAME                                READY   STATUS              RESTARTS   AGE
frontend                            0/2     ContainerCreating   0          45s
[root@master1 ~]# kubectl describe pod frontend		#这里只截取事件
Events:
  Type     Reason     Age                From                      Message
  ----     ------     ----               ----                      -------
  Normal   Scheduled  79s                default-scheduler         Successfully assigned default/frontend to 192.168.247.143
  Normal   Pulling    58s                kubelet, 192.168.247.143  pulling image "wordpress"
  Normal   Pulled     26s                kubelet, 192.168.247.143  Successfully pulled image "wordpress"
  Normal   Pulling    25s (x2 over 78s)  kubelet, 192.168.247.143  pulling image "mysql"
  Normal   Started    25s                kubelet, 192.168.247.143  Started container
  Normal   Created    25s                kubelet, 192.168.247.143  Created container
  Normal   Pulled     24s (x2 over 58s)  kubelet, 192.168.247.143  Successfully pulled image "mysql"
  Normal   Created    23s (x2 over 58s)  kubelet, 192.168.247.143  Created container
  Normal   Started    23s (x2 over 58s)  kubelet, 192.168.247.143  Started container
  Warning  BackOff    6s                 kubelet, 192.168.247.143  Back-off restarting failed container


yaml文件有误,但不影响验证

2.4 查看node节点的docker

[root@node01 ~]# docker ps -a | grep wp
a99b989fb2a7        wordpress                                                             "docker-entrypoint.s…"   2 minutes ago       Up 2 minutes                                    k8s_wp_frontend_default_50ec30e1-94b3-11ea-a668-000c29db840b_0
[root@node01 ~]# docker ps -a | grep mysql
a5f2dccad7cb        mysql                                                                 "docker-entrypoint.s…"   5 seconds ago        Up 4 seconds                                    k8s_db_frontend_default_50ec30e1-94b3-11ea-a668-000c29db840b_4
a2bad2be413f        mysql                                                                 "docker-entrypoint.s…"   About a minute ago   Exited (1) 56 seconds ago                       k8s_db_frontend_default_50ec30e1-94b3-11ea-a668-000c29db840b_3

2.5 回到master,发现已经重启四次

[root@master1 ~]# kubectl get pods -w
NAME                                READY   STATUS             RESTARTS   AGE
frontend                            1/2     CrashLoopBackOff   4          4m9s
frontend   2/2   Running   5     4m47s
frontend   1/2   OOMKilled   5     4m55s
frontend   1/2   CrashLoopBackOff   5     5m10s

2.6 查看pod所在node节点的描述信息

备注:从pod事件中可以知道pod在192.168.247.143node01上

[root@master1 ~]# kubectl describe node 192.168.247.143
Name:               192.168.247.143
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/hostname=192.168.247.143
Annotations:        node.alpha.kubernetes.io/ttl: 0
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Thu, 30 Apr 2020 11:40:08 +0800
Taints:             <none>
Unschedulable:      false
Conditions:
  Type             Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----             ------  -----------------                 ------------------                ------                       -------
  OutOfDisk        False   Wed, 13 May 2020 08:55:30 +0800   Fri, 08 May 2020 13:03:43 +0800   KubeletHasSufficientDisk     kubelet has sufficient disk space available
  MemoryPressure   False   Wed, 13 May 2020 08:55:30 +0800   Fri, 08 May 2020 13:03:43 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure     False   Wed, 13 May 2020 08:55:30 +0800   Fri, 08 May 2020 13:03:43 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure      False   Wed, 13 May 2020 08:55:30 +0800   Thu, 30 Apr 2020 11:40:08 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready            True    Wed, 13 May 2020 08:55:30 +0800   Tue, 12 May 2020 08:40:28 +0800   KubeletReady                 kubelet is posting ready status
Addresses:
  InternalIP:  192.168.247.143
  Hostname:    192.168.247.143
Capacity:
 cpu:                2
 ephemeral-storage:  309307844Ki
 hugepages-1Gi:      0
 hugepages-2Mi:      0
 memory:             3861364Ki
 pods:               110
Allocatable:
 cpu:                2
 ephemeral-storage:  285058108559
 hugepages-1Gi:      0
 hugepages-2Mi:      0
 memory:             3758964Ki
 pods:               110
System Info:
 Machine ID:                 e7c72a193a404cf587718e10bd4e5533
 System UUID:                13744D56-2BA1-6509-242B-ED05BBAA67FF
 Boot ID:                    54684508-2c2f-4e1f-81c7-427c94c4c16b
 Kernel Version:             3.10.0-1062.el7.x86_64
 OS Image:                   CentOS Linux 7 (Core)
 Operating System:           linux
 Architecture:               amd64
 Container Runtime Version:  docker://19.3.8
 Kubelet Version:            v1.12.3
 Kube-Proxy Version:         v1.12.3
Non-terminated Pods:         (4 in total)
  Namespace                  Name                                 CPU Requests  CPU Limits  Memory Requests  Memory Limits
  ---------                  ----                                 ------------  ----------  ---------------  -------------
  default                    frontend                             500m (25%)    1 (50%)     128Mi (3%)       256Mi (6%)
  default                    my-tomcat-6cbc7c4d65-hdmhc           0 (0%)        0 (0%)      0 (0%)           0 (0%)
  default                    nginx-deployment-78cdb5b557-f2hx2    0 (0%)        0 (0%)      0 (0%)           0 (0%)
  default                    pod1                                 0 (0%)        0 (0%)      0 (0%)           0 (0%)
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource  Requests    Limits
  --------  --------    ------
  cpu       500m (25%)  1 (50%)
  memory    128Mi (3%)  256Mi (6%)
Events:     <none>
[root@master1 ~]# 

2.7 node的限额信息

在这里插入图片描述

百分比是占用当前硬件的百分比,pod是k8s的最小执行单位

对pod的资源限制参数是pod内容器的限制之和

命名空间在不指定的情况下默认命名空间

[root@master1 ~]# kubectl get ns
NAME          STATUS   AGE
default       Active   12d
kube-public   Active   12d
kube-system   Active   12d
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值