기본 콘텐츠로 건너뛰기

[Kubernetes - Operator] Kubernetes 상의 Operator Tools 간략 비교

How to use Operator tools on Kubernetes

지난 게시글인 Kubernetes상의 Operator 나름대로 정리에 이어서 Operator 구현하는 툴들에 대해 정리한다.

Kubernetes를 Operators 관점에서 보면...

  • Orchestrate stateful applications using K8s API
  • Extend API using Custom Resource Definitions
  • Encode domain specific operational knowledge
  • Upgrades
  • Failure and Recovery Scenarios
  • Scaling up / down
  • Purpose built per application
  • Kubernetes is an Operations API

여러 상황들 검토

Kubernetes에 애플리케이션을 배포하는 것은 다양한 형태로 제공된다. 배치 패러다임, YAML 템플릿처리, IaC (Instrastructure as Code) Tooling (ansible, terraform), Controller 등에 대해서 검토한다.

IaC

IaC 툴들은 애플리케이션과 클라우드 인프라를 관리하는데 도움이 된다. 개발자는 이 툴들을 통해서 Kubernetes의 리소스들을 관리할 수 있다. 사용자는 이 툴들을 설치 및 유지보수 도구로 활용할 수 있다. 대표적인 것이 AnsibleTerraform 등이며, 다른 툴들도 많이 존재한다.

이 툴들은 가상머신이나 애플리케이션을 배포하는데 종종 사용되며 이런 자원들을 설명하는데 cattle (소 떼) vs. Pets (반려동물) 패턴을 사용한다. 소 떼는 교체가 쉽고 상태가 중요하지 않은 구성 요소들을 의미하고 주로 웹 서비스, APIs, Jobs 등을 의미한다. 반려동물은 데이터베이스를 포함해 교체나 갱신이 어려운 구성 요소들을 의미한다.

IaC 툴들은 위의 두 가지 유형의 애플리케이션을 비슷하게 다루기 때문에 설치한 이후의 변화를 알지 못하게 된다. 그러나 Operator는 애플리케이션이 동작하는 동안의 관리를 수행할 수 있으며 사용자 정의 리소스와 컨트롤러가 결합되어 있기 때문에 항상 애플리케이션의 정의된 상태와 현재의 상태가 일치하는지를 지속적으로 관리하게 된다.

참고

Terraform Kubernetes Provider v1.10.0 에서는 CRD와 CR에 대한 지원을 계획하고 있지만 아직 제공되지 않는 상태이며 다른 3rd Terraform Provider 에서 지원이 되는 것들이 존재한다.

Static Definition Formats

일반적인 정의 (YAML) 로 정적인 포맷은 클러스터 외부에서 정의되고 이를 다른 도구와 사용하면 애플리케이션 설치, 업그레이드, 롤백할 수는 있지만 클러스터에 설치된 애플리케이션에 대해 자동으로 요청된 상태로 유지하거나 클러스터와 상호 작용하는 매커니즘은 존재하지 않는다.

대부분은 클러스터에 추가로 설치되는 구성 요소가 없기 때문에 쉬운 설치와 사용자가 실행할 수 있는 권한만 있으면 된다. 즉 설치까지는 쉽지만 설치 이후의 제어를 할 수 없다는 것이다.

  • Easy installation
  • No installed component in the cluster
  • No requirements for admin permission on the cluster
  • Limited control over the installed application
  • No interaction with installed applications

Raw YAML 방식은 애플리케이션을 Kubernetes에 배포하는 가장 쉬운 방법이며 단순한 애플리케이션과 대 규모의 애플리케이션을 시작하는 측면에서는 적합하고 검증되어 있는 방식이지만 변화에 대한 처리 등에는 역시 대응하기 힘들다.

Kustomizse 방식은 구성된 YAML을 Kubernetes 클러스터에 적용하기 전에 패치, 머지, 변경이 가능하지만 단지 재 사용적인 측면이지, 이미 설치된 애플리케이션의 업그레이드와 상태 변화에 대응하는 방법은 제공되지 않는다.

Helm은 Kubernetes의 패키지 매니저로 chart 형식으로 패키지를 관리할 수 있고, 패키지의 설치, 업그레이드, 롤백과 커스터마이즈가 가능하다. Helm v2는 클러스터에 Tiller가 설치되고 클라이언트가 API 서버를 통해서 상호 작용하는 방식이며, Helm v3는 구성 요소에 의존하지 않고 클라이언트가 단독으로 처리하는 새로운 아키텍처를 사용한다. 그러나 역시 설치가 된 애플리케이션과의 상호작용이나 라이프사이클의 상태를 커버하지는 못한다.

High Level Frameworks

단순한 구성과 사용자 지정 컨틀롤러 사이의 영역에 존재하며 복잡한 Kubernetes의 내부적인 부분을 감추고 간단한 API 작업을 통해 지원하는 방식이다. 그러나 모든 상세한 것들을 다 노출해 주는 것은 아니기 떄문에 완전히 커스텀하게 컨트롤러를 작성하는 것보다는 제약이 존재한다

