26S06f

QK·약 8시간 전

Helm이 Kubernetes 위의 워크로드를 관리하는 도구라면, Kubespray/AWX(Ansible)는 Kubernetes 클러스터 그 자체와 하부 인프라를 프로비저닝하는 도구입니다.

Helm의 values.yaml에 1:1로 대응되는 Kubespray의 설정 관리 체계와, OS 커널 파라미터 등 노드 레벨의 설정을 엔터프라이즈 환경에서 관리하는 Best Practice를 정리해 드립니다.


1. Kubespray에서 Helm의 values.yaml에 해당하는 것

Kubespray는 내부적으로 Ansible 기반으로 동작하므로, Helm의 values.yaml에 정확히 대응되는 것은 Ansible의 인벤토리 변수 파일(Inventory Variables, group_vars)입니다.

Kubespray 프로젝트 디렉터리 내의 inventory/mycluster/group_vars/ 하위 파일들이 바로 그것입니다.

inventory/mycluster/
├── inventory.ini (또는 hosts.yaml)    # 노드 IP, 호스트명, 롤(마스터, 워커) 정의
└── group_vars/
    ├── all/                           # [모든 노드 공통 설정]
    │   ├── all.yml                    # 프록시(에어갭), 사내 Nexus 레지스트리 미러, HTTP 프록시 등
    │   ├── docker.yml / containerd.yml# 컨테이너 런타임 옵션 (Cgroup 드라이버, 레지스트리 미러)
    │   └── offline.yml                # 에어갭 다운로드 URL, 로컬 바이너리 경로
    └── k8s_cluster/                   # [Kubernetes 클러스터 컴포넌트 설정]
        ├── k8s-cluster.yml            # K8s 버전, Service/Pod CIDR, 네트워크 플러그인(Cilium 등)
        ├── k8s-net-cilium.yml         # CNI 상세 옵션 (Native Routing, eBPF Host Routing 등)
        └── addons.yml                 # Metrics Server, Local Path Provisioner 등 기본 애드온

Helm values.yaml vs Kubespray group_vars 비교

