이론 정리/인프라

K8S 에서 상태를 관리하는 방법을 살짝만 알아보자

철매존 2026. 3. 2. 22:55
728x90
반응형

K8S 에서 상태를 관리하는 방법을 살짝만 알아보자

그 전에 일단 Stateless 와 Stateful 에 대해 비교하면

  • Stateless
    • 말 그대로 상태가 없다.
    • 언제든지 죽거나 생성해도 되며, pod 의 존재 하나하나가 서비스에 영향을 주지 않는다.
    • 보통의 웹이나 API 서비스 등은 stateless 에 해당한다
  • Stateful
    • 얘는 반대로 상태가 충만한 친구
    • 죽었다가 살아나는 경우 이전의 데이터, 식별자, IP 를 유지한다.
    • 주로 DB, MQ 처럼 데이터 자체를 저장하고 다른 곳에서 같은 곳을 바라보는 것에 사용한다.

여기까지는 아마 대부분 알고 있을 것이라고 생각한다.

백엔드는 주로 Stateless 를 선호한다.

이유는 사실 뻔하기는 하다.

  • 수평 확장 용이
    • 딱히 뭔가 데이터를 관리하는게 아니라, 트래픽이 늘어나면 파드 개수만 늘리면 됨.
  • 장애 복구, 고가용성
    • pod 죽으면 그냥 auto healing 으로 살려주면 된다.
  • 무중단 배포
    • 상태 이전이 필요가 없으니 그냥 지우고 새로 만들면 된다.

그래서 stateless 를 활용하기는 한데...

근데 내 글은 상태를 관리하는 방법에 대해 적어둔 글이다.
왜 그랬는지 이제부터 설명해 본다.

그럼 Stateful 은 어떤 식으로 쓸 수 있을까?

위에서 DB, MQ 처럼 상태를 유지해야 하는 경우 stateful 을 쓴다고 했다.
그러면 이거는 어떻게 할 수 있을까?
중요한 것은 pod 가 죽었다가 살아나도 데이터가 그대로 남아있어야 한다는 것이다.

  • PV (Persistent Volume)
    • 간단하게 말하자면 pod 와는 상관없이 클러스터가 관리하는 스토리지 리소스이다.
    • 미리 특정 크기의 디스크를 만들어 두고, pod 가 삭제되어도 데이터를 보관시킨다.
  • PVC (Persistent Volume Claim)
    • 이거는 요청서라고 생각하면 된다.
    • pod 는 PV 를 직접 바라보지 않고 PVC 를 통해 k8s 에 PV 를 찾도록 요청한다.
    • 그래서 k8s 가 알아서 PVC 에 맞는 PV 를 pod 에 연결시키는 방식으로 간다.

이런 식으로 PV를 만들고 PVC 를 활용하여 Stateful 하도록 만들 수 있는 것이다.

그러면 StatefulSet 은 대체 무엇일까?
상술했듯, 이거는 데이터와 식별자를 유지하도록 pod 를 만드는 건데, 위의 것들을 활용한다.

  • 파드 이름을 예측 가능하게 (예를 들어 db-0, db-1, db-2 ... 이렇게) 만들고
  • 1:1 전용 PVC 할당 (db-0 은 pvc-0, db-1 은 pvc-1 ... 이렇게) 해서
  • pod 가 죽었다 살아나면 그 이름 그대로 딱 맞는 pvc 를 할당받게 하면?

위에서 말한 것들을 해낼 수 있다.

그러면 Stateless 는 이런거 없나?

결론부터 말하자면 Stateless 에서도 PV, PVC 를 쓰는 경우가 많이 있다.
당연하지만 위의 Stateful 과는 목적이나 방식이 전혀 다르다.

이거는 하나의 pod 가 하나의 PVC 를 갖는게 아니라 많이 있는 pod 들이 하나의 PVC 를 공유할 수 있다(ReadWriteMany 사용해서)
이렇게 하면 클러스터의 데이터를 공유할 수 있는 것이다.
그럼 무슨 장점이 있냐면

  • 정적 파일 공유
    • 여러 Nginx 웹 서버가 동일한 이미지 파일을 서비스해야 하는 경우 하나의 PV 에서 모든 Nginx 가 같은 파일을 읽어서 보내주면 됨
  • 대용량 파일의 임시 처리
    • 뭔가 엄청 큰 파일을 업로드해서 내부 처리해야 하는 경우 파드의 기본 메모리로 부족할 수 있으니 이 때 PV / PVC 를 붙여서 파일을 다운받아 변환한 뒤 외부 저장소에 올리고 지워버리는 식으로 활용한다.
  • Log 수집
    • 파드가 죽을 수 있으니... 파드에서 로그를 저장하면 안된다. 그래서 공용 PV 에 로그 파일을 쓸 수 있다.
      • 물론 이거는 안티패턴에 가깝다. 여러 pod 가 하나의 PV 에 계속해서 텍스트를 쓰면 안되기 때문... 힙덤프를 여기 쓰는건 많이들 하기는 한다.

