• K8S实战(十八)| 容器资源分配和资源限制


    前言

    为了防止容器调度到资源不足的节点上,可以为容器指定资源最少要求量。

    为了防止容器无节制的使用 CPU、内存 等资源,可以为容器指定资源最大允许使用量。

    更新历史

    资源请求和资源约束

    可以为容器指定资源请求量和资源约束量。

    资源一般指 CPU、内存。

    资源请求量,指容器要求节点分配的最小容量,如果该节点可用容量小于容器要求的请求量,容器将被调度到其他合适节点。

    资源约束量,指容器要求节点限制其使用的最大容量,如果容器内存使用量超过内容约束量,容器将被杀掉,如果指定了重启策略,容器杀掉后将被重启。

    涉及的参数

    约束量
    spec.containers[].resources.limits.cpu
    spec.containers[].resources.limits.memory
    spec.containers[].resources.limits.hugepages-<size>
    
    请求量
    spec.containers[].resources.requests.cpu
    spec.containers[].resources.requests.memory
    spec.containers[].resources.requests.hugepages-<size>
    

    示例

    apiVersion: v1
    kind: Pod
    metadata:
      name: frontend
    spec:
      containers:
      - name: app
        image: images.my-company.example/app:v4
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "password"
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
      - name: log-aggregator
        image: images.my-company.example/log-aggregator:v6
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
    

    资源单位

    K8S 中的一个 cpu 等于云平台上的 1 个 vCPU/核或裸机 Intel 处理器上的 1 个超线程

    spec.containers[].resources.requests.cpu 为 0.5 的容器肯定能够获得请求 1 CPU 的容器的一半 CPU 资源。表达式 0.1 等价于表达式 100m, 可以看作 “100 millicpu”。具有小数点(如 0.1)的请求由 API 转换为 100m;最大精度是 1m。

    优先考虑使用 100m 的形式。

    内存可以使用E、P、T、G、M、K。也可以使用对应的 2 的幂数:Ei、Pi、Ti、Gi、Mi、Ki。

    Pod 的资源请求和约束

    Pod 的请求量等于内部所有容器的请求量之和。

    Pod 的约束量等于内部所有容器的约束量之和。

    带资源请求的 Pod 如何调度

    调度程序确保所调度的 Pod 的资源请求量小于节点的容量。

    即,调度程序将查找到资源可用量充足的,可用量大于请求量的节点来放置 Pod。

    带资源约束的 Pod 如何运行

    内存资源约束

    如果容器超过其内存最大限制,则可能会被终止。如果容器可重新启动,kubelet 将重新启动容器。

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

    CPU 资源约束

    每个容器可能被允许也可能不被允许使用超过其 CPU 约束的处理时间。 但是,容器不会由于 CPU 使用率过高而被杀死。

    spec.containers[].resources.limits.cpu 先被转换为 millicore 值,再乘以 100。其结果就是每 100 毫秒内容器可以使用的 CPU 时间总量。在此期间(100ms),容器所使用的 CPU 时间不会超过它被分配的时间。

    默认的配额(quota)周期为 100 毫秒。 CPU配额的最小精度为 1 毫秒。

    如何获知集群资源使用情况,需要通过 metrics-server 来获取。

    metrics-server

    查看是否已安装 metrics-server,以下说明没安装

    # kubectl top node
    Error from server (NotFound): the server could not find the requested resource (get services http:heapster:)
    # kubectl get pods,svc,deployments -n kube-system | grep metrics-server
    # 
    

    开始安装 metrics-server

    git clone https://github.com/kubernetes-incubator/metrics-server
    cd metrics-server/
    git checkout release-0.3
    

    修改 metrics-server/deploy/1.8+/metrics-server-deployment.yaml

          containers:
          - name: metrics-server
            #image: k8s.gcr.io/metrics-server/metrics-server:v0.3.6
            image: registry.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6
            imagePullPolicy: IfNotPresent
            args:
              - --cert-dir=/tmp
              - --secure-port=4443
              - --metric-resolution=30s
              - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
              - --kubelet-insecure-tls
    

    参数说明

    --metric-resolution=30s:从 kubelet 采集数据的周期;
    --kubelet-preferred-address-types:优先使用 InternalIP 来访问 kubelet,这样可以避免节点名称没有 DNS 解析记录时,通过节点名称调用节点 kubelet API 失败的情况(未配置时默认的情况);
    --kubelet-insecure-tls:kubelet 的10250端口使用的是https协议,连接需要验证tls证书。--kubelet-insecure-tls不验证客户端证书
    

    安装

    kubectl apply -f deploy/1.8+/
    

    再次查看,需要多等一会儿,确保采集到数据。

    [root@master01 ~]# kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes"
    {"kind":"NodeMetricsList","apiVersion":"metrics.k8s.io/v1beta1","metadata":{"selfLink":"/apis/metrics.k8s.io/v1beta1/nodes"},"items":[]}
    
    [root@master01 1.8+]# kubectl top nodes
    NAME       CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
    master01   163m         4%     2093Mi          56%       
    master02   147m         3%     1638Mi          44%       
    master03   151m         3%     1609Mi          43%       
    work01     141m         3%     1084Mi          29%       
    work02     150m         3%     1097Mi          29%       
    work03     138m         3%     1471Mi          39%   
    
    [root@master01 1.8+]# kubectl top pod
    NAME                                      CPU(cores)   MEMORY(bytes)   
    mysql-0                                   15m          202Mi           
    mysql-1                                   14m          191Mi           
    mysql-2                                   13m          182Mi           
    nfs-client-provisioner-7db698bbc9-8ph55   2m           8Mi  
    

    已经可以看到资源使用情况。

    实践内存限额

    创建一个测试用命名空间

    # kubectl create namespace mem-example
    namespace/mem-example created
    

    创建一个最大限额 100M,但最少需要 250M 的容器

    # cat memory-request-limit-2.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: memory-demo-2
      namespace: mem-example
    spec:
      containers:
      - name: memory-demo-2-ctr
        image: polinux/stress
        resources:
          requests:
            memory: "50Mi"
          limits:
            memory: "100Mi"
        command: ["stress"]
        args: ["--vm", "1", "--vm-bytes", "250M", "--vm-hang", "1"]
    
    # kubectl apply -f memory-request-limit-2.yaml
    pod/memory-demo-2 created
    

    查看发现创建失败

    # kubectl get pod -n mem-example
    NAME            READY   STATUS             RESTARTS   AGE
    memory-demo-2   0/1     CrashLoopBackOff   3          88s
    

    查看原因

    # kubectl get pod -n mem-example -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"
    LastState: "}}{{.lastState}}{{end}}' memory-demo-2
    Container Name: memory-demo-2-ctr
    LastState: map[terminated:map[containerID:docker://aaf41e exitCode:1 reason:OOMKilled ]]
    

    其中有 reason:OOMKilled,说明超过了内存最大限额,导致了 OOM 然后被杀掉。

    结束语

    通过 resources.requests 和 resources.limits,可以对资源进行最少容量要求和最大容量限制,确保容器可以运行在资源充足的节点上,同时也不会由于自身占用了过多资源而影响节点上其他容器。

    联系我

    微信公众号:zuolinux_com

    微信扫码关注

  • 相关阅读:
    bash快捷建-光标移到行首、行尾等
    VitualBox中linux系统ping ip能通域名不通的解决办法
    linux下使用tar命令
    Windows平台下Git服务器搭建
    android 在使用studio 编写百度地图中遇到APP Scode码校验失败 问题
    android 开发中 添加库文件 和so 文件的存放位置和添加依赖
    Volley之 JsonRequest 解析JSON 数据
    利用Volley封装好的图片缓存处理加载图片
    使用Volley执行网络数据传输
    android 测试 Monkey 和 MonkeyRunner 的使用
  • 原文地址:https://www.cnblogs.com/zuolinux/p/13693807.html
Copyright © 2020-2023  润新知