全部產品
Search
文件中心

Container Service for Kubernetes:線上服務與視頻轉碼應用混部

更新時間:Jul 12, 2025

線上服務與離線計算應用混部在同一節點的情境下,您可以在ACK叢集中通過ack-koordinator組件開啟差異化SLO能力。本文介紹如何使用ack-koordinator實現線上服務與視頻轉碼應用的混部。

本文將在 ACK 叢集中部署線上服務 Nginx,並在同一節點混部離線視頻轉碼應用 FFmpeg,以充分利用叢集中已申請但未使用的實體資源。通過啟用ack-koordinator的資源隔離功能,可以確保線上服務穩定啟動並執行同時,避免離線應用受到幹擾。

前提條件

  • 已在ACK託管叢集Pro版中建立2個節點用於構建混部環境。

    • 測試機:一個節點用於運行Nginx和FFmpeg的混部測試。

      為了充分使用ack-koordinator提供的混部最佳化能力,建議測試機使用神龍裸金屬伺服器,作業系統選擇Alibaba Cloud Linux

    • 壓測機:一個節點用於運行用戶端的wrk,向Nginx請求Web服務,製造壓測請求。

  • 已參見快速入門安裝ack-koordinator(ack-slo-manager)並開啟相關混部策略。

    本文以ack-koordinator v0.8.0版本為例。

  • 在壓測機上,執行以下命令,部署壓測工具wrk。

    yum install -y unzip
    wget -O wrk-4.2.0.tar.gz https://github.com/wg/wrk/archive/refs/tags/4.2.0.tar.gz && tar -xvf wrk-4.2.0.tar.gz
    cd wrk-4.2.0 && make && chmod +x ./wrk

應用部署架構

本文將在 ACK 叢集中運行 Nginx 作為線上服務,並與視頻解碼應用 FFmpeg 混部。其中,Nginx Pod 的 QoS 等級為高優先順序的Latency Sensitive型(LS);FFmpeg Pod為低優先順序的Best Effort型(BE)。本文將對比不同混部配置下 Nginx 應用的效能表現。

在離線混部過程中主要使用的功能特性:

本文將進行三組實驗,分別採用以下三種應用部署模式,對比不同混部模式下線上應用的效能表現和節點的資源使用率。

部署方式

說明

線上應用獨立部署(基準)

在測試機上僅部署線上應用 Nginx,不部署離線視頻轉碼應用 FFmpeg。使用壓測機上的 wrk 工具向 Nginx 發起請求,類比未混部情境,測試 Nginx 在無離線應用幹擾下的效能表現及節點資源使用率。

K8s預設混合部署(對照組)

在測試機上混合部署線上應用 Nginx 和離線視頻轉碼應用 FFmpeg。使用壓測機上的 wrk 工具向 Nginx 發起請求。FFmpeg 應用採用Best Effort 模式部署,其 Pod 不設定 Requests 和 Limits。通過調整進程數將節點 CPU 使用率控製為 65%,類比 K8s 預設混部情境,測試 Nginx 的效能表現及節點資源使用率。

ACK差異化SLO混部(實驗組)

在測試機上混合部署線上應用 Nginx 和離線視頻轉碼應用 FFmpeg。使用壓測機上的 wrk 工具向 Nginx 發起請求。FFmpeg 應用採用差異化 SLO 的 BE 模式部署,其 Pod 啟用動態資源超賣擴充資源。測試機開啟 啟用CPU資源彈性限制式能力啟用容器CPU QoS啟用容器L3 Cache及記憶體頻寬隔離等 SLO 功能,類比SLO 混部情境,測試 Nginx 的效能表現及節點資源使用率。

操作步驟

