Linux

리눅스 커널 파라미터(sysctl) 기초와 실전 적용

Somaz 2025. 5. 15. 11:32
728x90
반응형

Overview

리눅스 커널 파라미터(kernel parameters, sysctl 설정)는 운영체제의 동작을 런타임에 세부 조정할 수 있게 해주는 설정 값들이다.

 

 

이러한 파라미터들은 가상 파일시스템인 `/proc/sys` 경로를 통해 노출되며 (`/proc/sys/vm/swappiness` 등), `sysctl` 명령어를 사용하여 조회하거나 변경할 수 있다.

 

 

주요 활용 분야로는 성능 튜닝, 보안 강화, 네트워킹 설정 등이 있으며,

메모리 관리부터 네트워크 스택 동작, 시스템 보안 옵션까지 다양한 커널 동작을 제어한다.

 

 

예를 들어 메모리 관리 관련 파라미터를 조정해 성능을 개선하거나,

특정 네트워크 기능을 활성/비활성화하여 트래픽 처리나 보안을 최적화하고,

보안과 관련된 파라미터를 조절해 시스템을 한층 강화할 수 있다.

 

 

커널 파라미터의 주요 활용 사례는 다음과 같다.

  • 메모리 관리: 스왑 사용 비율 조정, 파일 디스크립터 최대값 설정 등
  • 네트워크 튜닝: TCP 커넥션 처리, 포워딩, TIME_WAIT 재사용 등
  • 보안 강화: 커널 포인터 주소 노출 방지, 주소 공간 레이아웃 무작위화 등

 

 

커널 파라미터는 일시적으로 변경하여 현재 부팅된 커널에 즉시 적용할 수도 있고, 설정 파일을 통해 영구적으로 구성하여 부팅 시 자동 적용할 수도 있다.

 

 

런타임 중에는 `/proc/sys` 아래 해당 파일에 값을 쓰거나 `sysctl` 을 통해 변경하며, 재부팅 후에도 값이 유지되게 하려면 `/etc/sysctl.conf` 또는 `/etc/sysctl.d/` 설정 파일에 값을 넣어 두어야 한다

 

 

아래에서는 커널 파라미터를 확인하고 일시/영구적으로 적용하는 방법과 함께, 자주 사용하는 핵심 파라미터 사례들, 그리고 Kubernetes 등의 컨테이너 환경에서의 적용 방법까지 순차적으로 설명한다.

 

 

 

 

 

 

 


 

 

 

커널 파라미터 확인 방법

 

현재 시스템의 커널 파라미터 값을 확인하려면 `sysctl` 명령어나 `/proc/sys` 경로의 파일을 조회하는 두 가지 방법이 있다.

`sysctl -a` 명령을 사용하면 사용 가능한 모든 커널 파라미터와 현재 값을 한꺼번에 출력할 수 있다. 출력되는 목록이 매우 방대하기 때문에 `grep` 등을 활용해 키워드를 필터링할 수도 있다.

 

 

특정 파라미터 하나만 알고 싶다면 `sysctl <파라미터명>` 형식으로 조회가 가능하다. 예를 들어 IP 포워딩 설정 값을 알고 싶다면 `sysctl net.ipv4.ip_forward` 명령으로 확인할 수 있고, 이는 `/proc/sys/net/ipv4/ip_forward` 파일을 직접 여는 것과 동일한 결과를 보여준다.

 

 

아래 예시에서는 `vm.swappiness` 값을 `sysctl` 로 조회한 경우와 `cat` 으로 직접 파일을 읽은 경우를 보여준다.

$ sysctl vm.swappiness
vm.swappiness = 60

$ cat /proc/sys/vm/swappiness
60

 

  • 위와 같이 `sysctl` 을 쓰나 `/proc` 경로의 파일을 직접 읽으나 결과는 동일하다.
  • 특히 `sysctl` 은 내부적으로 해당 `/proc/sys` 파일을 열어 값을 읽어오는 방식이므로, 두 방법 모두 커널로부터 현재 설정 값을 가져오는 역할을 한다.

 

 

 

 

커널 파라미터 일시적 변경 방법

실행 중인 시스템에 커널 파라미터를 일시적으로 변경하여 즉시 적용하고 싶다면,

`sysctl -w <파라미터>=<값>` 명령을 사용하거나

