Shell脚本如何配置容器优先级类

wen 实用脚本 2

本文目录导读:

Shell脚本如何配置容器优先级类

  1. 设置CPU优先级(nice值)
  2. 设置I/O优先级
  3. 综合配置脚本示例
  4. 使用systemd配置容器优先级
  5. 验证和监控脚本
  6. 注意事项

在Shell脚本中配置容器优先级类(通常指CPU优先级或I/O优先级),主要有以下几种方法:

设置CPU优先级(nice值)

方法1:使用nice命令

#!/bin/bash
# 启动容器并设置优先级(-20到19,数值越小优先级越高)
# 示例:以最高优先级启动Nginx容器
nice -n -20 docker run --name web \  
  -p 80:80 \
  nginx:latest
# 使用renice调整运行中容器的进程优先级
docker inspect --format='{{.State.Pid}}' container_name | xargs renice -n -20

方法2:通过dockerd配置CPU优先级

#!/bin/bash
# 启动容器时设置CPU权重(相对优先级)
docker run --name worker \
  --cpus="1.5" \                    # 限制CPU使用
  --cpu-quota=50000 \              # 设置CPU配额(微秒)
  --cpu-shares=768 \               # CPU权重(默认1024)
  --cpuset-cpus="0,1" \            # 绑定特定CPU核心
  ubuntu:latest

设置I/O优先级

方法1:使用ionice命令

#!/bin/bash
# I/O优先级类别(0-3,0最高,3最低)
# 类别:1-实时, 2-尽力, 3-空闲
ionice -c 2 -n 0 docker run --name db \
  -v /data:/var/lib/mysql \
  mysql:8.0
# 调整已有容器进程的I/O优先级
docker inspect --format='{{.State.Pid}}' db_container | \
  xargs ionice -c 2 -n 4 -p

方法2:Docker I/O限制

#!/bin/bash
# 限制容器I/O带宽
docker run --name heavy-io \
  --device-read-bps /dev/sda:10mb \      # 读取速度限制
  --device-write-bps /dev/sda:10mb \     # 写入速度限制
  --device-read-iops /dev/sda:100 \      # IOPS限制
  --device-write-iops /dev/sda:100 \
  ubuntu:latest

综合配置脚本示例

#!/bin/bash
set -e
# 容器优先级配置函数
configure_container_priority() {
    local container_name=$1
    local cpu_priority=$2           # -20 到 19
    local io_priority=$3            # 0-7
    local cpu_quota=${4:-50000}     # 默认50ms
    echo "Configuring priority for container: $container_name"
    # 获取容器PID
    container_pid=$(docker inspect --format='{{.State.Pid}}' "$container_name" 2>/dev/null)
    if [ -z "$container_pid" ] || [ "$container_pid" = "0" ]; then
        echo "Error: Container not running"
        return 1
    fi
    # 设置CPU优先级
    renice -n "$cpu_priority" -p "$container_pid"
    # 设置I/O优先级
    ionice -c 2 -n "$io_priority" -p "$container_pid"
    # 设置CPU配额(通过cgroups)
    local cgroup_path="/sys/fs/cgroup/cpu/docker/$(docker inspect --format='{{.Id}}' $container_name)"
    if [ -d "$cgroup_path" ]; then
        echo "$cpu_quota" > "$cgroup_path/cpu.cfs_quota_us"
        echo "CPU quota set to $cpu_quota microseconds"
    fi
    echo "Priority configuration complete"
}
# 启动带优先级的容器
start_priority_container() {
    local name=$1
    local image=$2
    local cpu_shares=${3:-1024}      # CPU权重
    # 启动容器时设置优先级
    docker run -d --name "$name" \
        --cpu-shares="$cpu_shares" \
        --memory="512m" \
        --memory-reservation="256m" \
        "$image" \
        sleep infinity
    # 配置进程优先级
    configure_container_priority "$name" -10 2
}
# 示例:启动不同优先级的容器
echo "Starting high priority container..."
start_priority_container "high_prio_app" "nginx:latest" 2048
echo "Starting low priority container..."
start_priority_container "low_prio_batch" "ubuntu:latest" 256
# 监控优先级
echo -e "\nContainer priority status:"
for container in "high_prio_app" "low_prio_batch"; do
    pid=$(docker inspect --format='{{.State.Pid}}' "$container")
    if [ "$pid" != "0" ]; then
        echo "Container: $container (PID: $pid)"
        echo "  CPU Priority: $(ps -o nice -p $pid --no-headers)"
        echo "  IO Priority: $(ionice -p $pid 2>/dev/null)"
    fi
done

使用systemd配置容器优先级

#!/bin/bash
# 创建systemd service文件
cat > /etc/systemd/system/container-priority@.service << 'EOF'
[Unit]
Description=Container Priority Service for %i
After=docker.service
Requires=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/set-container-priority.sh %i
ExecStop=/usr/local/bin/reset-container-priority.sh %i
[Install]
WantedBy=multi-user.target
EOF
# 创建优先级设置脚本
cat > /usr/local/bin/set-container-priority.sh << 'SETPRIORITY'
#!/bin/bash
CONTAINER_NAME=$1
# 等待容器启动
for i in {1..30}; do
    if docker inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
        break
    fi
    sleep 1
done
PID=$(docker inspect --format='{{.State.Pid}}' "$CONTAINER_NAME")
if [ "$PID" != "0" ]; then
    # 高优先级配置
    renice -n -20 -p $PID
    ionice -c 1 -p $PID
    echo "Container $CONTAINER_NAME set to high priority"
fi
SETPRIORITY
chmod +x /usr/local/bin/set-container-priority.sh

验证和监控脚本

#!/bin/bash
# 监控容器优先级状态
while true; do
    clear
    echo "=== Container Priority Monitor ==="
    echo "Time: $(date)"
    echo ""
    docker ps --format "table {{.Names}}\t{{.Status}}" | while read line; do
        container=$(echo $line | awk '{print $1}')
        if [ "$container" != "NAMES" ]; then
            pid=$(docker inspect --format='{{.State.Pid}}' "$container" 2>/dev/null)
            if [ "$pid" != "0" ] && [ -n "$pid" ]; then
                cpu_pri=$(ps -o nice -p $pid --no-headers 2>/dev/null)
                io_pri=$(ionice -p $pid 2>/dev/null)
                echo "Container: $container"
                echo "  PID: $pid"
                echo "  CPU Priority: $cpu_pri"
                echo "  IO Priority: $io_pri"
                echo "---"
            fi
        fi
    done
    sleep 5
done

注意事项

  1. 系统限制:设置负优先级(高优先级)需要root权限
  2. 资源平衡:过高优先级可能影响其他系统服务
  3. 持久化:容器重启后优先级设置会失效,需要在启动脚本中重新配置
  4. 监控优先:先建立基线监控,再调整优先级

这些方法可以根据你的具体需求组合使用,实现精细化的容器优先级管理。

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