Operators & CRDs(CustomResourceDefinitions) on Kubernetes

6 분 소요

Operators in Kubernetes

Operators 란?

정의(Definition) : Kubernetes Application 을 패키징, 배포, 관리하는 방법. Helm과는 조금 달라 따로 이야기 해보고자 한다.

기본적으로 Kubernetest Application은 kubernetes에 의해 배포되고 kubect과 kube-API를 사용하여 관리한다.

결론적으로 말하면 Kubernetes에 내가 만든 application을 서비스하고 관리하려면 결국 Kubernetes의 API들을 모두 이해하고 사용할수 있어야 한다. 일반적인 개발자에게 진입장벽이 어느정도 있다고 보여지며 이를 모두 이해시키는것도 조직적인 측면에서는 낭비일수 도 있다. 그래서 Helm등을 통한 application배포 전략을 세우기도 하지만 이것도 한계가 있을수 있다. 그래서 Operator는 Kubernetes상에서 application을 관리하는 런타임이라고 생각하는게 맞는것 같다.

etcd

Operators

Operators는 application마다 운영정보를 넣을수 있다.

Kubernetes 에 배포된 응용프로그램의 모든 특성을 알 필요가 없고 이를 통해 사용자는 매니지드 클라우드 서비스 경험(기존 IaaS/PaaS관리와 유사)과 유사하게 운영이 가능하다.

Operator가 배포되면 Kubernetes API확장 개념인 CRDs(Custom Resource Definitions)을 사용하여 관리할수 있다. Kubernetes에 Stateful 서비스를 배포하는 단순하고 좋은 방법이 될수 있다.

예를 들면, Postgres 클러스터, Prometheus 클러스터, Etcd 클러스터 같이 운영측면의 application들을 유지, 운영하는데 쓰일수 있다. (자세한건 뒤쪽 예시로 설명하겠다)

그러면 먼저 CRDs(Custom Resource Definitions)에 대해서 먼저 알아본다. CRDs에 대해서는 별도로 정리하려 하다가 내용이 많이 않아 핵심적인 내용만 같이 적어본다.

  • Custom Resource Definitions(a.k.a CRDs)
  • k8s Object를 확장해서 사용할 수 있는 가장 간단한 방법
  • CRDs는 Kubernetes의 확장 기능
  • Kubernetes 사용자가 클러스터내에서 직접 custom Object를 yaml형태로 생성, 수정, 삭제, 사용할수 있도록 하는 기능
    • K8s database(etcd)와 API를 그대로 활용할 수 있음)
    • CRUD 가능 (Create, Read, Update, Delete)
  • 모든 클러스터에 동적으로 resource 등록/삭제 가능
  • Operators는 CRDs를 포함하고 있음
    • Operator를 추가하면 CRDs가 등록됨
  • Resource 당 하나의 API 버전만 지원(~1.10버전, 1.11버전 이후 개수 제한 없어짐)
  • 1.8+ 이후부터 JSON 스키마 유효성 검증 가능 ** *주의사항 : etcd가 별도 분리된 managed서비스나 etcd 인스턴스가 분리된 환경에서 사용권고**

주요 활용용도

  • Operators
  • Application 정보 저장
  • RouteRule on istio
  • GameServer on Agones

CRDs 관련 발표자료

https://ddiiwoong.github.io/2018/openinfraday18/

Operators example

etcd, Rook, Prometheus, Vault, MySQL, Postgres, Redis, kafka-비공식 등 Operator로 배포될수 있는 예시들은 해당 링크를 보면 자세히 확인할 수 있다. (오라클이 공격적으로 K8s비지니스로 뛰어드는듯한 그림이다…)

주로 저장소나 키-밸류 스토어, RDB등의 운영안정성을 위한 클러스터 구성을 위한것들이 대부분이며 점점 도입을 해나가는 추세이긴것 같긴 하다. 이번에 진행해보고자 하는건 분산 키-밸류 스토어이자 kubernetes의 메인저장소로 쓰이는 etcd 이다.