`/proc/sys/...` 경로에 값을 써서 설정할 수 있다.

 

 

예를 들어 시스템의 최대 파일 오픈 수 제한(`fs.file-max`)을 늘리려면 다음과 같이 할 수 있다.

# sysctl -w fs.file-max=100000
fs.file-max = 100000

# echo 100000 > /proc/sys/fs/file-max   # 동일한 효과 (별도 출력 없음)

 

 

 

위 두 명령은 결국 동일한 작업를 수행하며, 실제로 sysctl 명령은 내부적으로 /proc/sys 경로의 해당 파일에 값을 써주는 역할을 한다.

 

 

`sysctl -w` 를 사용하면 변경된 값이 화면에 다시 표시되며, `echo` 로 직접 쓰는 방법은 조용히 값을 설정하는 차이가 있지만 효과는 같다. 이렇게 설정한 커널 파라미터 값은 시스템 전체에 즉시 반영되지만,

 

 

영구적인 설정은 아니므로 재부팅하면 기본값으로 되돌아간다는 점을 유의해야 한다.

참고: 중요한 커널 파라미터를 실시간으로 변경할 때에는 시스템 안정성에 영향을 줄 수 있으므로 신중해야 한다. 
특히 네트워킹 관련 파라미터나 메모리 관리 파라미터는 잘못 설정하면 성능 저하나 예기치 않은 동작을 초래할 수 있으므로, 변경 전 해당 파라미터의 의미와 효과를 충분히 이해해야 한다.

 

 

 

커널 파라미터 영구 적용 방법

커널 파라미터를 재부팅 후에도 지속적으로 적용하려면 설정 파일을 통해 영구 설정을 해주어야 한다. 일반적으로 두 가지 방법이 있다.

 

 

전역 설정 파일 사용

배포판 공통으로 `/etc/sysctl.conf` 파일에 설정을 추가하는 방법이다. 이 파일에 `<파라미터>=<값>` 형식으로 한 줄씩 원하는 설정을 작성해두면, 시스템 부팅 시 또는 `sysctl -p` 명령을 통해 해당 값들이 커널에 적용된다.

 

 

예를 들어 `vm.swappiness` 를 영구적으로 10으로 낮추고 싶다면 `/etc/sysctl.conf` 파일에 `vm.swappiness = 10` 라인을 추가한 뒤 `sysctl -p` 로 즉시 적용할 수 있다.

 

 

디렉토리별 설정 파일 사용

sytemd 기반의 현대적인 리눅스 배포판에서는 `/etc/sysctl.d/` 디렉토리 아래에 별도의 설정 파일을 두어 관리하는 방법을 선호하기도 한다. 예를 들어 `/etc/sysctl.d/99-custom.conf` 라는 파일을 만들고 필요한 커널 변수들을 넣어둘 수 있다.

 

 

이러한 .conf 파일들은 시스템 부팅 시 `systemd-sysctl` 서비스가 자동으로 읽어들여 커널 파라미터를 적용한다. 여러 개의 파일이 있을 경우 숫자나 이름 순으로 모두 적용되며, 충돌 시 마지막 설정이 우선한다.

 

 

 

 

위 두 방식 중 편한 것을 선택하면 되며, 기본적으로 효과는 동일하다. 이미 많은 배포판에서 기본 보안/네트워크 설정을 이 방식으로 `/etc/sysctl.conf` 또는 `/etc/sysctl.d` 에 미리 설정해두고 있다.

 

 

앞서 언급했듯, `/proc/sys` 에 직접 쓴 값이나 `sysctl -w` 로 변경한 값은

재부팅하면 사라지기 때문에 영구 적용을 위해서는 반드시 설정 파일에 추가해야 한다. 

 

 

설정을 추가한 후 재부팅하지 않고 즉시 적용하려면 `sysctl -p` 명령을 수동으로 실행하면

`/etc/sysctl.conf` 및 `/etc/sysctl.d` 의 모든 설정을 바로 커널에 반영해준다.

# echo "fs.file-max = 100000" >> /etc/sysctl.conf   # 설정 추가
# sysctl -p                                       # 설정 즉시 적용 (부팅 시도 자동 적용됨)

 

 

