devops

쿠버네티스 이해하기: watcher vs informer

Kubernetes는 다양한 환경에서 컨테이너화된 애플리케이션을 관리하기 위한 오케스트레이션 표준으로 자리 잡았는데, 그 이유 중 하나는 애플리케이션이 클러스터 내의 상태 변화에 동적으로 대응할 수 있기 때문이다. 이러한 기능을 가능하게 하는 두 가지 핵심 개념은 와처와 인포머이다. 이 포스팅에서는 이 두 개념이 무엇인지, 어떻게 다른지, 언제 두 개념을 함께 사용해야 하는지에 

Watcher: 쿠버네티스의 실시간 알림

쿠버네티스의 와처는 즉각성과 실시간 업데이트에 관한 것이다. 쿠버네티스 리소스에서 와처를 사용하면 애플리케이션이 쿠버네티스 API 서버와 직접 통신을 연결한다. 이는 파드, 서비스 또는 디플로이먼트와 같은 특정 리소스 유형에 대한 업데이트를 subscribe하는 것과 비슷하다.

작동 방식은 다음과 같다. 쿠버네티스 API 서버는 클라이언트에 대해 HTTP 연결을 열어둔다. 파드, 서비스와 같은 지정된 리소스가 변경될 때마다 해당 리소스의 현재 상태를 나타내는 새 JSON 객체를 보낸다. 이는 변경 사항이 발생할 때 애플리케이션에 정보를 제공하는 간단하고 직관적인 방법이다.

하지만 단순하고 저순준 api인 만큼 대가가 따른다. 와처는 상태를 유지하지 않고 단지 변경 사항을 알리기만 한다. 애플리케이션에서 전체 컨텍스트를 이해하거나 변경 이력을 유지해야 하는 경우 직접 컴포넌트 개발이 

Informer: 정교하고 상태가 저장된 감시

인포머는 와처를 한 단계 더 발전시킨 것이다. 이는 쿠버네티스의 고 패키지인 ’client-go’의 일부이며 쿠버네티스 API와 상호 작용하는 보다 정교한 방법을 제공한다. 인포머는  와처를 아래 추가 기능들로 감싼다.

1. 캐싱: 인포머는 감시하는 리소스의 로컬 캐시를 유지하여 애플리케이션이 API 서버에 접속하지 않고도 리소스의 현재 상태를 쿼리할 수 있도록 한다.

2. 인덱싱: 이 기능을 사용하면 특정 리소스 필드를 기반으로 빠른 조회 및 목록 작업을 수행할 수 있다.

3. 이벤트 핸들러: 핸들러를 사용하면 다양한 유형의 리소스 변경(추가, 업데이트, 삭제)에 대한 이벤트 핸들러를 등록하여 변경에 구조적으로 대응할 수 있다.

4. 복원력: API 서버의 감시가 중단될 경우 자동으로 재연결 로직을 처리하여 서버 상태의 일관성을 보장한다.

인포머의 로컬 캐시는 특히 강력합니다. 이 캐시는 API 서버의 이벤트 스트림을 수신하여 로컬 저장소를 업데이트하고 클러스터의 현재 상태와 항상 동기화되도록 한다. 그런 다음 이 캐시는 애플리케이션에 대한 단일 데이터 소스 역할을 하게 된다. 와처에 비해 불필요한 요청과 리소스를 많이 줄게 된다.

파이썬으로 작성된 와처 예시를 보면 와처는 스트림으로 이벤트를 계속 받는다. 이후 이벤트 타입에 따라 다르게 처리되는데 캐싱, 이벤트 핸들러등은 직접 구현하여야 한다.

인포머는 와처에서 추상화 레이어가 추가된 고수준 기능이다. 로컬 캐싱 메커니즘, 정교한 이벤트 핸들러, 운영 내부에 복원력과 같은 기능이 추가되었다. 인포머는 변경 사항을 알려줄 뿐만 아니라 리소스의 현재 상태를 유지하고, 재연결을 처리하며, 복잡한 이벤트 중심 로직에 집중할 수 있게 한다.

인포머의 예시 코드를 보자. 인포머는 파이썬 kubernetes 패키지엔 없고, 고 패키지에 구현되어 있다. 인포머의 경우, 인포머 자체에서 처리해주는 것들이 있기 때문에 사용자는 단순히 이벤트 핸들러에만 집중할 수 있고, 와처에 비해 효율적이다.

와처와 인포머를 사용할 경우

와처를 사용할지 인포머를 사용할지는 어플리케이션의 복잡성에 따라 결정된다.

와처를 사용하는 경우:

  - 변경 사항에 대한 응답으로 간단한 작업을 수행해야 하는 경우.

  - 애플리케이션이 상태를 유지할 필요가 없는 경우.

  - 적은 수의 리소스를 관리하고 있는 경우.