기본적으로 etcd cluster objects는 CRDs로 생성한다. Kubernetes 기본 resource가 아닌 CRDs 이기 때문에 안정성 측면에서 불안하다고 생각할수도 있다. 하지만 User Aggregated API Servers 를 적용하여 안정성, 유효성 검사 및 버전 관리가 개선되었다고 한다. Aggregated API를 사용하면 사용자에게 최소한의 영향을 주면서 Kubernetes objects가 생성되거나 사용자가 etcd operator를 배포,관리할수 있다. (말이 길어서 그렇지 그냥 etcd 클러스터 구성)

현재 프로젝트는 베타로 0.9.2까지 나와 있으며 RedHat이 CoreOS를 합병하는 바람에 문서들이 업데이트가 늦어지는것 같긴하지만 조만간에 1.0이 나올것 같긴 하다.

etcd-operator

etcd operator는 기본적으로 다음과 같은 기능을 한다.

  • Create and Destroy
  • Resize
  • Failover
  • Rolling upgrade
  • Backup and Restore

Requirements

  • Kubernetes 1.8+
  • etcd 3.2.13+

Installation guide

설치는 단순하다. 먼저 RBAC설정을 한다.

$ git clone https://github.com/coreos/etcd-operator.git
$ cd etcd-operator
$ example/rbac/create_role.sh

그리고 etcd-operator 배포

$ kubectl create -f example/deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: etcd-operator
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: etcd-operator
    spec:
      containers:
      - name: etcd-operator
        image: quay.io/coreos/etcd-operator:v0.9.2
        command:
        - etcd-operator
        # Uncomment to act for resources in all namespaces. More information in doc/clusterwide.md
        #- -cluster-wide
        env:
        - name: MY_POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name

deployment.yaml 내용을 보면 CustomResourceDefinition이 존재하지 않는다. etcd-operator가 자동으로 CRD를 생성하기 때문에 아래와 같이 CRD를 확인할 수 있다.

$ kubectl get customresourcedefinitions
NAME                                    KIND
etcdclusters.etcd.database.coreos.com   CustomResourceDefinition.v1beta1.apiextensions.k8s.io

etcd cluster create/resize/failover/upgrade

operator를 이용하여 etc cluster를 구성한다. operator를 통한 클러스터 구성내용을 확인하면 아주 단순하다. 버전과 사이즈뿐이다.

$ cat example/example-etcd-cluster.yaml
apiVersion: "etcd.database.coreos.com/v1beta2"
kind: "EtcdCluster"
metadata:
  name: "example-etcd-cluster"
  ## Adding this annotation make this cluster managed by clusterwide operators
  ## namespaced operators ignore it
  # annotations:
  #   etcd.database.coreos.com/scope: clusterwide
spec:
  size: 3
  version: "3.2.13"
$ kubectl create -f example/example-etcd-cluster.yaml
etcdcluster.etcd.database.coreos.com/example-etcd-cluster created

순차적으로 etcd cluster가 구성되는것을 볼수 있다.

$ kubectl get pods
NAME                              READY     STATUS    RESTARTS   AGE
etcd-operator-69b559656f-wrhxz    1/1       Running   0          3h
example-etcd-cluster-2kd4t667j5   1/1       Running   0          1m
example-etcd-cluster-k4lxm96v7h   1/1       Running   0          1m
example-etcd-cluster-lm7mkhvldw   1/1       Running   0          1m

이번에는 scale-out 테스트를 진행한다.
example/example-etcd-cluster.yaml 내용에서 size: 3size: 5 로 변경하고 다시 적용하면 2 node가 추가로 생성된다.

$ kubectl apply -f example/example-etcd-cluster.yaml
$ kubectl get pods
NAME                              READY     STATUS    RESTARTS   AGE
etcd-operator-69b559656f-wrhxz    1/1       Running   0          3h
example-etcd-cluster-2kd4t667j5   1/1       Running   0          9m
example-etcd-cluster-2pwm84lrf4   1/1       Running   0          34s
example-etcd-cluster-97qk6gs4sp   1/1       Running   0          50s
example-etcd-cluster-k4lxm96v7h   1/1       Running   0          9m
example-etcd-cluster-lm7mkhvldw   1/1       Running   0          8m

