研发工程师玩转Kubernetes——CPU配额

部署运行你感兴趣的模型镜像

在一个Pod中,可以有多个容器,比如一个主要业务容器和若干辅助业务容器。如果辅助业务容器内程序有问题,导致占用了大量的CPU资源,进而影响了主要业务容器的执行效率,那就需要进行干涉了。本节我们将使用“资源配额”来限制容器的CPU使用。

服务部署

为了让程序更多的消耗CPU,我们对测试代码做了相关改动

# main.py
from http.server import HTTPServer, BaseHTTPRequestHandler
import argparse
import os
import random
import math

def docpu():
    random_number_a = random.randint(10000,100000000000)
    random_number_b = random.randint(100000000000,10000000000000)
    random_number = random_number_a * random_number_b
    while random_number > 2:
        random_number = math.sqrt(random_number)
    return random_number

class Resquest(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()
        random_number_sum = 0
        while True:
            random_number = docpu()
            if random_number_sum > 1000:
                break
            else:
                random_number_sum += random_number
            
        data = "{0}".format(random_number)
        self.wfile.write(data.encode())
 
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Process some integers.')
    parser.add_argument('-port', metavar='N', type=int, help='port of service', required=True)
    args = parser.parse_args()
    host = ('0.0.0.0',  args.port)
    server = HTTPServer(host, Resquest)
    print("Starting server, listen at: {0}:{1}".format(os.environ.get("POD_IP", ""), args.port))
    server.serve_forever()

这段代码内部不停地对随机数开方,用于消耗CPU。

部署

在kubernetes中,1个CPU资源被切分成1000份被分配,每份叫1毫核。这是配额的最小单元了。如下,我们就让容器可以使用100毫核,即0.1个CPU核。

        resources:
          limits:
            cpu: 100m

完整的清单文件如下

# simple_http_deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: simple-http-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: simple_http
  template:
    metadata:
      labels:
        app: simple_http
    spec:
      containers:
      - name: simple-http-container
        image: localhost:32000/simple_http:v4
        ports:
        - containerPort: 8888
        command: ["python","main.py","-port","$(SERVER_PORT)"]
        env:
        - name: SERVER_PORT
          value:  "8888"
        resources:
          limits:
            cpu: 100m
---
apiVersion: v1
kind: Service
metadata:
  name: simple-http-service
spec:
  type: NodePort
  selector:
    app: simple_http
  ports:
  - port: 80
    targetPort: 8888
    nodePort: 30000

在这个清单中,我们创建了一个Deployment用于部署Pod,其中resources指定每个Pod只能使用0.1个CPU(100m)。还创建了一个Service用于接收请求,这些请求将被路由到上述Pod上。

kubectl create -f simple_http_deployment.yaml

deployment.apps/simple-http-deployment created
service/simple-http-service created

使用《研发工程师玩转Kubernetes——启用microk8s的监控面板(dashboard)》中的控制面板,我们可以看到没有请求时两个Pod的CPU利用情况——最低的1毫核。
在这里插入图片描述

测试压力

我们使用wrk来做压力测试,如果没有安装它,可以使用sudo apt install wrk来安装。
下面命令让wrk启动10个线程,10个连接,发送120秒。

wrk -t10 -c10 -d120  http://192.168.137.248:30000 

运行结束会显示如下结果

  10 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     6.61ms   15.40ms 418.80ms   90.63%
    Req/Sec   177.20    135.77   772.00     53.58%
  77331 requests in 2.00m, 10.45MB read
  Socket errors: connect 0, read 77331, write 0, timeout 0
Requests/sec:    643.89
Transfer/sec:     89.13KB

这个结果simple_http服务每秒处理了643个请求,即我们所谓的QPS是643。
我们将压力加倍,启动20个线程,20个连接。

wrk -t20 -c20 -d120  http://192.168.137.248:30000  
Running 2m test @ http://192.168.137.248:30000
  20 threads and 20 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     6.15ms   17.88ms 455.17ms   92.87%
    Req/Sec   120.62    125.10     0.86k    81.23%
  77893 requests in 2.00m, 10.53MB read
  Socket errors: connect 0, read 77893, write 0, timeout 0
Requests/sec:    648.62
Transfer/sec:     89.79KB

可以看到QPS是648,和之前的QPS(643)相差不大。我们可以认为simple_service已经抗压到极限了。
下图是所有Pod的资源使用情况。因为我们每个Pod只有一个容器,每个容器CPU上限是0.1——即我们看到两个Pod的CPU使用最高是0.2。
在这里插入图片描述
下面两个图是每个Pod的资源使用情况。可以看到每个容器都在0.1个CPU核配额之下运行。
在这里插入图片描述
在这里插入图片描述

修改配额

我们将CPU配额从100毫核调整到200毫核,看看simple_http_service抗压能力是否有1倍的提升。

# simple_http_deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: simple-http-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: simple_http
  template:
    metadata:
      labels:
        app: simple_http
    spec:
      containers:
      - name: simple-http-container
        image: localhost:32000/simple_http:v4
        ports:
        - containerPort: 8888
        command: ["python","main.py","-port","$(SERVER_PORT)"]
        env:
        - name: SERVER_PORT
          value:  "8888"
        resources:
          limits:
            cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
  name: simple-http-service
spec:
  type: NodePort
  selector:
    app: simple_http
  ports:
  - port: 80
    targetPort: 8888
    nodePort: 30000

只做了resources.limit.cpu的修改,然后我们提交这个文件

kubectl apply -f simple_http_deployment.yaml

稍微等一会儿,待新Pod创建完成并运行(老的Pod会被删除)。
然后我们再使用wrk进行压测

wrk -t20 -c20 -d120  http://192.168.137.248:30000
Running 2m test @ http://192.168.137.248:30000
  20 threads and 20 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     2.33ms    9.79ms 429.11ms   97.27%
    Req/Sec   258.82    299.89     2.02k    76.98%
  153609 requests in 2.00m, 20.77MB read
  Socket errors: connect 0, read 153609, write 0, timeout 0
Requests/sec:   1279.56
Transfer/sec:    177.13KB

可以看到QPS上升了接近一倍(之前是648)。
在这里插入图片描述

参考资料

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

breaksoftware

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值