인포머를 사용해야 하는 경우:

  - 리소스의 로컬 상태를 최신 상태로 유지해야 하는 경우.

  - 리소스를 관리하거나 모니터링하는 컨트롤러 또는 운영자를 구축하는 경우.

  - 이벤트 핸들러를 사용하여 이벤트를 보다 체계적으로 처리하려는 경우.

  - 복원력 및 자동 재연결 처리가 필요한 경우

요약

와처는 좋아하는 프로그램이 새 에피소드를 공개하는 순간 알려주는 기본 구독 서비스와 같다. 반면, 인포머는 알림뿐만 아니라 에피소드를 녹화하고, 출연진에 대한 추가 정보를 제공하며, 연결이 끊어질 경우 중단한 지점부터 재생을 재개하는 프리미엄 서비스와 비슷하다.

쿠버네티스를 기반으로 구축하는 개발자에게는 와처와 인포머 중 어느 쪽을 이해하고 선택하는 것이 중요하다. 올바른 선택은 코드를 간소화하고, 성능을 개선하며, 동적 컨테이너 환경에서 애플리케이션이 필요한 만큼의 응답성과 복원력을 갖도록 보장할 수 있다.

cgroup 드라이버 이해하기: systemd, cgroupfs, 그리고 쿠버네티스 관점으로

소개

쿠버네티스와 같은 컨테이너 오케스트레이션 기술에서 효율적인 리소스 관리는 컨테이너화된 애플리케이션의 원활한 운영을 보장하는 핵심 기술이다. 클러스터가 커지고 워크로드가 변동함에 따라 리소스 사용량을 할당, 추적, 제한하는 기능은 필수적인 기능이다. 바로 이 부분에서 control group(cgroup)은 기본 메커니즘으로 프로세스 그룹 간에 시스템 리소스를 격리하고 관리할 수 있게 해준다. cgroup 드라이버는 이러한 cgroups의 추상화를 더욱 세밀하게 조절하여 시스템의 리소스 할당을 관리하는 구조화된 방식을 제공한다.

cgroup 드라이버, 특히 systemd 및 cgroupfs는 리소스 할당을 조율하는 지휘자 역할을 하며, 각각 고유한 접근 방식과 기능을 가지고 있다. 이 두 드라이버는 모두 쿠버네티스와 같은 최신 컨테이너 오케스트레이션 시스템의 효율적인 기능에 필수적인 요소이지만, 컨테이너 오케스트레이션의 리소스 관리 메커니즘을 자세히 알아보려면 개별적으로, 쿠버네티스와 함께 작동하는 방식의 미묘한 차이를 이해하는 것이 중요하다.

이 포스트에서는 cgroup 드라이버의 레이어를 살펴보고, systemd와 cgroupfs에 대해 간단하게 알아보고, Kubernetes 환경 내에서 이들 간의 상호 작용을 본다. 그 다음 systemd, cgroupfs 및 Kubernetes에서의 역할에 보고, 컨테이너화된 애플리케이션의 최적화된 운영에 필수적인 일관된 리소스 관리 프레임워크를 형성하기 위해 이러한 구성 요소가 어떻게 결합되는지 이해한다.

cgroup 드라이버

control group(cgroup)은 Linux 커널의 핵심 기능으로, 프로세스를 그룹화하고 리소스 할당을 체계적으로 관리할 수 있는 메커니즘을 제공한다. cgroup은 서로 다른 프로세스 그룹 간에 CPU, 메모리 및 디스크 I/O와 같은 리소스를 격리하고 제어할 수 있도록 하여 시스템의 전반적인 안정성과 성능을 유지하며, 각 프로세스가 리소스를 할당받을 수 있도록 한다. 지금의 컨테이너 기술이 있게 한 가장 핵심적인 기술이다.

리눅스 시스템과 cgroup 사이에서 중개자 역할을 하는 cgroup 드라이버는 이러한 리소스 관리를 조율하는데 중요한 역할을 한다. 이 드라이버는 cgroup을 생성, 구성 및 삭제하여 시스템에서 리소스가 할당되고 관리되는 방식에 대한 구조화된 접근 방식을 제공한다.

cgroup 드라이버에는 systemd와 cgroupfs의 두 가지 기본 드라이버가 있으며, 각 드라이버는 cgroup 관리에 대한 서로 다른 접근 방식을 가진다. systemd와 cgroupfs 중 어떤 것을 선택할지는 배포할 환경의 특정 요구 사항으로 결정되는 경우가 많다. 

요약하면, systemd는 보다 통합적인 접근 방식을 제공하는 반면, cgroupfs는 cgroup 관리를 위한 전용의 간단한 인터페이스를 제공한다.