구분Helm (values.yaml)Kubespray (group_vars/*.yml)
관리 대상Deployment, Service, ConfigMap 등 K8s 리소스kube-apiserver, kubelet, containerd, CNI, OS 파라미터
설정 주입 방식helm install -f my-values.yamlansible-playbook -i inventory/mycluster cluster.yml
AWX(타워) 연동Helm CLI 인자 또는 ArgoCD RepoAWX Survey Variable 또는 Git 기반 Extra Vars
버전 관리Git (GitOps)Git (인벤토리 전용 Git 저장소 분리 권장)

AWX에서의 실무 운영 팁:
Kubespray 소스 코드가 들어있는 Git 저장소와 사내 클러스터별 인벤토리(inventory/mycluster) 저장소를 별도 Git Repo로 분리합니다. AWX에서는 인벤토리 Repo를 바라보게 하고, 설정 변경이 필요할 때 Git PR을 거쳐 Merge한 뒤 AWX Job Template을 실행하도록 파이프라인을 구성합니다.


2. Node 차원(OS 커널/시스템 설정) 관리 Best Practice

K8s 상위 컴포넌트(apiserver, kubelet)와 달리, OS 커널 파라미터(sysctl), 디스크 마운트 옵션, HugePages, CPU 거버너, Ulimit 등은 "노드 레벨(Host OS)"의 영역입니다.

대규모 베어메탈/온프레미스 환경에서 이를 관리하는 표준 접근법 3가지와 권장 조합입니다.


접근법 A: Kubespray 내부 Hook 활용 (가장 간편, 초기 구축용)

Kubespray 자체에 노드 커널 파라미터를 주입할 수 있는 변수 슬롯이 내장되어 있습니다.

  • 위치: inventory/mycluster/group_vars/all/all.yml
  • 설정 방식:
# Kubespray 실행 시 /etc/sysctl.d/99-sysctl.conf에 자동 반영됨
sysctl_file_spec:
  - name: 99-kubernetes-custom.conf
    rules:
      - { name: net.core.somaxconn, value: 65535 }
      - { name: net.netfilter.nf_conntrack_max, value: 2097152 }
      - { name: vm.max_map_count, value: 2621440 }
      - { name: fs.inotify.max_user_watches, value: 1048576 }
      - { name: net.ipv4.conf.all.rp_filter, value: 2 }
  • 장점: 별도 도구 없이 Kubespray 플레이북 1회 실행으로 K8s 설치와 커널 설정이 동시에 완료됩니다.
  • 단점: 클러스터가 이미 운영 중인 상태에서 커널 값 하나만 바꾸려 해도 Kubespray를 다시 돌려야 하므로 무겁습니다.

접근법 B: 노드 프로비저닝 파이프라인 분리 (Ansible 베이스라인 롤) — [강력 추천]

인프라 운영 성숙도가 높은 엔터프라이즈 환경에서 가장 널리 쓰이는 표준 아키텍처입니다. "OS 베이스라인 설정"과 "K8s 설치"를 완전히 독립된 라이프사이클로 분리합니다.

[ 신규 베어메탈 노드 인도 ]
         │
         ▼
[ Step 1: Base OS Provisioning (AWX/Ansible) ]
  - 사내 공통 보안 정책 적용
  - /etc/security/limits.d/ (Ulimit) 설정
  - /etc/sysctl.d/99-k8s.conf (네트워크/메모리 커널 파라미터)
  - NIC 점보 프레임 (MTU 9000), 링 버퍼(Ring Buffer 4096) 설정
  - GPU 노드인 경우: NVIDIA Driver .run, Fabric Manager 설치
         │ (인수 테스트 통과)
         ▼
[ Step 2: K8s Clustering (Kubespray Playbook) ]
  - Containerd, Kubelet 배포
  - etcd, Control Plane 구성
  - CNI(Cilium) 배포
  • 구현 방법:
    AWX에 os-baseline-tuning이라는 별도의 Ansible Job Template을 만듭니다. 이 플레이북은 사내 공통 템플릿(templates/sysctl.conf.j2)을 배포하고 sysctl --system을 실행하는 역할만 담당합니다.
  • 효과: K8s 설치 전 노드 인수 단계에서 OS 튜닝을 완벽하게 끝낼 수 있고, 운영 중 커널 값 변경 시 10초 만에 전체 노드에 롤링 적용이 가능합니다.

접근법 C: Kubernetes-Native 방식 (Node Tuning Operator / DaemonSet)

노드가 이미 K8s 클러스터에 조인된 이후, K8s GitOps 파이프라인(ArgoCD)을 통해 호스트 OS 커널 파라미터를 선언적으로 관리하는 방식입니다.

  • 특권(Privileged) DaemonSet 활용:
    초기화 컨테이너(Init Container)가 호스트의 /etc/sysctl.d에 파일을 쓰고 nsenter로 호스트 네임스페이스에서 sysctl을 적용합니다.
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-tuning-operator
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: node-tuning
  template:
    metadata:
      labels:
        app: node-tuning
    spec:
      hostPID: true
      containers:
      - name: sysctl-tuner
        image: nexus.internal:8082/ubi9/ubi-minimal:latest
        securityContext:
          privileged: true
        command: ["/bin/sh", "-c"]
        args:
        - |
          cat <<EOF > /host/etc/sysctl.d/99-k8s.conf
          net.core.somaxconn = 65535
          net.netfilter.nf_conntrack_max = 2097152
          vm.max_map_count = 2621440
          EOF
          nsenter --target 1 --mount --uts --ipc --net --pid -- sysctl --system
          sleep infinity
        volumeMounts:
        - name: host-root
          mountPath: /host
      volumes:
      - name: host-root
        hostPath:
          path: /
  • 장점: OS 접속용 SSH 키나 Ansible 없이도 K8s Manifest(YAML)를 수정하여 GitOps로 전체 노드의 커널 파라미터를 통제할 수 있습니다. 노드 라벨(nodeSelector)을 통해 GPU 노드, 스토리지 전용 노드별로 서로 다른 sysctl을 자동 적용하기 매우 좋습니다.

결론: 실무 엔지니어링 권장 조합 (Best Practice)

  1. K8s 상위 설정 (kube-apiserver, CNI, etcd 등):
  • Kubespray의 group_vars/*.yml을 Git 저장소로 형상 관리하고, AWX를 통해 변경 사항을 제어합니다.
  1. OS 하부 설정 (네트워크 튜닝, NIC Ring Buffer, 커널 sysctl):
  • 초기 노드 인수 시점: AWX의 독립된 OS 베이스라인 플레이북으로 프로비저닝 단계에서 1차 적용합니다.
  • 운영 중 상시 관리: K8s 조인 후에는 특정 노드 풀(GPU, Storage) 전용 튜닝을 특권 DaemonSet(또는 Node Tuning Operator)을 활용해 GitOps로 관리하는 구조가 가장 유지보수성과 가시성이 뛰어납니다.

===

요약
목표: RHEL 10.2 기반 NVIDIA B300·Intel E810 노드의 전달 전 검수(check-in)용 표준 인수테스트 및 커널 설정.
대상: Intel Xeon 서버, B300 GPU, Intel E810 NIC, RHEL 10.2, Kubernetes 클러스터(Cilium, AIStor/MinIO), Keycloak/Vault 등 일반 앱.
테스트 포인트: 스위치→물리 NIC→PCIe→CPU/NUMA→커널 네트워크 스택→CNI(eBPF)→파드 네트워크 경로 검증, CPU/메모리 부하 검증 등.
절차: BIOS/하드웨어 설정 확인, OS/커널 튜닝 적용, Kubernetes 노드 설정 검증, 단계별 T1~Tn 테스트 수행(하드웨어→네트워크→K8s).
커널 파라미터: net.core.netdev_max_backlog, rmem_max/wmem_max, tcp_rmem/wmem, somaxconn, swappiness, dirty_ratio, CPU governor 등.
Kubernetes 설정: systemd cgroup, --kube-reserved/--system-reserved, CPU Manager static, Topology Manager 정책, hugepages.
모니터링: Prometheus(node_exporter, cAdvisor, kubelet, Cilium 지표 등) 기반 CPU·메모리·네트워크·인터럽트·패킷 손실 등 감시.
문서출처: RHEL/Tuned 성능가이드, Intel NIC 성능 안내, Kubernetes 공식 문서, Cilium 요구사항 등.
1. 하드웨어/BIOS 점검
BIOS 설정: CPU 전원관리(performance 모드), 모든 C-State 비활성(혹은 C1만 허용, intel_idle.max_cstate=1 커널 파라미터), 에러검출(ECC) 최소화, CPU 토폴로지 수동 설정(예: MADT Core Enumeration을 Linear로), 인터럽트/타이머를 특정 코어에 제한(Reserved CPUs).
CPU: Turbo Boost 정상, SpeedStep/performance governor(cpupower frequency-set -g performance), SMT(Hyper-threading) 고려(성능 테스트 후 결정).
NIC/PCIe:
lspci: PCIe 슬롯 대역폭(x8/x16) 확인.
ethtool -i : 드라이버(ice), 펌웨어 버전 확인. 공식 Intel i225/ice 드라이버 권장.
링크 속도/모드: 25GbE 혹은 RoCE 사용시 RDMA 모드 등 확인.
리던던시: 2포트 NIC인 경우 bonding(LACP)시 승리/라운드로빈 설정 및 mode=802.3ad 확인.
IRQ와 NUMA: 인터럽트가 NUMA 노드에 고루 분배되도록 irqbalance 활성화하거나, 필요시 특정 코어로 고정(예: Tuned net-iplus 프로파일). Intel 권장: IRQ affinity 수동 설정(채널 수 조정) 및 CPU affinity 조정.
GPU: NVIDIA 드라이버, Fabric Manager, NVSwitch 정상 로드.

mermaid
복사
flowchart LR
Switch[외부 네트워크 (스위치)] --> NIC[Intel E810 NIC]
NIC -->|PCIe x8| PCIe[PCIe 버스]
PCIe --> CPU[Intel Xeon CPU]
CPU --> Kernel["커널 네트워크 스택"]
Kernel --> Cilium[Cilium eBPF 데이터경로]
Cilium --> PodNetwork[파드 네트워크 인터페이스]
PodNetwork --> Application[컨테이너 애플리케이션]
그림: 물리 NIC에서 파드 네트워크에 이르는 데이터 경로. 하드웨어→커널→CNI(eBPF)→파드.

  1. OS/커널 튜닝
    CPU & 스케줄링: kernel.sched_child_runs_first=0, kernel.sched_autogroup_enabled=0(성능 위주), vm.swappiness=10(스왑 억제), CPU governor performance. tuned-adm profile network-throughput 추천.
    메모리:
    vm.dirty_ratio=10/vm.dirty_background_ratio=5 (적은 비율로 설정해 쓰기 배경작업).
    vm.min_free_kbytes 충분히 큰 값 (예: 5% 메모리).
    HugePages: 필요시 2MB/1GB 페이지(예: nr_hugepages=###), GPU 사용시 NVIDIA가 요구하는 HugePages 확인.
    파일/프로세스:
    fs.file-max=2097152, fs.aio-max-nr=1048576, fs.inotify.max_user_instances=1024 등 필요에 맞게 상향.
    kernel.pid_max=4194304 (필요시 pid 수 제한 상향).
    네트워크 커널 파라미터 (IP/TCP):
    버퍼: net.core.rmem_max/wmem_max=16-128MB, net.ipv4.tcp_rmem="4096 87380 16777216" 등 TCP 버퍼 자동 조정 범위 확대.
    큐백로그: net.core.netdev_max_backlog=30000-65535까지 증가. net.core.somaxconn=65535, net.ipv4.tcp_max_syn_backlog=65535.
    혼잡제어: net.ipv4.tcp_congestion_control=bbr 사용(동시 연결/대역폭 위주). net.core.default_qdisc=fq(BBR용).
    기타: net.ipv4.tcp_fin_timeout=30, tcp_tw_reuse=1, net.ipv4.tcp_slow_start_after_idle=0, tcp_no_metrics_save=1, tcp_mtu_probing=1 등.
    NF_CONNTRACK: 연결 추적 대량 처리 가능토록 net.netfilter.nf_conntrack_max=200000 이상(필요시 조정). 참고: 많은 단기 연결 시 conntrack 부하 발생 가능.
    Ethernet offloads: 대역폭/지연에 따라 조정. 기본 켜짐(TX/RX checksum, TSO, GSO, GRO), 고성능 필요시 LRO/GRO 비활성(특히 Calico/Cilium 필요시). Jumbo Frame(MTU=9000) 사용 권장(스위치 설정 일치).
    RPS/XPS: 다중 CPU 환경에서 다중 IRQ 큐 사용. /sys/class/net//queues/rx-*/rps_cpus 등을 설정해 다중 코어로 분산. IRQ balance 및 smp_affinity 점검.
    파라미터 추천 설정 설명/근거
    net.core.netdev_max_backlog 30000–65535 입력 큐 부족시 패킷 드롭 방지, 점진적 2배 증대 반복
    net.core.rmem_max/wmem_max 16–128MB TCP 버퍼 최대치, 고처리량 요구 시 상향
    net.ipv4.tcp_rmem/wmem 4096 87380 16777216 TCP recv/send 버퍼 범위, 최대 16MB로 확대
    net.ipv4.ip_local_port_range 1024 65535 포트 범위 확장, 동시 연결 증가 시 필요
    net.ipv4.tcp_congestion_control bbr (또는 cubic) BBR 사용 권장, 고처리량 시 성능 유리
    net.core.default_qdisc fq (BBR용) BBR 스케줄러에 적합 (기본 fq_codel→fq)
    net.ipv4.tcp_max_syn_backlog 65535 SYN 큐 버퍼 크기 증가, RHEL 기본 1024
    net.ipv4.tcp_fin_timeout 30 연결 종료 시 WAIT 시간 단축 (기본 60)
    vm.swappiness 10 스왑 억제; 메모리 성능 우선
    vm.dirty_ratio, dirty_background_ratio 10, 5 dirty 페이지 임계값 낮추어 자주 flush
    fs.file-max ≥ 2000000 파일 디스크립터 상한, 많은 소켓/파일 처리 시
    IRQ affinity IRQ 분산(irqbalance) or 특정 코어 고정 다중 큐가 각 CPU에 고르게 할당되도록

(※ 위 수치는 일반적인 레퍼런스 예시입니다. 실제 환경 부하에 따라 유연 조정하고, 각 설정 변경 전후 성능/모니터링을 수행하십시오.)

  1. Kubernetes 노드 설정
    cgroup: cgroupsPerQOS=true, cgroup v2 사용. 컨테이너 런타임(systemd)과 kubelet 설정 일치.
    CPU Manager: --cpu-manager-policy=static, --topology-manager-policy=single-numa-node로 구성하여 NUMA 정렬 및 CPU 핀닝 활성화.
    Reserved Resources: --kube-reserved=cpu=100m,memory=256Mi(kubelet 등), --system-reserved=cpu=100m,memory=256Mi(OS 데몬 등) 등 클러스터 정책에 맞게 설정. 예를 들어 64코어 서버는 각 500m/512Mi 이상 권장. --eviction-hard=memory.available<100Mi,nodefs.available<10% 등 기본값 유지.
    CPU 고정 예약: 필요시 --reserved-system-cpus="0-3"로 특정 CPU군을 시스템/킬렛에 고정. Telco/NFV용으로 추천되는 설정.
    HugePages: GPUs나 데이터베이스가 사용한다면 노드 수준 2MB/1GB HugePages 활성화(예: hugepages-2Mi=##). Kubelet --hugepages-2Mi=##Mi와 풀리 hugepage 리소스 요청으로 Pods에 할당.
    Container runtime (containerd):
    systemd cgroup 드라이버 사용.
    log-opts: max-size= "100m", max-file="3" 등 로깅 제한.
    no_proxy 설정에 메타데이터 서버 등 필요 리소스 추가.
    Cilium: Linux 커널 ≥5.10 필요. net.netfilter.nf_conntrack_max 충분히 높여 둠. 방화벽/iptables가 Cilium의 eBPF 정책과 충돌 없도록 net.bridge.bridge-nf-call-iptables=1 등 필요시 설정.
  2. 인수 테스트(T1~Tn)
    아래 표는 단계별 테스트 사례입니다. 각 테스트는 명확한 목적과 측정 방법, PASS/FAIL 기준을 제공합니다. 가능한 컨테이너화하여 K8s Pod에서 실행합니다.

ID 테스트 (목적) 사전조건 명령어/컨테이너 측정 지표 PASS 기준
T1 OS 기본 검증 (CPU, 메모리, 커널) 노드 부팅 완료, BIOS 설정 완료 lscpu, free -m, uname -r, dmesg CPU 수, 메모리 크기, 커널 버전, XID 에러 하드웨어 사양 일치, XID 에러 없음
T2 NIC/드라이버 확인 (링크/속도, 오프로드) NIC 연결(케이블, 스위치) 완료 ethtool -i eth0, ethtool -S eth0, ethtool -k eth0 드라이버/펌웨어 버전, 속도, 오프로드 상태 최신 드라이버·펌웨어, 링크 25Gbps, 오프로드 정상
T3 IRQ/NUMA 분포 점검 irqbalance 실행 중 grep "eth0" /proc/interrupts, numactl --hardware 인터럽트별 CPU 분포, NUMA 노드별 CPU IRQ가 NUMA 노드에 고르게 분배됨
T4 PCIe 대역폭 테스트 NVMe 빈 슬롯에서 전용 PCIe 장치 준비 lspci -vvv, sudo lspci -s <장치>: -xxx PCIe 버스 속도(x8/x16), 비트폭 PCIe 링크가 x8 (최소)로 동작
T5 네트워크 대역폭 (iperf3) 노드간 물리 경로 열려있음 서버: iperf3 -s, 클라이언트: iperf3 -c -t 30 -P 4 Throughput (Gbps), 지연 양방향/단방향 대역폭 기대치 달성 (예: ≥20 Gbps)
T6 패킷 드롭/RSS/NIC 큐 테스트 MTU=9000 설정 (스위치 포함) tc -s qdisc show dev eth0, pktgen 모듈 이용 예: echo 100000 > /proc/sys/net/core/netdev_max_backlog drops 카운터, RX 큐별 패킷 분배 netdev_max_backlog 확대 후 drops=0, RSS 큐 활성화
T7 RDMA 성능(선택: RoCE) RoCE 설정, PFC 지원 스위치 RDMA 툴 ib_write_bw, ib_read_bw 실행 RDMA Throughput, RNR-NA/NACK 오차 기대 대역폭(약 40 Gbps) 달성, 에러 없음
T8 K8s 노드 기능 검증 Kubernetes 구성 완료 kubectl get nodes, kubectl describe node Ready 상태, Kubelet flags, 리소스 할당 Node Ready, kube-reserved/system-reserved 적용
T9 파드 네트워크(지연/MTU) CNI(Cilium) 정상 기동 파드에서 ping -s 8972 <다른노드IP> , iperf3 최대 MTU 도달 가능, 지연 정도 MTU 9000 유지, 지터/패킷 손실 없음
T10 CPU/메모리 부하 테스트 스레드/코어 동시점유 컨테이너 stress-ng --cpu 8 --vm 2 --vm-bytes 50% --timeout 60s CPU util, 메모리 사용률, 응답 시간 CPU 100% 활용, 지연 및 에러 없음
T11 메모리 대역폭(예: STREAM) (옵션) Intel MKL/Kernellib STREAM 벤치마크 또는 numactl 를 이용한 메모리 스트레스 GB/s, NUMA 노드 간 대역폭 메모리 대역폭 사양 근접 또는 결함 없음

각 테스트 수행 시 Node Exporter/cAdvisor를 통해 CPU 이용률, 메모리 등 리소스 사용률을 동시에 모니터링하여 병목점 여부를 파악합니다.

T1: 하드웨어/BIOS 점검

T2: NIC/IRQ 검사

T3: PCIe/NUMA 검사

T4: 네트워크 대역폭

T5: 패킷 드롭/RSS 테스트

T6: RDMA 테스트

T7: K8s 노드 설정 확인

T8: 파드 네트워크/MTU 테스트

T9: CPU/메모리 부하 테스트

T10: 메모리 벤치마크

코드 표시
그림: 테스트 흐름 다이어그램. 하드웨어부터 K8s, 애플리케이션까지 단계별 검증.

  1. 모니터링 지표 및 PASS/FAIL 기준
    Nodeexporter: CPU(node_cpu_seconds_total), 메모리(node_memory), 디스크(nodedisk), 네트워크(nodenetwork_receive_bytes_total/transmit_bytes_total/drop_total), 인터럽트(node_intr), 소프트IRQ(nodesoftirq).
    Kubelet/K8s: Node Ready 상태, kubenode_status_condition{condition="Ready"}, 할당량(kube_node_status_allocatable_cpu_cores, _memory_bytes), Pod 수(kubelet_running_pod_count). 예약 리소스(node_cpu_kube_reserved_cores 등).
    cAdvisor/Kube-State: 컨테이너별 CPU 사용(container_cpu_usage_seconds_total), 메모리(container_memory_working_set_bytes), QoS.
    Cilium: cilium_endpoint_policies_total, cilium_drop_count_total, cilium_connection_tracking
    등. eBPF 로드, L7/프로토콜 정책 관련.
    NIC/RDMA: ethtool -S 혹은 node exporter nodenetwork
    errors, node_network*_dropped. RoCE 관련 메트릭(패킷 손실, 재전송).
    GPU/DCGM: (추가 GPU 작업 시) GPU 이용률(DCGM_FI_DEV_GPU_UTIL) 참고.
    각 테스트별 PASS 기준 예시:

T4/5 네트워크 테스트: Throughput이 기대치의 ≥90% 이상, 에러/재전송(iperf3 -e 결과) 0.
T6 RDMA: 기대 대역폭(예: 50G 케이블→40Gbps 이상) 달성, ibv_rc_pingpong RTT 안정적.
T8 K8s 설정: kubectl get nodes 상태 Ready, kube-reserved/system-reserved 설정이 kubectl describe node 에 반영.
T10 CPU 스트레스: CPUutil ≥99%, 메모리 작업 완료, 노드 캐시/페이지캐시 과도 사용 없음. 시스템 응답 가능.
T11 메모리 벤치: STREAM 메모리 대역폭이 명세의 ≥80% 이상. NUMA 간 대역폭 불균형 없음.
문제 발생 시 Grafana 대시보드로 직관 확인:

CPU/메모리 대시보드: nodecpu_seconds_total, node_memory_MemAvailable_bytes, node_swaptime_seconds_total 등.
네트워크 대시보드: node_network
bytes_total, drop/err, NIC별 큐 대기수, 인터럽트 분포.
Kube 리소스 대시보드: kube_node_status_capacity
, kube_pod_container_resource_requests, container_memory_working_set_bytes 등으로 예약/사용 비교.
Cilium 대시보드: 활성 파드/엔드포인트, 흐름수, BPF 코드로드 시간, conntrack 테이블 사용량.
RDMA 대시보드: QP별 throughput/latency, ib_tx_rate, ib_rx_rate. 예: RoCE PFC가 제대로 작동하지 않으면 패킷 drop/Latency 급증.
예시 PASS/FAIL 경보:

네트워크 PASS: node_network_receive_drop_total 증가 없음, rx/tx throughput 일정, node_network_carrier_changes_total 없음.
메모리 PASS: node_memory_MemAvailable_bytes 충분, node_memory_Slab, node_memory_Buffers 정상, node_vmstat_pgmajfault 저수준.
CPU PASS: node_cpu_seconds_total 가 높은 부하 구간에서 균일 분포, C-state 진입 최소화.
디스크 PASS: (필요 시) node_disk_io_time_seconds_total 저, 파일시스템 메타데이터 잠김 없음.
6. 결론
이 표준안은 NVIDIA B300 + Intel E810 + RHEL 10.2 + Kubernetes(Cilium) 기반 대규모 클러스터의 노드 인수 검증에 초점을 둡니다. 각 테스트는 하드웨어와 네트워크, OS, Kubernetes 설정까지 단계별로 분리하여 문제 원인을 빠르게 진단할 수 있습니다. 제안된 커널 및 시스템 설정은 고성능 네트워킹과 컨테이너 워크로드에 대한 일반적인 베이스라인이며, 실사용 패턴에 따라 추가 조정이 필요할 수 있습니다.

참고자료: Red Hat RHEL 성능 조정 가이드, Intel NIC 성능 가이드, Kubernetes 공식 운영 가이드, Cilium 시스템 요구사항 등.

===

대규모 K8s 클러스터(수백~수천 노드 단위, 고성능 AIStor/DB/보안 스택 연동 환경)에서 노드를 인도받았을 때, 향후 Cilium eBPF 네트워크, OpenEBS/CNPG 로컬 I/O, 플랫폼 컴포넌트(Keycloak, Vault, Kyverno 등)의 병목을 사전에 차단하기 위한 하드웨어/OS 인수 테스트 프레임워크표준 베이스라인 커널 파라미터 셋입니다.


1. 노드 인수 테스트(Acceptance Test) 체크리스트

하드웨어 결함이나 초기 설정 오류가 클러스터 조인 후 Pod Eviction, etcd Split-brain, 네트워크 플래핑으로 번지는 것을 방지하기 위해 4개 레이어로 나누어 점검합니다.

(1) CPU & 메모리(NUMA) 하드웨어 검증

  • NUMA 토폴로지 대칭성 및 코어 할당:
  • 각 소켓별 코어 수, 하이퍼스레딩 배분, 메모리 용량이 1:1 대칭인지 확인합니다. 비대칭 구성은 Kubelet의 Topology Manager 정책 적용 시 파드 스케줄링 실패를 유발합니다.
numactl --hardware
lscpu | grep -E "Socket|Core\(s\)|NUMA node|Model name"
  • 하드웨어 메모리 무결성(EDAC/MCE) 이력:
  • 부팅 시점의 Corrected/Uncorrected ECC 메모리 에러 여부를 점검합니다.
dmesg | grep -iE "mce|edac|hardware error|corrected"
  • 10분 숏 번인(Short Burn-in):
  • 잠재적 CPU 코어 불량 및 전원 공급 불안정을 걸러냅니다.
stress-ng --cpu 0 --vm 4 --vm-bytes 80% --timeout 10m --metrics-brief

(2) 네트워크 & NIC (물리~L2/L3 계층) 검증

  • PCIe 링크 폭/속도 및 NUMA 바인딩:
  • 고속 NIC(25G/100G)가 올바른 PCIe 슬롯(예: Gen4/Gen5 x16)에 체결되었는지, 어느 소켓(NUMA Node) 버스에 직결되었는지 확인합니다.
lspci -vvv -s <NIC_PCI_ADDR> | grep -E "LnkCap|LnkSta"
cat /sys/class/net/<ETH>/device/numa_node
  • NIC 물리 링크 및 링 버퍼(Ring Buffer):
  • 링크 속도, 듀플렉스 및 버퍼 기본값을 점검합니다. 버퍼가 최소치로 잡혀 있으면 버스트 트래픽 인입 시 패킷이 즉시 드롭됩니다.
ethtool <ETH> | grep -E "Speed:|Duplex:|Link detected:"
ethtool -g <ETH>  # Current와 Maximum 비교
  • 점보 프레임 (MTU 9000) End-to-End 실측:
  • 스위치 포트와 호스트 간 MTU 불일치는 대규모 데이터 전송(AIStor S3, Spark 셔플) 시 조용한 패킷 드롭(Silent Drop)을 일으킵니다.
# DF(Don't Fragment) 플래그를 설정하고 8972바이트(ICMP 헤더 28 포함 = 9000) 송신
ping -M do -s 8972 -c 5 <GATEWAY_OR_PEER_IP>
  • NIC 하드웨어 패킷 드롭 카운터 베이스라인 기록:
ethtool -S <ETH> | grep -iE "drop|discard|error|miss"

(3) 로컬 스토리지 (NVMe/SSD) 검증

OpenEBS LocalPV, etcd, CNPG(PostgreSQL), Kafka 저널이 사용할 로컬 디스크의 수명과 I/O 성능을 확인합니다.

  • SMART 헬스 및 예비 블록 점검:
nvme smart-log /dev/nvme0n1 | grep -E "critical_warning|temperature|percentage_used|media_errors"
  • 4K 동기식 쓰기 지연(fsync Latency) 실측:
  • 분산 합의 알고리즘(etcd, Raft, WAL 로그)의 99% 병목은 4K fsync 지연에서 발생합니다. (기준치: 평균 10ms 이하 통과 권장)
fio --name=fsync-test --filename=/var/lib/test-wal --size=512M \
    --rw=randwrite --bs=4k --direct=1 --fdatasync=1 --runtime=15 --time_based
rm -f /var/lib/test-wal

(4) OS 및 베이스라인 컴플라이언스

  • 시간 동기화 오차(NTP/Chrony): 클러스터 내 오차가 5ms 이내인지 확인 (TLS 인증서 유효성, 분산 트랜잭션 충돌 방지).
chronyc tracking | grep -E "RMS offset|System time"
  • 스왑(Swap) 비활성화: Kubelet 기본 동작 조건.
free -m | grep -i swap  # Total이 0이어야 함

2. 대규모 K8s 클러스터 베이스라인 커널 파라미터

스위치에서 출발한 대용량 패킷이 물리 NIC, 커널 softirq, Cilium eBPF 엔진을 거쳐 Pod 내부 소켓에 도달하기까지의 패킷 손실을 막고, 메모리 집약적 워크로드(AIStor, StarRocks, CNPG) 구동을 위해 권장되는 파라미터 세트입니다.

/etc/sysctl.d/99-k8s-platform-baseline.conf 파일로 영구 반영합니다.

### ====================================================================
### 1. 파일 시스템 & Inotify 확장
### 용도: 수천 개 컨테이너, Fluentbit/Vector 로그 수집기, Kyverno/Vault 감시
### ====================================================================
fs.file-max = 20971520
fs.nr_open = 20971520
fs.inotify.max_user_watches = 1048576
fs.inotify.max_user_instances = 8192

### ====================================================================
### 2. 가상 메모리(VM) & NUMA 튜닝
### 용도: CNPG/AIStor/StarRocks 대용량 mmap 지원 및 백그라운드 지연 스파이크 차단
### ====================================================================
vm.swappiness = 0
vm.overcommit_memory = 1
vm.panic_on_oom = 0
# DB, 벡터 검색, Java 힙 할당을 위한 VMA 슬롯 확장
vm.max_map_count = 2621440

# [중요] 백그라운드 페이지 마이그레이션으로 인한 P99 레이턴시 튐 방지
kernel.numa_balancing = 0

# 메모리 단편화 완화
vm.min_free_kbytes = 1048576

### ====================================================================
### 3. 네트워크 코어 & 큐(Queue) 확장
### 용도: 25G/100G 고속 환경에서 NAPI softirq 큐 포화 및 패킷 드롭 방지
### ====================================================================
# NIC 링 버퍼에서 커널로 넘겨받는 큐 크기 확장
net.core.netdev_max_backlog = 100000

# 소켓 listen 대기열 확장 (Keycloak, Vault, Webhook 일시적 트래픽 집중 대응)
net.core.somaxconn = 65535

# 1회 softirq 인터럽트 처리 주기당 처리할 패킷 수 상향 (time_squeeze 방지)
net.core.netdev_budget = 600
net.core.netdev_budget_usecs = 4000

# BDP(Bandwidth-Delay Product)를 수용할 수 있는 최대 소켓 버퍼 (16MB 할당)
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 1048576
net.core.wmem_default = 1048576
net.core.optmem_max = 2048576

### ====================================================================
### 4. TCP/IP 스택 & 연결 관리
### 용도: 대규모 Pod-to-Pod 통신, ZeroWindow 방지, BBR 혼잡 제어
### ====================================================================
net.ipv4.tcp_window_scaling = 1
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

# TCP 버퍼 오토튜닝 [min default max] (최대 16MB)
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

# 로컬 아웃바운드 포트 고갈 방지
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_max_syn_backlog = 3240000
net.ipv4.tcp_max_tw_buckets = 1440000

# 세션 유지 및 고스트 커넥션 신속 회수
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5

### ====================================================================
### 5. 라우팅, BGP ECMP, CNI(Cilium) & Conntrack 필수 설정
### 용도: 비대칭 라우팅 패킷 드롭 방지 및 수십만 동시 연결 추적
### ====================================================================
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1

# BGP/ECMP 다중 경로 및 Cilium DSR 사용 시 패킷 드롭 방지 (Loose Mode)
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2

# iptables/br_netfilter 브리지 트래픽 전달
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1

# 연결 추적(Conntrack) 테이블 포화 방지 (기본 65,536에서 2백만으로 확장)
net.netfilter.nf_conntrack_max = 2097152
net.netfilter.nf_conntrack_tcp_timeout_established = 86400
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 3600

# 대규모 클러스터 Pod IP 수용을 위한 ARP 캐시 테이블 확장
net.ipv4.neigh.default.gc_thresh1 = 8192
net.ipv4.neigh.default.gc_thresh2 = 32768
net.ipv4.neigh.default.gc_thresh3 = 65536

3. 계층별 성능 관리 절차 (향후 튜닝 연계 구조)

초기 노드 인수 시 세팅한 베이스라인은 향후 상위 스택을 얹었을 때 다음과 같이 연계되어 튜닝 기준점이 됩니다.

[ 물리 계층 (HW/Switch) ]  ── NIC Ring Buffer (4096) / MTU 9000 / PCIe NUMA 바인딩
            │
[ OS 커널 (Sysctl) ]      ── netdev_budget / tcp_rmem(16M) / rp_filter=2 / numa_balancing=0
            │
[ K8s / CNI 계층 ]        ── Cilium Native Routing (BPF Host Routing) / Kubelet CPU Manager (static)
            │
[ 스토리지 / 인프라 앱 ]   ── OpenEBS (NVMe Direct I/O) / MinIO AIStor (Drive 병렬성)
            │
[ 플랫폼 애플리케이션 ]     ── Kyverno (Webhook somaxconn) / Vault (mmap) / Goldilocks (VPA 프로파일링)
  1. Cilium CNI 배포 시:
  • 커널의 net.ipv4.conf.all.rp_filter = 2와 BBR 세팅 덕분에 BGP Control Plane 및 BPF Host Routing을 통한 veth 바이패스 최적화가 병목 없이 활성화됩니다.
  1. Kyverno, Vault, Keycloak 등 고트래픽 플랫폼 앱 구동 시:
  • Admission Webhook 호출 폭주 시 커널의 net.core.somaxconn = 65535net.netfilter.nf_conntrack_max 설정이 Connection refused나 SYN 패킷 드롭을 방어합니다.
  1. Goldilocks / VPA 및 Kubelet 리소스 튜닝 시:
  • 커널의 vm.max_map_countGuaranteed QoS(정수 코어 바인딩)를 적용함으로써, Cgroups CFS Quota에 의한 인위적 CPU Throttling을 방지하고 골디락스를 통해 파드별 권장 리소스를 오버프로비저닝 없이 정밀 측정할 수 있습니다.

==

인수(Acceptance) 단계에서는 "고장 유무 확인 + 튜닝 기준선(baseline) 확보"가 목적이므로, GPU 클러스터처럼 며칠씩 burn-in 하는 수준은 아니지만 ①스펙/재고 검증 → ②HW 스트레스/건전성 → ③OS/커널 기본값 → ④네트워크(스위치~NIC) 검증 순으로 체크리스트를 잡는 게 효율적입니다.

1. 인수 테스트 항목

(1) 인벤토리/스펙 검증

  • dmidecode -t system/bios/processor/memory, lscpu, lspci -vvv, lsblk -o NAME,SIZE,MODEL,ROTA → 발주 스펙(CPU 모델/코어수, DIMM 개수·용량·속도, NIC 모델·포트수, 디스크 종류/용량)과 실물 일치 여부
  • BIOS/펌웨어 버전, BMC(iDRAC/iLO/XCC) 접속·펌웨어 버전, out-of-band 관리 정상 동작
  • BIOS 설정값 확인: SR-IOV, VT-d/IOMMU, NUMA 활성화, Hyper-Threading, C-state/P-state, Power Profile(Performance 권장), Turbo Boost

(2) CPU

  • stress-ng --cpu $(nproc) --timeout 10-30m --metrics 로 전 코어 부하 → 크래시/throttling 여부
  • 부하 중 turbostat 또는 sensors로 온도/클럭 다운(thermal throttling) 관찰
  • numactl -H로 NUMA 노드/코어 매핑이 스펙과 일치하는지

(3) 메모리

  • stress-ng --vm 4 --vm-bytes 90% --timeout 10-20m 또는 memtester로 비트 오류 검출
  • dmidecode -t memory로 DIMM 슬롯 채널 밸런스(성능에 큰 영향) 확인
  • ECC 에러 로그 확인: edac-util, mcelog, ras-mc-ctl --summary
  • (선택) mlc(Intel Memory Latency Checker) 또는 STREAM 벤치마크로 대역폭 baseline 기록 → 이후 노드간 편차 비교용

(4) 스토리지

  • smartctl -a /dev/sdX / nvme smart-log /dev/nvme0 → Health/Wear/에러 카운터
  • fio로 순차/랜덤 R/W IOPS·처리량·latency baseline 확보 (예: fio --name=test --rw=randrw --bs=4k --iodepth=32 --numjobs=4 --size=10G --runtime=60)
  • RAID/HBA 펌웨어, 캐시 정책(WriteBack/WriteThrough), NVMe 개수/PCIe lane 배치(멀티소켓시 NUMA affinity)

(5) NIC (스위치~노드 구간, 병목 확인 핵심)

  • ethtool <iface> → Link speed/duplex, 협상 결과가 스위치 포트 설정과 일치하는지(예: 100G 풀듀플렉스)
  • ethtool -S <iface> 로 rx/tx error, dropped, overrun 카운터가 0인지
  • ethtool -i <iface>로 driver/firmware 버전, ethtool -k로 offload(GRO/TSO/LRO/checksum) 설정 확인
  • ethtool -l/-L로 RX/TX 큐 개수(RSS) 확인 → 코어 수 대비 큐 개수 부족하면 이후 병목 원인
  • LLDP로 실제 연결된 스위치 포트가 설계도와 일치하는지 확인 (lldpctl 또는 lldpad)
  • MTU/Jumbo Frame 종단 테스트: ping -M do -s 8972 <gateway> (9000 MTU 가정)
  • Bonding/LACP 구성 시 cat /proc/net/bonding/bond0로 슬레이브 상태, 케이블 뽑아서 failover 테스트
  • 노드↔ToR 스위치, 노드↔노드 간 iperf3 실측 처리량이 이론치(예: 100G의 90%+) 나오는지 → 이게 실제 "스위치→Pod" 병목 분석의 기준선이 됨
  • VLAN 태깅/서브넷 라우팅 정상 여부, 게이트웨이/DNS 응답 지연

(6) OS/커널 기본 상태

  • 커널 버전, 배포판 버전이 K8s/CNI(Cilium) 호환 매트릭스에 맞는지
  • swapoff -a/etc/fstab에서 swap 제거(K8s 필수)
  • timedatectl/chronyc tracking으로 NTP 동기화 상태(수 ms 이내)
  • 필수 커널 모듈 로드 여부: overlay, br_netfilter, ip_vs, ip_vs_rr, nf_conntrack
  • ulimit -n(open files), ulimit -u(nproc) 기본값 확인
  • SELinux/AppArmor 상태가 설계된 정책과 일치하는지
  • 디스크 파티션/LVM 레이아웃(특히 containerd/kubelet data dir, etcd 전용 디스크 여부)이 설계와 일치하는지
  • 호스트명, 로컬 저장소(yum/apt repo), 시간대 등 기본 프로비저닝 값 확인

이 항목들을 스크립트로 묶어 노드별 결과를 표로 남겨두면, 이후 "이 노드만 유독 latency가 높다" 같은 이상치를 인수 시점 기록과 비교해 빠르게 원인 분리할 수 있습니다.

2. 대규모 K8s 클러스터 baseline 커널(sysctl) 설정값

아래는 "일단 이 값으로 시작해서 실측하며 조정"하는 baseline 성격입니다. 워크로드 특성(커넥션 수, conntrack 규모, RDMA 사용 여부)에 따라 추후 조정이 필요합니다.

네트워크 – 소켓/버퍼

net.core.somaxconn = 32768
net.core.netdev_max_backlog = 250000
net.core.netdev_budget = 600
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 262144
net.core.wmem_default = 262144
net.core.optmem_max = 65536

네트워크 – IPv4/TCP

net.ipv4.ip_forward = 1
net.ipv4.tcp_max_syn_backlog = 32768
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_mtu_probing = 1
net.ipv4.neigh.default.gc_thresh1 = 8192
net.ipv4.neigh.default.gc_thresh2 = 16384
net.ipv4.neigh.default.gc_thresh3 = 32768

브리지/netfilter (kube-proxy iptables/Cilium eBPF 공존 대비)

net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.netfilter.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_buckets = 262144
net.netfilter.nf_conntrack_tcp_timeout_established = 3600

※ conntrack buckets/max는 위 huaweicloud 자료처럼 nf_conntrack_count / 0.7 기준으로 노드 실제 커넥션 수에 맞춰 재산정 권장. Cilium을 eBPF 데이터플레인(kube-proxy replacement)으로 쓰면 conntrack 의존도가 낮아지므로 이후 실측 후 낮춰도 됨.

메모리/VM

vm.max_map_count = 262144
vm.swappiness = 0
vm.overcommit_memory = 1
vm.min_free_kbytes = 65536
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5

파일시스템/디스크립터

fs.file-max = 2097152
fs.nr_open = 1048576
fs.inotify.max_user_watches = 524288
fs.inotify.max_user_instances = 8192
fs.aio-max-nr = 1048576

커널 일반

kernel.pid_max = 4194304
kernel.threads-max = 4194304
kernel.panic = 10
kernel.panic_on_oops = 1

추가로 커널 파라미터는 아니지만 baseline에 같이 점검할 항목

  • CPU governor: performance (cpufreq가 ondemand/powersave면 job 시작 시 클럭 램프업 지연 → CPU 병목 원인)
  • Transparent Huge Pages: 워크로드에 따라 madvise 권장 (DB 계열은 never 검토)
  • IRQ affinity/RPS/RFS/XPS: 고성능 NIC는 irqbalance 끄고 NIC 큐를 코어에 수동 pin, RSS 큐 수가 vCPU 대비 충분한지 (스위치→Pod 경로 병목의 상당수가 여기서 발생)
  • net.core.busy_poll/busy_read는 극한 저지연 요구시에만 검토 (일반은 off)

이 baseline을 노드 인수 시점에 적용/기록해두고, 이후 Cilium(특히 eBPF datapath, XDP 여부), CNPG/OpenEBS 같은 스토리지 IO 헤비 워크로드, Vault/Keycloak 같은 latency 민감 서비스별로 conntrack, ulimit, RSS 큐 배분 등을 개별 튜닝해나가는 구조가 맞습니다.

==

노드 인수(Acceptance) 점검 툴킷

인프라팀이 OS 설치까지 마쳐 인도한 물리 노드를, DevOps 관점에서 K8s 클러스터에
투입하기 전 HW(NIC 포함)/OS/커널 기본 상태를 점검하고, 이후 성능 튜닝의
baseline으로 남기기 위한 스크립트 2종입니다.

node_check.sh        각 노드에서 실행하는 점검 스크립트 (raw 로그 + summary.csv 생성)
aggregate_report.py  여러 노드의 summary.csv를 모아 통계/이상치를 뽑는 스크립트
README.md            이 문서 (사용법 + 판단 기준)

1. 사용 흐름

[각 노드]                                [집계 서버/작업 PC]
node_check.sh 실행                       
  -> /var/log/node-accept/<host>_<ts>/     
       ├─ summary.csv                    결과 디렉터리를 한 곳에 모음
       └─ raw/*.log                      (scp/rsync/ansible fetch 등)
                                          results/
                                            node01_<ts>/summary.csv
                                            node02_<ts>/summary.csv
                                            ...
                                          
                                          python3 aggregate_report.py results/
                                            -> results/_aggregate_report/
                                                 AGGREGATE_SUMMARY.md
                                                 FAIL_WARN_NODES.csv
                                                 OUTLIERS.csv

1-1. 노드에서 점검 실행

# 기본 실행 (부하 테스트는 CPU/메모리만 기본 ON, fio/iperf3는 기본 OFF)
sudo ./node_check.sh

# fio까지 켜고 싶으면 스크립트 상단 RUN_STORAGE_FIO=1 로 바꾸거나,
# 대상 경로를 지정해서 환경변수로 오버라이드
sudo FIO_TESTDIR=/data/fio-test RUN_STORAGE_FIO=1 ./node_check.sh

# iperf3까지 켜려면 상대 서버(다른 노드 등)를 지정
sudo IPERF_TARGET=10.0.0.5 RUN_NIC_IPERF=1 ./node_check.sh

결과는 /var/log/node-accept/<hostname>_<timestamp>/ 아래에 생성됩니다.
(경로는 RESULT_ROOT 환경변수로 바꿀 수 있음)

1-2. 여러 노드 결과 취합

각 노드의 결과 디렉터리를 한 곳(results/)에 모은 뒤:

python3 aggregate_report.py results/ --out report/ --zscore 2.0
  • --zscore : 클수록 이상치 판정이 둔감해짐(기본 2.0). 신규 클러스터라 노드 수가
    적을 때(5~10대)는 1.5 정도로 낮춰서 넓게 잡아보는 것을 권장합니다.

2. node_check.sh 커스터마이징

  • 스크립트 상단 "카테고리 on/off 스위치" 섹션에서 RUN_*=1/0 으로 점검
    카테고리를 켜고 끕니다.
  • 새 점검을 추가하려면: ① RUN_XXX 스위치 하나 추가 → ② check_xxx() 함수
    작성(내부에서 run_and_log로 raw 로그 남기고 record로 summary.csv에 한 줄
    기록) → ③ main()의 호출부에 한 줄 추가.
  • 점검을 빼려면: main()의 해당 호출 줄만 지우거나 스위치를 0으로 두면 됩니다
    (함수 자체를 안 지워도 무해함).
  • record 함수 형식: record <category> <check> <value> <unit> <status> <note>
    • statusPASS/WARN/FAIL/INFO 중 하나만 사용하세요. 아래 3번 표와
      aggregate_report.py가 이 값을 그대로 신뢰합니다.

3. 판단 기준 (status를 어떻게 정했는가)

스크립트가 자체적으로 PASS/FAIL을 낼 수 있는 항목과, 절대 기준이 없어
여러 노드를 모아야 이상치를 알 수 있는(INFO) 항목을 구분했습니다.

카테고리체크판단 기준근거
oskmod_overlay, kmod_br_netfilter모듈 로드 여부K8s(kubelet/CNI)가 요구하는 필수 커널 모듈. 미로드시 파드 네트워킹/컨테이너 런타임 자체가 불안정
osnet.ipv4.ip_forward1이어야 PASS컨테이너 간 라우팅에 필수. 0이면 사실상 K8s 노드로 못 씀
osswap_total0이어야 PASS(설정 가능)kubelet은 기본적으로 swap이 켜진 노드에서 정상 스케줄링을 보장하지 않음
osvm.max_map_count>=262144면 PASS, 미만 WARNElasticsearch/일부 DB·워크로드의 요구 최소치(262144)를 기준값으로 채택. 클러스터에 그런 워크로드가 없다면 WARN 정도로만 취급해도 무방
nic<if>_link_detectedyes면 PASS케이블/포트 결선 여부의 1차 확인
nic<if>_speedTHRESH_NIC_MIN_SPEED_MBPS 이상이면 PASS스위치 포트와의 speed/duplex 협상 실패(예: 100G 포트인데 실제론 25G로 링크업) 조기 발견용. 클러스터의 실제 설계 속도로 스크립트 상단 값을 반드시 맞출 것
nic<if>_error_countersethtool -S 의 err/drop/discard 계열 합이 0이면 PASS0이 아니면 케이블 불량, SFP 문제, MTU 불일치 등 물리 계층 이슈 가능성
memoryecc_errorsCorrected/Uncorrected 에러 미검출시 PASSECC correctable 에러가 반복 누적되면 DIMM 불량 전조 신호인 경우가 많음
storagesmarthealth*SMART PASSED면 PASS디스크 자체 진단 결과. FAIL이면 즉시 교체 대상
cpu / memorystress_teststress-ng 정상 종료(크래시/재부팅 없음)면 PASSburn-in 목적의 최소 확인. 장시간(수시간~24시간) burn-in이 필요하면 *_STRESS_DURATION 값을 늘려서 재실행
timechrony_offset_sec100ms 미만이면 PASSK8s/etcd/인증서 클럭 스큐 이슈를 예방하기 위한 보수적 기준
storagefio_randread/write_iops절대 기준 없음 → INFO디스크 모델/구성에 따라 정상 범위가 다름. aggregate_report.py가 fleet 평균 대비 편차(z-score)로 "이 노드만 유독 느림"을 잡아냄
niciperf3_throughput절대 기준 없음 → INFO스위치 포트/케이블/광모듈 조합에 따라 이론치 대비 실측 편차가 있을 수 있어, 노드간 상대 비교로 이상치를 판단하는 것이 더 신뢰도 높음
inventorysystem_vendor/model/bios_versionINFO만 기록발주 스펙서와의 대조는 사람이 최종 확인해야 하는 영역이라 텍스트로만 남김

위 임계값들은 스크립트 상단 THRESH_* 변수로 모아뒀으니, 클러스터/장비
스펙이 바뀌면 그 값만 조정하면 됩니다.


4. aggregate_report.py 출력물 해석

AGGREGATE_SUMMARY.md

체크 항목별로 전체 노드의 상태 분포(PASS/WARN/FAIL/INFO 개수)와, 숫자값이면
min/max/mean/stdev를 보여줍니다. "클러스터 전체적으로 어떤 항목이 자주
걸리는지" 한눈에 보는 용도.

FAIL_WARN_NODES.csv

node_check.sh가 이미 절대 기준으로 FAIL/WARN 판정한 항목들을 노드별로 나열한
액션 리스트입니다. FAIL부터 우선 조치하세요.

OUTLIERS.csv

절대 기준이 없는 INFO성 수치(예: fio IOPS, iperf3 처리량)에 대해 fleet 평균/
표준편차 대비 z-score를 계산해, |z| >= --zscore인 노드를 뽑습니다.

  • zscore가 음수(-)면 fleet 평균보다 낮은 값 → 대개 "저성능 의심" 노드
  • 노드가 3대 미만인 항목은 통계적 의미가 약해 자동으로 제외됩니다
  • CATEGORY_HINTS(스크립트 상단)에 항목을 등록하면 "높을수록 좋음/낮을수록
    좋음" 방향까지 같이 표시됩니다. 새 INFO성 항목을 추가했다면 여기에도
    등록해주세요.

5. 참고: 이후 단계와의 연결

이 baseline 점검은 커널/K8s/Cilium/애플리케이션(Keycloak, OpenEBS, CNPG,
Vault, Kyverno, Goldilocks 등) 단위의 심화 튜닝을 시작하기 전 "출발선이
고르게 맞춰졌는지" 확인하는 용도입니다. 여기서 잡힌 FAIL/WARN/이상치를
해소한 뒤에 커널 sysctl 세부 튜닝, Cilium eBPF datapath 설정, 워크로드별
리소스 요청/제한(Goldilocks) 조정 등으로 넘어가는 순서를 권장합니다.

profile
engineer

0개의 댓글