本文目录导读:

在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
}
注意事项
- 权限要求:需要root权限或适当的cgroup权限
- 系统支持:需要Linux内核支持cgroup v1或v2
- CPU编号:CPU编号从0开始,需确认系统CPU数量
- 性能影响:过度绑定可能导致资源浪费或性能下降
- 热插拔:某些系统支持热添加CPU,注意动态调整
选择合适的CPU亲和性策略可以显著提升容器化应用在特定场景下的性能表现。