Shell脚本如何配置容器CPU亲和性

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置容器CPU亲和性

  1. 使用 taskset 命令(最常用)
  2. 使用 cset 命令(更细粒度控制)
  3. 使用Docker Compose配置
  4. 完整的Shell脚本示例
  5. 高级用法:基于负载动态调整
  6. 注意事项

在Shell脚本中配置容器CPU亲和性,主要有以下几种方法:

使用 taskset 命令(最常用)

设置运行中容器的CPU亲和性

#!/bin/bash
# 获取容器PID
CONTAINER_ID="your_container_id"
PID=$(docker inspect --format '{{.State.Pid}}' $CONTAINER_ID)
# 绑定到CPU 0-3
taskset -p -c 0-3 $PID

创建容器时直接设置

#!/bin/bash
# 创建容器并绑定到特定CPU
docker run -d --cpuset-cpus="0-3" --name myapp nginx
# 或者绑定到特定CPU核心
docker run -d --cpuset-cpus="0,2,4" --name myapp nginx

使用 cset 命令(更细粒度控制)

#!/bin/bash
# 创建CPU集合
cset set --cpu=0-3 --set=container_cpus
# 将容器PID加入集合
CONTAINER_PID=$(docker inspect --format '{{.State.Pid}}' container_name)
cset proc --move --pid=$CONTAINER_PID --toset=container_cpus
# 查看当前CPU绑定
cset proc --list

使用Docker Compose配置

# docker-compose.yml
version: '3.8'
services:
  myapp:
    image: nginx
    deploy:
      resources:
        reservations:
          cpus: '2'
        limits:
          cpus: '4'
    cpuset: "0-3"  # CPU亲和性设置

完整的Shell脚本示例

#!/bin/bash
# 配置容器CPU亲和性的完整脚本
set -e
# 颜色输出
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m'
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}
log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}
# 检查依赖
check_dependencies() {
    command -v docker >/dev/null 2>&1 || { log_error "Docker is required"; exit 1; }
    command -v taskset >/dev/null 2>&1 || { log_error "taskset is required"; exit 1; }
}
# 运行容器并设置CPU亲和性
run_container_with_cpu_affinity() {
    local CONTAINER_NAME=$1
    local IMAGE=$2
    local CPU_CORES=$3
    local MEMORY=$4
    log_info "Starting container with CPU affinity..."
    # 启动容器
    CONTAINER_ID=$(docker run -d \
        --name $CONTAINER_NAME \
        --cpuset-cpus="$CPU_CORES" \
        --memory="$MEMORY" \
        $IMAGE)
    if [ $? -eq 0 ]; then
        log_info "Container started: $CONTAINER_ID"
        # 验证CPU亲和性
        verify_cpu_affinity $CONTAINER_ID
    else
        log_error "Failed to start container"
        exit 1
    fi
}
# 修改运行中容器的CPU亲和性
modify_running_container_affinity() {
    local CONTAINER_ID=$1
    local NEW_CPU_CORES=$2
    log_info "Modifying CPU affinity for container: $CONTAINER_ID"
    # 获取容器PID
    PID=$(docker inspect --format '{{.State.Pid}}' $CONTAINER_ID)
    if [ -z "$PID" ]; then
        log_error "Container not found"
        exit 1
    fi
    # 使用taskset设置CPU亲和性
    taskset -p -c $NEW_CPU_CORES $PID
    if [ $? -eq 0 ]; then
        log_info "CPU affinity changed to: $NEW_CPU_CORES"
    else
        log_error "Failed to change CPU affinity"
    fi
}
# 验证CPU亲和性
verify_cpu_affinity() {
    local CONTAINER_ID=$1
    log_info "Verifying CPU affinity..."
    # 方法1:通过docker inspect
    local CPU_SET=$(docker inspect --format '{{.HostConfig.CpusetCpus}}' $CONTAINER_ID)
    log_info "Docker configured CPU set: $CPU_SET"
    # 方法2:通过taskset查看
    local PID=$(docker inspect --format '{{.State.Pid}}' $CONTAINER_ID)
    log_info "Actual CPU affinity: $(taskset -p -c $PID 2>&1)"
}
# 监控CPU使用情况
monitor_cpu_usage() {
    local CONTAINER_ID=$1
    local INTERVAL=$2
    log_info "Monitoring CPU usage for container: $CONTAINER_ID"
    while true; do
        docker stats --no-stream $CONTAINER_ID | grep -v CONTAINER
        sleep $INTERVAL
    done
}
# 主函数
main() {
    check_dependencies
    # 示例用法
    local CONTAINER_NAME="my-app"
    local IMAGE="nginx:latest"
    local CPU_CORES="0-2"  # 绑定到CPU 0,1,2
    local MEMORY="512m"
    # 启动容器并设置CPU亲和性
    run_container_with_cpu_affinity $CONTAINER_NAME $IMAGE $CPU_CORES $MEMORY
    # 等待5秒
    sleep 5
    # 修改CPU亲和性(如果需要)
    # modify_running_container_affinity $CONTAINER_NAME "0,3,4"
    # 监控CPU使用(可选)
    # monitor_cpu_usage $CONTAINER_NAME 2
}
# 执行主函数
main

高级用法:基于负载动态调整

#!/bin/bash
# 动态CPU亲和性调整脚本
adjust_cpu_affinity() {
    local CONTAINER_ID=$1
    local THRESHOLD=$2  # CPU使用率阈值百分比
    while true; do
        # 获取容器CPU使用率
        CPU_USAGE=$(docker stats --no-stream --format "{{.CPUPerc}}" $CONTAINER_ID | sed 's/%//')
        # 根据CPU使用率调整亲和性
        if (( $(echo "$CPU_USAGE > $THRESHOLD" | bc -l) )); then
            # 高负载:绑定到所有核心
            PID=$(docker inspect --format '{{.State.Pid}}' $CONTAINER_ID)
            taskset -p -c 0-7 $PID
            log_info "High CPU usage detected. Binding to all cores."
        else
            # 低负载:绑定到特定核心
            PID=$(docker inspect --format '{{.State.Pid}}' $CONTAINER_ID)
            taskset -p -c 0-3 $PID
            log_info "Low CPU usage. Binding to cores 0-3."
        fi
        sleep 10
    done
}

注意事项

  1. 权限要求:需要root权限或适当的cgroup权限
  2. 系统支持:需要Linux内核支持cgroup v1或v2
  3. CPU编号:CPU编号从0开始,需确认系统CPU数量
  4. 性能影响:过度绑定可能导致资源浪费或性能下降
  5. 热插拔:某些系统支持热添加CPU,注意动态调整

选择合适的CPU亲和性策略可以显著提升容器化应用在特定场景下的性能表现。

抱歉,评论功能暂时关闭!