線上應用獨立部署樣本

  1. 在測試機上部署線上應用Nginx。

    1. 使用以下YAML內容,建立ls-nginx.yaml檔案。

      展開查看YAML詳情

      ---
      # nginx應用配置
      apiVersion: v1
      data:
        config: |-
          user  nginx;
          worker_processes  80; # Nginx的Worker個數,影響Nginx Server的並發。
      
          events {
              worker_connections  1024;  # 預設值為1024。
          }
      
          http {
              server {
                  listen  8000;
      
                  gzip off;
                  gzip_min_length 32;
                  gzip_http_version 1.0;
                  gzip_comp_level 3;
                  gzip_types *;
              }
          }
      
          #daemon off;
      kind: ConfigMap
      metadata:
        name: nginx-conf
      
      ---
      # Nginx執行個體,作為線上類型服務應用。
      apiVersion: v1
      kind: Pod
      metadata:
        labels:
          koordinator.sh/qosClass: LS
          app: nginx
        name: nginx
      spec:
        containers:
          - image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            imagePullPolicy: IfNotPresent
            name: nginx
            ports:
              - containerPort: 8000
                hostPort: 8000 # 壓測請求訪問的連接埠。
                protocol: TCP
            resources:
              limits:
                cpu: '80'
                memory: 10Gi
              requests:
                cpu: '80'
                memory: 10Gi
            volumeMounts:
              - mountPath: /etc/nginx/
                name: config
        hostNetwork: true
        restartPolicy: Never
        volumes:
          - configMap:
              items:
                - key: config
                  path: nginx.conf
              name: nginx-conf
            name: config
        nodeName: cn-beijing.192.168.2.93  # 請替換為您的測試機的節點名稱。
    2. 執行以下命令,部署Nginx應用。

      kubectl apply -f ls-nginx.yaml
    3. 執行以下命令,查看Nginx應用的Pod狀態。

      kubectl get pod -l app=nginx -o wide

      預期輸出:

      NAME    READY   STATUS    RESTARTS   AGE    IP               NODE                      NOMINATED NODE   READINESS GATES
      nginx   1/1     Running   0          43s    11.162.XXX.XXX   cn-beijing.192.168.2.93   <none>           <none>

      由預期輸出得到,Pod的狀態為Running ,表示Nginx應用已在測試機上正常運行。

  2. 使用壓測工具wrk,向Nginx應用發起壓測請求。

    # node_ip填寫測試機的IP地址,用於wrk向測試機發起壓測;8000是Nginx暴露到測試機的連接埠。
    ./wrk -t6 -c54 -d60s --latency http://${node_ip}:8000/

    預期輸出:

      Running 1m test @ http://${node_ip}:8000/
      6 threads and 54 connections
      Thread Stats   Avg      Stdev     Max   +/- Stdev
        Latency   402.18us    1.07ms  59.56ms   99.83%
        Req/Sec    24.22k     1.12k   30.58k    74.15%
      Latency Distribution
         50%  343.00us
         75%  402.00us
         90%  523.00us
         99%  786.00us
      8686569 requests in 1.00m, 6.88GB read
    Requests/sec: 144537.08
    Transfer/sec:    117.16MB

    RT指標是本次衡量線上服務Nginx應用在不同情境下運行效能的關鍵計量。由預期輸出得到,Latency Distribution部分包含了wrk請求在Nginx應用上回應時間RT(Response Time)的分布。例如,90% 523.00us表示本次壓測中RT的90分位值(P90)為523.00us。Nginx應用在未混部情境下壓測得到的RT-P50、RT-P90、RT-P99分別為343us、523us、786us。

  3. 執行以下命令,擷取測試機的節點CPU平均利用率。

    kubectl top node

    預期輸出:

    NAME                      CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
    cn-beijing.192.168.2.93   29593m       29%    xxxx            xxxx
    cn-beijing.192.168.2.94   6874m        7%     xxxx            xxxx

    由預期輸出得到,壓測中測試機的平均CPU資源使用率約為29%

