Skip to content

필사 모드: Linux 커널 파라미터 튜닝 가이드: sysctl + Boot Params, 안전한 변경과 롤백

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

들어가며

커널 파라미터 튜닝은 **서버 성능과 안정성에 직접적 영향**을 미치는 작업이다. 잘못된 값 하나가 OOM Kill을 유발하거나, 네트워크 연결을 끊거나, 보안 취약점을 만들 수 있다.

이 글에서는 **sysctl(런타임 파라미터)**과 **부트 파라미터(커널 커맨드라인)**를 구분하여 각 항목의 의미·권장값·적용 방법을 정리하고, 프로덕션 환경에서의 **안전한 변경 절차와 롤백 전략**을 제시한다.

1. 커널 파라미터의 두 가지 경로

| 구분 | sysctl (런타임) | Boot Params (부트 시) |

| --------- | ------------------------ | -------------------------------- |

| 적용 시점 | 즉시 (재부팅 불필요) | 다음 부팅 시 |

| 설정 파일 | `/etc/sysctl.d/*.conf` | `/etc/default/grub` → `grub.cfg` |

| 확인 명령 | `sysctl <param>` | `cat /proc/cmdline` |

| 영구 적용 | `sysctl.d` + `sysctl -p` | `grub2-mkconfig` / `update-grub` |

| 롤백 | 이전 값 복원 | GRUB 이전 엔트리 선택 |

| 범위 | `/proc/sys/` 하위 항목 | 커널 부팅 옵션 전체 |

2. 안전한 변경 절차 (프로덕션 프로토콜)

2.1 변경 전 체크리스트

#!/usr/bin/env bash

pre-tuning-check.sh - 튜닝 전 상태 백업

BACKUP_DIR="/root/kernel-tuning-backup/$(date +%Y%m%d-%H%M%S)"

mkdir -p "$BACKUP_DIR"

1. 현재 sysctl 전체 덤프

sysctl -a > "$BACKUP_DIR/sysctl-before.txt" 2>/dev/null

2. 현재 부트 파라미터

cat /proc/cmdline > "$BACKUP_DIR/cmdline-before.txt"

3. GRUB 설정 백업

cp /etc/default/grub "$BACKUP_DIR/grub-before"

[[ -d /etc/sysctl.d ]] && cp -r /etc/sysctl.d "$BACKUP_DIR/sysctl.d-before"

4. 시스템 상태 스냅샷

free -h > "$BACKUP_DIR/memory-before.txt"

ss -s > "$BACKUP_DIR/socket-stats-before.txt"

vmstat 1 5 > "$BACKUP_DIR/vmstat-before.txt"

cat /proc/net/sockstat > "$BACKUP_DIR/sockstat-before.txt"

echo "백업 완료: $BACKUP_DIR"

2.2 변경 단계

1. 스테이징 환경에서 테스트

2. Canary 서버 1대에 적용 → 모니터링 (최소 24시간)

3. 문제 없으면 그룹 단위 Rolling 적용

4. 적용 후 메트릭 비교 (before vs after)

2.3 롤백 절차

sysctl 롤백 - 백업에서 특정 파라미터 복원

PARAM="net.core.somaxconn"

OLD_VALUE=$(grep "^${PARAM}" /root/kernel-tuning-backup/latest/sysctl-before.txt | awk '{print $3}')

sysctl -w "${PARAM}=${OLD_VALUE}"

전체 sysctl 롤백

while IFS='= ' read -r key value; do

sysctl -w "${key}=${value}" 2>/dev/null

done < /root/kernel-tuning-backup/latest/sysctl-before.txt

부트 파라미터 롤백 - GRUB 이전 설정 복원

cp /root/kernel-tuning-backup/latest/grub-before /etc/default/grub

grub2-mkconfig -o /boot/grub2/grub.cfg # RHEL

update-grub # Ubuntu

3. 네트워크 튜닝

3.1 TCP 연결 관리

/etc/sysctl.d/10-network.conf

TCP 백로그 - 고트래픽 서버 필수

net.core.somaxconn = 65535

net.ipv4.tcp_max_syn_backlog = 65535

TCP 소켓 버퍼 (바이트)

min / default / max

net.core.rmem_default = 262144

net.core.rmem_max = 16777216