cgroup 그리고 cgroupV2

cgroupV2는 cgroup의 단점들을 해결하려는 업데이트 버전이다. 2016년부터 개발되어 왔으며 커널 4.5부터 도입되었는데 우분투에서는 21.10부터 기본값으로 cgroupV2를 쓴다고 한다. 하지만 현재 대부분의 리눅스 버전에서 이미 cgroupV2를 쓰고 있을 확률이 높다.

cgroupV2는 통합 계층 구조를 적용하여 복잡성과 잠재적 혼란을 줄였다. 이 통합 계층 구조는 리소스 관리를 간소화하고 다양한 프로세스 그룹에 리소스를 할당할 때 일관된 접근 방식을 보장한다. 간단하게 cgroup보다 훨씬 간결한 리소스 관리 인터페이스를 제공한다. 이외에 PSI(압력 스톨 정보) 및 IO 비용 모델과 같은 향상된 기능, 간소화된 구성, 향상된 리소스 제어 메커니즘, 최신 컨테이너화된 워크로드 및 쿠버네티스와 같은 오케스트레이션 시스템과의 더 나은 연계 등 몇 가지 주목할 만한 개선된 것들도 많다.

systemd

UNIX와 유사한 운영 체제의 주요 초기 시스템인 systemd는 부팅 프로세스와 서비스 관리 방식을 크게 간소화하는 기술이다. systemd는 초기화 시스템으로서의 역할 외에도 시스템 리소스를 관리하기 위해 cgroup 기능과 복잡하게 얽혀 있으며, 프로세스 수명 주기 관리와 리소스 할당 간의 공생 관계를 보여준다.

cgroup 관리를 systemd에 통합하는 것은 시스템 초기화 및 리소스 관리에 대한 총체적인 접근 방식이다. 이러한 통합 접근 방식은 효율적이기는 하지만, 컨테이너를 사용하기 이전 베어메탈 서버를 그대로 쓰던 시절에 간단하게 많이 쓰였지만, 특히 쿠버네티스와 같은 복잡한 오케스트레이션 환경에서 효과적으로 활용하기 위해서는 미묘한 이해가 필요하다.

cgroupfs

cgroupfs는 systemd와 뚜렷한 대조를 이루며, cgroup 관리에만 집중하는 전용 cgroup 드라이버를 구현한다. 가상 파일 시스템을 추상화하여 리소스 할당을 관리하기 위한 단순하고 직관적인 인터페이스를 제공한다. 이러한 추상화를 통해 관리자와 도구가 cgroup과 상호 작용하는 인터페이스를 보다 간단하고 이해하기 쉽게 만들 수 있다. 단순히 cat FILE, echo 1 >> FILE 과 같은 파일 시스템을 수정하는 것만으로 cgroup을 관리 할 수 있는 것이다.

독립적으로 운영하든 쿠버네티스와 같은 컨테이너 오케스트레이션 환경 내에서 운영하든, cgroupfs는 효과적이고 간단한 cgroup 관리를 위한 방법이다

쿠버네티스에 통합

쿠버네티스가 cgroup 드라이버로 systemd와 cgroupfs를 모두 지원한다는 것은 다양한 리소스 관리 패러다임에 부합하는 플랫폼의 유연성을 보여준다. cgroup 드라이버는 쿠버네티스가 노드와 파드 전반에서 리소스를 관리하는 방식에서 중요한 역할을 하며 리소스 할당, 격리, 모니터링 및 서비스 품질(QoS) 적용에 영향을 미친다.

쿠버네티스의 원활한 운영을 위해서는 쿠버네티스, 선택한 cgroup 드라이버, 컨테이너 런타임 간의 호환성이 매우 중요하다. 쿠버네티스 역시 1.25부터 cgroup V2를 정식 지원한다. cgroupV2 지원으로의 전환은 리소스 관리를 더욱 세분화하여 리소스 사용량을 더욱 정밀하게 제어하고 모니터링할 수 있을 것으로 기대된다.

결론

systemd, cgroupfs, 그리고 이 둘의 쿠버네티스와의 상호 작용을 통해 컨테이너 오케스트레이션의 리소스 관리 메커니즘 대략적으로 이해했다. 이러한 이해는 리소스 효율성과 애플리케이션 성능 간의 균형을 보장하여 강력하고 탄력적인 컨테이너 오케스트레이션 에코시스템을 조성함으로써 Kubernetes 환경을 최적화하려는 모든 사람에게 중요한 역할을 할 것이다.

참조

https://kubernetes.io/docs/setup/production-environment/container-runtimes/#cgroup-drivers

https://kubernetes.io/docs/concepts/architecture/cgroups/

https://kubernetes.io/blog/2022/08/31/cgroupv2-ga-1-25/