만약 `/etc/sysctl.d` 경로를 사용했다면 `sysctl -p /etc/sysctl.d/99-custom.conf` 형태로 특정 파일을 지정해 불러올 수도 있다.

Tip: 유지보수를 위해 여러 튜닝 설정을 분리하고 싶다면 `/etc/sysctl.d` 에 파일을 나누어 넣는 것이 좋다.
예를 들어 성능 튜닝 관련 설정은 `99-performance.conf`,
보안 관련 설정은 `99-security.conf` 와 같이 구분하면 가독성이 높아진다.
Ubuntu 등의 배포판에서는 패키지들이 자신의 기본 sysctl 설정 파일을 `/usr/lib/sysctl.d` 나 `/etc/sysctl.d` 에 넣기도 한다.

 

 

 

 

 

 

 


 

 

 

 

 

 

 

자주 사용되는 커널 파라미터 예시

이제 실무에서 자주 활용되는 핵심 커널 파라미터들을 분야별(성능, 네트워크, 보안)로 살펴보겠습니다. 각 파라미터가 무엇을 제어하며 어떤 상황에서 조정되는지 간단히 설명한다.

 

 

 

 

성능 조정 관련

 

vm.swappiness

메모리 스와핑(swap) 강도를 조절하는 값이다. 0부터 100까지의 값을 가지며, 높은 값일수록 적극적으로 메모리 페이지를 디스크로 스왑 아웃하게 되고 낮은 값일수록 가능한 한 메모리를 유지하려고 한다. 

 

기본값은 대부분의 리눅스 배포판에서 60이며, 데이터베이스 서버 등 스왑 사용을 최소화하고 싶은 워크로드에서는 이 값을 10 이하로 낮춰 메모리 활용을 높이는 튜닝을 자주 한다.

 

단, 너무 낮게 설정하면 메모리가 부족할 때 OOM(Out-Of-Memory) 상황이 빨리 올 수 있으므로 신중한 테스트가 필요하다.

 

 

 

fs.file-max

시스템 전역에서 열 수 있는 최대 파일 핸들(파일 디스크립터)의 개수를 의미한다.

즉, 커널이 동시에 열어둘 수 있는 파일(및 소켓 등의 총합) 개수의 상한선으로,

기본값은 시스템 메모리에 따라 정해지며 보통 수만 단위이다.

 

이 한도에 도달하면 ENFILE 에러가 발생하며 더 이상 파일이나 소켓을 열 수 없으므로,

많은 동시 접속이나 파일을 필요로 하는 서버의 경우 이 값을 늘려야 한다. 

 

예를 들어 대용량 웹 서버라면`fs.file-max` 를 수십만까지 올려 놓는 것이 일반적이다. 이 값은 루트 권한 프로세스(CAP_SYS_ADMIN)는 한계를 무시하고 열 수 있다는 점도 참고해야 한다. 

 

또한 프로세스별 파일 디스크립터 제한(`ulimit -n` 으로 확인)은 별도로 존재하며, `fs.file-max` 는 시스템 전체의 총합 제한이라는 차이가 있다.

 

 

 

 

 

네트워크 관련

 

net.core.somaxconn

TCP 소켓의 대기 큐(backlog) 사이즈 최대값을 지정한다.

리스닝 소켓이 한 번에 처리하지 못하고 대기할 수 있는 최대 연결 요청 개수를 의미하며, 기본값은 128이다.

동시 접속 요청이 많은 서버(예: 웹 서버의 Listen backlog)에서는 이 값을 높여야 서버가 더 많은 연결을 일시 대기시킬 수 있다.

예를 들어 고부하 환경에서 이 값을 1024나 그 이상으로 높여 두면,  애플리케이션에서 허용하는 한도 내에서 순간적인 연결 폭주를 커널이 더 잘 감당할 수 있다.

 

단, 너무 큰 backlog는 메모리 사용 증가를 야기할 수 있으므로 적정 수준으로 조절한 다.

 

 

 

net.ipv4.tcp_tw_reuse

TIME_WAIT 상태의 소켓을 새로운 연결에 재사용할지를 결정하는 옵션이다. 보통 서버에서 많은 단기 연결이 발생하면 대량의 소켓이 TIME_WAIT 상태로 남는데, 이 값을 1로 켜두면 안전한 경우에 한해 TIME_WAIT 소켓을 즉시 재사용하여 자원을 절약할 수 있다.  

 

