脚本中Sysctl内核参数如何调

wen 实用脚本 12

本文目录导读:

脚本中Sysctl内核参数如何调

  1. 核心原则
  2. 方法一:Shell 脚本(最常用)
  3. 方法二:Ansible 自动化(适用于大规模运维)
  4. 方法三:Python 脚本
  5. 常见内核参数调优建议(脚本中常用)
  6. 注意事项

在脚本中调优 sysctl 内核参数,通常有以下几种常用方法,最佳实践取决于你的操作系统(Linux)和脚本语言(Shell、Python、Ansible 等)。

核心原则

  • 临时生效sysctl -w <参数>=<值> (重启后失效)
  • 永久生效:修改 /etc/sysctl.conf/etc/sysctl.d/ 下的 .conf 文件
  • 立即加载sysctl -p (读取配置文件并应用)
  • 查看当前值sysctl <参数名>cat /proc/sys/...

Shell 脚本(最常用)

适用于快速部署、自动化运维脚本(如 bashsh)。

直接设置(临时 + 永久)

#!/bin/bash
# ----- 定义需要设置的参数(建议按功能分组) -----
# 网络优化
NET_CORE_PARAMS=(
    "net.core.somaxconn=1024"
    "net.core.rmem_max=134217728"
    "net.core.wmem_max=134217728"
)
# 内存/虚拟内存
VM_PARAMS=(
    "vm.swappiness=10"
    "vm.dirty_ratio=30"
    "vm.dirty_background_ratio=5"
)
# 安全/内核常规
KERNEL_PARAMS=(
    "kernel.pid_max=65535"
    "net.ipv4.tcp_tw_reuse=1"
    "net.ipv4.ip_local_port_range=1024 65000"
)
# ----- 执行函数 -----
set_sysctl() {
    local param=$1
    local param_name="${param%%=*}"   # 提取参数名(等号左边)
    local param_value="${param#*=}"   # 提取参数值(等号右边)
    echo "设置: $param_name = $param_value"
    # 1. 临时生效(立即生效)
    sysctl -w "$param" 2>/dev/null || {
        echo "警告: 临时设置 $param_name 失败"
        return 1
    }
    # 2. 永久生效(写入 /etc/sysctl.d/ 下单独文件,避免冲突)
    local config_file="/etc/sysctl.d/99-custom-params.conf"
    # 如果不希望重复写入,可以先检查是否已经存在
    if grep -q "^${param_name}\s*=" "$config_file" 2>/dev/null; then
        # 替换已有行
        sed -i "s|^${param_name}\s*=.*|$param|" "$config_file"
    else
        # 追加新行
        echo "$param" >> "$config_file"
    fi
}
# ----- 主流程 -----
echo "开始设置内核参数..."
# 合并所有参数并遍历设置
for param_group in "NET_CORE_PARAMS[@]" "VM_PARAMS[@]" "KERNEL_PARAMS[@]"; do
    for param in "${!param_group}"; do
        set_sysctl "$param"
    done
done
echo "全部设置完成。"
# 可选:重新加载配置文件以确保所有文件都已应用
sysctl --system  # systemd 系统推荐,会加载所有 /etc/sysctl.d/ 和 /etc/sysctl.conf

安全增强:备份 + 检查

# 备份当前 /etc/sysctl.conf
cp /etc/sysctl.conf /etc/sysctl.conf.backup.$(date +%Y%m%d)
# 写入前检查值是否合理(防止错误配置导致系统无法启动)
check_value() {
    local param=$1
    if [[ "$param" =~ ^net\.ipv4\.ip_local_port_range ]]; then
        local min=$(echo "$param" | awk '{print $2}')
        local max=$(echo "$param" | awk '{print $3}')
        if [ "$min" -ge "$max" ]; then
            echo "错误: ip_local_port_range 最小值($min)必须小于最大值($max)"
            exit 1
        fi
    fi
}

Ansible 自动化(适用于大规模运维)

如果使用 Ansible,可以利用 sysctl 模块,这是最推荐的幂等方式(重复执行不会出错,只会确保参数正确)。

