ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Kubernetes] PodDisruptionBudget 과 Out of Memory ( OOM ) 관계 알아보기
    Kubernetes 2024. 6. 8. 13:08
    728x90
    반응형

     

    - 목차

     

    들어가며.

    Kubernetes 클러스터에서 Out of Memory(OOM) 을 유발하는 PodPod Disruption Budget(PDB) 와의 관계를 알아봅니다.

    Out of Memory(OOM)Pod Disruption Budget(PDB)의 관계를 살펴보면, OOMPDB 에서 보호하는 의도적인 종료와는 무관합니다.

    PDB관리자에 의해 발생하는 의도적인 Pod 삭제나 중단(예: 노드 유지보수, 클러스터 스케일링)을 제어하기 위해 설계되었습니다.

    반면, OOM 은 애플리케이션 자체의 메모리 부족으로 인해 발생하는 비의도적인 종료로, PDB의 보호 대상이 아닙니다.

     

    이 글에서는 OOM이 Kubernetes 환경에서 발생할 때의 동작을 확인하고, PDB 설정이 의도적인 종료 상황에서 어떻게 가용성을 보장하는지 함께 알아보겠습니다.

     

    Local Kubernetes Cluster 세팅하기.

    Local Kubernetes 클러스터를 구성하기 위해 kind 를 사용합니다.

    https://westlife0615.tistory.com/407

     

    KinD 알아보기.

    - 목차 소개. KinD 는 "카인드" 라고 발음되며, 로컬 머신에서 쿠버네티스를 간편하게 실행할 수 있는 도구입니다. KinD 는 Kubernetes in Docker 의 약자이구요. Docker 를 활용하여 쿠버네티스 환경을 구성

    westlife0615.tistory.com

     

    아래의 명령어는 Local Kubernetes Cluster 의 명세를 정의하는 yaml 파일입니다.

    cat <<'EOF'> /tmp/local_k8s.yaml
    kind: Cluster
    apiVersion: kind.x-k8s.io/v1alpha4
    nodes:
      - role: control-plane
      - role: worker
    EOF

     

    그리고 kind 명령어를 통해서 Cluster 를 실행합니다.

    kind create cluster \
    --name test-cluster \
    --image kindest/node:v1.25.0 \
    --config /tmp/local_k8s.yaml

     

    Out of Memory (OOM) 을 발생시킬 프로그램 작성.

    아래와 같은 구조로 Dockerfile 과 Nodejs 파일을 생성합니다.

    project/
    ├── Dockerfile
    └── oom_test.js

     

    oom_test.js 파일은 아래와 같습니다.

    mkdir -p /tmp/project
    
    cat <<'EOF'> /tmp/project/oom_test.js
    const memoryHog = [];
    
    try {
      while (true) {
        memoryHog.push(new Array(1_000_000).fill('oom_test'));
      }
    } catch (err) {
      console.error('Out of Memory Error:', err);
    }
    EOF

     

    Dockerfile 또한 생성해줍니다.

    mkdir -p /tmp/project
    
    cat <<'EOF'> /tmp/project/Dockerfile
    FROM node:18
    WORKDIR /app
    COPY . .
    CMD ["node", "--max-old-space-size=50", "oom_test.js"]
    EOF

     

    이제 Docker Image 를 빌드합니다.

    docker build -t nodejs-oom-test -f /tmp/project/Dockerfile /tmp/project

     

    마지막으로 Local Kubernetes Cluster 이 이미지를 등록합니다.

    kind load docker-image nodejs-oom-test:latest --name test-cluster

     

     

    Deployment 및 PodDisruptionBudget 생성하기.

    다음으로 OOM을 유발하는 애플리케이션을 Kubernetes에 배포합니다.

    아래는 /tmp/deployment.yaml 파일을 생성하는 스크립트입니다.

    replicas 를 10으로 설정하였고, 메모리 제한을 50Mi 로 설정하였습니다.

    cat <<'EOF'> /tmp/deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nodejs-oom-test
    spec:
      replicas: 10
      selector:
        matchLabels:
          app: nodejs-oom
      template:
        metadata:
          labels:
            app: nodejs-oom
        spec:
          containers:
          - name: nodejs-oom
            image: nodejs-oom-test
            imagePullPolicy: Never
            resources:
              limits:
                memory: "50Mi"
              requests:
                memory: "50Mi"
    EOF

     

    아래는 /tmp/pdbyaml 파일을 생성하는 스크립트입니다.

    PodDisruptionBudget 의 maxUnavailable 의 값을 2로 설정하였습니다.

    종료되는 Pod 의 갯수를 최대 2개로 설정하는 의도입니다.

    cat <<'EOF'> /tmp/pdb.yaml
    apiVersion: policy/v1
    kind: PodDisruptionBudget
    metadata:
      name: nodejs-oom-pdb
    spec:
      maxUnavailable: 2
      selector:
        matchLabels:
          app: nodejs-oom
    EOF

     

    OOM 과 PodDisruptionBudget 테스트.

    시나리오는 아래와 같습니다.

    1. replicas 가 10인 Deployment 를 생성합니다.
    2. maxUnavailable 이 2인 PodDisruptionBudget 을 생성합니다.
    3. Pod 들은 OOM 으로 비정상 종료가 되며, PodDisruptionBudget 은 최대 2개까지의 Pod 의 종료를 제지해야합니다.
    4. 하지만 PodDisruptionBudget 은 비정상 종료되는 Pod 를 제지할 수 없음을 모니터링합니다.

     

    항상 kubectl 명령어를 사용할 때에 현재 연결된 context 를 확인합니다.

    kubectl config current-context

     

    그리고 PodDisruptionBudget 과 Deployment 를 생성합니다.

    kubectl apply -f /tmp/pdb.yaml
    kubectl apply -f /tmp/deployment.yaml

     

     

    아래의 결과는 Deployment 의 생성 이후의 Pod 들의 상황입니다.

    OOM 으로 종료와 Restart 를 반복합니다.

    그리고 PodDisruptionBudget 의 상태를 보았을 때에 Current 와 Desired 의 값이 서로 상이합니다.

     

     

    반응형
Designed by Tistory.