기본값은 0(비활성화)이며, 이 값을 변경하는 것은 프로토콜 면에서 안전한지 신중히 판단해야 한다. 

 

특히 NAT 환경 등에서는 예기치 않은 동작이 있을 수 있어 최신 리눅스에서는 일반적으로 기본값을 유지하고 `tcp_tw_reuse` 활성화는 추천하지 않거나 제한적으로만 활용한다.

 

 

 

net.ipv4.ip_forward (및 net.ipv4.conf.all.forwarding)

IP 패킷 포워딩(라우팅) 기능을 활성화할지 결정한다. 기본값은 0 (비활성화)이고 1로 설정하면 이 호스트가 라우터처럼 여러 인터페이스 간 패킷 전달을 수행할 수 있게 된다. 

 

 

이 값을 켜면 커널이 네트워크 인터페이스들 간에 패킷을 전달하게 되므로, 리눅스 박스를 라우터나 게이트웨이로 사용할 때 반드시 활성화해야 하는 옵션이다. 예를 들어 두 개 이상의 네트워크를 중계하거나 Kubernetes 등의 컨테이너 호스트에서 Pod 네트워크를 통신 가능하게 하려면 이 값을 1로 설정해야 한다. 

 

 

값을 변경하면 커널이 즉시 라우팅 동작을 변경하며, 활성화 시 호스트에 설정된 기존 네트워크 관련 파라미터들이 (RFC 규격에 따라) 기본값으로 재설정될 수 있음을 유의해야 한다.

 

 

 

 

보안 관련

 

kernel.kptr_restrict

`/proc` 등 커널 인터페이스를 통해 커널 포인터 주소 값의 노출을 제한하는 설정이다.

 

 

이 값을 0으로 두면 제한이 없지만,

1로 설정하면 비특권 사용자에게 커널 포인터 값이 00000000 등의 무의미한 값으로 표시되어 정보가 숨겨진다. 

2로 설정하면 루트 등의 관리자 권한이 있더라도 커널 포인터가 항상 0으로 표시된다. 

 

 

공격자가 커널 메모리 주소를 알아내는 것을 어렵게 만들어 커널 익스플로잇 공격의 난이도를 높이는 보안 강화 차원의 옵션이다. 기본값은 과거에는 1이었으나 최신 커널에서는 0으로 완화되었으므로, 보안이 중시되는 시스템에서는 이를 1로 바꾸어 설정하는 것이 권장된다. 이 값은 Linux 3.4부터는 CAP_SYS_ADMIN 권한이 있어야만 변경할 수 있도록 제어되고 있다.

 

 

kernel.randomize_va_space

 

프로세스의 가상 메모리 주소 배치를 무작위화하는 ASLR(Address Space Layout Randomization) 기능을 제어한다.

 

 

값 0이면 ASLR을 완전히 끔으로써 프로세스 메모리 주소가 고정된다. 

1이면 mmap 베이스 주소, 스택, vdso 영역 등 주요 영역의 주소를 무작위화하여 공유 라이브러리나 PIE 실행파일의 배치 주소를 랜덤화한다.  2로 설정하면 힙 영역까지 포함해 전체 메모리 영역의 배치를 무작위화하며, 대부분의 현대 시스템에서 기본값으로 사용된다

 

 

일반적으로 보안 강화를 위해서는 이 값을 2로 설정하여 ASLR을 최대한 활용하는 것이 좋다. 다만, 혹시 호환성 문제가 있는 오래된 프로그램(메모리 배치에 의존하는 경우 등)이 있다면 1로 낮추어 동작을 확인하기도 한다. 가능한 경우 풀 ASLR(=2) 상태를 유지하는 것이 시스템 보안을 위해 권장된다.

 

 

 

 


 

 

 

 

컨테이너/Kubernetes 환경에서의 커널 파라미터 튜닝

 

Kubernetes와 같은 컨테이너 오케스트레이션 환경에서는 커널 파라미터 설정이 전체 호스트(노드)에 영향을 미치며, 해당 노드에서 동작하는 모든 컨테이너(Pod)에도 그 영향이 미친다. 도커(Docker)와 같은 리눅스 컨테이너는 기본적으로 호스트 커널을 공유하기 때문에, 컨테이너 내부에서 함부로 커널 파라미터를 변경할 수 없도록 기본 제약이 있다.

 

 