근데 뭔가 이상한게 있기는 하다. Log 나 파일의 임시 처리를 굳이 PV 에서 할 필요가 있을까?

EmptyDir 를 쓴다면 어떨까?

위에서 말한 "임시 공간" 이라면 emptyDir 로 대체할 수 있고, 그게 더 권장되는 방식이다.
(물론 데이터 공유를 위해서는 PV 가 필요함)

  • emptyDir 가 뭔데?
    • 임시 작업 공간이라고 보면 된다.
    • 파드가 노드에 생성될 때 빈 공간으로 만들어지고, 파드가 삭제되면 그 내부 데이터도 삭제된다. (캐시같은 느낌?)
      • 위에서 말한 대용량 파일의 임시 처리를 하는 경우 여기서 처리하면 된다.
      • 로그같은 경우도 여기에 로그를 저장하고 로그 수집기가 여기 쌓인 로그를 긁어가면 된다.

이렇게 되면 굳이 복잡하게 PV, PVC 를 만들어둘 필요가 없을 것이다.
하지만 보면 알겠지만 pod 에 종속되어 있기 때문에 여전히 동일한 파일을 서비스하거나 파드가 죽어도 데이터를 보관해야 하는 경우는 PV 를 써야할 것이다.

근데 임시 파일이면 이거 중간에 죽어버리면 어떡하지?

사실 임시라고 해도 당연히 중요할 수 있다.
예를 들어... 로그를 저장하고 다른 곳에서 읽어야 하는데 그거 가져가기 전에 pod 가 죽으면 영원히 왜 죽었는지 모르기도 하고 데이터를 처리하다가 죽으면 곤란하기도 하고.

  • 동기 처리
    • 예를 들어 대규모 파일을 저장하자 마자 S3 같은 외부 저장소로 보낸다고 한다면
    • 사용자 -> Pod -> 바로 S3 저장 -> Pod 의 emptyDir 에서 제거
    • 사실 이거는 매우 깔끔하다. 죽으면 죽는대로 유저가 문제를 알것이고 아니면 잘 처리 될것이고.
    • 다만 S3 가 죽어버리는 경우 스트리밍 방식에 따라 emptyDir 에 찌꺼기가 남을 수는 있다. 이거는 코드로 잘 해제시키는 것이 필요하다
      • 되게 중요한게, 이거는 디스크 파일에 생기는 것이라 java 같은 애플리케이션 GC 의 대상이 아니다. 잘 지워줘야 한다.
  • 비동기 처리
    • 예를 들어 로그 수집기를 사용하는 경우
    • pod 가 로그 emptyDir 에 저장 -> 같은 pod 의 로그 수집기가 그걸 어딘가로 보냄 -> emptydir 의 로그는 로그 로테이션이 알아서 관리
    • 이거는 뭔가 애매하다. 예를 들어 pod 가 OOM 으로 죽어버린다고 가정하면 로그 수집기가 해당 로그를 수집하기 전에 데이터가 사라져 버린다.
      • 그러면 어떻게 해결함?
        • stdout 같은걸로 텍스트를 뱉으면 k8s 의 node 시스템 디스크에 기록된다.
          • 나중에 글로벌 로그 수집기가 저걸 쓸어가면 된다.
        • 근데 이미 emptyDir 에 쓰고 있다면?
          • 힙덤프 (애매한 해결)
            • 위의 OOM 의 경우는 보통 컨테이너가 죽고, 그러면 힙덤프를 남긴다.
              • 그러면 컨테이너를 파드 내에서 재시작시키는 경우 emptyDir 가 남아있다.
              • 다만 이 힙덤프의 크기가 큰 경우 k8s 가 디스크 용량이 위험하다고 판단해서 파드를 Evict 시켜버릴 수도 있다.
                • 힙덤프만 어떻게 잘 PV 에 설정하는 것이 좋다.

결론

  • Stateless, Stateful 에 대해서, Stateless 에서 어쨌든 데이터에 대해 처리하는 방법에 대해 정리해 봤다.
  • PV, PVC, emptyDir 를 적절히 사용하면 된다.
  • 개인적으로는
    • emptyDir 는 뭔가 정보를 담기보다는 진짜 임시용으로 사용하기
    • PV, PVC 는 공용 파일, 혹은 정말 중요한 파일 보관용
    • 로그같은 애들은 각 파드에서 stdout 으로 뱉고 공용 로그 수집기(daemonset) 이 알아서 긁어가기
    • 이게 좋아 보이고, 이미 구성이 다른 방식으로 되어 있으면 알아서 상황에 맞춰서 처리하면 될 것 같다.
반응형