K8s預設混合部署樣本

  1. 在測試機上部署線上應用Nginx。

    1. 使用以下YAML內容,建立ls-nginx.yaml檔案。

      展開查看YAML詳情

      ---
      # nginx應用配置
      apiVersion: v1
      data:
        config: |-
          user  nginx;
          worker_processes  80; # Nginx的Worker個數,影響Nginx Server的並發。
      
          events {
              worker_connections  1024;  # 預設值為1024。
          }
      
          http {
              server {
                  listen  8000;
      
                  gzip off;
                  gzip_min_length 32;
                  gzip_http_version 1.0;
                  gzip_comp_level 3;
                  gzip_types *;
              }
          }
      
          #daemon off;
      kind: ConfigMap
      metadata:
        name: nginx-conf
      
      ---
      # Nginx執行個體,作為線上類型服務應用。
      apiVersion: v1
      kind: Pod
      metadata:
        labels:
          koordinator.sh/qosClass: LS
          app: nginx
        name: nginx
      spec:
        containers:
          - image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            imagePullPolicy: IfNotPresent
            name: nginx
            ports:
              - containerPort: 8000
                hostPort: 8000 # 壓測請求訪問的連接埠。
                protocol: TCP
            resources:
              limits:
                cpu: '80'
                memory: 10Gi
              requests:
                cpu: '80'
                memory: 10Gi
            volumeMounts:
              - mountPath: /etc/nginx/
                name: config
        hostNetwork: true
        restartPolicy: Never
        volumes:
          - configMap:
              items:
                - key: config
                  path: nginx.conf
              name: nginx-conf
            name: config
        nodeName: cn-beijing.192.168.2.93  # 請替換為您的測試機的節點名稱。
    2. 執行以下命令,部署Nginx應用。

      kubectl apply -f ls-nginx.yaml
    3. 執行以下命令,查看Nginx應用的Pod狀態。

      kubectl get pod -l app=nginx -o wide

      預期輸出:

      NAME    READY   STATUS    RESTARTS   AGE    IP               NODE                      NOMINATED NODE   READINESS GATES
      nginx   1/1     Running   0          43s    11.162.XXX.XXX   cn-beijing.192.168.2.93   <none>           <none>

      由預期輸出得到,Pod的狀態為Running ,表示Nginx應用已在測試機上正常運行。

  2. 在測試機上部署離線應用。

    1. 使用以下YAML內容,建立be-ffmpeg.yaml檔案。

      展開查看YAML詳情

      # FFmpeg執行個體,作為離線類型計算應用。
      apiVersion: v1
      kind: Pod
      metadata:
        name: be-ffmpeg
        labels:
          app: ffmpeg
        # 1. 按照K8s預設混合部署模式部署:刪除以下koordinator.sh/qosClass=BE的label。
        # 2. 按照ACK差異化SLO混部模式部署:保留以下koordinator.sh/qosClass=BE的label。
          koordinator.sh/qosClass: BE
      spec:
        containers:
          # FFmpeg的進程數量可以根據測試需求調節,進程數越多對應的離線資源使用率越高,預設為25個進程,每個進程有兩個線程並發工作。
          - command:
              - start-ffmpeg.sh
              - '25'
              - '2'
              - /apps/ffmpeg/input/HD2-h264.ts
              - /apps/ffmpeg/
            image: 'registry.cn-zhangjiakou.aliyuncs.com/acs/ffmpeg-4-4-1-for-slo-test:v0.1'
            imagePullPolicy: Always
            name: ffmpeg
            resources:
            # 1. 按照K8s預設混合部署模式部署:刪除以下擴充資源kubernetes.io/batch-cpu和kubernetes.io/batch-memory。
            # 2. 按照ACK差異化SLO混部模式部署:保留以下擴充資源kubernetes.io/batch-cpu和kubernetes.io/batch-memory。
            # 具體資源需求量請按節點規格按需調整。
              limits:
                kubernetes.io/batch-cpu: 70k
                kubernetes.io/batch-memory: 22Gi
              requests:
                kubernetes.io/batch-cpu: 70k
                kubernetes.io/batch-memory: 22Gi
        hostNetwork: true
        restartPolicy: Never
        nodeName: cn-beijing.192.168.2.93  # 請替換為您的測試機的節點名稱。
    2. 執行以下命令,部署FFmpeg應用。

      kubectl apply -f be-ffmpeg.yaml
    3. 執行以下命令,查看FFmpeg應用的Pod狀態。

      kubectl get pod -l app=ffmpeg -o wide

      預期輸出:

      NAME        READY   STATUS    RESTARTS   AGE    IP               NODE                      NOMINATED NODE   READINESS GATES
      be-ffmpeg   1/1     Running   0          15s    11.162.XXX.XXX   cn-beijing.192.168.2.93   <none>           <none>

      由預期輸出得到,Pod的狀態為Running ,表示FFmpeg應用已在測試機上正常運行。

  3. 使用壓測工具wrk,執行以下命令,向Nginx應用發起壓測請求。

    # node_ip填寫測試機的IP地址,用於wrk向測試機發起壓測;8000是Nginx暴露到測試機的連接埠。
    ./wrk -t6 -c54 -d60s --latency http://${node_ip}:8000/
  4. 執行以下命令,查看測試機的CPU資源使用率。

    kubectl top node

    壓測結果請參見實驗結果總覽