Kubernetes에서는 변경 가능한 `sysctl` 을 안전(`sysctl.allow`)한 것과 안전하지 않은 것으로 구분하여, 네임스페이스로 격리된 파라미터만 일부 Pod에서 조정할 수 있게 허용하고 있다.

 

 

예를 들어 `net.ipv4.ip_local_port_range` 등의 몇몇 네트워크 파라미터나 `kernel.shm_rmid_forced` 같은 IPC 파라미터는 “안전한” 범주로 분류되어 있어 Pod 단위로 설정이 가능하지만, 대부분의 커널 파라미터는 네임스페이스로 격리되지 않거나 시스템 전체에 영향을 주기 때문에 기본적으로 Pod에서 직접 변경이 금지(`unsafe sysctl`)되어 있다.

 

 

안전한 sysctl의 경우 Kubernetes Pod 정의의 securityContext에서 해당 파라미터 이름과 값을 지정하여 컨테이너 시작 시 적용할 수 있다. 예를 들어 아래와 같이 Pod 매니페스트에 `securityContext.sysctls` 섹션을 넣어 `net.core.somaxconn` 등을 조정할 수 있다.

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
spec:
  securityContext:
    sysctls:
    - name: net.core.somaxconn
      value: "1024"
    - name: kernel.msgmax
      value: "65536"
  ...

 

 

 

위와 같이 선언된 sysctl 값들은 해당 Pod의 컨테이너 네임스페이스에 한해서 커널에 적용된다.

 

 

안전하지 않은 sysctl(예: `net.ipv4.conf.all.forwarding` 이나 `vm.overcommit_memory` 등 노드 전체에 영향을 주는 설정)은 위처럼 Pod에서 바로 설정할 수 없으며, 클러스터 관리자 권한으로 노드 자체에 설정해야 한다.

 

 

 

Kubernetes 클러스터에서 노드 커널 파라미터를 조정하는 일반적인 방법으로는 다음과 같은 접근이 있다.

  • 노드 수동 설정: 가장 단순하게는 각 노드의 `/etc/sysctl.conf` 등에 필요한 값을 설정해 두는 것이다.
  • 예를 들어 Kubernetes 노드에서는 기본적으로 `net.ipv4.ip_forward=1` 로 설정되어 있어야 하며 (Pod 네트워킹을 위해) 만약 꺼져 있다면 수동으로 활성화해야 한다.
  • 배포판에 따라 쿠버네티스 설치 시 이 값이 자동으로 켜져 있지만, 관리형 쿠버네티스가 아닌 경우 운영자가 직접 확인해야 한다.

 

  • DaemonSet 활용: Kubernetes DaemonSet 리소스를 만들어 모든 노드에서 커널 파라미터를 설정하는 Pod를 띄울 수 있다.
  • 이 Pod에는 initContainer나 privileged 권한으로 동작하는 컨테이너를 두어 부팅 시 `sysctl -w` 명령을 실행하게 한다.
  • 예를 들어 다음과 같은 init 컨테이너를 가진 DaemonSet을 구성할 수 있다.