net.core.wmem_default = 262144

net.core.wmem_max = 16777216

net.ipv4.tcp_rmem = 4096 262144 16777216

net.ipv4.tcp_wmem = 4096 262144 16777216

TCP 혼잡 제어

net.ipv4.tcp_congestion_control = bbr

net.core.default_qdisc = fq

TIME_WAIT 관리

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_fin_timeout = 15

net.ipv4.tcp_max_tw_buckets = 2000000

Keepalive (로드밸런서 뒤 서버)

net.ipv4.tcp_keepalive_time = 60

net.ipv4.tcp_keepalive_intvl = 10

net.ipv4.tcp_keepalive_probes = 6

3.2 네트워크 파라미터 설명표

| 파라미터 | 기본값 | 권장값 | 설명 |

| --------------------------------- | ----------- | ---------- | ----------------------- |

| `net.core.somaxconn` | 4096 | 65535 | listen() 백로그 최대값 |

| `net.ipv4.tcp_max_syn_backlog` | 1024 | 65535 | SYN 큐 최대 크기 |

| `net.core.rmem_max` | 212992 | 16MB | 수신 소켓 버퍼 최대 |

| `net.core.wmem_max` | 212992 | 16MB | 송신 소켓 버퍼 최대 |

| `net.ipv4.tcp_congestion_control` | cubic | bbr | 혼잡 제어 알고리즘 |

| `net.ipv4.tcp_tw_reuse` | 0(2) | 1 | TIME_WAIT 소켓 재사용 |

| `net.ipv4.tcp_fin_timeout` | 60 | 15 | FIN-WAIT-2 타임아웃 |

| `net.ipv4.tcp_keepalive_time` | 7200 | 60 | Keepalive 시작 시간(초) |

| `net.ipv4.ip_local_port_range` | 32768-60999 | 1024-65535 | 아웃바운드 포트 범위 |

3.3 BBR 활성화

BBR 커널 모듈 로드

modprobe tcp_bbr

echo "tcp_bbr" >> /etc/modules-load.d/bbr.conf

sysctl 적용

sysctl -w net.core.default_qdisc=fq

sysctl -w net.ipv4.tcp_congestion_control=bbr

확인

sysctl net.ipv4.tcp_congestion_control

net.ipv4.tcp_congestion_control = bbr

> **BBR vs CUBIC**: BBR은 패킷 손실 기반이 아닌 **대역폭 추정 기반** 혼잡 제어로, 특히 장거리·고지연 네트워크에서 성능이 크게 향상된다.

4. 메모리 튜닝

4.1 가상 메모리 관리

/etc/sysctl.d/20-memory.conf

Swap 사용 성향 (0=최소, 100=적극)

DB 서버: 1-10, 웹 서버: 10-30

vm.swappiness = 10

Dirty page 비율 - 디스크 쓰기 지연

vm.dirty_ratio = 40 # 전체 메모리 대비 dirty page 최대 비율

vm.dirty_background_ratio = 10 # 백그라운드 flush 시작 비율

OOM 관련

vm.overcommit_memory = 0 # 0=기본(휴리스틱), 1=항상허용, 2=제한

vm.panic_on_oom = 0 # OOM 시 패닉 여부 (0=OOM Killer 실행)

최대 메모리 맵 영역 (Elasticsearch, MongoDB 등)

vm.max_map_count = 262144

파일시스템 캐시 해제 (긴급 시에만)

echo 3 > /proc/sys/vm/drop_caches # 1=pagecache, 2=dentries+inodes, 3=all

4.2 메모리 파라미터 가이드

| 파라미터 | DB 서버 | 웹/API 서버 | ML 워크로드 |

| --------------------------- | ------- | ----------- | ----------- |

| `vm.swappiness` | 1~5 | 10~30 | 1 |

| `vm.dirty_ratio` | 40 | 20 | 40 |

| `vm.dirty_background_ratio` | 10 | 5 | 10 |

| `vm.overcommit_memory` | 0 | 0 | 1 |

| `vm.max_map_count` | 262144 | 65530 | 262144 |

4.3 Huge Pages

Transparent Huge Pages (THP) - DB에서는 비활성화 권장

부트 파라미터로 설정

GRUB_CMDLINE_LINUX에 추가:

transparent_hugepage=never

런타임 확인·변경

cat /sys/kernel/mm/transparent_hugepage/enabled

echo never > /sys/kernel/mm/transparent_hugepage/enabled

Static Huge Pages (Oracle DB, DPDK 등)

/etc/sysctl.d/20-memory.conf

vm.nr_hugepages = 1024 # 2MB * 1024 = 2GB

확인

grep -i huge /proc/meminfo

5. 파일시스템·I/O 튜닝

/etc/sysctl.d/30-fs.conf

최대 열린 파일 수 (시스템 전체)

fs.file-max = 2097152

inotify 감시 제한 (IDE, 파일 감시 서비스)

fs.inotify.max_user_watches = 524288

fs.inotify.max_user_instances = 8192

AIO (비동기 I/O) 최대 요청 수

fs.aio-max-nr = 1048576

ulimit 연동

/etc/security/limits.d/99-app.conf

sysctl의 fs.file-max 와 함께 설정해야 효과

* soft nofile 1048576

* hard nofile 1048576

* soft nproc 65535

* hard nproc 65535

* soft memlock unlimited

* hard memlock unlimited

I/O 스케줄러 설정

현재 스케줄러 확인

cat /sys/block/sda/queue/scheduler

SSD: none 또는 mq-deadline 권장

echo mq-deadline > /sys/block/sda/queue/scheduler

영구 설정 (udev rule)

/etc/udev/rules.d/60-scheduler.rules

ACTION=="add|change", KERNEL=="sd*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="mq-deadline"

ACTION=="add|change", KERNEL=="sd*", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"

| 스케줄러 | 디스크 타입 | 특징 |

| ------------- | ----------- | ------------------- |

| `none` (noop) | NVMe SSD | 오버헤드 최소 |

| `mq-deadline` | SATA SSD | 지연 시간 보장 |

| `bfq` | HDD | 공정 대역폭 분배 |

| `kyber` | 고속 SSD | 읽기/쓰기 지연 제어 |

6. 보안 관련 파라미터

/etc/sysctl.d/40-security.conf

ASLR (Address Space Layout Randomization)

kernel.randomize_va_space = 2 # 0=끔, 1=부분, 2=완전

SysRq 제한 (긴급 복구용만 허용)

kernel.sysrq = 176 # 비트마스크: sync + remount-ro + reboot

코어 덤프 제한

kernel.core_pattern = |/bin/false

fs.suid_dumpable = 0

dmesg 접근 제한

kernel.dmesg_restrict = 1

커널 포인터 숨김

kernel.kptr_restrict = 2

BPF 제한 (비특권 사용자)

kernel.unprivileged_bpf_disabled = 1

네트워크 보안

net.ipv4.conf.all.rp_filter = 1 # Reverse Path Filtering

net.ipv4.conf.all.accept_redirects = 0 # ICMP 리다이렉트 거부

net.ipv4.conf.all.send_redirects = 0

net.ipv6.conf.all.accept_redirects = 0

net.ipv4.conf.all.accept_source_route = 0 # Source Routing 거부

net.ipv4.conf.all.log_martians = 1 # 의심 패킷 로깅

net.ipv4.icmp_echo_ignore_broadcasts = 1 # Smurf 공격 방어

IP 포워딩 (라우터/컨테이너 호스트가 아니면 비활성)

net.ipv4.ip_forward = 0

컨테이너 호스트일 경우:

net.ipv4.ip_forward = 1

보안 파라미터 체크리스트

| 파라미터 | 보안 권장값 | CIS Benchmark | 비고 |

| ------------------------------------ | ----------- | ------------- | ---------------------- |

| `kernel.randomize_va_space` | 2 | 필수 | ASLR 완전 활성화 |

| `kernel.dmesg_restrict` | 1 | 권장 | 일반 사용자 dmesg 차단 |

| `kernel.kptr_restrict` | 2 | 권장 | 커널 주소 노출 방지 |

| `net.ipv4.conf.all.rp_filter` | 1 | 필수 | IP 스푸핑 방지 |

| `net.ipv4.conf.all.accept_redirects` | 0 | 필수 | MITM 방지 |

| `net.ipv4.conf.all.log_martians` | 1 | 권장 | 비정상 패킷 감사 |