ACK差異化SLO混合部署樣本

在測試機上以ACK差異化SLO的BE Pod的形式部署視頻轉碼應用FFmpeg,測試線上服務在與視頻轉碼應用在差異化SLO混部下的效能資料。

  1. 參考管理混部策略,開啟差異化SLO混部。

    相關功能說明如下:

    • 啟用動態資源超賣:採用開啟後的預設配置。用於合理超賣節點未使用的實體資源,提供給BE Pod調度。

    • 啟用CPU資源彈性限制式能力cpuSuppressThresholdPercent設定為65,其他採用開啟後的預設配置。用於在節點CPU資源使用率超出閾值(65%)時,壓制BE應用的CPU使用,以保障LS應用的CPU效能。

    • 啟用容器CPU QoS:採用開啟後的預設配置。用於啟用Alibaba Cloud Linux的CPU Identity能力,在核心調度中優先保障LS應用的CPU調度,避免因BE應用對LS應用運行在同一對SMT超執行緒上而產生的幹擾。

    • 啟用容器L3 Cache及記憶體頻寬隔離:採用開啟後的預設配置。用於啟用裸金屬伺服器的容器L3 Cache和記憶體頻寬隔離機制,優先保障LS應用的L3 Cache和記憶體頻寬使用,緩解BE應用的資源競爭幹擾。

    重要
    • 容器CPU QoS功能僅在節點的作業系統版本為Alibaba Cloud Linux時生效;使用其他動作系統版本時,該功能不會開啟。

    • 容器L3 Cache及記憶體頻寬隔離功能僅在節點為裸金屬伺服器時生效;使用其他伺服器類型時,該功能不會開啟。

  2. 在測試機上部署線上應用Nginx。

    1. 使用以下YAML內容,建立ls-nginx.yaml檔案。

      展開查看YAML詳情

      ---
      # nginx應用配置
      apiVersion: v1
      data:
        config: |-
          user  nginx;
          worker_processes  80; # Nginx的Worker個數,影響Nginx Server的並發。
      
          events {
              worker_connections  1024;  # 預設值為1024。
          }
      
          http {
              server {
                  listen  8000;
      
                  gzip off;
                  gzip_min_length 32;
                  gzip_http_version 1.0;
                  gzip_comp_level 3;
                  gzip_types *;
              }
          }
      
          #daemon off;
      kind: ConfigMap
      metadata:
        name: nginx-conf
      
      ---
      # Nginx執行個體,作為線上類型服務應用。
      apiVersion: v1
      kind: Pod
      metadata:
        labels:
          koordinator.sh/qosClass: LS
          app: nginx
        name: nginx
      spec:
        containers:
          - image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            imagePullPolicy: IfNotPresent
            name: nginx
            ports:
              - containerPort: 8000
                hostPort: 8000 # 壓測請求訪問的連接埠。
                protocol: TCP
            resources:
              limits:
                cpu: '80'
                memory: 10Gi
              requests:
                cpu: '80'
                memory: 10Gi
            volumeMounts:
              - mountPath: /etc/nginx/
                name: config
        hostNetwork: true
        restartPolicy: Never
        volumes:
          - configMap:
              items:
                - key: config
                  path: nginx.conf
              name: nginx-conf
            name: config
        nodeName: cn-beijing.192.168.2.93  # 請替換為您的測試機的節點名稱。
    2. 執行以下命令,部署Nginx應用。

      kubectl apply -f ls-nginx.yaml
    3. 執行以下命令,查看Nginx應用的Pod狀態。

      kubectl get pod -l app=nginx -o wide

      預期輸出:

      NAME    READY   STATUS    RESTARTS   AGE    IP               NODE                      NOMINATED NODE   READINESS GATES
      nginx   1/1     Running   0          43s    11.162.XXX.XXX   cn-beijing.192.168.2.93   <none>           <none>

      由預期輸出得到,Pod的狀態為Running ,表示Nginx應用已在測試機上正常運行。

  3. 在測試機上部署離線應用。

    1. 使用以下YAML內容,建立be-ffmpeg.yaml檔案。

      展開查看YAML詳情

      # FFmpeg執行個體,作為離線類型計算應用。
      apiVersion: v1
      kind: Pod
      metadata:
        name: be-ffmpeg
        labels:
          app: ffmpeg
        # 1. 按照K8s預設混合部署模式部署:刪除以下koordinator.sh/qosClass=BE的label。
        # 2. 按照ACK差異化SLO混部模式部署:保留以下koordinator.sh/qosClass=BE的label。
          koordinator.sh/qosClass: BE
      spec:
        containers:
          # FFmpeg的進程數量可以根據測試需求調節,進程數越多對應的離線資源使用率越高,預設為25個進程,每個進程有兩個線程並發工作。
          - command:
              - start-ffmpeg.sh
              - '25'
              - '2'
              - /apps/ffmpeg/input/HD2-h264.ts
              - /apps/ffmpeg/
            image: 'registry.cn-zhangjiakou.aliyuncs.com/acs/ffmpeg-4-4-1-for-slo-test:v0.1'
            imagePullPolicy: Always
            name: ffmpeg
            resources:
            # 1. 按照K8s預設混合部署模式部署:刪除以下擴充資源kubernetes.io/batch-cpu和kubernetes.io/batch-memory。
            # 2. 按照ACK差異化SLO混部模式部署:保留以下擴充資源kubernetes.io/batch-cpu和kubernetes.io/batch-memory。
            # 具體資源需求量請按節點規格按需調整。
              limits:
                kubernetes.io/batch-cpu: 70k
                kubernetes.io/batch-memory: 22Gi
              requests:
                kubernetes.io/batch-cpu: 70k
                kubernetes.io/batch-memory: 22Gi
        hostNetwork: true
        restartPolicy: Never
        nodeName: cn-beijing.192.168.2.93  # 請替換為您的測試機的節點名稱。
    2. 執行以下命令,部署FFmpeg應用。

      kubectl apply -f be-ffmpeg.yaml
    3. 執行以下命令,查看FFmpeg應用的Pod狀態。

      kubectl get pod -l app=ffmpeg -o wide

      預期輸出:

      NAME        READY   STATUS    RESTARTS   AGE    IP               NODE                      NOMINATED NODE   READINESS GATES
      be-ffmpeg   1/1     Running   0          15s    11.162.XXX.XXX   cn-beijing.192.168.2.93   <none>           <none>

      由預期輸出得到,Pod的狀態為Running ,表示FFmpeg應用已在測試機上正常運行。

  4. 使用壓測工具wrk,執行以下命令,向Nginx應用發起壓測請求。

    # node_ip填寫測試機的IP地址,用於wrk向測試機發起壓測;8000是Nginx暴露到測試機的連接埠。
    ./wrk -t6 -c54 -d60s --latency http://${node_ip}:8000/
  5. 執行以下命令,查看測試機的CPU資源使用率。

    kubectl top node

    預期輸出:

    NAME                      CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
    cn-beijing.192.168.2.93   65424m       63%    xxxx            xxxx
    cn-beijing.192.168.2.94   7040m        7%     xxxx            xxxx

    由預期輸出得到,壓測中測試機的平均CPU資源使用率約為63%

  6. 等待wrk運行結束,擷取wrk列印的壓測結果。

    壓測結果請參見實驗結果總覽

