Shell脚本如何配置容器PID限制

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置容器PID限制

  1. 使用Docker运行容器时设置PID限制
  2. 使用Podman运行容器
  3. 使用containerd/nerdctl运行容器
  4. 通过cgroup直接配置(底层方法)
  5. 完整的Shell脚本示例
  6. 监控和测试PID限制
  7. 高级配置:动态调整PID限制
  8. 注意事项

在Shell脚本中配置容器的PID限制,主要取决于你使用的容器运行时(Docker、containerd/podman等),以下是几种常见方法的实现:

使用Docker运行容器时设置PID限制

通过docker run命令参数

#!/bin/bash
# Docker运行时限制PID数量
docker run -d \
  --name my_container \
  --pids-limit 100 \  # 限制最大PID数量为100
  --memory 512m \
  --cpus 0.5 \
  nginx:latest
echo "容器已启动,PID限制:100"

在docker-compose.yml中配置

# docker-compose.yml
version: '3.8'
services:
  web:
    image: nginx:latest
    deploy:
      resources:
        limits:
          pids: 100  # 限制PID数量
    pids_limit: 100  # 或使用此语法

使用Podman运行容器

#!/bin/bash
# Podman限制PID
podman run -d \
  --name my_container \
  --pids-limit=100 \
  --memory 512m \
  nginx:latest
echo "Podman容器已启动,PID限制:100"

使用containerd/nerdctl运行容器

#!/bin/bash
# nerdctl限制PID
nerdctl run -d \
  --name my_container \
  --pids-limit 100 \
  nginx:latest

通过cgroup直接配置(底层方法)

对于更底层的控制,可以直接配置cgroup:

#!/bin/bash
# 创建容器
CONTAINER_NAME="my_container"
CONTAINER_ID=$(docker run -d --name $CONTAINER_NAME nginx:latest)
# 获取容器的cgroup路径
CGROUP_PATH=$(docker inspect --format '{{.HostConfig.CgroupParent}}' $CONTAINER_NAME)
if [ -z "$CGROUP_PATH" ]; then
    # 如果为空,使用默认路径
    CGROUP_PATH="/sys/fs/cgroup/pids/docker/$CONTAINER_ID"
fi
# 设置PID限制(例如100)
echo 100 | sudo tee "$CGROUP_PATH/pids.max"
echo "已为容器 $CONTAINER_NAME 设置PID限制:100"

完整的Shell脚本示例

#!/bin/bash
# 设置PID限制的完整脚本
LIMIT=${1:-100}  # 默认限制100个PID
IMAGE=${2:-nginx:latest}
CONTAINER_NAME="limited_container_$(date +%s)"
echo "=== 容器PID限制配置脚本 ==="
echo "PID限制值: $LIMIT"
echo "使用镜像: $IMAGE"
echo "容器名称: $CONTAINER_NAME"
# 检查Docker是否运行
if ! docker info > /dev/null 2>&1; then
    echo "错误: Docker未运行"
    exit 1
fi
# 启动容器并设置PID限制
docker run -d \
    --name "$CONTAINER_NAME" \
    --pids-limit "$LIMIT" \
    --memory 256m \
    --cpus 0.25 \
    "$IMAGE"
if [ $? -eq 0 ]; then
    echo "✓ 容器已成功启动"
    echo "容器ID: $(docker ps -q -f name=$CONTAINER_NAME)"
    echo "PID限制: $LIMIT"
    # 验证配置
    echo ""
    echo "验证PID限制配置:"
    docker inspect --format '{{.HostConfig.PidsLimit}}' "$CONTAINER_NAME"
else
    echo "✗ 容器启动失败"
    exit 1
fi
# 显示帮助信息
echo ""
echo "用法: $0 [限制数量] [镜像名称]"
echo "示例: $0 200 nginx:latest"

监控和测试PID限制

#!/bin/bash
# 测试PID限制的脚本
CONTAINER_NAME="test_container"
# 启动容器
docker run -d --name $CONTAINER_NAME --pids-limit 50 alpine sleep 3600
echo "启动进程爆炸测试..."
# 创建大量进程测试限制
docker exec $CONTAINER_NAME sh -c '
    echo "尝试创建大量进程..."
    for i in $(seq 1 100); do
        (while true; do sleep 3600; done) &
        if [ $? -ne 0 ]; then
            echo "进程创建失败,达到限制"
            break
        fi
    done
    wait
' &
sleep 5
# 监控状态
echo "当前容器的进程数:"
docker top $CONTAINER_NAME | wc -l
# 清理
echo "清理测试容器..."
docker stop $CONTAINER_NAME
docker rm $CONTAINER_NAME

高级配置:动态调整PID限制

#!/bin/bash
# 动态调整已有容器的PID限制
adjust_pid_limit() {
    local container_name=$1
    local new_limit=$2
    echo "正在调整容器 $container_name 的PID限制为 $new_limit"
    # 方法1:使用docker update
    docker update --pids-limit "$new_limit" "$container_name"
    # 方法2:直接修改cgroup(需要root权限)
    # local cgroup_path=$(find /sys/fs/cgroup/pids -name "*$container_name*" 2>/dev/null | head -1)
    # if [ -n "$cgroup_path" ]; then
    #     echo $new_limit | sudo tee "$cgroup_path/pids.max"
    # fi
    echo "调整完成"
}
# 使用示例
# adjust_pid_limit "my_container" 200

注意事项

  1. PID限制值:Linux系统默认每个进程的PID范围是0-32768,设置过小可能导致服务无法正常启动
  2. 系统限制:容器的PID限制不能超过主机的PID最大值(/proc/sys/kernel/pid_max
  3. 兼容性:确保Docker版本支持--pids-limit参数(Docker 1.11+支持)
  4. 容器类型:某些基础镜像(如基于busybox)可能不支持子进程管理

选择哪种方法取决于你的具体需求和容器运行时环境,通常推荐使用Docker/Podman提供的参数直接配置,既简单又可靠。

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