kubernetes云原生纪元:资源管理(k8s)Resource(上)

初识

硬件是万物的基础,跟大多技术一样kubenetes 也需要

  • CPU
  • 内存
  • GPU
  • 持久化存储

gpu用的不多这里不说

这里假设一个场景:

一个集群里面有很多node节点,kubectl 会搜集所有node信息,这些信息就包括内存,CPU。现在需要在集群上跑一个占用20G内存的应用,他会调度到一个满足这条件的机器上,所以kubernetes 会先收集node节点信息,安排一个适合的节点,如果这个时候出现一个bug疯狂的占用内存,这个使用就出现了资源限制

image-20200116162043531

核心设计

cpu和内存都可以对两个参数的设置

  • Requests

    容器希望被分配到可以完全保证的一个资源量 。

    什么用:他会给调度器一个值,调度器根据值参与到调度器策略的计算。从而给我们找到最适合的节点。

  • Limits

    是容器使用资源的上限。

    当资源不足,发生资源竞争,会参考这个值进行计算,从而作出进一步的决策。把哪个应用杀掉。这是资源限制的策略。

如何使用

我们这里针对pod 做资源限制🚫。需求在yaml配置文件增加resoruces关键字来设置requestslimits的 参数。

指定使用内存100兆CPU100m,最大限制内存不能超过100兆CPU不能超过200m不管机器上有10核20核可以用的只有0.2核💻

requests:
    memory: 100Mi
     cpu: 100m
limits:
    memory: 100Mi
    cpu: 200m   

设置参数的时候一定要加单位,不加单位是字节数

单位

  • 内存

一般内存使用兆Mi、Gi,

  • cpu

是使用小写m,不写单位代表,比如 cpu:100 就是使用100个cpu

一核CPU=1000m,100m=0.1核

通过demo 测试使用,创建一个web项目配置如下:

Web-dev.yaml

#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-demo
  namespace: dev
spec:
  selector:
    matchLabels:
      app: web-demo
  replicas: 1
  template:
    metadata:
      labels:
        app: web-demo
    spec:
      containers:
      - name: web-demo
        image: hub.zhang.com/kubernetes/demo:2020011512381579063123
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: 100Mi
            cpu: 100m
          limits:
            memory: 100Mi
            cpu: 200m
---
#service
apiVersion: v1
kind: Service
metadata:
  name: web-demo
  namespace: dev
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: web-demo
  type: ClusterIP

---
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: web-demo
  namespace: dev
spec:
  rules:
  - host: web.demo.com
    http:
      paths:
      - path: /
        backend:
          serviceName: web-demo
          servicePort: 80

创建项目:

[root@master-001 ~]# kubectl apply -f web-dev.yaml

查看使用量

[root@master-001 ~]# kubectl describe node node-001
Name:               node-001
Roles:              <none>
Labels:             app=ingress
                    beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=node-001
                    kubernetes.io/os=linux
Annotations:        kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
                    node.alpha.kubernetes.io/ttl: 0
                    projectcalico.org/IPv4Address: 172.16.126.137/24
                    projectcalico.org/IPv4IPIPTunnelAddr: 192.168.93.64
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Thu, 02 Jan 2020 13:53:26 +0800
Taints:             <none>
Unschedulable:      false
Conditions:
  Type                 Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----                 ------  -----------------                 ------------------                ------                       -------
  NetworkUnavailable   False   Thu, 16 Jan 2020 11:00:52 +0800   Thu, 16 Jan 2020 11:00:52 +0800   CalicoIsUp                   Calico is running on this node
  MemoryPressure       False   Thu, 16 Jan 2020 17:30:45 +0800   Sat, 04 Jan 2020 12:11:53 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure         False   Thu, 16 Jan 2020 17:30:45 +0800   Sat, 04 Jan 2020 12:11:53 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure          False   Thu, 16 Jan 2020 17:30:45 +0800   Sat, 04 Jan 2020 12:11:53 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready                True    Thu, 16 Jan 2020 17:30:45 +0800   Sat, 04 Jan 2020 12:11:53 +0800   KubeletReady                 kubelet is posting ready status
Addresses:
  InternalIP:  172.16.126.137
  Hostname:    node-001
Capacity:
 cpu:                2
 ephemeral-storage:  17394Mi
 hugepages-1Gi:      0
 hugepages-2Mi:      0
 memory:             1863104Ki
 pods:               110
Allocatable:
 cpu:                2
 ephemeral-storage:  16415037823
 hugepages-1Gi:      0
 hugepages-2Mi:      0
 memory:             1760704Ki
 pods:               110
System Info:
 Machine ID:                 ee5a9a60acff444b920cec37aadf35d0
 System UUID:                A5074D56-3849-E5CC-C84D-898BBFD19AFD
 Boot ID:                    44c86e13-aea4-4a7e-8f5e-3e5434357035
 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.5
 Kubelet Version:            v1.16.3
 Kube-Proxy Version:         v1.16.3
