Flyte propeller 와 k8s CRD 상관 관계 정리

Ryan Kim
6 min readDec 29, 2022

--

Flyte 다중 배포 과정에서 발견한 flyte propeller 와 k8s CRD의 역할

Flyte와 관련하여 RBAC 문제를 해결하기 위해 했던 시도 중, 하나의 쿠버네티스 클러스터에 2개 이상의 Flyte 애플리케이션을 배포하는 작업을 한 적이 있다.

차라리 클러스터 내 flyte를 팀 단위로 배포를 진행하여, DNS를 다르게 하여 팀 별로 해당 도메인의 flyte를 사용하자는 전략이었다.

(Flyte에서 RBAC을 설정하는 것은 유료 서비스인 union ml이라는 서비스를 사용할 때만 가능하다.)

오픈 소스 코드를 그대로 가져와 회사 상황에 맞게 커스텀하여 사용하는 것도 하나의 방법이 되겠지만, 이 경우 추후 업데이트 되는 flyte 버전을 반영하기 어렵다는 단점도 분명히 존재하기에 두 flyte 사이의 동기화를 빠르게 반영하기 어렵다는 문제도 존재했다.

결과만 놓고 말하자면 flyte를 다중 배포하는 작업은 실패했다.

flyte의 기본 컴포넌트 (admin, propeller, datacatalog, scheduler 등…)은 배포가 잘 되는데, 문제는 flyte에서 자체적으로 정의한 CRD였다.

추후에 Flyte Community에 관리자에게 물어보니, CRD로 네임스페이스 사용 제한이 있어, 하나의 클러스터에서는 하나의 flyte만 사용하다는 답변도 확인했다.

CRD(Custom Resource Definition)란?

flyte에서 CRD가 왜 적용이 되는지, 안되는지를 알아가기에 앞서 CRD에 대해 아는 정보가 적어 이 부분부터 정리하기 시작했다.

CRD는 쿠버네티스에서 사용자가 직접 정의하는 리소스로, 여기서 정의하는 리소스란 CPU, Memory 같은 것이 아니라 쿠버네티스 내부에서 정의하는 Object에 해당하는 Pod, Deployment, Daemonset 등을 말하며, 쿠버네티스에서 본래 정의 되어 있는 이러한 Object들 말고, 사용자가 직접 정의하는 객체를 CRD를 통해 만들 수 있다는 뜻이다.

이 때 만들어지는 CRD는 어떤 특정 네임스페이스에 소속되어 사용되는 것이 아니고, 쿠버네티스에서 전역 설정으로 배포되기 때문에, kubectl get crd라고 CLI를 입력하면, 전역으로 검색 값이 탐색되는 것을 볼 수 있다.

대략 이런 검색 값이 나온다.

그리고 crd 내부 포맷은 아래와 같은 형태를 띄고 있다.

일부 발췌

이 CRD는 사용자가 정의한 Object 중 하나로 취급 되기 때문에 사용자가 필요한 리소스를 쿠버네티스 내에서 확장하여 사용하는 것이 가능하고, 쿠버네티스 공식 문서에서도 CRD를 “쿠버네티스 API 확장하기” 라는 섹션에서 다루고 있다.

링크

그렇다면 Flyte에서는 이 애플리케이션에서 정의한 CRD를 어떻게 사용하고자 하는가?

FlytePropller와 CRD의 관계

Flyte는 기본적으로 정의된 workflow를 실행하여 각 Task별 실행 상태를 유지하기 위해 Flyte CRD를 사용하고 있다.

이 때, CRD는 아래의 Flytepropeller 아키텍처에서 전체 workflow 상태, 노드/작업 단계, 상태/단계 전환 타임스탬프 등을 포함한 워크플로에 대한 메타데이터를 추적한다.

이에 대한 내용을 도식화한 것이 아래 Flyte propeller architecture 문서에서 제공되는 이미지다.

Flytepropeller는 CRD 인스턴스가 생성/업데이트될 때마다 알림을 전송받으며 Flyte 워크플로의 실행 일정 및 추적을 담당한다.

즉, 이 구조에서 CRD는 주기적으로 평가되며 목표는 관찰된 상태에서 요청된 상태로 전환하는 것이다.

구조대로라면, CRD는 k8s 내에서 global 설정이므로 flyte를 동일 클러스터 내에서 2번 이상 다른 네임 스페이스로 배포하더라도 사용이 가능해져야한다.

무엇보다, Custom k8s 리소스이므로, 여러 네임 스페이스에서 호출해 사용하는 것이 불가능하다는 점이 찾아볼 수록 이상했다.

정답은 CRD 내부에…

그렇게 원인을 찾던 과정에서 배포도 다시 해보고, flyte helm chart도 다운로드 받아 확인해봤다.

그 와중에 CRD yaml 파일을 하나씩 뜯어보니, 한 가지 의심되는 사항이 있었다.

CRD 내부에 “Scope”이라고 선언되어 있던 부분.

이 부분을 검색해보니, 아래 두 링크에서 정답을 확인할 수 있었다.

Scope 부분이 Namespaced라고 되어 있다면, 하나의 Namespace에서만 CRD를 사용할 수 있었던 것.

알고 나니 무척 현타가 왔지만, 정확하게 모른 채 넘어가면 찝찝한 부분을 남긴채로 업무를 봐야하기 때문에 이번에 시간을 투여하길 잘했다는 생각이 든다.

그리고 CRD에 관해 추가적으로 한 가지 더 알게 된 사실은 Object의 현재 상태를 spec에 정의한 상태와 일치시켜주기 위해 컨트롤러라는 것이 쿠버네티스 상에 존재하는데, 이 컨트롤러가 CRD의 상태를 관리해준다.

결국 k8s 객체에 대해 명확하게 모른 것이 문제의 시발점이었던 것.

그런데 문제를 이해하고 나니, 새로운 의문이 들었다.

Scope에 Cluster를 선언하면, CRD를 클러스터 전체로 확산시킬 수 있는 것인가?

이 부분은 개발 서버에서 한 번 테스트를 해보도록 해야겠다.

휴가 기간 동안에 새로 공부해 볼 것

내년부터 본격적으로 사내 ML Infra Platform을 구축하면서 새로운 플랫폼이나 프레임워크가 회의 중에 많이 등장했다.

Influx DB, Druid, Hydra, Hadoop, kafka, ksql, OLAP, OHLCV, TimeScale, presto, Doris, tiered storage, ceph, zfs, postgresql

대중 이 정도인데, 데이터를 처리하기 위한 DB부터 정하는 작업에 착수 중이다.

원최 생소하다보니 관련 내용들을 하나씩 정리해야겠다.

결국 AI 관련 업무는 돌고 돌아 데이터로 오는 것 같다.

Ryan

--

--