apiVersion: apps/v1
kind: DaemonSet
...
  spec:
    initContainers:
    - name: sysctl-init
      image: busybox:latest
      command: ["/bin/sh", "-c", "sysctl -w vm.overcommit_memory=1; sysctl -w net.ipv4.conf.all.forwarding=1"]
      securityContext:
        privileged: true
    containers:
    - name: dummy
      image: busybox:latest
      command: ["sleep", "3600"]

 

  • 위 예시는 모든 노드에서 `vm.overcommit_memory=1` 및 `net.ipv4.conf.all.forwarding=1` 설정을 적용하여, 노드 부팅 시 메모리 오버커밋 모드를 항상 허용하고 IP 포워딩을 켜도록 하는 DaemonSet이다.
  • 참고로 Red Hat OpenShift와 같은 쿠버네티스 환경에서는 노드 부팅 시 이러한 설정을 자동으로 적용하는데, 예를 들어 OpenShift는 모든 노드 커널에서 `vm.overcommit_memory=1` 로 설정하여 메모리 오버커밋을 허용하고 OOM 발생 시 커널 패닉이 없도록 `vm.panic_on_oom=0` 으로 설정한다.
  • 이는 쿠버네티스가 컨테이너별 cgroup 제한을 활용해 메모리를 관리하므로 커널 레벨에서는 메모리 할당 실패를 최소화하기 위한 조치이다.

 

  • 클러스터 설정 조정: 쿠버네티스 클러스터 자체 설정으로 `unsafe sysctl` 를 허용할 수도 있다.
  • kubelet 실행 옵션에 `--allowed-unsafe-sysctls` 파라미터를 사용하면 특정 파라미터를 Pod에서 설정 가능하도록 화이트리스트에 등록할 수 있다.
  • 다만, 이러한 설정은 시스템 안정성을 해칠 위험이 있으므로 꼭 필요한 경우에만 제한적으로 활용해야 한다.
  • 일반적으로는 위의 DaemonSet 방식처럼 노드 수준에서 설정을 적용하고, 해당 노드에는 해당 파라미터가 필요한 Pod만 스케줄하도록 `taint/toleration` 을 설정하는 패턴이 권장된다

 

요약하면 Kubernetes 환경에서는 커널 파라미터 변경이 호스트 노드 수준에서 이루어지며, Pod 단위로는 격리된 일부 설정만 허용됩니다. 노드 전체에 영향을 주는 설정은 운영자가 책임지고 변경해야 하며, 이러한 변경은 클러스터 문서와 커뮤니티 모범 사례를 참고하여 신중하게 시행해야 한다.

 

 

 

 


 

 

 

 

마무리

리눅스 커널 파라미터는 시스템의 동작을 근본적으로 좌우할 수 있는 강력한 도구인 만큼,

변경에 앞서 공식 문서를 통해 해당 파라미터의 의미와 영향을 충분히 확인하고 테스트하는 것이 중요하다.

 

 

잘못된 설정은 성능 저하나 보안 취약을 초래할 수 있으므로,

항상 작은 값부터 실험해보고 모니터링을 거쳐 적용하는 보수적인 접근이 권장된다.

커널 문서에서도 “일부 파라미터는 시스템을 망가뜨릴 수 있으므로 조정 전에 문서와 소스를 읽어보는 것이 바람직하다”고 명시하고 있다.

 

 

특히 Kubernetes와 같은 환경에서는 여러 애플리케이션이 노드를 공유하기 때문에

커널 파라미터 변경이 미치는 범위가 넓다.

 

 

가급적 쿠버네티스에서 공식적으로 지원하는 방법(securityContext를 통한 안전한 sysctl 지정,

필요한 경우 initContainer/DaemonSet 활용)으로 적용하고,

변경 시에는 노드 전체에 레이블이나 테인트를 활용하여 특정 워크로드에만 영향이 가도록 관리해야 한다.

  • 실험적 튜닝은 소규모 시스템이나 테스트 환경에서 먼저 검증할 것
  • 변경 사항은 /etc/sysctl.d/ 디렉토리에 구분된 파일로 관리해 유지 보수성을 높일 것
  • Kubernetes에서는 보안 및 네임스페이스 제한으로 인해 Pod 수준의 커널 파라미터 조정이 제한되므로, 필요한 경우 DaemonSet을 활용해 노드 전체에 반영할 것

 

 

마지막으로, 커널 파라미터 튜닝에 관한 더욱 자세한 내용과 가이드라인은 아래 Reference 공식 문서 및 커뮤니티 자료를 참고하시기 바란다.

 

 

 

 

 

 

 

 

 


 

Reference

 

  • Linux Kernel 공식 문서 – 커널의 /proc/sys 인터페이스와 sysctl 파라미터 설명 kernel.org
  • Red Hat Documentation – RHEL 시스템의 커널 파라미터 튜닝 가이드 (sysctl 활용 방법)  docs.redhat.com
  • Ubuntu 매뉴얼 페이지 – sysctl(8) 사용법 및 /etc/sysctl.conf 등 설정 파일에 대한 매뉴얼  manpages.ubuntu.com
  • Kubernetes 공식 문서 – Kubernetes에서 sysctl 사용하기 가이드 (안전/비안전 sysctl 설명 등)  kubernetes.io

 

 

728x90
반응형