| `fs.suid_dumpable` | 0 | 필수 | SUID 코어덤프 방지 |

7. 부트 파라미터 (Kernel Command Line)

7.1 설정 방법

현재 부트 파라미터 확인

cat /proc/cmdline

RHEL / Rocky

vi /etc/default/grub

GRUB_CMDLINE_LINUX="... 추가할_파라미터"

grub2-mkconfig -o /boot/grub2/grub.cfg

Ubuntu

vi /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="... 추가할_파라미터"

update-grub

7.2 주요 부트 파라미터

| 파라미터 | 값 | 용도 |

| ---------------------------- | ------------------------ | -------------------------------- |

| `transparent_hugepage=never` | never / always / madvise | DB 서버 THP 비활성화 |

| `mitigations=auto` | off / auto / auto,nosmt | CPU 취약점 완화 제어 |

| `numa_balancing=disable` | disable / enable | NUMA 자동 밸런싱 |

| `isolcpus=2-7` | CPU 목록 | 특정 CPU를 스케줄러에서 격리 |

| `nohz_full=2-7` | CPU 목록 | Tick-less 모드 (실시간 워크로드) |

| `intel_iommu=on` | on / off | IOMMU 활성화 (SR-IOV, VFIO) |

| `iommu=pt` | pt / off | IOMMU pass-through |

| `default_hugepagesz=1G` | 2M / 1G | 기본 Huge Page 크기 |

| `hugepagesz=1G hugepages=16` | 크기 + 개수 | 1GB Huge Page 할당 |

| `crashkernel=256M` | 크기 | kdump 메모리 예약 |

| `audit=1` | 0 / 1 | 커널 감사 로그 |

7.3 CPU 취약점 완화 vs 성능

현재 적용된 완화 목록 확인

grep -r . /sys/devices/system/cpu/vulnerabilities/ 2>/dev/null

완화 비활성화 (벤치마크·격리 환경에서만!)

GRUB_CMDLINE_LINUX에 추가:

mitigations=off

성능 영향 (워크로드에 따라 다름)

mitigations=auto: 시스콜 집약 워크로드에서 5~30% 오버헤드

mitigations=off: 보안 위험 - 프로덕션 비권장

> **주의**: `mitigations=off`는 Spectre/Meltdown/MDS 등의 보안 완화를 모두 비활성화한다. **격리된 벤치마크 환경**에서만 사용하고, 프로덕션에서는 절대 사용하지 마라.

8. 워크로드별 튜닝 프로파일

8.1 웹 서버 / API 서버

/etc/sysctl.d/99-web-server.conf

네트워크

net.core.somaxconn = 65535

net.ipv4.tcp_max_syn_backlog = 65535

net.ipv4.ip_local_port_range = 1024 65535

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_fin_timeout = 15

net.ipv4.tcp_keepalive_time = 60

net.ipv4.tcp_keepalive_intvl = 10

net.ipv4.tcp_keepalive_probes = 6

net.ipv4.tcp_congestion_control = bbr

net.core.default_qdisc = fq

net.core.rmem_max = 16777216

net.core.wmem_max = 16777216

파일

fs.file-max = 2097152

메모리

vm.swappiness = 10

8.2 데이터베이스 서버

/etc/sysctl.d/99-database.conf

메모리

vm.swappiness = 1

vm.dirty_ratio = 40

vm.dirty_background_ratio = 10

vm.overcommit_memory = 0

vm.max_map_count = 262144

파일

fs.file-max = 2097152

fs.aio-max-nr = 1048576

네트워크 (내부 통신 위주)

net.core.somaxconn = 65535

net.ipv4.tcp_keepalive_time = 60

Huge Pages (PostgreSQL, Oracle 등)

vm.nr_hugepages 계산: shared_buffers / 2MB + 약간의 여유

예: shared_buffers=8GB → vm.nr_hugepages = 4200

vm.nr_hugepages = 4200

부트 파라미터:

transparent_hugepage=never

8.3 컨테이너 호스트 (Docker/K8s)

/etc/sysctl.d/99-container-host.conf

IP 포워딩 필수

net.ipv4.ip_forward = 1

net.bridge.bridge-nf-call-iptables = 1

net.bridge.bridge-nf-call-ip6tables = 1

네트워크