實驗結果總覽

本實驗通過以下指標評估不同混部模式下 Nginx 應用的效能表現及節點資源使用率:

  • 回應時間RT(Response Time)分位值:RT 是衡量線上應用效能的重要指標,數值越低表示服務效能越好。實驗中通過 wrk 壓測結果擷取 RT 資料,反映 Nginx 處理請求的耗時。例如,RT-p50 表示 Nginx 處理前 50% 請求的最大耗時(中位元),RT-p90 表示處理前 90% 請求的最大耗時。

  • 節點CPU平均利用率:該指標反映節點上應用對 CPU 資源的使用方式,數值越高表明實體資源利用越充分。實驗中通過 kubectl top node 擷取該資料,用於評估不同混部模式下的 CPU 資源使用率。

預期結果如下:

指標/部署模式

基準(線上應用獨立部署)

對照組(K8s預設混合部署)

實驗組(ACK差異化SLO混部)

Nginx RT-p90(ms)

0.533

0.574(+7.7%)

0.548(+2.8%)

Nginx RT-p99(ms)

0.93

1.07(+16%)

0.96(+3.2%)

節點CPU平均利用率

29.6%

65.1%

64.8%

  • 對比基準和對照組:採用K8s預設的混合部署後,節點CPU平均利用率明顯提升(從29.6%變為65.1%),Nginx RT-p90和RT-p99明顯增大,RT效能出現了長尾現象。

  • 對比基準和實驗組:採用ACK差異化SLO混部後,節點CPU平均利用率明顯提升(從28.5%變為64.8%),Nginx RT-p90和RT-p99相對基準有所增高,但仍屬於可接受範圍內。

  • 對比對照組和實驗組:ACK差異化SLO混部相比K8s預設混部,節點CPU平均利用率相近,Nginx RT-p90和RT-p99明顯下降,基本與基準資料持平。

