Shell脚本如何配置容器磁盘IO限制

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置容器磁盘IO限制

  1. Docker容器磁盘IO限制
  2. Podman容器
  3. 高级IO限制配置脚本
  4. 配置示例文件 (config.csv)
  5. 使用cgroups直接配置(高级)
  6. 验证IO限制
  7. 注意事项

在Shell脚本中配置容器磁盘IO限制,主要取决于你使用的容器运行时环境,以下是针对DockerPodman的常用方法:

Docker容器磁盘IO限制

基本命令格式

# 限制读BPS
--device-read-bps=/dev/sda:1mb
# 限制写BPS  
--device-write-bps=/dev/sda:1mb
# 限制读IOPS
--device-read-iops=/dev/sda:100
# 限制写IOPS
--device-write-iops=/dev/sda:100

Shell脚本示例

#!/bin/bash
# Docker容器限制IO示例
docker run -d \
  --name io-limited-container \
  --device-read-bps=/dev/sda:10mb \
  --device-write-bps=/dev/sda:5mb \
  --device-read-iops=/dev/sda:1000 \
  --device-write-iops=/dev/sda:500 \
  nginx:latest

动态调整IO限制

#!/bin/bash
# 更新已有容器的IO限制
update_container_io() {
    local container_name=$1
    local device="/dev/sda"
    # 更新读BPS限制
    docker update --device-read-bps=${device}:10mb ${container_name}
    # 更新写BPS限制
    docker update --device-write-bps=${device}:5mb ${container_name}
}
# 获取当前容器IO限制
get_container_io() {
    docker inspect "$1" --format '{{json .HostConfig.BlkioDeviceReadBps}}'
}

Podman容器

#!/bin/bash
# Podman IO限制(语法与Docker类似)
podman run -d \
  --name podman-limited \
  --device-read-bps=/dev/sda:10mb \
  --device-write-bps=/dev/sda:5mb \
  nginx:latest

高级IO限制配置脚本

#!/bin/bash
set -e
# 配置容器IO限制函数
configure_container_io() {
    local container_name="$1"
    local device="${2:-/dev/sda}"
    local read_bps="${3:-10mb}"
    local write_bps="${4:-5mb}"
    local read_iops="${5:-1000}"
    local write_iops="${6:-500}"
    echo "正在配置容器 ${container_name} 的IO限制..."
    # 检查容器是否存在
    if ! docker ps -a --format '{{.Names}}' | grep -q "^${container_name}$"; then
        echo "错误:容器 ${container_name} 不存在"
        return 1
    fi
    # 应用IO限制
    docker update \
        --device-read-bps="${device}:${read_bps}" \
        --device-write-bps="${device}:${write_bps}" \
        --device-read-iops="${device}:${read_iops}" \
        --device-write-iops="${device}:${write_iops}" \
        "${container_name}"
    echo "IO限制配置完成!"
}
# 批量配置多个容器
batch_configure_io() {
    local config_file="$1"
    while IFS=, read -r container device read_bps write_bps read_iops write_iops; do
        # 跳过注释行和空行
        [[ "$container" =~ ^#.*$ || -z "$container" ]] && continue
        configure_container_io "$container" "$device" "$read_bps" "$write_bps" "$read_iops" "$write_iops"
    done < "$config_file"
}
# 创建容器时带IO限制
create_container_with_io_limit() {
    local image="$1"
    local container_name="$2"
    local device="${3:-/dev/sda}"
    docker run -d \
        --name "${container_name}" \
        --device-read-bps="${device}:10mb" \
        --device-write-bps="${device}:5mb" \
        --device-read-iops="${device}:1000" \
        --device-write-iops="${device}:500" \
        "${image}"
}
# 监控容器的IO使用情况
monitor_container_io() {
    local container_name="$1"
    echo "监控容器 ${container_name} 的IO使用情况..."
    docker stats "${container_name}" --no-stream | head -5
}
# 主函数
main() {
    local action="$1"
    shift
    case "$action" in
        create)
            create_container_with_io_limit "$@"
            ;;
        update)
            configure_container_io "$@"
            ;;
        batch)
            batch_configure_io "$1"
            ;;
        monitor)
            monitor_container_io "$1"
            ;;
        *)
            echo "使用方法: $0 {create|update|batch|monitor} [参数...]"
            echo "示例:"
            echo "  $0 create nginx:latest my-nginx"
            echo "  $0 update my-nginx /dev/sda 20mb 10mb 2000 1000"
            echo "  $0 batch /path/to/config.csv"
            echo "  $0 monitor my-nginx"
            exit 1
            ;;
    esac
}
# 执行主函数
main "$@"

配置示例文件 (config.csv)

# 格式: 容器名,设备,读BPS,写BPS,读IOPS,写IOPS
web-app,/dev/sda,10mb,5mb,1000,500
db-server,/dev/sdb,50mb,20mb,5000,2000
cache-service,/dev/sda,20mb,10mb,2000,1000

使用cgroups直接配置(高级)

对于更精细的控制,可以直接使用cgroups:

#!/bin/bash
# 使用cgroups v2配置IO限制
configure_cgroup_io() {
    local container_id="$1"
    local read_mbps="${2:-10}"
    local write_mbps="${3:-5}"
    # 获取容器cgroup路径
    local cgroup_path=$(find /sys/fs/cgroup/ -name "*${container_id}*" -type d | head -1)
    if [ -z "$cgroup_path" ]; then
        echo "未找到容器的cgroup路径"
        return 1
    fi
    # 设置IO限制(cgroup v2)
    echo "${read_mbps}:${write_mbps}" > "${cgroup_path}/io.max"
    echo "Cgroup IO限制已配置:读=${read_mbps}MB/s, 写=${write_mbps}MB/s"
}

验证IO限制

#!/bin/bash
# 测试容器的IO性能
test_container_io() {
    local container_name="$1"
    echo "测试容器 ${container_name} 的IO性能..."
    # 使用dd命令测试
    docker exec "${container_name}" sh -c '
        echo "写测试:"
        dd if=/dev/zero of=/tmp/test bs=1M count=100 oflag=direct 2>&1 | tail -1
        echo "读测试:"
        dd if=/tmp/test of=/dev/null bs=1M count=100 iflag=direct 2>&1 | tail -1
        # 清理
        rm -f /tmp/test
    '
}

注意事项

  1. 设备路径:确保使用正确的设备名(/dev/sda/dev/sdb等)
  2. 块设备:IO限制只对块设备有效,不适用于文件系统
  3. 版本要求:需要Docker 1.7+或Podman 1.0+
  4. 权限:需要root权限或docker组权限

选择合适的IO限制策略,可以根据你的业务需求调整容器的资源使用,避免某个容器过度消耗磁盘IO影响其他服务。

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