net.core.somaxconn = 65535

net.ipv4.ip_local_port_range = 1024 65535

net.netfilter.nf_conntrack_max = 1048576

inotify (Pod 다수 실행 시)

fs.inotify.max_user_watches = 524288

fs.inotify.max_user_instances = 8192

PID 제한

kernel.pid_max = 4194304

파일

fs.file-max = 2097152

9. 자동화와 검증

Ansible로 sysctl 관리

roles/sysctl/tasks/main.yml

- name: Apply sysctl parameters

ansible.posix.sysctl:

name: "{{ item.key }}"

value: "{{ item.value }}"

sysctl_file: /etc/sysctl.d/99-tuning.conf

reload: true

state: present

loop: "{{ sysctl_params | dict2items }}"

roles/sysctl/defaults/main.yml

sysctl_params:

net.core.somaxconn: 65535

net.ipv4.tcp_max_syn_backlog: 65535

vm.swappiness: 10

fs.file-max: 2097152

적용 후 검증 스크립트

#!/usr/bin/env bash

verify-tuning.sh - 튜닝 값 검증

declare -A EXPECTED=(

["net.core.somaxconn"]="65535"

["net.ipv4.tcp_congestion_control"]="bbr"

["vm.swappiness"]="10"

["fs.file-max"]="2097152"

)

FAILED=0

for param in "${!EXPECTED[@]}"; do

actual=$(sysctl -n "$param" 2>/dev/null)

expected="${EXPECTED[$param]}"

if [[ "$actual" != "$expected" ]]; then

echo "FAIL: $param = $actual (expected: $expected)"

(( FAILED++ ))

else

echo "OK: $param = $actual"

fi

done

echo "---"

if (( FAILED > 0 )); then

echo "검증 실패: ${FAILED}건"

exit 1

else

echo "모든 파라미터 검증 통과"

fi

10. 트러블슈팅

| 증상 | 확인 명령 | 관련 파라미터 |

| ---------------------------------- | -------------------------------------------------------------------- | --------------------------------------- |

| "Too many open files" | `ulimit -n`, `sysctl fs.file-max` | `fs.file-max`, limits.conf |

| "Connection refused" (백로그 초과) | `ss -lnt`, `netstat -s \| grep overflow` | `net.core.somaxconn` |

| TIME_WAIT 폭증 | `ss -s` | `tcp_tw_reuse`, `tcp_fin_timeout` |

| OOM Kill 빈발 | `dmesg \| grep -i oom`, `/proc/meminfo` | `vm.swappiness`, `vm.overcommit_memory` |

| 높은 I/O wait | `iostat -x 1`, `vmstat 1` | `vm.dirty_ratio`, I/O 스케줄러 |

| "Cannot allocate memory" (mmap) | `sysctl vm.max_map_count` | `vm.max_map_count` |

| nf_conntrack 테이블 포화 | `dmesg \| grep conntrack`, `sysctl net.netfilter.nf_conntrack_count` | `nf_conntrack_max` |

마무리

커널 파라미터 튜닝의 핵심 원칙을 정리한다.

1. **측정 먼저, 튜닝 나중**: 병목이 확인되지 않은 상태에서 값을 변경하지 마라.

2. **한 번에 하나씩**: 여러 파라미터를 동시에 변경하면 효과를 분리할 수 없다.

3. **반드시 백업**: 변경 전 현재 값을 기록하라. 롤백 경로 없는 변경은 하지 마라.

4. **Canary 적용**: 전체 서버에 한꺼번에 적용하지 말고 1~2대에서 먼저 검증하라.

5. **문서화**: 왜 이 값으로 변경했는지, 어떤 효과를 확인했는지 기록하라.

올바른 튜닝은 서버 성능을 극적으로 개선할 수 있지만, 잘못된 튜닝은 장애의 직접 원인이 된다. 항상 **안전하게, 점진적으로, 측정 가능하게** 접근하자.

현재 단락 (1/232)

커널 파라미터 튜닝은 **서버 성능과 안정성에 직접적 영향**을 미치는 작업이다. 잘못된 값 하나가 OOM Kill을 유발하거나, 네트워크 연결을 끊거나, 보안 취약점을 만들 수 ...

작성 글자: 0원문 글자: 10,867작성 단락: 0/232