MetaController는 웹 후크 (Webhook)를 기반으로 커스텀 컨트롤러를 개발하는 프레임워크로 커스텀 리소스에 대한 동작을 쉽게 정의할 수 있고 기존 API에 기능을 추가할 수 있도록 한다. jsonnet이나 다른 언어들과 같은 기존 도구와 같이 작업할 수 있지만 이런 자유도는 오히려 라이프사이클 컨트롤러를 개발하는데 복잡성만 더 높이는 상황이 될 수 있다.

Custom Controllers

커스텀 컨트롤러를 개발하는 것은 애플리케이션의 라이프사이클을 관리하기 위한 코드를 작성하는 과정으로 다양하게 발생할 수 있는 상황들을 관리하기에 많은 노력이 필요하고 Kubernetes에 대한 많고 자세한 지식들이 필요하고 테스트, Kubernetes 클러스터의 업그레이드, Operator의 데이터 저장 변경과 API 변경 등에 대한 부분도 감안해야 하기 때문에 쉬운 작업이 아니다.

  • Full control over the cluster and deployed resources
  • Allows reaction to changes in the cluster, custom resources, validation
  • Allows any required behavior
  • Requires intimate knowledge of Kubernetes internals
  • Is an extra software to develop, test and manage

Kubernetes Client

가장 많은 자유도가 있는 방식으로 어떤 Wrapper나 Layer가 없이 직접 Low level로 Kubernetes API를 접속하는 클라이언트를 작성하는 것이며, 각종 언어들 (Go, Java, JS/Typescript, ...)의 활용이 가능하다. 개발에 어떤 제한이나 권장이 없기 때문에 알려진 여러 문제들이나 Kubernetes 영역에서 공통적으로 제시하는 가이드들이 없기 때문에 스스로 해결해야 하는 문제가 있다.

Kubebuilder

CRD를 이용해서 Kubernetes API를 구축하기 위한 프레임워크로 Go를 사용하고 새로운 컨틀롤러들을 개발하는데 controller-runtime 라이브러리를 활용한다.

Kubebuilder 접근 방식은 데이터를 CRD에 저장하고 CR들과 다른 리소스들을 감시하고 작성한 비즈니스 로직을 따르는 변경 처리를 수행하는 루프를 구현한다.

Operator SDK

controller-runtime을 중심으로 Higher level 프레임워크로 많은 Scaffolding들을 제공하고 Helm 이나 Ansible과 통합을 허용하고 많은 Feature Set들을 제공한다.

Operator 개발을 위한 툴 비교

참고

Kubernetes의 원래 초점은 애플리케이션의 오케스트레이션이기 때문에 상태가 저장되지 않는 일반적인 애플리케이션을 대상으로 했었지만, 실제 운용되는 애플리케이션들은 상태관리가 필요한 것들이 많기 때문에 쿠버네티스 1.5부터 StatefulSet을 추가해서 안정적인 네트워크와 스토리지 개념을 제공했지만, 실제 파드 내에서 어떤 일이 발생하는지를 모르기 때문에 단순히 애플리케이션의 중지/배포/시작의 단순한 처리로는 해결되지 않는 부분이 많으며, 이를 해결하기 위한 운영자의 노력과 지식을 자동화해 보자는 시도가 Operator라는 것으로 진행되고 있다.

오퍼레이터 패턴에 대해 다시 정리하면 상태 저장 애플리케이션 (상태를 근거로 하나 이상의 인스턴스가 서로 긴밀하게 연결되는)을 구성하고, 유지 관리하기 위한 사람들의 지식을 포착해서 Kubernetes상의 API 를 확장 (CRD or API Aggregation Layer)하고 자동화하는 수단을 제공하는 것이다.

대표적인 수행 작업들은 아래와 같으며, 애플리케이션이 동작하는 동안의 거의 모든 작업들을 처리할 수 있다.

  • 백업
  • 데이터 조정
  • 확장
  • 설정 변경

이와 같이 Kubernetes 만으로는 해결할 수 없는 것들을 처리히기 위한 운영자의 지식을 자동화하는 Operator는 여러 가지 방법으로 구성할 수 있다.

  1. Operator Framework
  2. KubeBuilder and MetaController
  3. KUDO

1, 2 번이 SDK에 근거해서 코드를 작성하고 Kubernetes에 대한 지식을 기반으로 하는 것에 반해서 KUDO의 경우는 다형성 기반의 선언적 접근 방식이다.

Operator Development 관점의 비교

Operator Framework Kubebuilder Kudobuilder
Redhat / IBM Project Kubernetes SIG API Machinery sub-project Polymorphic
Implement using Ansible, Helm charts, or Go Written in Go with a focus on code generation Universal Operator
Existing implementations often don't cover the entire lifecycle Existing implementations often don't cover the entire lifecycle Built using community projects (Kubebuilder, Kustomize, ...)
Ansible and Helm are limited. Go requires 1,000s of lines of controller code Write Operators as templated YAML manifests
Provide high level CRDs that represent workloads
Focused on higher level coordination of software lifecycles
Day 2 Operators
support test framework kuttl for check operator

Operator Framework Architecture

Operator Framework Architecture

KUDO Architecture

Architecture of KUDO

다음에는 가장 Kubernetes의 선언적 운영 방식에 좀 더 적합한 것으로 판단되는 KUDO 정리 (Kubernetes Universal Declarative Operator - Kudobuilder) 해 보도록 한다.

참고 자료

댓글