반대로 줄이는것도 동일하다.

failover 테스트의 경우에도 그냥 pod를 삭제하거나 worker를 날리는것으로도 동일하게 spec을 유지하는 kubernetes resource 특성으로 인해 바로 생성이 되는것을 확인할수 있다.

이번에는 operator만 날려보겠다. 아래처럼 operator deployment만 삭제를 해도 pods는 남아있는것을 볼수 있다.

$ kubectl delete -f example/deployment.yaml
deployment "etcd-operator" deleted
deployment.extensions "etcd-operator" deleted
$ kubectl get pod
NAME                              READY     STATUS    RESTARTS   AGE
example-etcd-cluster-2kd4t667j5   1/1       Running   0          14m
example-etcd-cluster-2pwm84lrf4   1/1       Running   0          5m
example-etcd-cluster-97qk6gs4sp   1/1       Running   0          5m
example-etcd-cluster-k4lxm96v7h   1/1       Running   0          14m
example-etcd-cluster-lm7mkhvldw   1/1       Running   0          13m

etcd pod 하나를 날려본다. 4개 pod만 남은것을 확인할 수 있다.

$ kubectl delete pod example-etcd-cluster-2kd4t667j5 --now
pod "example-etcd-cluster-2kd4t667j5" deleted
$ kubectl get pod
NAME                              READY     STATUS    RESTARTS   AGE
example-etcd-cluster-2pwm84lrf4   1/1       Running   0          9m
example-etcd-cluster-97qk6gs4sp   1/1       Running   0          9m
example-etcd-cluster-k4lxm96v7h   1/1       Running   0          18m
example-etcd-cluster-lm7mkhvldw   1/1       Running   0          17m

다시한번 operator를 배포하게 되면 잠시후에 5개로 다시 pod가 복원된것을 확인할수 있다.

$ kubectl create -f example/deployment.yaml
deployment.extensions/etcd-operator created
$ kubectl get pod
NAME                              READY     STATUS    RESTARTS   AGE
etcd-operator-69b559656f-8ks8m    1/1       Running   0          44s
example-etcd-cluster-2pwm84lrf4   1/1       Running   0          11m
example-etcd-cluster-97qk6gs4sp   1/1       Running   0          11m
example-etcd-cluster-k4lxm96v7h   1/1       Running   0          20m
example-etcd-cluster-kskgvlbsm9   1/1       Running   0          10s
example-etcd-cluster-lm7mkhvldw   1/1       Running   0          19m

업그레이드의 경우도 다른 resource와 동일하게 version 부분을 변경하여 rollout이 가능하다.

정리

다음 소스를 통해 직접 operator를 개발이 가능하다.
(Source: https://coreos.com/operators/)

Operator SDK를 사용하면 Kubernetes API 상세스펙을 배우지 않고도 쉽게 operator 빌드가 가능하다. 또한 관리를 위한 Operator Lifecycle Manager나 Operator Metering 같은 기능을 사용하여 좀더 관리측면에서 강화하고자 하는 CoreOS진영의 노력이 보이는듯 하다.

아직 alpha, beta단계의 operator 프로젝트들이 대부분이지만 helm차트와 같이 kubernetes API 스펙을 이해하고 사용하지 않고도 쉽게 운영자가 기반 어플리케이션을 관리 할수 있다는것으로 보아 향후 RedHat이나 Oracle 진영에서 본인들 kubernetes 관련 제품들을 홍보하고 서비스라인에 포함시키는 방향으로 적극적으로 개발을 하고 있는것으로 보인다. 앞으로 mysql, redis, kakfa 등을 operator로 배포하고 관리하는 일이 더 많아 질것 같다.

댓글남기기