綜上,線上服務與離線視頻轉碼應用混部情境下,採用ACK差異化SLO混部模式能夠有效提升節點CPU資源使用率,抑制資源混部幹擾。

後續操作

關於在離線混部功能的更多資訊,請參見:

常見問題

在使用wrk壓測中,測試結果提示“Socket errors: connect 54,”怎麼辦?

問題描述

在使用wrk壓測中,測試結果提示Socket errors: connect 54,。測試中的wrk Client和Nginx Server建立串連失敗,測試結果失效。

問題原因

該錯誤通常是因為用戶端的串連數受限,導致用戶端建立串連失敗。

解決辦法

為了避免該錯誤,請在壓測機上檢查系統的TCP串連配置,並嘗試啟用TCP串連重用。

  1. 登入壓測機,執行如下命令,查看是否開通TCP串連重用。

    sudo sysctl -n net.ipv4.tcp_tw_reuse

    命令輸出為02,說明系統未完全開啟TCP串連重用。

  2. 執行如下命令,啟用TCP串連重用。

    sudo sysctl -w net.ipv4.tcp_tw_reuse=1
  3. 使用wrk工具再次發起壓測請求。

    檢查測試結果不再包含Socket errors: connect 54, ...的報錯提示,說明測試結果有效。

說明

操作步驟中使用的指令僅在壓測機上執行,測試機無需配置。測試完成後,請通過sysctl -w net.ipv4.tcp_tw_reuse恢複原始配置,避免不必要的影響。