[kt cloud Container개발팀 정선훈 님]
Container의 kernel 튜닝
Kubernetes Worker Node는 대부분의 워크로드의 요구사항을 충족하는 안정성 및 최적화, 성능에 맞게 구성되지만 특정 워크로드의 성능 최적화를 위해 kernel 설정을 변경해야 하는 경우가 있을 수 있습니다.
Kubernetes에서는 sysctl 설정을 통해 Pod에 독립적으로 kernel 파라미터 수정을 할 수 있도록 제공하고 있습니다.
본 글은 워크로드 성능 최적화를 위해 Pod별로 kernel 파라미터를 변경하는 방법에 대한 내용 입니다.
Container Kernel 파라미터
- 컨테이너의 격리 메커니즘과 Linux의 Namespace를 통해 각각의 컨테이너는 독립적인 환경에서 실행되며, 호스트(VM)와 분리된 커널 파라미터를 가질 수 있습니다.
- Namespace(Linux) : Linux에서 프로세스를 격리 시키는 기술/기능.
- cgroup : cgroup 설정(각 컨테이너에 CPU, 메모리, 디스크 I/O 등의 리소스를 할당 및 제한. )은 kernel 파라미터에 영향을 미침.
- Kubernetes는 namespace와 cgroup을 통해 container와 호스트(VM)의 kernel 파라미터를 격리하여 보안과 안정성을 강화하고 각각의 컨테이너가 독립적으로 운영되도록 하여, 호스트와 다른 kernel 파라미터를 가질 수 있게 만들어 줍니다.
sysctl 설정
- Linux kernel 동작을 제어하는 명령어입니다.
- K8S의 sysctls 설정은 Global(node-level)과 Namespace 항목으로 구분됩니다..
- Global(node-level) - Host OS에서 kernel 파라미터를 변경하면 Pod kernel 파라미터도 변경.
- Namespace - Host OS와는 격리되어 Host OS kernel을 변경하여도 Pod kernel 파라미터는 별개로 동작. Pod마다 sysctl로 kernel 파라미터 설정 가능.
- K8S의 Namespace sysctls 설정은 safe와 unsafe 파라미터로 구분하여 관리됩니다.
- safe 파라미터는 default로 enable 상태입니다.
- unsafe 파라미터는 관리자의 수동작업 필요합니다. (사용 가능하게끔 enable 작업 필요)
- K8S에서 커널 파라미터 변경을 위해 {spec.securityContest.sysctls} 에서 설정 가능합니다.
[safe 파라미터]
- kernel.shm_rmid_forced
- net.ipv4.ip_local_port_range
- net.ipv4.tcp_syncookies
- net.ipv4.ping_group_range
- net.ipv4.ip_unprivileged_port_start
[unsafe 파라미터]
- kernel.shm*
- kernel.msg*
- kernel.sem
- fs.mqueue.*
- net.*
|
K8S 설정 방법
- K8S 1.27 기준
unsafe sysctl 활성화 방법
1.. kubelet drop-in 파일 확인
systemctl status kubelet |
● kubelet.service - kubelet: The Kubernetes Node Agent Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled) Drop-In: /usr/lib/systemd/system/kubelet.service.d └─10-kubeadm.conf ...중략... |
2. kubelet EnvironmentFile 경로 확인
cat /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf |
[Service] Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf" ...중략... EnvironmentFile=-/etc/sysconfig/kubelet ...중략.... ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS |
3.EnvironmentFile에 KUBELET_EXTRA_ARGS 추가.
vi /etc/sysconfig/kubelet |
KUBELET_EXTRA_ARGS="--allowed-unsafe-sysctls=kernel.msg*,kernel.shm*,kernel.sem,fs.mqueue.*,net.*" |
아래 네임스페이스 이외의 unsafe sysctl를 allow 할 경우 kubelet이 정상 동작 하지 않을 수 있음. (kubelet 에러 발생.)
|
4.kubelet 재기동
systemctl daemon-reload |
systemctl restart kubelet |
5. 적용 확인
ps -ef | grep kubelet | grep allowed-unsafe |
활성화된 unsafe sysctl를 container에 적용하는 방법
- pod의 security context 필드에 사용하려는 sysctl 파라미터 추가
- deployment, statefulset, daemonset 모두 동일하게 사용 가능
apiVersion: v1 …중략… spec: template: spec: securityContext: sysctls: - name: kernel.msgmax valule: "65536" - name: kernel.sem value: "32000 1024000000 10000 32000" ...중략... |
|
OCP/OKD 설정 방법
- OKD 4.10 기준
unsafe sysctl 활성화 방법
1.machine config pool에 labels 추가
oc edit machineconfigpool worker |
apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfigPool metadata: generation: 1 labels: custom-kubelet: sysctl ##추가 ...중략.... |
2.kubelet config에 대한 custom resource (CR) 생성
vi set-sysctl-worker.yaml |
apiVersion: machineconfiguration.openshift.io/v1 kind: KubeletConfig metadata: name: custom-kubelet spec: machineConfigPoolSelector: matchLabels: custom-kubelet: sysctl ##1번의 labels과 동일하게 설정 kubeletConfig: allowedUnsafeSysctls: ##sysctl 허용할 커널 파라미터 명 - "kernel.msgmax" - "kernel.msgmnb" |
3.custom resource (CR) 적용
- mcp가 수행되며 노드 재기동 발생.
oc apply -f set-sysctl-worker.yaml |
아래 네임스페이스 이외의 unsafe sysctl를 allow 할 경우 mcp가 정상 동작 하지 않을 수 있음. (kubelet 에러 발생.)
|
4.적용 확인
oc get machineconfig {99-worker-generated-kubelet} -o json | grep ownerReference -A7 |
…중략... "ownerReferences": [ { "apiVersion": "machineconfiguration.openshift.io/v1", "blockOwnerDeletion": true, "controller": true, "kind": "KubeletConfig", "name": "custom-kubelet", …중략... |
활성화된 unsafe sysctl를 container에 적용하는 방법
- pod의 security context 필드에 사용하려는 sysctl 파라미터 추가
- deployment, statefulset, daemonset 모두 동일하게 사용 가능
apiVersion: v1 …중략… spec: template: spec: securityContext: sysctls: - name: kernel.msgmax valule: "65536" - name: kernel.sem value: "32000 1024000000 10000 32000" ...중략... |
|
'Tech story > Container' 카테고리의 다른 글
Harbor, 어떻게 쓸 것인가: Replication Rule (11) | 2024.11.18 |
---|---|
OKD Container migration (1) | 2024.11.07 |
OpenTelemetry를 활용한 K8S Metric, Log, Trace 데이터 통합 수집기 (0) | 2024.11.04 |
쿠버네티스 무작정 따라하기 - #1. kt cloud 에서 K8S Cluster 만들기 (4) | 2024.10.31 |
Container APM 서비스의 HA(High Availability) 테스트 (2) | 2024.10.29 |