PodCIDR:                     10.244.1.0/24
PodCIDRs:                    10.244.1.0/24
Non-terminated Pods:         (9 in total)
  Namespace                  Name                                         CPU Requests  CPU Limits  Memory Requests  Memory Limits  AGE
  ---------                  ----                                         ------------  ----------  ---------------  -------------  ---
  default                    rntibp-deployment-84d77f8f78-f99pp           0 (0%)        0 (0%)      0 (0%)           0 (0%)         12d
  default                    tomcat-demo-5f4b587679-7mpz9                 0 (0%)        0 (0%)      0 (0%)           0 (0%)         13d
  dev                        web-demo-74d747dbb5-z85fj                    100m (5%)     200m (10%)  100Mi (5%)       100Mi (5%)     3m1s #这里可以看刚才部署项目的内存
  ingress-nginx              nginx-ingress-controller-646bdb48f6-nrj59    100m (5%)     0 (0%)      90Mi (5%)        0 (0%)         13d
  kube-system                calico-kube-controllers-648f4868b8-q7tvb     0 (0%)        0 (0%)      0 (0%)           0 (0%)         14d
  kube-system                calico-node-6sljh                            250m (12%)    0 (0%)      0 (0%)           0 (0%)         14d
  kube-system                coredns-58cc8c89f4-lhwp2                     100m (5%)     0 (0%)      70Mi (4%)        170Mi (9%)     14d
  kube-system                coredns-58cc8c89f4-mq4jm                     100m (5%)     0 (0%)      70Mi (4%)        170Mi (9%)     14d
  kube-system                kube-proxy-s25k5                             0 (0%)        0 (0%)      0 (0%)           0 (0%)         14d
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests     Limits
  --------           --------     ------
  cpu                650m (32%)   200m (10%) # cpu使用650m
  memory             330Mi (19%)  440Mi (25%) # 内存 330Mi
  ephemeral-storage  0 (0%)       0 (0%)
Events:              <none>

K8s 资源利用是根据docker隔离机制,需要重启启动一个docker才能加上对应的隔离机制

我们来到node节点用 docker命令查看

[root@node-001 ~]# docker ps | grep web-demo
7945a3283097        c2c8abe7e363                                        "sh /usr/local/tomca…"   12 minutes ago      Up 12 minutes                           k8s_web-demo_web-demo-74d747dbb5-z85fj_dev_08cc53f8-ea1a-4ed5-a3bb-9f6727f826ee_0
[root@node-001 ~]# docker inspect 7945a3283097 查看应用参数设置

其他参数声咯…只说我们传给你docker 的四个值requests: memory: cpu limits:memory: cpu

CpuShares:我们在yaml resources : cpu 配置是100m(0.1核), 把这个值转化成0.1核 然后在✖️1024就等于102.4。然后把这个值传给docker ,这个值在docker 是一个相对的权重,作用是当docker 发生资源竞争的时候,分配给容器资源的一个比例。比如:有两个容器CPU的参数设置1和2,对应CpuShares:的参数值就是1024和2048。如果发生资源竞争,docker会尝试按照一比二的比例,将CPU分配给这两个容器。他是一个相对的,当资源发生竞争用来决定CPU分配比例。

Memory:内存,104857600➗1024➗1024=100兆,这个值是在yaml 配置request Memory设置的。docker运行的时候直接指定limits内存为Memory

“CpuShares”: 102,
“Memory”: 104857600,

CpuPeriod: docker 默认值 100000纳秒转毫秒100

CpuQuota : 是yaml 配置limits设置的cpu 200m=0.2盒✖️100000=20000

这两个值一起使用表示100毫秒内最多分配给这个容器cpu 的量是20000

“CpuPeriod”: 100000,
“CpuQuota”: 20000,

极限测试
内存过小会怎么样

我们把demo 的容器requests内存写小点,然后在容器内部写一个非常吃内存的脚本,这里就不测试。

经测试:吃内存的脚本进程跑一会就会被杀死,但是容器并没有停止,说明kubenetes 会把占用内存最大的进程给他杀掉,而不是一定要把容器重启。

修改limits限制内存/CPU过大会怎么样

修改yaml limits 内存和CPU到超越当前机器的容量

经测试: 依然可以正常启动,他不依赖limits 设置

把requests 内存/CPU调大会怎么样
 resources:
          requests:
            memory: 20000Mi #20G
            cpu: 10000m 
          limits:
            memory: 100Gi
            cpu: 20000m

然后启动

经测试:无法启动改容器,因为没有满足reputes内存的节点

把 requests 内存变成10g启动三个副本

经测试:只能启动两个,因为指定10g就必须预留10g,但是不够10g就无法启动

但是CPU超量不会被杀死,因为CPU是可压缩资源内存不是,这就是区别

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