---
- name: 系统内核参数优化
  hosts: all
  become: yes
  vars:
    # 定义需要的参数
    sysctl_network:
      net.core.somaxconn: 1024
      net.core.rmem_max: 134217728
      net.core.wmem_max: 134217728
      net.ipv4.tcp_tw_reuse: 1
      net.ipv4.ip_local_port_range: "1024 65000"
    sysctl_vm:
      vm.swappiness: 10
      vm.dirty_ratio: 30
    sysctl_kernel:
      kernel.pid_max: 65535
      # 禁用 IPv6 重定向(安全)
      net.ipv6.conf.all.accept_redirects: 0
  tasks:
    - name: 应用 sysctl 参数
      ansible.posix.sysctl:
        name: "{{ item.key }}"
        value: "{{ item.value }}"
        state: present          # 确保参数存在
        reload: yes             # 立即生效
        sysctl_set: yes         # 同时写入 sysctl.d 永久生效
        sysctl_file: "/etc/sysctl.d/99-custom-params.conf"  # 写入单独文件
      loop: "{{ sysctl_network | dict2items + sysctl_vm | dict2items + sysctl_kernel | dict2items }}"
      # 注意: 参数值类型:字符串用引号,数字不用(Ansible 会自动处理)
    - name: 验证设置 (可选)
      command: sysctl "{{ item.key }}"
      loop: "{{ sysctl_network | dict2items + sysctl_vm | dict2items + sysctl_kernel | dict2items }}"
      register: output
    - debug:
        msg: "{{ output.results | map(attribute='stdout_lines') | list }}"

Python 脚本

#!/usr/bin/env python3
import subprocess
import os
import sys
def set_sysctl(param_name, param_value, make_permanent=True):
    """
    设置内核参数
    :param param_name: 参数名称,如 'net.core.somaxconn'
    :param param_value: 参数值,如 '1024'
    :param make_permanent: 是否写入配置文件永久生效
    """
    # 1. 临时生效
    try:
        subprocess.run(['sysctl', '-w', f'{param_name}={param_value}'], check=True,
                       capture_output=True, text=True)
        print(f"临时生效: {param_name} = {param_value}")
    except subprocess.CalledProcessError as e:
        print(f"错误: 设置 {param_name} 失败 - {e.stderr.strip()}", file=sys.stderr)
        return False
    # 2. 永久生效(追加或替换)
    if make_permanent:
        config_dir = '/etc/sysctl.d'
        config_file = os.path.join(config_dir, '99-custom-params.conf')
        # 如果文件不存在则创建,存在则检查是否已有该参数
        if not os.path.exists(config_file):
            with open(config_file, 'w') as f:
                f.write(f'{param_name} = {param_value}\n')
            print(f"创建文件并写入: {config_file}")
        else:
            with open(config_file, 'r') as f:
                lines = f.readlines()
            param_exists = False
            for i, line in enumerate(lines):
                if line.strip().startswith(param_name):
                    lines[i] = f'{param_name} = {param_value}\n'
                    param_exists = True
                    break
            with open(config_file, 'w') as f:
                f.writelines(lines)
            if param_exists:
                print(f"替换已有参数: {param_name} = {param_value}")
            else:
                # 追加到文件末尾
                with open(config_file, 'a') as f:
                    f.write(f'{param_name} = {param_value}\n')
                print(f"追加参数: {param_name} = {param_value}")
        # 重新加载配置文件(确保永久设置也立即生效)
        subprocess.run(['sysctl', '--system'], check=True)
        print("重新加载所有 sysctl 配置文件")
    return True
# 使用示例
if __name__ == '__main__':
    params = {
        'net.ipv4.tcp_tw_reuse': '1',
        'vm.swappiness': '10',
        'kernel.pid_max': '65535',
    }
    for name, value in params.items():
        set_sysctl(name, value, make_permanent=True)

常见内核参数调优建议(脚本中常用)

参数 建议值 说明
网络
net.core.somaxconn 1024 ~ 65535 高并发连接队列长度
net.ipv4.tcp_tw_reuse 1 复用 TIME_WAIT 状态连接(高并发场景)
net.ipv4.ip_local_port_range "1024 65000" 本地端口范围,扩大后支持更多连接
net.core.rmem_max / wmem_max 134217728(128MB) 增加网络缓冲区(大流量场景)
内存
vm.swappiness 10 降低使用交换分区的倾向(服务器建议 10~30)
vm.dirty_ratio 30% 写缓存占内存上限
vm.dirty_background_ratio 5% 后台异步写回阈值
文件系统
fs.file-max 65535~1000000 系统最大文件句柄数
fs.nr_open 1048576 进程单进程最大文件句柄(= file-max*2)
安全
net.ipv4.conf.all.rp_filter 1 开启反向路径过滤(防 IP 欺骗)
kernel.randomize_va_space 2 ASLR 保护(安全建议)

注意事项

  1. 测试环境先试sysctl -a | grep <参数> 先查看当前值。
  2. 一致性检查:如果使用 sysctl.d/ 下的多个文件,注意优先级(按字母顺序加载,后加载的会覆盖先加载的)。
  3. 重启验证:永久配置写入后,最好 sysctl --system 立即生效,然后重启服务器验证配置是否持久。
  4. 不要使用 sysctl -w 写入 /proc/sys 而不写文件:这样重启会丢失。
  5. 避免写错vm.swappiness 写成 vm.swapiness,不会报错但不会生效。

根据你的使用场景,选择 Shell 脚本(灵活、部署快)、Ansible(大规模、幂等)或 Python(程序化控制)。

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