DevOps/Docker & K8S

Kubernetes Operator

SKaSha 2020. 12. 7. 12:24

Operator와 CRD는 쿠버네티스의 철학과 동작 원리를 잘 나타낸다.

Operator

Operators are software extensions to Kubernetes that make use of custom resources to manage applications and their components.

오퍼레이터는 쿠버네티스와 쿠버네티스 이외의 것들을 둘 다 이해하는 쿠버네티스 컨트롤러이다.
이 두 영역에 대한 지식을 결합함으로써, 두 도메인을 모두 이해하는 실제 운영자가 필요한 작업을 자동화할 수 있다.

Custom Resource Definition (CRD)

In the Kubernetes API a resource is an endpoint that stores a collection of API objects of a certain kind.
For example, the built-in pods resource contains a collection of Pod objects.

A custom resource is an object that extends the Kubernetes API or allows you to introduce your own API into a project or a cluster.

CRD는 Kubernetes Object를 모아놓은 Kubernetes API의 엔드포인트이다.

Controller & Reconciliation

Operator와 CRD를 잘 이해하기 위해서는, 쿠버네티스의 기본 철학인 reconciliation에 대해서 이해하고 있어야한다.
레컨실리에이션의 궁긍적인 목표는 실제 상태와 원하는 상태가 동일하도록 지속적으로 조정하는 것이다.

쿠버네티스에서 쿠버네티스 오브젝트를 생성하게 되면 바로 인스턴스화 되는것이 아니다.
사용자가 kubectl을 이용해서 쿠버네티스 오브젝트를 수정하게 되면 kube-apiserver를 통해 etcd에 원하고자 하는 상태 값이 변경 될 것이다.
그리고 요청과 동시에 실제 상태도 변경되는 것이 아니라, 쿠버네티스 시스템이 지속적으로 현재 Status 값과 Object Spec을 비교하면서 만약 이 값이 서로 다를 경우 현재 Status를 Object Spec과 동일한 상태로 reconciliation을 한다.

정리

쿠버네티스의 기본 철학인 쿠버네티스가 어떻게 우리가 원하는 상태로 지속적으로 reconcilitaion 할수 있는지 알아보았다.
위에서 정의 했던 Operator와 CRD에 대해 다시 한번 정의를 내려보자.

CRD는 쿠버네티스 플랫폼에서 특정 도메인 컨셉을 관리하기 위한 목적으로 사용되는 오브젝트 확장으로써 기본 쿠버네티스 오브젝트와 동일하게 Kubernetes API를 통하여 etcd에 저장된다.
오브젝트에 관련되어 CRUD 작업을 하기 위해서는 Kubernetes API를 통해야 하는데, Operator는 이 Kubernetes API를 확장하여 좀 더 복잡한 상태의 어플리케이션 인스턴스를 생성하고 관리할 수 있게 해주며 CRD와 함께 구현되는 Custom Controller이다.
그러므로 오퍼레이터는 CRD를 사용하는 컨트롤러와 상속 관계(is-a)라고 하기도 한다.

예시

CRD는 완전 새로운 형태의 쿠버네티스 오브젝트가 아니고 기존에 존재하는 오브젝트들을 조합하여 새로운 이름의 오브젝트로 명명하는 것이다.
예를 들어 프로메테우스를 설치할때, 이를 위해서 여러가지 컨포넌트들을 설치하고 각각의 컨포넌트들의 생애 주기를 별도로 관리해야하는데, 이를 하나의 커스텀 리소스로 추상화할 수 있다.
또한 오브젝트를 제어하기 위한 API를 직접 구현할 수 있어 관리가 더 용이해진다.

kubectl get deployment 와 같이, kubectl get prometheus 등의 명령어도 사용할수 있다.

공식 예제: https://github.com/kubernetes/sample-controller

컨트롤러와 오퍼레이터의 범위

도메인 로직을 캡슐화하는 방안으로 CRD를 사용할 수 있지만, 컨피그맵을 사용하는 것도 훌륭한 대안이다.
일반 컨피그맵을 사용하면, 사용자에게 CRD 등록을 위한 클러스터 관리자 권한이 없어도 된다는 장점이 있다.
컨피그맵은 status 필드를 모델링 하는데 제한이 있지만, CRD를 사용하게 되면 사용자가 원하는 대로 상태 모델을 정의할 수 있다.

CRD의 또 다른 장점은 CRD의 종류에 따라 갭려 조정이 가능한 세분화된 권한 모델이 있다는 것이다.
같은 네임스페이스의 컨피그맵들은 동일한 권한 설정을 공유하기 때문에,
모든 도메인 설정이 컨피그맵에 캡슐화되어 있을 경우에 RBAC(role-based access controll) 보안이 불가능 하다.

Aggregation API

Aggregation API는 확장된 API server들을 하나의 API 서버처럼 사용하는 기능이다.
CRD 등에 대해 정의한 서버 API를 등록할수 있도록 쿠버네티스는 API Registration이라는 기능을 제공하고 있다.
이러한 API 서버들은 각각의 엔드포인트가 존재하는 것이 아니라, 여러개의 엔드포인트를 하나의 추상 엔드포인트로 제공할수 있도록 Aggregation API를 사용할수 있다.

이러한 Aggregation API를 구현하기 위해서는 apiserver-builderkubebuilder 를 사용하여 구현할 수 있다.

Aggregation API vs CRD

CRD는 사용하기가 더 쉽지만 애그리게이트 API가 더 유연하다.

CRD 애그리게이트 API
프로그래밍이 필요하지 않다. 사용자는 CRD 컨트롤러에 대한 모든 언어를 선택할 수 있다. Go로 프로그래밍하고 바이너리와 이미지를 빌드해야 한다.
실행할 추가 서비스가 없다. CR은 API 서버에서 처리한다. 추가 서비스를 생성하면 실패할 수 있다.
CRD가 생성된 후에는 지속적인 지원이 없다. 모든 버그 픽스는 일반적인 쿠버네티스 마스터 업그레이드의 일부로 선택된다. 업스트림에서 버그 픽스를 주기적으로 선택하고 애그리게이트 API 서버를 다시 빌드하고 업데이트해야 할 수 있다.
여러 버전의 API를 처리할 필요가 없다. 예를 들어, 이 리소스에 대한 클라이언트를 제어할 때 API와 동기화하여 업그레이드할 수 있다. 인터넷에 공유할 익스텐션을 개발할 때와 같이 여러 버전의 API를 처리해야 한다.

공식 도큐먼트

Operator와 Helm의 차이

Q: How is this different than Helm?

A: Helm is a tool for packaging multiple Kubernetes resources into a single package. The concept of packaging up multiple applications together and using Operators that actively manage applications are complementary. For example, traefik is a load balancer that can use etcd as its backend database. You could create a Helm Chart that deploys a traefik Deployment and etcd cluster instance together. The etcd cluster would then be deployed and managed by the etcd Operator.

coreos 기술 블로그

Helm은 리소스를 템플릿을 이용하여 패키지 차트로 배포하는데 중점을 두었다면,
Operator는 커스텀 리소스를 정의하여 원하는 방식으로 동작하도록 하는것이 주 목적이다.