From e602fd0da406efa6dcebaeb93dfaf94048dd6123 Mon Sep 17 00:00:00 2001 From: SuminSSon Date: Tue, 10 Sep 2024 18:19:09 +0900 Subject: [PATCH] docs(main): add korean translation Signed-off-by: SuminSSon --- .../ko/wgs/operator/whitepaper/v1/index.md | 913 ++++++++++++++++++ 1 file changed, 913 insertions(+) create mode 100644 website/content/ko/wgs/operator/whitepaper/v1/index.md diff --git a/website/content/ko/wgs/operator/whitepaper/v1/index.md b/website/content/ko/wgs/operator/whitepaper/v1/index.md new file mode 100644 index 00000000..c509a1ab --- /dev/null +++ b/website/content/ko/wgs/operator/whitepaper/v1/index.md @@ -0,0 +1,913 @@ +--- +title: "CNCF 오퍼레이터 문서" +pdf: https://github.com/cncf/tag-app-delivery/blob/main/operator-whitepaper/v1/CNCF_Operator_WhitePaper_v1-0_20210715.pdf +version_info: https://github.com/cncf/tag-app-delivery/blob/main/operator-whitepaper/latest/README.md +description: "이 문서에서는 오퍼레이터의 분류 체계뿐만 아니라 권장 구성, 구현 및 오퍼레이터 애플리케이션 관리 시스템의 사용 사례에 대해서도 설명합니다." +type: whitepapers +--- + +## 목차 + +- [목차](#목차) +- [정의](#정의) +- [요약](#요약) +- [소개](#소개) + - [문서의 목표](#문서의-목표) + - [타겟 청중 / 최소 경험 수준](#타겟-청중--최소-경험-수준) +- [기초](#기초) + - [오퍼레이터 디자인 패턴](#오퍼레이터-디자인-패턴) + - [오퍼레이터의 특성](#오퍼레이터의-특성) + - [동적 구성](#동적-구성) + - [운영 자동화](#운영-자동화) + - [도메인 지식](#도메인-지식) + - [쿠버네티스의 오퍼레이터 구성요소](#쿠버네티스의-오퍼레이터-구성요소) + - [쿠버네티스 컨트롤러](#쿠버네티스-컨트롤러) + - [사용자 정의 리소스 및 사용자 정의 리소스 정의](#사용자-정의-리소스-및-사용자-정의-리소스-정의) + - [제어 루프](#제어-루프) + - [오퍼레이터 기능](#오퍼레이터-기능) + - [애플리케이션 설치 / 애플리케이션 소유권 가져오기](#애플리케이션-설치--애플리케이션-소유권-가져오기) + - [애플리케이션 업그레이드](#애플리케이션-업그레이드) + - [백업](#백업) + - [백업에서 복구](#백업에서-복구) + - [자동 복구](#자동-복구) + - [모니터링/메트릭스 - 가시성](#모니터링메트릭스---가시성) + - [스케일링](#스케일링) + - [자동 스케일링](#자동-스케일링) + - [자동 구성 조정](#자동-구성-조정) + - [제거 / 연결 해제](#제거--연결-해제) +- [보안](#보안) + - [오퍼레이터 개발자](#오퍼레이터-개발자) + - [투명성 및 문서화](#투명성-및-문서화) + - [오퍼레이터 범위](#오퍼레이터-범위) + - [취약성 분석](#취약성-분석) + - [애플리케이션 개발자 (오퍼레이터 "사용자")](#애플리케이션-개발자-오퍼레이터-사용자) +- [쿠버네티스를 위한 오퍼레이터 프레임워크](#쿠버네티스를-위한-오퍼레이터-프레임워크) + - [CNCF 오퍼레이터 프레임워크](#cncf-오퍼레이터-프레임워크) + - [Kopf](#kopf) + - [kubebuilder](#kubebuilder) + - [Metacontroller - 경량 Kubernetes 컨트롤러 서비스](#metacontroller---경량-kubernetes-컨트롤러-서비스) + - [Juju - 모델 기반 오퍼레이터 프레임워크](#juju---모델-기반-오퍼레이터-프레임워크) +- [오퍼레이터 수명 주기 관리](#오퍼레이터-수명-주기-관리) + - [오퍼레이터 업그레이드](#오퍼레이터-업그레이드) + - [선언적 상태 업그레이드](#선언적-상태-업그레이드) + - [CRD 관계 관리](#crd-관계-관리) +- [오퍼레이터 사용 사례](#오퍼레이터-사용-사례) +- [잘 알려진 오퍼레이터 및 패턴](#잘-알려진-오퍼레이터-및-패턴) + - [프로메테우스 오퍼레이터](#프로메테우스-오퍼레이터) + - [GitOps를 위한 오퍼레이터](#gitops를-위한-오퍼레이터) + - [성공적인 패턴](#성공적인-패턴) + - [단일 유형의 애플리케이션 관리](#단일-유형의-애플리케이션-관리) + - [오퍼레이터의 오퍼레이터](#오퍼레이터의-오퍼레이터) + - [컨트롤러당 하나의 CRD](#컨트롤러당-하나의-crd) + - [오퍼레이터를 게시하고 찾는 곳](#오퍼레이터를-게시하고-찾는-곳) + - [추가 읽을 거리](#추가-읽을-거리) +- [오퍼레이터 설계](#오퍼레이터-설계) + - [요구 사항 분석](#요구-사항-분석) + - [사용자 정의 또는 서드파티 오퍼레이터](#사용자-정의-또는-서드파티-오퍼레이터) + - [올바른 도구 사용](#올바른-도구-사용) + - [올바른 프로그래밍 언어 사용](#올바른-프로그래밍-언어-사용) + - [필요에 맞게 오퍼레이터 설계하기](#필요에-맞게-오퍼레이터-설계하기) + - [참고자료](#참고자료) +- [미래의 새로운 패턴](#미래의-새로운-패턴) + - [오퍼레이터 수명 주기 관리](#오퍼레이터-수명-주기-관리-1) + - [정책 인식 오퍼레이터](#정책-인식-오퍼레이터) + - [오퍼레이터 데이터 모델링](#오퍼레이터-데이터-모델링) + - [참고자료](#참고자료-1) +- [결론](#결론) +- [관련 연구](#관련-연구) + - [참고자료](#참고자료-2) +- [감사의 말](#감사의-말) + - [V1.1](#v11) + - [기여자](#기여자) + - [리뷰어](#리뷰어) + - [V1.0](#v10) + - [기여자](#기여자-1) + - [리뷰어](#리뷰어-1) + +## 정의 + +오퍼레이터는 사람의 행동을 소프트웨어로 구현하여 애플리케이션의 전체 라이프사이클 기능을 효율적으로 관리할 수 있게 해주는 도구입니다. + +## 요약 + +애플리케이션 인프라를 유지 관리하려면 지속적인 가치가 없는 반복적인 인간 작업이 많이 필요합니다. 컴퓨터는 정확한 작업을 수행하고 객체의 상태를 검증하는 데 선호되는 방법이므로 인프라 요구 사항을 코드화할 수 있습니다. 오퍼레이터는 애플리케이션의 필요한 활동, 확인 및 상태 관리를 캡슐화하는 방법을 제공합니다. + +쿠버네티스에서 오퍼레이터는 API의 기능을 확장하여 지능적이고 동적인 관리 기능을 제공합니다. + +이러한 오퍼레이터 구성 요소는 일반적인 프로세스의 자동화뿐만 아니라 환경에 지속적으로 적응할 수 있는 반응형 애플리케이션을 가능하게 합니다. 이는 더 적은 오류와 더 빠른 복구 시간, 그리고 엔지니어링 자율성 증가를 통해 더 빠른 개발을 가능하게 합니다. + +오퍼레이터 패턴의 인기가 높아짐에 따라, 초보자와 전문가 모두가 커뮤니티에서 인정하는 모범 사례를 통해 목표를 달성할 수 있도록 돕는 참고 문서가 필요하게 되었습니다. 이 문서에서는 오퍼레이터의 분류뿐만 아니라 오퍼레이터 애플리케이션 관리 시스템의 권장 구성, 구현 및 사용 사례를 설명합니다. + +## 소개 + +이 문서는 쿠버네티스보다 더 넓은 맥락에서 오퍼레이터를 정의합니다. 오퍼레이터의 특성과 구성 요소를 설명하고, 현재 사용되는 일반적인 패턴에 대한 개요를 제공하며, 쿠버네티스 컨트롤러와 어떻게 다른지 설명합니다. + +또한 쿠버네티스 컨트롤러의 기능, 백업, 복구 및 자동 구성 조정에 대해 자세히 설명합니다. 현재 사용 중인 프레임워크, 수명 주기 관리, 보안 위험 및 사용 사례에 대한 추가 통찰력을 제공합니다. + +이 문서에는 관찰성, 보안 및 기술 구현을 포함한 모범 사례가 포함되어 있습니다. + +마지막으로 관련 작업을 소개하고, 이 문서가 제공하는 추가적인 가치와 오퍼레이터의 다음 단계를 강조합니다. + + +### 문서의 목표 + +이 문서의 목표는 쿠버네티스 및 기타 컨테이너 오케스트레이터의 맥락에서 클라우드 네이티브 애플리케이션에 대한 오퍼레이터 정의를 제공하는 것입니다. + +### 타겟 청중 / 최소 경험 수준 + +이 문서는 애플리케이션 개발자, 쿠버네티스 클러스터 오퍼레이터, 그리고 서비스 제공자(내부 또는 외부)를 대상으로 합니다. 이들은 오퍼레이터와 그들이 해결할 수 있는 문제에 대해 학습하고자 하는 분들입니다. 또한 이미 오퍼레이터를 살펴보고 있는 팀들에게는 언제 어떻게 사용해야 가장 효과적인지에 대한 정보를 제공합니다. 이 문서는 파드와 디플로이먼트(Deployment)와 같은 쿠버네티스의 기본 지식을 전제로 합니다. + +## 기초 + +쿠버네티스와 다른 오케스트레이터들의 성공은 컨테이너의 주요 기능에 집중했기 때문입니다. 회사들은 클라우드 네이티브로의 여정을 시작하면서 더 구체적인 사용 사례(마이크로서비스, 상태가 없는 애플리케이션 등)에 집중하는 것이 더 의미가 있었습니다. 쿠버네티스와 다른 컨테이너 오케스트레이터들이 명성과 확장성을 쌓으면서 요구 사항도 더욱 야심차게 커졌습니다. 오케스트레이터의 전체 라이프사이클 기능을 사용하고자 하는 욕구도 분산도가 높은 데이터 저장소로 옮겨졌습니다. + +쿠버네티스 기본 요소는 기본적으로 상태를 관리하기 위해 구축되지 않았습니다. 쿠버네티스 기본 요소에만 의존하면 복제, 장애 조치 자동화, 백업/복원 및 업그레이드(너무 특정한 이벤트를 기반으로 발생할 수 있음)와 같은 상태에 맞는 애플리케이션 요구사항을 관리하기가 어렵습니다. + +오퍼레이터 패턴은 상태 관리 문제를 해결할 수 있습니다. 자체 복구, 조정 및 확장과 같은 쿠버네티스 내장 기능과 애플리케이션별 복잡성을 활용함으로써 모든 애플리케이션 라이프사이클, 운영을 자동화하고 높은 성능을 제공하는 제품으로 전환할 수 있습니다. + +오퍼레이터들은 쿠버네티스와 동의어로 여겨집니다. 그러나 관리가 완전히 자동화된 애플리케이션의 아이디어는 다른 플랫폼으로 내보낼 수 있습니다. 이 문서의 목적은 이 개념을 쿠버네티스 자체보다 더 높은 수준으로 끌어올리는 것입니다. + +### 오퍼레이터 디자인 패턴 + +이 섹션에서는 높은 수준의 개념으로 오퍼레이터 디자인 패턴을 설명합니다. +다음 섹션인 _쿠버네티스 오퍼레이터 정의_에서는 쿠버네티스 객체와 개념을 기반으로 한 이 패턴의 구현을 설명할 것입니다. + +오퍼레이터 디자인 패턴은 도메인별 지식과 선언적 상태를 사용하여 애플리케이션 및 인프라 리소스를 관리하는 방법을 정의합니다. 이 패턴의 목표는 애플리케이션이 정상적으로 동작하고 잘 유지하는 데 필요한 수동 명령형 작업(백업, 스케일 조정, 업그레이드 등)의 양을 줄이는 것입니다. 이를 위해 도메인 특화 지식을 코드로 캡처하고 선언적 API를 통해 이를 노출합니다. + +오퍼레이터 패턴을 사용하면 리소스을 조정하고 유지하는 방법에 대한 지식이 코드 내에 포함되며 종종 단일 서비스(컨트롤러라고도 함) 내에 구현됩니다. + +오퍼레이터 디자인 패턴을 사용할 때 사용자는 애플리케이션과 리소스의 원하는 상태를 기술하는 것만 요구됩니다. 오퍼레이터 구현은 원하는 상태에 있도록 세상에서 필요한 변화를 만들어야 합니다. 또한 운영자는 실제 상태를 지속적으로 모니터링하고 실제 상태를 건강하고 동일한 상태로 유지하기 위한 조치를 취할 것입니다 (변동 방지). + +일반적인 오퍼레이터의 다이어그램은 원하는 사양을 읽고 설명된 리소스을 생성하고 관리할 수 있는 소프트웨어를 포함합니다. + +![Operator Design Pattern](img/02_1_operator_pattern.png) + +오퍼레이터 패턴은 세 가지 구성 요소로 구성됩니다: + +* 관리하고자 하는 애플리케이션 또는 인프라입니다. +* 사용자가 선언적인 방법으로 원하는 응용 프로그램 상태를 지정할 수 있도록 하는 도메인 특정 언어입니다. +* 지속적으로 실행되는 컨트롤러: + * 현재 상태를 읽고 인식합니다. + * 작업 상태 변경 시 자동으로 작업을 실행합니다. + * 선언적 방법으로 애플리케이션 상태를 보고합니다. + +이 디자인 패턴은 다음 섹션에서 쿠버네티스와 오퍼레이터에게 적용될 것입니다. + +### 오퍼레이터의 특성 + +모든 오퍼레이터의 핵심 목적은 새로운 도메인 지식으로 오케스트레이터의 기본 API를 확장하는 것입니다. 예를 들어, 쿠버네티스 내의 오케스트레이션 플랫폼은 파드 및 서비스 객체를 통해 컨테이너 및 4계층 로드밸런서와 같은 것을 기본적으로 이해합니다. 오퍼레이터는 더 복잡한 시스템 및 애플리케이션을 위한 새로운 기능을 추가합니다. 예를 들어, 프로메테우스 오퍼레이터는 새로운 객체 유형 _프로메테우스_를 도입하여 프로메테우스 서버를 배포하고 실행하기 위한 높은 수준의 지원으로 쿠버네티스를 확장합니다. + +오퍼레이터가 제공하는 기능은 동적 구성, 운영 자동화 및 도메인 지식의 세 가지 주요 범주로 분류할 수 있습니다. + +#### 동적 구성 + +소프트웨어 개발 초기부터 소프트웨어를 구성하는 주요 방법은 설정 파일과 환경 변수 두 가지였습니다. 클라우드 네이티브 환경에서는 API를 시작할 때 잘 알려진 API를 쿼리하는 프로세스를 기반으로 한 새로운 방법들이 만들어졌습니다. 대부분의 기존 소프트웨어는 이 두 옵션의 조합에 의존하고 있습니다. 쿠버네티스는 컨피그맵(ConfigMap)과 시크릿(Secret)와 같은 도구들을 제공하여 사용자 정의 구성을 가능하게 합니다. 대부분의 쿠버네티스 리소스는 일반적이기 때문에 특정 애플리케이션을 수정하는 데 필요한 구체적인 내용을 이해하지 못합니다. 반면, 오퍼레이터는 쿠버네티스 컨텍스트에서 특정 애플리케이션의 구성을 더 잘 표현하기 위해 새로운 사용자 정의 객체 유형(사용자 정의 리소스)을 정의할 수 있습니다. + +검증 및 데이터 구조화를 개선하면 작은 구성 오류의 가능성을 줄이고 팀이 스스로 서비스를 제공하는 능력을 향상시킵니다. 이는 각 팀이 기존에 요구되었던 바와 같이 기본 오케스트레이터나 대상 애플리케이션에 대한 이해를 수용할 필요가 없습니다. 여기에는 몇 가지 고급 설정을 사용하여 모범 사례 기반 구성 파일을 채우는 프로그래시브 기본값이나 사용 가능한 하드웨어 또는 클러스터 크기에 따라 예상되는 로드에 맞게 리소스 사용량을 조정하는 등의 적응형 구성이 포함될 수 있습니다. + +#### 운영 자동화 + +대부분의 오퍼레이터는 사용자 정의 리소스와 함께 적어도 하나의 사용자 정의 컨트롤러를 포함합니다. 이러한 컨트롤러는 다른 오퍼레이터와 마찬가지로 오케스트라 내부에서 실행되지만 기본 API에 연결하고 일반적이거나 반복적인 작업의 자동화를 제공하는 데몬입니다. 이는 오케스트라(쿠버네티스와 같은)가 구현된 방식과 동일합니다. 여태까지 컨트롤러 관리자 또는 클라우드 컨트롤러 매니저에 언급된 적이 있을 것입니다. 그러나 구성에서와 마찬가지로, 오퍼레이터는 클러스터 소프트웨어 배포, 자동 백업 및 복원 제공, 또는 부하에 따른 동적 스케일링과 같은 고급 자동화를 통해 오케스트레이터를 확장하고 향상시킬 수 있습니다. + +이러한 일반적인 운영 작업을 코드로 넣음으로써 반복 가능하고 테스트 가능하며 표준화된 방식으로 업그레이드할 수 있습니다. 빈번한 작업에서 인간의 개입을 최소화함으로써 단계를 누락하거나 제외되는 것을 방지하고, 작업의 각 부분이 서로 동기화되지 않도록 합니다. 이는 애플리케이션 백업과 같은 지루하지만 중요한 유지 관리 작업에 소비되는 시간을 줄이며, 팀의 자율성을 향상시킵니다. + +#### 도메인 지식 + +운영 자동화와 마찬가지로, 특정 소프트웨어나 프로세스에 대한 특화된 도메인 지식을 오퍼레이터에 포함시킬 수 있습니다. 이는 주로 애플리케이션 업그레이드와 관련하여 나타납니다. 간단한 무상태 애플리케이션은 롤링 업그레이드를 통해 처리할 수 있지만, 데이터베이스와 같은 상태를 가지는 애플리케이션은 안전하게 업그레이드하기 위해 매우 구체적인 단계가 필요할 수 있습니다. 오퍼레이터는 현재 상태와 요청된 버전을 인식하고 필요할 때 특화된 업그레이드 코드를 실행하여 이를 자율적으로 처리할 수 있습니다. 더 일반적으로 이는 클라우드 네이티브 이전의 환경에서 수동 체크리스트로 사용되었던 모든 작업에 적용될 수 있습니다 (오퍼레이터를 실행 가능한 런북으로 사용). +자동화된 도메인 지식을 활용하는 또 다른 일반적인 방법은 오류 복구입니다. 예를 들어, 쿠버네티스의 내장 복구 동작은 주로 "컨테이너를 다시 시작하여 작동할 때까지"로 끝나지만, 이는 강력한 해결책이지만 항상 최선이나 가장 빠른 해결책은 아닙니다. 오퍼레이터는 애플리케이션을 모니터링하고 오류 발생 시 특정 동작을 통해 자동으로 해결하거나 문제가 자동으로 해결될 수 없는 경우 문제를 에스컬레이트할 수 있습니다. 이는 MTTR(평균 복구 시간)을 줄이고 반복적인 문제로 인한 운영자의 피로를 감소시킬 수 있습니다. + +### 쿠버네티스의 오퍼레이터 구성요소 + +*“오퍼레이터는 쿠버네티스와 다른 두 가지 도메인을 이해하는 쿠버네티스 컨트롤러입니다. 두 도메인에 대한 지식을 결합함으로써 일반적으로 두 도메인을 모두 이해하는 사람 오퍼레이터가 필요한 작업을 자동화할 수 있습니다.”* +(Jimmy Zelinskie, https://github.com/kubeflow/tf-operator/issues/300#issuecomment-357527937) + +![Operator Big Picture](img/02_2_operator.png) +오퍼레이터는 쿠버네티스 API를 운영 지식으로 확장할 수 있게 해줍니다. +이는 쿠버네티스 컨트롤러와 관리되는 객체들을 결합하여 달성됩니다. 이 컨트롤러는 하나 이상의 객체를 감시할 수 있으며, 객체들은 디플로이먼트(Deployment), 서비스와 같은 쿠버네티스의 기본 개체일 수도 있고, 가상 머신이나 데이터베이스와 같은 클러스터 외부에 있는 개체일 수 있습니다. + +원하는 상태는 코드로 정의되어 있고 오퍼레이터가 관리하도록 구성된 모든 리소스를 의미합니다. 이후 현재 상태는 해당 리소스들의 배포된 인스턴스를 나타냅니다. + +컨트롤러는 재조정 루프를 사용하여 원하는 상태와 현재 상태를 지속적으로 비교하며, 이를 통해 관리되는 객체들이 정의된 방식에 따라 원하는 상태로 전환되도록 보장합니다. + +원하는 상태는 하나 이상의 쿠버네티스 사용자 정의 리소스에 캡슐화되며, 컨트롤러에는 배포나 서비스와 같은 객체들을 목표 상태로 전환시키기 위해 필요한 운영 지식이 포함되어 있습니다. + +#### 쿠버네티스 컨트롤러 + +쿠버네티스 컨트롤러는 특정 리소스 유형으로 표현된 원하는 상태가 현재 상태와 일치하도록 보장하기 위해 반복적인 작업을 처리합니다(현재 상태, https://engineering.bitnami.com/articles/a-deep-dive-into-kubernetes-controllers.html, https://fntlnz.wtf/post/what-i-learnt-about-kubernetes-controller/). 예를 들어, 디플로이먼트(Deployment) 컨트롤러는 원하는 수의 파드 복제본이 실행 중인지 확인하며, 하나의 파드가 삭제되거나 실패할 때 새로운 파드를 생성합니다. + +기술적으로 일반적인 컨트롤러와 오퍼레이터 사이에는 차이가 없습니다. 종종 언급되는 차이는 오퍼레이터에 포함된 운영 지식입니다. 따라서 컨트롤러는 구현을 의미하며, 오퍼레이터는 사용자 정의 컨트롤러와 CRD(Custom Resource Definitions)를 사용하는 패턴입니다. 이를 통해 자동화를 달성하려는 것입니다. 결과적으로, 사용자 정의 리소스가 생성될 때 파드를 생성하고 이후에 파드를 삭제하는 컨트롤러는 단순한 컨트롤러로 설명될 수 있습니다. 만약 컨트롤러가 업그레이드 방법이나 오류 복구와 같은 운영 지식을 가지고 있다면, 그것은 오퍼레이터입니다. + +#### 사용자 정의 리소스 및 사용자 정의 리소스 정의 + +사용자 정의 리소스는 기본 쿠버네티스 API(https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/)를 확장하여 구조화된 데이터를 쿠버네티스에 저장하고 검색하는 데 사용됩니다. +오퍼레이터의 경우, 사용자 정의 리소스는 리소스(예: 애플리케이션)의 원하는 상태를 포함하지만, 구현 논리는 포함하지 않습니다. 이러한 정보는 애플리케이션 구성 요소의 버전 정보일 수 있으며, 애플리케이션의 활성화된 기능이나 애플리케이션 백업 위치 정보 등이 될 수 있습니다. 사용자 정의 리소스 정의(CRD, Custom Resource Definition)는 이러한 객체가 어떻게 생겼는지, 예를 들어 어떤 필드가 존재하는지와 CRD의 이름을 정의합니다. 이러한 CRD는 오퍼레이터 SDK와 같은 도구를 사용하여 스캐폴딩하거나 직접 작성할 수 있습니다. + +다음 예제는 이러한 사용자 정의 리소스 인스턴스 정의를 보여줍니다: + +```yaml +apiVersion: example-app.appdelivery.cncf.io/v1alpha1 +kind: ExampleApp +metadata: + name: appdelivery-example-app +spec: + appVersion: 0.0.1 + features: + exampleFeature1: true + exampleFeature2: false + backup: + enabled: true + storageType: “s3” + host: “my-backup.example.com” + bucketName: “example-backup” + status: + currentVersion: 0.0.1 + url: https://myloadbalancer/exampleapp/ + authSecretName: appdelivery-example-app-auth + backup: + lastBackupTime: 12:00 +``` + +이 예제는 "ExampleApp" 종류의 "appdelivery-example-app"라는 이름을 가진 사용자 정의 리소스를 나타냅니다. + +"spec" 섹션은 사용자가 원하는 상태를 선언할 수 있는 곳입니다. 이 예제는 앱 버전 0.0.1이 배포되어야 하며, 한 가지 기능이 활성화되고 다른 기능은 비활성화되어야 함을 선언합니다. 또한, 이 애플리케이션의 백업이 만들어져야 하며, S3 버킷이 사용되어야 합니다. + +"status" 섹션은 운영자가 사용자에게 유용한 정보를 전달할 수 있는 곳입니다. 이 예제에서 상태는 현재 배포된 버전을 보여줍니다. 만약 이것이 spec의 "appVersion"과 다르다면, 사용자는 운영자가 spec에서 요청한 버전을 배포하기 위해 작업 중이라는 것을 예상할 수 있습니다. 상태 섹션에서 흔히 볼 수 있는 다른 정보로는 애플리케이션에 연결하는 방법과 애플리케이션의 상태가 포함됩니다. + +#### 제어 루프 +쿠버네티스 컨트롤러의 제어(조정) 루프는 사용자가 CRD를 사용하여 선언한 상태가 애플리케이션의 상태와 일치하는지, 그리고 상태 간의 전환이 의도한 대로 작동하는지 확인합니다. 일반적인 사용 사례는 애플리케이션을 업그레이드할 때 데이터베이스 스키마를 마이그레이션하는 것입니다. 제어 루프는 CRD의 변경과 같은 특정 이벤트나 데이터 백업과 같은 시간 기반으로 트리거될 수 있습니다. + +### 오퍼레이터 기능 +오퍼레이터는 다양한 작업을 해결함으로써 애플리케이션이나 기타 관리되는 구성 요소의 운영을 지원할 수 있습니다. 오퍼레이터에 대해 이야기할 때 가장 잘 알려진 첫 번째 기능은 상태 저장 애플리케이션의 설치 및 업그레이드 능력입니다. 그러나 오퍼레이터는 설치/업그레이드 시 수동 입력 없이 애플리케이션의 전체 수명 주기를 관리할 수 있습니다. + +다음 섹션은 오퍼레이터가 가질 수 있는 기능과 오퍼레이터가 이러한 기능을 구현했을 때 사용자가 기대할 수 있는 내용을 개괄적으로 설명합니다. + +#### 애플리케이션 설치 / 애플리케이션 소유권 가져오기 +오퍼레이터는 설치 과정에서 수동 작업이 필요 없도록 모든 필요한 리소스를 프로비저닝하고 설정할 수 있어야 합니다. 오퍼레이터는 프로비저닝된 리소스가 예상대로 작동하고 사용 준비가 되었는지 확인하고 검증해야 합니다. + +오퍼레이터는 설치 과정 이전에 프로비저닝된 리소스를 인식하고, 나중에 사용할 수 있도록 그 소유권만 가져와야 합니다. 이 경우 소유권 이전 과정은 중단 없이 원활하게 이루어져야 합니다. 소유권 이전 과정의 목적은 리소스를 오퍼레이터로 쉽게 마이그레이션할 수 있도록 하는 것입니다. + +오퍼레이터는 프로세스 중에 리소스의 버전과 상태를 보고해야 합니다. + +#### 애플리케이션 업그레이드 +오퍼레이터는 애플리케이션/리소스의 버전을 업그레이드할 수 있어야 합니다. 오퍼레이터는 필요한 종속성을 업데이트하고 데이터베이스 마이그레이션 실행과 같은 사용자 정의 명령을 실행하는 방법을 알아야 합니다. + +오퍼레이터는 업데이트를 모니터링하고, 과정 중에 문제가 발생하면 롤백해야 합니다. + +오퍼레이터는 과정 중에 리소스의 버전과 상태를 보고해야 합니다. 오류가 발생한 경우 보고된 버전은 현재 사용 중인 버전이어야 합니다. + +#### 백업 +이 기능은 데이터를 관리하고 일관된 백업을 생성할 수 있도록 하는 오퍼레이터를 위한 것입니다. 이 백업은 오퍼레이터의 사용자가 데이터가 손실되거나 손상된 경우 이전 버전을 복원할 수 있다는 확신을 가질 수 있도록 해야 합니다. 또한, 제공된 상태 정보는 마지막 백업 실행 시기와 위치를 명확히 알려줘야 합니다. + +![Example Backup Process](plantuml/backup-sequence.png) + +위 그림은 이러한 과정이 어떻게 진행될 수 있는지를 보여줍니다. 처음에 백업은 사람이 직접 실행하거나 다른 트리거(예: 시간 기반 트리거)에 의해 시작됩니다. 오퍼레이터는 감시 중인 리소스(애플리케이션)에게 일관된 상태(예: 일관된 스냅샷)를 설정하도록 지시합니다. 이후 적절한 도구를 사용하여 애플리케이션의 데이터를 외부 스토리지에 백업합니다. 이는 외부 스토리지로 직접 백업하는 단일 단계 과정일 수도 있고, 처음에는 지속 가능한 볼륨에 작성한 후 외부 스토리지로 이동하는 여러 단계 과정일 수도 있습니다. 외부 스토리지는 온프레미스의 NFS/CIFS 공유(또는 다른 네트워크 파일 시스템)가 될 수도 있고, 클라우드 제공 인프라의 객체 스토어/버킷일 수도 있습니다. 백업이 성공 여부 관계 없이, 백업된 애플리케이션 버전과 백업 위치를 포함한 상태(백업의 상태)는 사용자 정의 리소스의 상태 섹션에 기록될 수 있습니다. + +#### 백업에서 복구 + +오퍼레이터의 복구 기능은 사용자가 성공적인 백업에서 애플리케이션 상태를 복원하는 데 도움을 줄 수 있습니다. 따라서 애플리케이션 상태(애플리케이션 버전 및 데이터)가 복원되어야 합니다. + +이를 달성하는 방법에는 여러 가지가 있을 수 있습니다. 한 가지 가능한 방법은 현재 애플리케이션 상태(구성 포함)를 백업하는 것입니다. 이렇게 하면 사용자가 애플리케이션을 위한 커스텀 리소스를 생성하고 백업을 지정하기만 하면 됩니다. 오퍼레이터는 구성을 읽고 애플리케이션 버전을 복원하며 데이터를 복원합니다. 또 다른 가능한 해결책은 사용자가 데이터만 백업하고 애플리케이션에서 사용된 버전을 지정해야 하는 경우입니다. 어느 경우든 오퍼레이터는 지정된 백업 데이터를 사용하여 애플리케이션이 이후에 정상적으로 작동하도록 보장합니다. + +#### 자동 복구 +오퍼레이터의 자동 복구 기능은 라이브 및 준비성 프로브(readiness probes)와 같은 상태 점검 메커니즘으로 처리하거나 감지할 수 없는 더 복잡한 실패 상태에서 애플리케이션을 복원할 수 있도록 해야 합니다. 따라서 오퍼레이터는 애플리케이션에 대한 깊은 이해를 가지고 있어야 합니다. 이는 애플리케이션 실패나 오류를 나타낼 수 있는 메트릭을 통해 달성할 수 있으며, 쿠버네티스 메커니즘(예: 상태 점검)을 처리함으로써도 가능합니다. + +일부 예시로는 다음과 같습니다: +* 버전 변경 후 정의된 수만큼의 파드 시작이 실패하면 마지막으로 알려진 구성으로 롤백합니다. 어떤 경우에는 애플리케이션을 재시작하는 것이 단기적인 해결책이 될 수 있으며, 이는 오퍼레이터가 수행할 수 있습니다. +* 오퍼레이터가 의존 서비스의 다른 오퍼레이터에게 백엔드 시스템이 현재 접근할 수 없음을 알려서 복구 조치를 취할 수 있게 하는 상황도 상상해볼 수 있습니다. + +어떤 상황에서도 이 기능은 시스템이 계속해서 작동할 수 있도록 오퍼레이터가 조치를 취할 수 있습니다. + +#### 모니터링/메트릭스 - 가시성 +관리되는 애플리케이션은 자체적으로 모니터링 데이터를 제공해야 하지만, 오퍼레이터는 자체 동작에 대한 메트릭을 제공하고 애플리케이션 상태에 대한 고수준 개요만 제공할 수 있습니다(자동 복구와 같은 경우). 또한, 오퍼레이터가 제공하는 일반적인 모니터링 데이터에는 복구 조치 횟수, 백업 지속 시간, 마지막 오류 또는 처리된 운영 작업에 대한 정보가 포함될 수 있습니다. + +#### 스케일링 +스케일링은 애플리케이션/리소스를 기능적으로 유지하기 위해 오퍼레이터가 관리할 수 있는 Day-2 운영의 일부입니다. 스케일링 기능은 자동화를 요구하지 않지만, 오퍼레이터가 수평 및 수직 스케일링 측면에서 리소스를 변경하는 방법을 알아야 합니다. + +오퍼레이터는 소유한 리소스(예: CPU, 메모리, 디스크 크기 및 인스턴스 수)를 증가시키거나 감소시킬 수 있어야 합니다. + +이상적으로는 스케일링 작업이 다운타임 없이 수행되어야 합니다. 스케일링 작업은 모든 리소스가 일관된 상태에 있고 사용 준비가 되면 종료되므로 오퍼레이터는 모든 리소스의 상태를 확인하고 보고해야 합니다. + +#### 자동 스케일링 +오퍼레이터는 임계값에 따라 지속적으로 수집하는 메트릭을 기반으로 스케일링 기능을 수행할 수 있어야 합니다. 오퍼레이터는 소유한 모든 리소스를 자동으로 증가시키고 감소시킬 수 있어야 합니다. + +오퍼레이터는 최소 및 최대 기본 스케일링 구성을 준수해야 합니다. + +#### 자동 구성 조정 +이 기능은 오퍼레이터가 관리되는 애플리케이션의 구성을 관리할 수 있게 해야 합니다. 예를 들어, 오퍼레이터는 운영 환경(예: 쿠버네티스)에 따라 애플리케이션의 메모리 설정을 조정하거나 DNS 이름 변경에 대응할 수 있어야 합니다. 또한, 오퍼레이터는 구성 변경이 원활하게 이루어지도록 처리할 수 있어야 하며, 예를 들어 구성 변경이 재시작을 필요로 하는 경우 이를 자동으로 트리거할 수 있어야 합니다. + +이러한 기능은 사용자에게 투명하게 제공되어야 합니다. 사용자는 원할 경우 이러한 자동 구성 메커니즘을 재정의할 수 있는 가능성을 가져야 합니다. 또한, 자동 재구성은 인프라에서 어떤 일이 발생하는지 사용자가 이해할 수 있도록 잘 문서화되어야 합니다. + +#### 제거 / 연결 해제 +선언적 요청 상태(대부분의 경우 사용자 정의 리소스)를 삭제할 때, 오퍼레이터는 두 가지 동작을 허용해야 합니다: +- 제거: 오퍼레이터는 관리되는 모든 리소스를 완전히 제거하거나 삭제할 수 있어야 합니다. +- 연결 해제: 오퍼레이터는 프로비저닝된 리소스의 관리를 중지할 수 있어야 합니다. + +두 과정 모두 오퍼레이터가 직접 프로비저닝한 모든 리소스에 적용되어야 합니다. 오퍼레이터는 이 과정에서 발생한 모든 실패를 선언적 방식(예: [상태 필드](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#object-spec-and-status) 사용)으로 보고해야 합니다. + +## 보안 +![operator model](img/04_1_operator_model.png) + +오퍼레이터는 사용자 정의 리소스 정의를 사용하여 쿠버네티스 API 서버를 통해 상태와 구성을 관리하도록 설계되었습니다. 오퍼레이터가 관리하는 하위 API 리소스(종종 상태 저장 애플리케이션을 실행하는 파드)는 또한 쿠버네티스 API를 통해 수명 주기와 지원 RBAC, 서비스 등을 관리합니다. 일부 경우, 오퍼레이터는 네트워크를 통해 애플리케이션의 API와 상호 작용하기도 합니다. 이러한 모든 경로는 오퍼레이터와 그 리소스를 손상시킬 가능성이 있으므로, 아래에 제시된 모범 사례에 따라 보호되어야 합니다. + +### 오퍼레이터 개발자 +오퍼레이터 개발자는 오퍼레이터가 도입하는 보안 위험을 인식하고 안전한 사용을 문서화해야 합니다. 오퍼레이터를 개발할 때는 투명성과 문서화, 오퍼레이터 범위, 취약성 분석과 같은 주요 영역에 집중하는 것이 중요합니다. + +#### 투명성 및 문서화 +오퍼레이터를 개발하는 동안 개발자는 오퍼레이터가 쿠버네티스 내에서 어떻게 작동하고 인터페이스할 것인지 명확히 이해해야 합니다. 개발 단계에서 배포 단계로 전환할 때, 사용자가 오퍼레이터가 무엇을 하고 어떻게 작동하는지 명확히 이해할 수 있도록 해야 합니다. 개발자가 자신이 만든 것에 자부심을 느낄 수 있지만, 최종 사용자의 관점에서 생각해보세요. 사용자는 인터넷에서 소스 코드를 다운로드하거나, 대규모이거나 비용이 많이 들 수 있는 클러스터에서 관리 액세스 권한으로 실행되는 오퍼레이터를 신뢰해야 하며, 민감한 정보를 처리할 수도 있습니다. 개발자가 소프트웨어의 작동 방식, 보안 방법, 클러스터에 미칠 영향을 사용자에게 이해시키기 위해 할 수 있는 모든 것이 소프트웨어를 채택하는 데 도움이 됩니다. + +사용자가 오퍼레이터를 사용해야 할지 여부에 대해 정보에 입각한 결정을 내릴 수 있도록 도와주는 항목은 다음과 같습니다: + +* 오퍼레이터가 어떻게 통신하고 무엇과 통신하는지를 설명하는 다이어그램(위협 모델)은 사용자가 오퍼레이터를 어떻게 보호하고 정책을 적용해야 하는지 이해하는 데 도움이 되는 좋은 출발점입니다. +* 소프트웨어가 준수 범위 내에서 사용되도록 하기 위한 사용 사례를 문서화하지 않으면 범위를 벗어난 취약성 위험이 발생할 수 있습니다. +* 문서화된 RBAC 범위, 위협 모델, 통신 포트, 사용 가능한 API 호출, 파드 보안 정책 요구 사항(또는 OPA와 같은 다른 정책 엔진 요구 사항). +* 보안 보고, 공개, 및 사고 대응 프로세스: 잠재적인 보안 문제를 발견한 사람이 누구에게 연락해야 하고 어떤 유형의 응답을 기대할 수 있는지. +* 노출된 엔드포인트, 로그 레벨 또는 로그 집계를 통한 로깅 및 모니터링 연결. +* 오퍼레이터 문제, 기능, 버전 추적. +* 프로젝트가 과거에 보안 공개를 했던 적이 있다면, 이러한 공개(및 CVE ID)를 웹 페이지에 나열하는 것은 사용자와의 신뢰를 구축하는 강력한 단계입니다. 누구나 언젠가는 보안 문제를 겪게 되며, 문제를 처리하는 방식은 프로젝트의 성숙도를 나타냅니다. + +추가적인 개발 프로세스 보안 아이디어에 대해서는, 독자는 CNCF 보안 TAG의 [자체 평가 질문서](https://github.com/cncf/tag-security/blob/main/assessments/guide/self-assessment.md)를 검토해 볼 수 있습니다. + +#### 오퍼레이터 범위 +오퍼레이터에는 다양한 사용 사례가 있으며 설계할 수 있는 범위에는 사실상 제한이 없습니다. 오퍼레이터의 보안 특성을 명확히 하기 위해서는 각 범위와 관련된 명확한 소통이 필요합니다. 일반적으로 사용될 수 있는 범위는 클러스터 전체 오퍼레이터, 네임스페이스 오퍼레이터, 외부 오퍼레이터입니다. 이를 최적의 방식으로 보안하기 위해서는 통신, 생성된 모든 API, 컨트롤러와 그 책임, 애플리케이션 메트릭 엔드포인트에 대한 이해가 필요합니다. 이 정보가 오퍼레이터와 함께 제공되면 구현 범위 내에서 오퍼레이터 애플리케이션을 더욱 안전하게 할 수 있습니다. 이 정보가 제공되지 않으면 다양한 공격에 취약해질 수 있습니다. + +**클러스터 전체 오퍼레이터**는 해당 리소스가 다른 네임스페이스에 있든 없든 상관없이 클러스터 전체에서 사용자 정의 리소스를 실행하기 위해 존재합니다. +**네임스페이스 오퍼레이터**는 네임스페이스 내에서 사용자 정의 리소스를 실행하기 위해 존재합니다. 일반적으로 네임스페이스 범위 내에 한정시키기 위해 정책 엔진 정책이 적용되며, 네임스페이스 내의 파드와만 통신하도록 합니다. 이는 본질적으로 더 안전한 것으로 간주되지만, 동일한 규칙이 적용됩니다. +**외부 오퍼레이터**는 클러스터 외부의 사용자 정의 리소스를 실행하기 위해 존재합니다. 동일한 규칙이 적용되며, 이 범위를 안전하게 하기 위해서는 클러스터에서 외부 구성 요소로의 통신 특성을 알아야 합니다. + +이 문서는 사용자 관점에서 범위 설정에 대해서도 다루고 있지만, 오퍼레이터의 설계 방식은 운영 환경에서 적용할 수 있는 보안 통제 유형에 큰 영향을 미칩니다. 초기에는 느슨한 권한으로 시작하여 출시 전에 보안 개념을 적용하려는 의도가 흔합니다. 개발자가 작업을 시작할 때 오퍼레이터의 보안 설계에 대해 생각하는 데 시간을 할애하면 개발자와 사용자 모두에게 이 과정을 훨씬 더 쉽게 만들 수 있습니다. + +#### 취약성 분석 +오퍼레이터의 개발 및 보안에 중점을 두고, 오퍼레이터 개발자로서 검증과 적절한 보안 분석이 이루어졌는지 확인하기 위해 취해야 할 단계가 있습니다. CNCF 클라우드 네이티브 보안 문서를 따르면서, 오퍼레이터 개발자를 위한 [관심 계층](https://github.com/cncf/tag-security/blob/main/security-whitepaper/v2/cloud-native-security-whitepaper.md#cloud-native-layers)을 정의하는 명확한 생명 주기 프로세스가 있습니다. 모든 세 계층을 준수해야 하며, 오퍼레이터 개발자의 범위 내에서 개발 및 배포 계층에 엄격하게 집중해야 합니다. 개발 및 배포 계층에는 공급망에 대한 철저한 취약성 분석을 적용하여 개발 중인 오퍼레이터가 서명되고 신뢰할 수 있도록 하기 위한 많은 세부 지침이 포함되어 있습니다. CNCF [클라우드 네이티브 보안 문서](https://github.com/cncf/tag-security/blob/main/security-whitepaper/v2/cloud-native-security-whitepaper.md)는 이 링크에서 확인할 수 있습니다. + +공급망 외에도, 오퍼레이터의 위협 모델을 수행하여 개발자가 체크하고, 실수로 놓친 부분이 없어 공격의 문이 열리지 않도록 해야 합니다. 위협을 확인하기 위한 기본 모델은 CNCF 클라우드 네이티브 보안 문서의 [위협 모델링](https://github.com/cncf/tag-security/blob/main/security-whitepaper/v2/cloud-native-security-whitepaper.md#threat-modeling)에서 확인할 수 있습니다. + +### 애플리케이션 개발자 (오퍼레이터 "사용자") + +오퍼레이터는 볼륨 생성/첨부, 애플리케이션 배포, 인증서 관리 등 사용자를 대신하여 관리 작업을 수행합니다. 사용자가 오퍼레이터에게 제어를 위임함에 따라 필요한 작업을 수행할 수 있도록 기계 인증(machine authorization)을 제공하는 것이 중요하지만, 오퍼레이터가 역할을 수행하는 데 필요한 것보다 더 많은 권한을 부여하지 않도록 주의해야 합니다. + +오퍼레이터를 배포하면 서드파티 소프트웨어가 쿠버네티스 네임스페이스나 클러스터에 어느 정도 접근할 수 있게 됩니다. 오퍼레이터를 사용하는 데 보안 전문 지식이 필요하지는 않지만, 다음 쿠버네티스 개념들은 오퍼레이터를 사용할 때 보안 준비에 대한 중요한 사항을 강조합니다: + +**네임스페이스**는 리소스 그룹을 묶고 격리하는 주요 방법 중 하나입니다. 오퍼레이터와 관련하여, 사용자는 오퍼레이터가 작업할 네임스페이스를 고려해야 합니다. 특정 오퍼레이터가 전체 클러스터에 접근해야 하는 몇 가지 사용 사례가 있을 수 있지만, 2021년의 일반적인 사용 사례는 오퍼레이터가 쿠버네티스 내의 특정 애플리케이션과 함께 작동하는 것입니다. 따라서 해당 애플리케이션 및 관련 리소스/오퍼레이터를 위한 네임스페이스를 제공하는 것이 일반적입니다. 하위 리소스의 네임스페이스에서 느슨하거나 도난당한 RBAC으로부터 오퍼레이터를 분리하려면 오퍼레이터 전용 네임스페이스를 제공하는 것이 더 많은 분리를 제공합니다. + +**역할 기반 접근 제어**는 최신 쿠버네티스 릴리스에서 사용할 수 있습니다. 오퍼레이터에게 리소스에 대한 접근 권한을 부여할 때는 오퍼레이터가 작업을 수행하는 데 필요한 최소한의 권한만 부여하는 데 초점을 맞춰야 합니다. 이는 절대적으로 필요한 경우에만 ClusterRole을 부여하고, 특정 리소스/네임스페이스에 대한 특정 권한을 부여하는 것을 의미합니다. 사용자 가이드의 [RBAC 인증 사용](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) 장에서는 이 주제를 자세히 다룹니다. 오퍼레이터 SDK와 같은 오퍼레이터 빌드 키트는 개발자가 특정 오퍼레이터에 대해 세밀하게 조정하지 않은 일반적인 RBAC 기본값을 사용합니다. 클러스터 외부의 서비스 계정 ID로 부여되는 권한에는 다른 쿠버네티스 클러스터에 권한이 있는 페더레이션 및 크로스 클러스터 오퍼레이터가 포함됩니다. 오퍼레이터가 클러스터 외부 및 클라우드 리소스를 관리하는 데 점점 더 많이 사용됨에 따라, 손상된 오퍼레이터로부터 클라우드 계정 탈취를 방지하기 위해 클라우드 IAM 통합 권한을 구성해야 합니다. + +_한 가지 주의할 점_: 상당한/관리자 접근 권한을 요청하는 "권한 강탈"은 항상 악의적인 의도를 가진 것은 아닙니다. 개발자가 더 나은 방법을 모르거나 최소 권한 개념에 맞추어 필요한 권한을 조정할 시간이 없었을 수 있습니다. 가장 무고한 경우에도 여전히 경고 신호로 간주됩니다. 오퍼레이터가 충분히 채택되어 다른 사람들이 권한 남용에 대해 우려를 제기할 수 있게 되었을 수도 있고, 이는 오퍼레이터 내의 다른 보안 약점의 신호일 수 있습니다. 이러한 "권한 강탈"이 발견되면 주의해서 진행하는 것이 좋습니다. + +**소프트웨어 출처**: 이 문서를 작성할 당시, "소프트웨어 공급망"이 점점 더 많은 주목을 받고 있습니다. 오퍼레이터의 소스, 설치 방법, 악의적인 사용자가 쿠버네티스 클러스터에 접근하려는 이유와 방법을 고려하십시오. 설치 스크립트를 실행하기 전에 몇 분 동안 검토하는 것이 좋습니다. `kubectl create -f https://publicwebsite.com/install/operator.yaml`와 같이 kubectl 명령어는 공개 인터넷에서 직접 YAML 스크립트를 적용할 수 있는 기능을 지원하지만, 먼저 해당 파일을 로컬에 다운로드하여 검토한 후 `kubectl create -f operator.yaml` 명령어를 실행하는 것이 강력히 권장됩니다. + +스크립트를 검토할 때 다음 질문을 고려하십시오: + +* 이 스크립트의 목적은 무엇인가? +* 이 스크립트가 생성하는 리소스는 무엇인가? 이 스크립트가 역할과 역할 바인딩을 생성하는가? +* 스크립트가 사용하려는 서드파티 소스는 무엇인가? (예: 컨테이너 이미지, 다른 YAML 파일) Git 및 Docker 이미지 저장소는 얼마나 인기 있고 잘 유지되고 있는가? 이것들은 새로운 프로젝트, 더 이상 보안 업데이트를 받지 않는 소프트웨어, 또는 악의적인 의도를 가진 비공식 저장소의 징후일 수 있습니다. +* 스크립트가 얻으려는 권한은 무엇인가? 스크립트가 호스트 공유 또는 "특권 모드"로 컨테이너 보안 컨텍스트를 실행하려고 하는가? + +소프트웨어 공급망 보안에 대한 추가 정보는 [CNCF 공급망 보안 문서](https://github.com/cncf/tag-security/tree/main/supply-chain-security/supply-chain-security-paper)에서 확인할 수 있습니다. + +**고급 보안 제어**: SELinux, AppArmor 또는 seccomp와 같은 고급 보안 제어는 클러스터 정책에 의해 요구될 수 있습니다. 오픈 소스 오퍼레이터는 이러한 Linux 보안 모듈에 대한 구성을 가지고 있지 않을 가능성이 높지만, 조직이 이러한 제어 시스템 중 하나에 익숙하다면 오퍼레이터에 대한 적절한 보안 구성을 작성하는 데 많은 비용이 들지 않을 것입니다. + +**오퍼레이터 구성**: 이상적으로 프로젝트는 기본적으로 보안이 설정되어 있어야 하며, 이를 통해 오퍼레이터나 애플리케이션 배포의 보안성을 높일 수 있습니다. 보안이 설정되지 않은 기본값은 환경을 안전하게 하기 위해 수동 구성을 필요로 합니다. 새로운 오퍼레이터의 구성 매개변수를 배우는 것이 불필요한 작업처럼 보일 수 있지만, 필요한 보안 수준에 도달하기 위해 오퍼레이터 자체의 구성이나 소스 코드를 수동으로 조정하는 것이 좋습니다. + +## 쿠버네티스를 위한 오퍼레이터 프레임워크 +현재 오퍼레이터/컨트롤러 프로젝트의 부트스트래핑 프로세스를 단순화하고 오퍼레이터를 작성하기 위한 많은 프레임워크가 존재합니다. 이 장에서는 포괄성을 주장하지 않으면서 그 중 일부를 설명합니다. + +### CNCF 오퍼레이터 프레임워크 + +[Operator Framework](https://github.com/operator-framework)는 쿠버네티스 네이티브 애플리케이션, 즉 오퍼레이터를 효과적이고 자동화되며 확장 가능한 방식으로 관리하기 위한 오픈 소스 툴킷입니다. + +이 프레임워크는 오퍼레이터 개발자를 위해 SDK를 제공하여 스캐폴딩 도구([kubebuilder](https://github.com/kubernetes-sigs/kubebuilder)을 기반으로), 단위 테스트와 통합 테스트 및 기능 테스트를 위한 테스트 하니스, 그리고 사용자 구성 가능 업데이트 그래프와 함께 오퍼레이터의 버전 이력을 게시할 수 있는 패키징/배포 메커니즘을 통해 오퍼레이터 개발을 간소화합니다. 지원되는 프로젝트 유형은 Golang, Helm 및 Ansible입니다. Python과 Java는 현재 개발 중입니다. + +이 프레임워크는 여러 오퍼레이터가 설치된 다중 테넌트 환경에서 오퍼레이터를 설치, 구성 및 업데이트할 수 있는 중앙 집중식 관리 지점을 요구하는 Kubernetes 관리자에게도 적합합니다. 오퍼레이터 생애 주기의 다음 측면을 다룹니다: + +*[오퍼레이터 프레임워크](https://github.com/operator-framework)*는 오퍼레이터라고 불리는 쿠버네티스 네이티브 애플리케이션을 효과적이고 자동화되며 확장 가능한 방식으로 관리하기 위한 오픈 소스 툴킷입니다. + +- 지속적인 Over-the-Air 업데이트 및 오퍼레이터 카탈로그: 업데이트 소스 및 게시 메커니즘 제공 +- 종속성 모델: 오퍼레이터가 클러스터 기능이나 다른 오퍼레이터에 종속성을 가질 수 있도록 지원 +- 발견 가능성: 보통 CRD를 나열하거나 별도의 네임스페이스에 설치된 오퍼레이터를 볼 수 없는 권한이 적은 테넌트를 위한 기능 제공 +- 클러스터 안정성: 다중 테넌트 클러스터에서 오퍼레이터의 런타임 충돌을 피하면서 CRD의 글로벌 특성과 CRD 버전 관리 및 변환의 미묘한 차이를 존중 +- 선언적 UI 제어: 콘솔이 오퍼레이터 서비스와 상호 작용하는 최종 사용자에게 풍부한 UI 경험을 생성할 수 있도록 지원 + +오퍼레이터 프레임워크의 주요 장점: + +- 개발 단순화: 오퍼레이터 프레임워크는 오퍼레이터를 구축하기 위한 프레임워크, 도구 및 모범 사례를 제공하여 쿠버네티스 오퍼레이터의 개발을 단순화합니다. +- 재사용성: 오퍼레이터 프레임워크는 다양한 애플리케이션 및 프로젝트에서 사용할 수 있는 재사용 가능한 오퍼레이터의 생성을 촉진합니다. +- 쿠버네티스 네이티브: 오퍼레이터 프레임워크는 쿠버네티스 API 및 규칙을 기반으로 구축되어 쿠버네티스 생태계와 잘 통합되는 오퍼레이터를 개발하기 쉽게 합니다. +- 견고성: 오퍼레이터 프레임워크는 쿠버네티스 오퍼레이터를 구축하기 위한 모범 사례를 준수하는 코드를 생성하여 견고한 프로덕션급 애플리케이션을 구축하기 쉽게 합니다. +- 커뮤니티 주도: 오퍼레이터 프레임워크는 개발자가 시작하고 문제를 해결하는 데 도움을 줄 수 있는 지원, 리소스 및 예제를 제공하는 크고 활발한 커뮤니티를 가지고 있습니다. + +오퍼레이터 프레임워크의 주요 한계: + +- 학습 곡선: 오퍼레이터 프레임워크를 사용하여 쿠버네티스 오퍼레이터를 구축하는 것은 특히 쿠버네티스나 오퍼레이터 개념에 익숙하지 않은 개발자에게 여전히 복잡한 작업일 수 있습니다. +- 제한된 유연성: 오퍼레이터 프레임워크는 쿠버네티스 오퍼레이터를 구축하는 방법에 대해 의견이 있어 특정 경우 유연성과 사용자 정의 옵션이 제한될 수 있습니다. +- 성능 오버헤드: 오퍼레이터 프레임워크로 구축된 쿠버네티스 오퍼레이터는 특히 대규모 또는 분산 애플리케이션의 경우 쿠버네티스 클러스터에 성능 오버헤드를 추가할 수 있습니다. +- 유지 보수: 오퍼레이터 프레임워크는 새로운 쿠버네티스 릴리스 및 오퍼레이터의 종속성 변경 사항과의 호환성을 보장하기 위해 지속적인 유지 보수 및 업데이트가 필요합니다. + +### Kopf + +**[Kopf](https://github.com/nolar/kopf)** —**K**ubernetes **O**perator **P**ythonic **F**ramework— 는 몇 줄의 파이썬 코드만으로 쿠버네티스 오퍼레이터를 더 빠르고 쉽게 만들 수 있는 프레임워크입니다. 이 프레임워크는 대부분의 저수준 쿠버네티스 API 통신의 번거로움을 제거하고, 쿠버네티스 리소스 변경 사항을 파이썬 함수로 전달하고 다시 되돌려 줍니다. + + +```python +import kopf + +@kopf.on.create(kind='KopfExample') +def created(patch, spec, **_): + patch.status['name'] = spec.get('name', 'world') + +@kopf.on.event(kind='KopfExample', field='status.name', value=kopf.PRESENT) +def touched(memo, status, **_): + memo.last_name = status['name'] + +@kopf.timer('KopfExample', interval=5, when=lambda memo, **_: 'last_name' in memo) +def greet_regularly(memo, **_): + print(f"Hello, {memo['last_name']}!") +``` + +이 프레임워크를 사용하는 것을 고려해야 할 경우는 파이썬 3.7+에서 애드혹(즉석에서 한 번만 사용되는 비일반화된) 오퍼레이터를 만들고자 할 때입니다. 특히, 애플리케이션 도메인을 사용자 정의 리소스로 직접 쿠버네티스에 가져오고자 할 때 유용합니다. 더 많은 기능은 [문서](https://kopf.readthedocs.io/en/stable/)에서 확인할 수 있습니다. + +kopf를 사용하는 주요 장점: +- 사용 용이성: Kopf는 사용 및 이해하기 쉽게 설계되어, 쿠버네티스나 오퍼레이터를 처음 접하는 개발자에게 적합한 선택입니다. +- 파이썬 기반: 파이썬 기반 프레임워크로서, Kopf는 방대한 파이썬 생태계와 라이브러리를 활용할 수 있어 다른 도구 및 시스템과의 통합이 용이합니다. +- 선언적 접근 방식: Kopf는 선언적 접근 방식을 제공하여 시스템의 원하는 상태를 정의하고 업데이트 및 변경 사항을 자동으로 처리하기 쉽게 합니다. +- 경량 및 빠름: Kopf는 경량이며 오버헤드가 적어 자원이 제한된 환경에 배포해야 하는 오퍼레이터를 구축하는 데 적합합니다. + +주요 한계: + +- 파이썬 특화: 파이썬은 인기 있는 언어이지만, 일부 개발자는 쿠버네티스 오퍼레이터를 구축하는 데 다른 언어를 선호할 수 있습니다. +- 제한된 채택: 다른 프레임워크 및 도구와 비교할 때, Kopf의 커뮤니티와 채택률은 상대적으로 작아 리소스 및 지원의 가용성이 제한될 수 있습니다. +- 제한된 유연성: Kopf는 단순하고 사용하기 쉽게 설계되어 더 복잡하거나 특수한 사용 사례에 대한 유연성과 사용자 정의 옵션이 제한될 수 있습니다. +- 학습 곡선: Kopf는 사용하기 쉽게 설계되었지만, 쿠버네티스 오퍼레이터를 구축하려면 여전히 쿠버네티스 개념 및 모범 사례에 대한 지식이 필요하여 신규 사용자에게는 도전이 될 수 있습니다. + +### kubebuilder + +kubebuilder 프레임워크는 개발자가 사용자 정의 리소스 정의를 사용하여 쿠버네티스 API를 확장하고, 이러한 사용자 정의 리소스를 처리하는 컨트롤러를 생성할 수 있는 기능을 제공합니다. + +kubebuilder 프레임워크가 제공하는 주요 진입점은 *매니저*입니다. 기본 Kubernetes 컨트롤러가 단일 Kubernetes Controller Manager(`kube-controller-manager`)로 그룹화되는 것과 마찬가지로, 여러 컨트롤러를 생성하고 이를 단일 매니저가 관리하도록 할 수 있습니다. + +쿠버네티스 API 리소스가 도메인에 연결되고 그룹, 버전 및 종류로 구성되는 것처럼, 정의할 쿠버네티스 사용자 정의 리소스도 고유한 도메인에 연결되고 고유한 그룹, 버전 및 종류로 구성됩니다. + +kubebuilder를 사용할 때 첫 번째 단계는 도메인에 연결된 프로젝트를 생성하여 단일 매니저를 구축하기 위한 소스 코드를 생성하는 것입니다. + +특정 도메인으로 프로젝트를 시작한 후, 해당 도메인에 API를 추가하고 이러한 API를 매니저가 관리하도록 할 수 있습니다. + +프로젝트에 리소스를 추가하면 샘플 코드가 생성됩니다: 사용자 정의 리소스를 구축하기 위해 적응해야 하는 샘플 *사용자 지정 리소스 정의*과 이 리소스를 처리하는 오퍼레이터를 위한 조정 루프를 구현할 샘플 *Reconciler*입니다. + +kubebuilder 프레임워크는 `controller-runtime` 라이브러리를 활용하며, 이 라이브러리는 Manager와 Reconciler 개념 등을 제공합니다. + +kubebuilder 프레임워크는 매니저 바이너리를 구축하기 위한 모든 필수 요소, 매니저를 시작하는 컨테이너 이미지, 이 매니저를 배포하기 위한 Kubernetes 리소스, 사용자 정의 리소스를 정의하는 `CustomResourceDefinition` 리소스, 매니저를 배포하기 위한 `Deployment`, 쿠버네티스 API에 접근할 수 있도록 하는 오퍼레이터를 위한 RBAC 규칙 등을 제공합니다. + +kubebuilder를 사용하는 주요 장점: + +- 개발 단순화: Kubebuilder는 프레임워크와 도구를 제공하여 쿠버네티스 컨트롤러와 API 서버를 구축하는 데 필요한 반복적인 코드를 스캐폴딩하고 자동화하여, 개발자가 비즈니스 로직에 집중할 수 있도록 합니다. + +- 쿠버네티스 네이티브: Kubebuilder는 쿠버네티스 API와 규칙을 기반으로 구축되어, 쿠버네티스 생태계와 잘 통합되는 컨트롤러와 API를 개발하기 쉽게 만듭니다. + +- 재사용성: Kubebuilder는 재사용 가능하고 구성 가능한 컨트롤러와 API의 생성을 장려하며, 이를 통해 다양한 애플리케이션 및 프로젝트에서 공유할 수 있습니다. + +- 견고성: Kubebuilder는 쿠버네티스 컨트롤러와 API를 구축하기 위한 모범 사례를 준수하는 코드를 생성하여, 견고하고 프로덕션 급의 애플리케이션을 쉽게 구축할 수 있게 합니다. + +주요 한계: + +- 학습 곡선: Kubebuilder는 특히 쿠버네티스나 Go 프로그래밍 언어에 익숙하지 않은 개발자에게는 상당한 학습 곡선이 있을 수 있습니다. + +- 복잡성: Kubebuilder가 개발 프로세스의 많은 부분을 단순화하더라도, 쿠버네티스 컨트롤러와 API를 구축하는 것은 여전히 복잡한 작업일 수 있으며, 특히 대규모 또는 분산 애플리케이션의 경우 더욱 그렇습니다. + +- 제한된 유연성: Kubebuilder는 쿠버네티스 컨트롤러와 API가 어떻게 구축되어야 하는지에 대해 명확한 의견을 가지고 있어, 특정 경우에는 유연성이 제한될 수 있습니다. 예를 들어, 매우 맞춤화되거나 특수한 컨트롤러를 구축하는 데는 적합하지 않을 수 있습니다. + +### Metacontroller - 경량 Kubernetes 컨트롤러 서비스 + +[Metacontroller](https://metacontroller.github.io/metacontroller/)는 사용자 정의 오퍼레이터를 쉽게 작성하고 배포할 수 있게 해주는 오퍼레이터입니다. + +Metacontroller는 자체적으로 두 가지 CRD (2021)를 도입합니다: +* [Composite Controller](https://metacontroller.github.io/metacontroller/api/compositecontroller.html) - CRD에 의해 트리거되는 오퍼레이터를 작성할 수 있게 해줍니다. +* [Decorator Controller](https://metacontroller.github.io/metacontroller/api/decoratorcontroller.html) - 다른 오퍼레이터가 관리하는 것을 포함하여, 모든 쿠버네티스 객체에 의해 트리거되는 오퍼레이터를 작성할 수 있게 해줍니다. + +Metacontroller는 이러한 CRD 중 하나로 구성되며, 클러스터 상태를 관찰하고 사용자가 제공한 컨트롤러(사용자 컨트롤러)를 호출하여 필요한 작업을 수행합니다. + +사용자 컨트롤러는 입력으로 제공된 리소스를 바탕으로 종속 객체의 원하는 상태를 계산해야 합니다. +User controller should, having given resources as input, compute the desired state of dependent objects. + +이 패턴은 `람다 컨트롤러` 패턴이라고도 부를 수 있습니다([자세한 내용은 여기](https://metacontroller.github.io/metacontroller/concepts.html#lambda-controller)에서 확인), 출력은 입력과 Metacontroller에서 사용된 로직만을 고려하여 계산되며, 이 로직은 Function-as-a-Service 제공자에 위치할 수도 있습니다. + +Metacontroller의 주요 장점: +* 쿠버네티스 리소스를 감시하는 데 필요한 반복적인 코드를 작성할 필요 없이, 웹훅을 통해 호출되는 함수만 제공하면 됩니다. +* 이러한 함수는 어떤 언어로도 작성할 수 있으며, HTTP를 통해 노출할 수 있습니다. + +주요 한계: +* 위에서 언급한 특정 패턴만 구현할 수 있습니다. +* 현재 아키텍처는 클러스터 내 단일 metacontroller에 의존합니다. +* Metacontroller는 외부 상태에 대해 인식하지 못하며, 오로지 클러스터 상태에만 의존합니다. + +아래에 표시된 예제 metacontroller 구성은 `Service` 매니페스트를 명시적으로 정의하지 않고 `StatefulSet`에 대한 추가 네트워크 노출을 추가하는 데 사용됩니다. +```yaml +apiVersion: metacontroller.k8s.io/v1alpha1 +kind: DecoratorController +metadata: + name: service-per-pod +spec: + resources: + - apiVersion: apps/v1 + resource: statefulsets + annotationSelector: + matchExpressions: + - {key: service, operator: Exists} + - {key: port, operator: Exists} + attachments: + - apiVersion: v1 + resource: services + hooks: + sync: + webhook: + url: http://service-per-pod.metacontroller/sync-service-per-pod + timeout: 10s + +``` +위의 구성에서 : +* `metacontroller`는 `spec.resources` 설명과 일치하는 모든 객체(이 경우 `service` 및 `port` 주석이 있는 `apps/v1/statefulsets`)에 대해 해당 객체에서 발생하는 모든 변경 사항(생성/업데이트/삭제)을 감시하고, 각 변경 사항에 대해 `hooks.sync`를 호출합니다. +* `hooks.sync`는 `spec.attachments`에 설명된 객체(이 경우 `v1/services`)를 반환할 수 있으며, 이는 `hook`의 응답에 따라 `metacontroller`에 의해 생성/업데이트/삭제됩니다. + +예를 들어, 아래와 같은 `StatefulSet`이 배포될 경우: +```yaml +apiVersion: apps/v1 +kind: StatefulSet +metadata: + annotations: + service: "statefulset.kubernetes.io/pod-name" + ports: "80:8080" +... +``` +해당 `Service` 객체는 metacontroller에 의해 생성됩니다. +```yaml +apiVersion: "v1" +kind: "Service" +spec: + selector: "statefulset.kubernetes.io/pod-name" + ports: + - port: 80 + targetPort: 8080 +``` + +사용자가 정의한 엔드포인트(이 예에서는 `http://service-per-pod.metacontroller/sync-service-per-pod`)는 주어진 `StatefulSet`에 대해 `Service`를 어떻게 계산하고 어떤 형태로 나타내야 하는지만 신경 쓰면 됩니다. + +Metacontroller를 사용하여 구현할 수 있는 추가적인 예제와 아이디어는 [metacontroller-examples](https://metacontroller.github.io/metacontroller/examples.html) 페이지에서 확인할 수 있습니다! + +궁금한 점이 있으면 [#metacontroller](https://kubernetes.slack.com/archives/CA0SUPUDP) 슬랙 채널을 방문하시거나 [github discussions](https://github.com/metacontroller/metacontroller/discussions/)에서 질문을 남겨주세요. + +### Juju - 모델 기반 오퍼레이터 프레임워크 + +Juju 오퍼레이터 프레임워크는 클라우드 및 컨테이너 환경에서 복잡한 애플리케이션의 배포, 관리, 확장을 간소화하는 오픈 소스 도구입니다. Juju는 개발자가 애플리케이션 지식, 구성 및 로직을 캡슐화하는 재사용 가능하고 구성 가능한 "차밍(charms)"을 만들 수 있도록 하는 강력한 모델 기반 접근 방식을 제공합니다. 이러한 차밍은 Juju "오퍼레이터"에 의해 쉽게 배포되고 오케스트레이션될 수 있으며, 오퍼레이터는 애플리케이션의 수명 주기를 자동으로 처리하는 에이전트입니다. Juju의 중요한 장점 중 하나는 기본 인프라를 추상화할 수 있는 능력으로, 여러 클라우드 및 컨테이너 환경에서 애플리케이션을 더 쉽게 배포하고 관리할 수 있게 해줍니다. + +아래는 웹 애플리케이션과 데이터베이스 간의 통합 예제입니다. +``` +# Database charm +name: charm-db +# ... +provides: + database: + interface: charm-db +``` + +``` +# A web app charm connecting to the database +name: my-web-app +# ... +requires: + database: + interface: charm-db + limit: 1 +provides: + website: + interface: http + optional: true +``` + +Juju의 주요 장점: +- 추상화: Juju는 쿠버네티스에서 복잡한 애플리케이션의 배포 및 관리를 간소화할 수 있는 추상화 계층을 제공합니다. Juju는 쿠버네티스 API의 복잡성을 추상화하여 개발자가 애플리케이션 로직에 집중할 수 있게 해줍니다. + +- 통합: Juju에서 통합은 애플리케이션 간 또는 동일한 애플리케이션의 다른 유닛 간의 연결을 의미합니다(후자는 '피어 관계'라고도 함). 이러한 애플리케이션 간의 관계는 차밍에서 정의되며, Juju는 애플리케이션 간의 통합을 처리합니다. 이를 통해 애플리케이션 간에 데이터를 전달하고, 이벤트를 통해 작업을 트리거할 수 있습니다. + +- 클라우드에 종속되지 않음: Juju는 클라우드에 종속되지 않으며 다양한 클라우드 제공자 및 컨테이너 플랫폼에 애플리케이션을 배포할 수 있습니다. 이를 통해 개발자는 어떤 클라우드나 컨테이너 플랫폼에서도 쉽게 애플리케이션을 배포하고 관리할 수 있습니다. + +- 모델 기반 접근 방식: Juju는 애플리케이션의 수명 주기(확장, 업그레이드, 모니터링 포함)를 자동화하고 관리하기 쉽게 하는 모델 기반 접근 방식을 제공합니다. + +주요 한계: +- 이 프레임워크는 학습 곡선이 있으며, 효과적인 차밍을 만드는 데 상당한 개발 노력이 필요할 수 있어, 소규모 프로젝트보다는 기업용 사례에 더 적합합니다. + +## 오퍼레이터 수명 주기 관리 +오퍼레이터는 애플리케이션이므로, 이 섹션에서는 오퍼레이터 자체의 수명 주기에 대한 고려 사항을 설명합니다. + +### 오퍼레이터 업그레이드 +오퍼레이터를 업그레이드할 때는 관리되는 리소스에 대해 특별히 주의를 기울여야 합니다. 오퍼레이터 업그레이드 중에는 관리되는 리소스가 동일한 상태로 유지되고, 건강 상태를 유지해야 합니다. + +### 선언적 상태 업그레이드 +선언적 상태는 오퍼레이터의 API이며, 업그레이드가 필요할 수 있습니다. CRD 버전의 사용은 CRD와 오퍼레이터의 안정성을 나타냅니다 - [CRD 버전 관리에 대해 자세히 알아보기](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/) + +### CRD 관계 관리 + +오퍼레이터와 CRD의 수가 증가함에 따라 관리의 복잡성도 함께 증가합니다. 예를 들어, 두 개의 인그레스 관련 기능 간의 충돌을 어떻게 관리할 것인가? DB 클러스터와 DB 백업 CRD 간의 데이터 흐름의 종속성 또는 상관관계를 어떻게 관리할 것인가? + +이 문제를 해결하기 위해, 오퍼레이터와 CRD를 관리할 수 있는 구체적인 모델과 이를 정책 기반 엔진으로 감독할 수 있는 새로운 메커니즘이 필요합니다. [KubeVela](https://kubevela.io/)와 [Crossplane](https://crossplane.io/)과 같은 커뮤니티 노력은 CRD를 구성하는 솔루션을 제공하여 이 문제를 해결하려고 하고 있습니다. KubeVela는 또한 사용자 정의 리소스 간의 데이터 종속성 관리를 제공합니다. + +## 오퍼레이터 사용 사례 + +- 데이터베이스 관리: 오퍼레이터는 쿠버네티스에서 실행되는 데이터베이스의 배포, 확장 및 관리를 자동화하는 데 사용될 수 있습니다. 예를 들어, 오퍼레이터는 MySQL 또는 PostgreSQL 데이터베이스 클러스터의 배포를 관리하고, 확장, 백업 및 업그레이드와 같은 작업을 수행할 수 있습니다. + +- 애플리케이션 배포: 오퍼레이터는 쿠버네티스에서 실행되는 복잡한 애플리케이션의 배포 및 관리를 자동화하는 데 사용될 수 있습니다. 예를 들어, 오퍼레이터는 컨테이너화된 웹 애플리케이션의 배포를 관리하고, 롤링 업그레이드를 처리하며, CPU 사용량과 같은 메트릭을 기반으로 자동 확장을 수행할 수 있습니다. + +- 모니터링 및 로깅: 오퍼레이터는 Prometheus나 Elasticsearch와 같은 모니터링 및 로깅 도구의 배포 및 구성을 관리하는 데 사용될 수 있습니다. 오퍼레이터는 모니터링 경고 구성, 로그 수집 및 집계, 백업 수행과 같은 작업을 자동화할 수 있습니다. + +- 머신 러닝 워크플로: 오퍼레이터는 머신 러닝 워크플로와 모델의 배포 및 확장을 관리하는 데 사용될 수 있습니다. 예를 들어, 오퍼레이터는 TensorFlow 또는 PyTorch 클러스터의 배포를 관리하고, 확장, 모델 학습 및 배포와 같은 작업을 처리할 수 있습니다. + +- 인프라 관리: 오퍼레이터는 로드 밸런서, 스토리지 볼륨 및 네트워크 정책과 같은 인프라 리소스의 배포 및 구성을 관리하는 데 사용될 수 있습니다. 예를 들어, 오퍼레이터는 로드 밸런서의 배포를 관리하고, 확장 및 트래픽 라우팅과 같은 작업을 수행할 수 있습니다. + +## 잘 알려진 오퍼레이터 및 패턴 + + +### 프로메테우스 오퍼레이터 + +프로메테우스 오퍼레이터는 etcd와 함께 처음으로 작성된 오퍼레이터 중 하나로, 이 문제 영역에서의 사용 사례를 입증했습니다. + +_"프로메테우스 오퍼레이터는 쿠버네티스 상에서 프로메테우스를 가능한 한 쉽게 실행할 수 있도록 하면서, 쿠버네티스 네이티브 구성 옵션을 유지하는 역할을 합니다."_ + +[프로메테우스 오퍼레이터](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/user-guides/getting-started.md)가 설치되면, 오퍼레이터 컨트롤러 파드/배포 외에도, 프로메테우스 스택을 구성할 수 있는 다양한 API가 제공됩니다. 이 API는 사용자 정의 리소스 정의(CRDs, Custom Resource Definitions)로 표현되며, 다음과 같은 작업을 담당하는 객체를 구성할 수 있습니다: + +- 프로메테우스(ServiceMonitor)가 모니터링할 대상 집합을 설명합니다. +- 프로메테우스 배포의 원하는 상태를 선언적으로 설명합니다. +- 클라이언트 응용 프로그램에서 보낸 알림을 처리하는 [AlertManager](https://github.com/prometheus/alertmanager) 클러스터를 설명합니다. + +이점은 쿠버네티스 네이티브 구성을 사용하여 전체 운영 스택을 구성할 수 있으며, 쿠버네티스 리소스 검증 및 자가 치유 기능의 혜택을 받을 수 있다는 점입니다. + +오퍼레이터 컨트롤러는 쿠버네티스 API 서버와 통신하여 서비스 메트릭스 엔드포인트를 추가하고, 구성된 서비스에 대해 필요한 프로메테우스 스크래핑 구성을 자동으로 생성합니다. + +### GitOps를 위한 오퍼레이터 +오퍼레이터는 종종 애플리케이션을 설치, 업그레이드 및 운영하는 것과 관련이 있습니다. 그러나 오퍼레이터가 애플리케이션을 관리하지 않고도 다른 작업을 "운영"할 수 있는 예를 GitOps 세계에서 찾을 수 있습니다. GitOps는 모든 리소스의 진실된 정보를 Git에 저장하고 이를 기반으로 관리하는 방식입니다. + +주로 명령적으로 관리되던 애플리케이션을 더 선언적이고 Git 중심의 방식으로 오케스트레이션해야 하는 경우가 있을 수 있습니다. 이때 오퍼레이터는 Git 리포지토리에서 구성을 가져오고, 구성을 분석하여 변경이 필요한 사항과 취해야 할 조치를 결정하고, 그에 따라 조치를 수행할 수 있습니다. + +![GitOps 예시](img/071_GitOps_UseCase.png) + +위의 예시는 이러한 경우를 설명합니다: + +1. 구성 파일이 Git 리포지토리에서 확인됩니다. +2. 오퍼레이터는 사용자 정의 리소스 정의(CRD)를 사용하여 Git 리포지토리를 인식합니다(리포지토리 경로 및 비밀 정보가 저장됨). +3. 오퍼레이터는 구성을 가져와 분석합니다. +4. 오퍼레이터는 현재 상태에서 원하는 상태로 전환하기 위한 운영 지식을 적용합니다(애플리케이션의 현재 상태를 쿼리하고, 원하는 상태로 전환하기 위한 지침을 전송함). + +이를 통해 사용자는 Git 리포지토리에 버전 관리된 재현 가능한 구성을 가질 수 있습니다. + +### 성공적인 패턴 + +시간이 지나면서 다양한 소스에서 오퍼레이터 작성에 대한 모범 사례가 많이 발표되었습니다. 다음은 이러한 소스 중 일부를 언급하고, 시나리오를 기반으로 설명한 내용입니다. + +시나리오: 마이크로서비스 애플리케이션(“The PodTato Head”, https://github.com/cncf/podtato-head)을 오퍼레이터를 통해 완전히 관리해야 합니다(다른 배포 메커니즘이 더 적합할 수 있지만). 이 애플리케이션은 4개의 서비스와 1개의 데이터베이스로 구성되어 있으며, 다음과 같이 설명될 수 있습니다: + +![Sample Application](./img/08_1_sample.png) + +이 애플리케이션 배포에는 모범 사례가 적용되어야 합니다. + +### 단일 유형의 애플리케이션 관리 + +오퍼레이터가 제공하는 기능은 특정 애플리케이션에 맞춰져 있어야 합니다. 예를 들어, 위의 시나리오에 적용하면, 각 구성 요소(podtato-server, arm-service, foot-service, hat-service, 그리고 데이터베이스)를 관리하는 5개의 오퍼레이터가 있어야 합니다. 이렇게 하면 각 구성 요소에 대한 관심사를 명확하게 분리할 수 있습니다 (출처: https://cloud.google.com/blog/products/containers-kubernetes/best-practices-for-building-kubernetes-operators-and-stateful-apps). + +### 오퍼레이터의 오퍼레이터 + +애플리케이션 워크로드 배포 및 관리 수명 주기에서 사용되는 오퍼레이터의 수가 증가함에 따라, 여러 오퍼레이터 간의 자원 상호작용 및 메타 행동을 관리하는 새로운 방법이 필요해졌습니다. 예를 들어, 여러 비동기 오퍼레이터가 자원을 변경하는 작업을 관리하는 데 필요한 인지 부담을 줄이거나, 릴리스 버전 간의 연속성을 보장하기 위한 목적으로 오퍼레이터의 오퍼레이터 아키텍처가 몇몇 산업 사례에 적용되고 있습니다. 이 패러다임은 일반적으로 메타 오퍼레이터를 활용하여 여러 자원을 생성하고, 이를 비동기적으로 생성 및 업데이트하여 메타 리소스에 반영합니다. 이를 통해 단일 사용자 정의 리소스 정의로 원하는 상태 결과를 표현하고, 요구 사항을 분할하여 비동기적으로 실행할 수 있습니다. + +![distributed](./img/09_1_distributedops.png) + + +전체 스택의 설정 및 수명 주기를 조정하는 것은 여전히 복잡할 수 있습니다. 메타데이터 리소스를 제어하는 오퍼레이터는 스택의 다양한 부분을 조정하고 전체 스택을 나타내는 CRD를 노출하여 사용자를 이러한 복잡성으로부터 보호할 수 있습니다. 이러한 경우, *메타* 오퍼레이터는 더 구체적인 부분에 대해서는 다른 오퍼레이터에게 작업을 위임해야 합니다. + +이 스택의 하위 구성 요소를 소유하는 컨트롤러는 두 가지 방식으로 나타날 수 있습니다: + +- 오퍼레이터 배포 패키지는 스택의 하위 구성 요소를 각각 처리하는 여러 개의 별도 컨트롤러와 주요 컨트롤러(스택 전체를 나타내는 엔드 유저 대상의 CRD를 담당)를 포함할 수 있습니다. 이러한 다중 컨트롤러 오퍼레이터를 단일 패키지로 배포하면 모든 컨트롤러가 동시에 실행되며(각각 하나의 파드), 실제로 엔드 유저 대상의 API/CRD만이 공개적으로 노출되고 문서화됩니다. 이때, 이 API를 담당하는 컨트롤러는 "내부" CRD를 사용하여 패키징된 다른 컨트롤러에게 여러 작업을 위임합니다. 이는 전체 "스택"이 동일한 오퍼레이터 작성자 그룹에 의해 소유 및 개발되고 "하위" 컨트롤러가 독립된 프로젝트로는 적합하지 않을 때 유용합니다. 최종 사용자에게 이 컨트롤러 세트는 여전히 단일 오퍼레이터로 나타납니다. 여기서 주요 이점은 오퍼레이터 프로젝트 내에서 관심사의 분리입니다. + +![Stack-Operator](./img/08_2_umbrella.png) + +기술적으로, 오퍼레이터가 관리하는 전체 스택에 대한 사용자 정의 리소스 정의(CRD)가 있을 것입니다. 이 오퍼레이터는 스택의 각 구성 요소에 대해 사용자 정의 리소스를 생성하며, 이들 리소스는 다시 오퍼레이터에 의해 관리되고 기본 리소스를 관리하게 됩니다. + +- 위에서 설명한 두 번째 패턴은 상위 수준의 워크로드 오퍼레이터를 묘사합니다. 이러한 오퍼레이터는 스택의 하위 구성 요소를 배포하기 위해 다른 범용 오퍼레이터 프로젝트에 의존합니다. 예를 들어, `cert-manager`, `prometheus operator`, `postgresql` 오퍼레이터에 의존하여 회전하는 인증서, 모니터링, SQL 데이터베이스를 사용하여 워크로드를 배포하는 오퍼레이터가 있을 수 있습니다. 이 경우 상위 수준의 워크로드 오퍼레이터는 실행 시 `cert-manager` 등을 함께 배포하거나 설치하려고 해서는 안 됩니다. 이는 오퍼레이터 작성자가 이러한 종속성의 특정 버전을 배포하고 유지 관리하는 책임을 지게 되며, CRD 수명 주기 관리와 관련된 일반적인 문제 영역을 처리해야 하기 때문입니다. + + *대신, 설치 시점에서 종속성 해결을 지원하는 패키지 관리 솔루션을 사용하여 필요한 다른 오퍼레이터 설치를 배경에서 패키지 관리자에게 위임하고, 상위 수준의 오퍼레이터 시작 코드의 일부로 포함하지 않도록 해야 합니다.* + + 이 방법은 자체적으로 유용하며 클러스터의 여러 다른 오퍼레이터와 공유될 수 있는 오퍼레이터에 의존하는 오퍼레이터에게 유익합니다. Operator Framework 프로젝트의 일부인 [OLM](https://github.com/operator-framework/operator-lifecycle-manager)은 이러한 패키지 관리자 중 하나입니다. + + +### 컨트롤러당 하나의 CRD +오퍼레이터가 관리하는 모든 CRD는 단일 컨트롤러에서 구현되어야 합니다. 이렇게 하면 코드가 더 읽기 쉬워지고 관심사의 분리가 이루어집니다. + +### 오퍼레이터를 게시하고 찾는 곳 +operatorhub.io 및 artifacthub.io와 같은 서비스는 최종 사용자가 오퍼레이터를 찾고 설치 방법에 대한 지침을 제공받을 수 있도록 도와줍니다. 이러한 서비스에는 종종 현재의 보안 문제와 오퍼레이터 소스에 대한 정보가 포함되어 있으며, 오퍼레이터의 기능에 대한 정보도 제공됩니다. + +### 추가 읽을 거리 +다른 여러 모범 사례도 있습니다: + +* 오퍼레이터는 배포된 네임스페이스에 대해 가정해서는 안 됩니다. +* 오퍼레이터 작성 시 SDK를 사용하는 것이 좋습니다. + +추가 정보는 다음 소스에서 확인할 수 있습니다: +* https://github.com/operator-framework/community-operators/blob/master/docs/best-practices.md +* https://cloud.google.com/blog/products/containers-kubernetes/best-practices-for-building-kubernetes-operators-and-stateful-apps + +## 오퍼레이터 설계 + +이전 장에서는 최초의 오퍼레이터 중 하나였던 오퍼레이터의 사용 사례를 설명했습니다. 이 장에서는 완전성을 주장하지는 않지만, 우리가 직접 작성하는 오퍼레이터를 작성할 때 도움이 되는 몇 가지 모범 사례에 대해 다루고자 합니다. 이는 우리의 경험이나 커뮤니티에서 설명된 내용을 기반으로 합니다. 그러나 실제 상태에 대한 명확한 지식이 없거나 우리가 달성하고자 하는 목표에 대한 명확한 아이디어가 없다면, 오퍼레이터가 수행해야 할 작업을 명확히 지정하기 위한 몇 가지 방법과 기술이 필요합니다. 따라서 요구 사항 분석의 일부 측면도 다루어야 할 것입니다. + +### 요구 사항 분석 + +쿠버네티스의 핵심 약속 중 하나는 여러 환경에 걸쳐 컨테이너화된 애플리케이션을 배포, 확장 및 관리하는 운영 작업을 자동화하여 최소한의 인력 개입으로 수행할 수 있도록 한다는 것입니다. 쿠버네티스에서는 상태 비저장 클라우드 네이티브 애플리케이션이 수평 확장, 자동 자가 치유 재시작, 또는 새로운 컨테이너의 점진적 롤아웃에 적합합니다. 그러나 클러스터형 또는 분산 환경에서 실행되는 복잡한 구성 요소를 가진 상태 저장 애플리케이션은 이러한 유형의 컨테이너 기반 인프라에 항상 적합하지 않습니다. 이러한 애플리케이션은 안정적인 상태를 유지하기 위해 지속성, 업그레이드 또는 고가용성과 같은 문제에서 여전히 인간의 개입이 필요합니다. + +쿠버네티스는 오퍼레이터를 사용하여 사용자 정의 애플리케이션을 생성하고 관리함으로써 이러한 문제를 새롭고 혁신적인 방식으로 해결합니다. 그러나 여기서 첫 번째 질문이 나옵니다: 개발자로서 이 유형의 애플리케이션이 내부 및 외부적으로 어떻게 작동하고 상호작용하는지 정말 알고 있습니까? 일상적인 IT 운영은 어떻게 이루어지나요? 애플리케이션의 백업(및 복구)은 어떻게 이루어지나요? 장애 발생 시 필요한 조치는 무엇이며, 소프트웨어 구성 요소 간에 종속성이 있습니까? + +따라서 오퍼레이터의 요구 사항 또는 조건을 결정하기 위해 포괄적인 요구 사항 분석이 필요합니다. 요구 사항 분석은 오퍼레이터의 성공 여부를 결정하는 중요한 요소입니다. 모든 요구 사항은 문서화되고, 측정 가능하며, 테스트 가능하고, 추적 가능해야 하며, 식별된 요구 사항과 관련이 있고, 시스템 설계를 위한 충분한 세부 수준으로 정의되어야 합니다. + +올바른 오퍼레이터를 구축하기 위한 단계: + +1. 오퍼레이터를 사용할지 확신이 서지 않을 경우, 먼저 타당성 평가를 수행해 보세요. 오퍼레이터를 사용하는 이유를 합리적이고 이해하기 쉽게 찾으세요. 오퍼레이터의 이점을 구현 및 운영에 필요한 노력과 비교해 보세요. + +2. 애플리케이션의 기존 문서를 연구하고, 책임 시스템 관리자 및 기타 이해 관계자와 인터뷰를 진행하세요(필요한 경우). 가능한 시스템 점검 활동 목록, 비즈니스 및 SLA 관련 KPI를 확인하고, 이를 기존 사건 보고서 또는 버그 추적 목록과 비교해 보세요. + +3. 구체적인 시나리오(예: 애플리케이션 장애 조치)를 "누가, 언제, 어떻게, 왜 무엇을 하는가"에 대한 세부 사항을 따라 자세히 설명하세요. + +4. 이전 시나리오를 독립적으로 실행하고 애플리케이션을 안정적이고 생산적인 상태로 유지하기 위해 오퍼레이터가 알아야 할 사항을 설명하세요. + +### 사용자 정의 또는 서드파티 오퍼레이터 + +이제 오퍼레이터를 사용하는 상황이 명확해졌으니, 다음으로 오퍼레이터 구현이 가능한 곳과 요구 사항을 가장 잘 충족하는 옵션에 대해 논의하겠습니다. + +적절한 쿠버네티스 오퍼레이터를 찾는 것은 어려울 수 있습니다. 한편으로는 수집한 요구 사항에 부합하는 것을 찾아야 하며, 다른 한편으로는 오퍼레이터가 정기적으로 업데이트되고 공급업체에 의해 적극적으로 지원되어야 합니다. + +간단히 말해, 오퍼레이터를 얻기 위해 선택할 수 있는 세 가지 방법이 있습니다: + +(1) 데이터베이스가 있고 오퍼레이터가 필요한가요? 공급업체의 웹사이트를 참조하세요. + +(2) 사용할 수 있는 쿠버네티스 오퍼레이터를 제공하는 공개(또는 비공개) 레지스트리를 검색할 수 있습니다. 예를 들어, \[1\]은 오퍼레이터의 배포를 간소화하여 오퍼레이터를 게시하고 공유할 수 있는 플랫폼을 제공합니다. 이 플랫폼은 지원되는 서비스와 기본 문서를 더 쉽게 찾을 수 있게 하며, 활발한 오퍼레이터 커뮤니티와 공급업체 지원 이니셔티브를 식별합니다. + +(3) 직접 오퍼레이터를 작성할 수도 있습니다. 처음부터 작성하거나 적합한 프레임워크를 사용할 수 있습니다. + +오퍼레이터는 애플리케이션에 특화되어 있으며, 그 기능은 단순한 설치 스크립트에서 업그레이드, 백업, 장애 처리를 다루는 정교한 로직에 이르기까지 다양합니다. 공개 레지스트리에서 적합한 오퍼레이터를 찾는 데에는 시간과 노력이 필요하며, 기능이 과도하거나 부족할 수 있습니다. 반면, 사용자 정의 오퍼레이터를 작성할 경우, 개발자가 구현하고자 하는 기능에는 제한이 없으나, 개발 및 유지 관리에 대한 비용이 발생할 수 있습니다. + +### 올바른 도구 사용 + +완전한 요구 사항 분석을 마치고 사용자 정의 쿠버네티스 오퍼레이터를 작성하기로 결정한 후, 다음으로 개발자가 사용할 도구를 선택해야 합니다. \[2\]에서 언급된 기사에서는 오퍼레이터를 작성하는 다양한 접근 방식을 논의하고 각 솔루션의 장단점을 나열합니다. 이 기사에서는 하나의 오퍼레이터를 예로 들어 다양한 기술과 도구를 사용하여 설명합니다. 구체적으로, 저자는 다음 도구들을 설명합니다: + +\(a\) Operator SDK (Helm, Go, Ansible). + +\(b\) Operator framework KOPF (Python) + +\(c\) Bare programming language (Java) + +앞서 언급한 것처럼, 이 기사에서는 개별 도구를 설명하는 것뿐만 아니라 그 접근 방식을 비교합니다. 저자는 명령형 프로그래밍 접근 방식이 개발 시 더 많은 시간과 작업, 주의가 필요함을 보여줍니다. 그 대가로, 개발자는 필요한 모든 종류의 로직을 프로그래밍할 수 있는 유연성을 얻습니다. 반면에, 선언적 접근 방식(Helm Chart, Ansible)은 매우 간단하고 정확하며 사람이 읽기 쉬운 형태로 오퍼레이터를 구현할 수 있게 해줍니다. + +\[2\]에서 제시한 모범 사례는 다음과 같습니다: + +1. 이미 **Helm 차트를 보유**하고 있으며, 복잡한 기능 수준이 필요하지 않은 경우 =\> Operator SDK: Helm + +2. **빠르게 오퍼레이터를 생성**하고 싶고, 복잡한 기능 수준이 필요하지 않은 경우 =\> Operator SDK: Helm + +3. **복잡한 기능**이 필요하거나 또는 향후 구현에 대해 유연하고 싶다면 =\> Operator SDK: Go + +4. 조직에서 **단일 프로그래밍 언어**를 유지하고 싶다면: + + a. 해당 언어에 대한 인기 있는 오퍼레이터 프레임워크가 존재하거나/또는 해당 프레임워크에 기여하고 싶다면 =\> Operator Framework + + b. 해당 프로그래밍 언어에 대한 인기 있는 오퍼레이터 프레임워크가 존재하지 않는다면 =\> Bare Programming Language + +5. **위의 어떤 경우에도 해당되지 않는다면** =\> Operator SDK: Go + +### 올바른 프로그래밍 언어 사용 + +오퍼레이터는 원하는 언어로 작성할 수 있는 프로그램입니다. 이는 쿠버네티스가 HTTP와 같은 경량 프로토콜을 사용하여 클라이언트와 통신할 수 있는 REST API를 제공하기 때문에 가능합니다. 따라서 REST API 사양을 준수하는 한, 소프트웨어 개발자는 선호하는 프로그래밍 언어로 오퍼레이터를 작성할 수 있습니다. + +하지만 개발자가 프로그래밍 언어를 자유롭게 선택할 수 있게 되면, 결국 다양한 기술과 언어가 혼재된 상황이 발생할 수 있습니다. 이는 유지 관리, 문제 해결, 버그 수정 및 지원 요청에 대한 비용을 증가시킬 수 있습니다. 더 나은 전략은 단일 프로그래밍 언어에 집중하여 팀으로서 개발하는 것입니다. 이는 팀 내 협업과 상호 지원을 크게 촉진합니다. + +그러나 \[1\]에 따르면, **Go 언어로 작성된 오퍼레이터**가 가장 인기가 많습니다. 그 이유는 두 가지입니다. 첫째, 쿠버네티스 환경 자체가 Go로 작성되었기 때문에 클라이언트 라이브러리가 완벽하게 최적화되어 있습니다. 둘째, Operator SDK(내장된 Kubebuilder 포함)는 Go로 오퍼레이터를 구현하는 것을 기본적으로 지원합니다. 이는 개발자가 많은 코드 스캐폴딩 작업을 절약할 수 있게 해주며, 무료로 코드 생성을 제공합니다. + +### 필요에 맞게 오퍼레이터 설계하기 + +다음은 다양한 소스에서 발견되고 발표된 모범 사례들을 정리한 목록입니다. + +- 오퍼레이터를 작성할 때는 쿠버네티스 API를 사용해야 합니다. 이 작업을 효율적으로 처리하고 개발 및 테스트를 쉽게 할 수 있도록 Operator-SDK와 같은 프레임워크를 사용하는 것이 좋습니다. \[3\] + +- 오퍼레이터를 설계할 때, 오퍼레이터가 중지되거나 제거되더라도 애플리케이션 인스턴스가 영향을 받지 않고 계속 효과적으로 실행될 수 있도록 해야 합니다. + +- 애플리케이션당 하나의 오퍼레이터를 개발하는 것이 좋습니다. \[4\] + +- 오퍼레이터는 이전에 생성된 리소스의 이전 버전을 항상 이해할 수 있도록 하며, 하위 호환성을 가져야 합니다. + +- 비동기 동기화 루프를 사용하세요. \[4\] + +- 오퍼레이터는 가능한 경우 레플리카 세트(replica sets) 및 서비스와 같은 내장된 쿠버네티스 기본 요소를 활용해야 합니다. 잘 알려지고 충분히 테스트된 코드를 사용하는 것이 좋습니다. + +- 가능한 경우, 파드, 구성, 스토리지 및 네트워킹의 잠재적 실패를 시뮬레이션하는 테스트 스위트에 대해 오퍼레이터를 테스트하세요. + +### 참고자료 + +\[1\] https://operatorhub.io + +\[2\] +https://hazelcast.org/blog/build-your-kubernetes-operator-with-the-right-tool/ + +\[3\] +https://github.com/operator-framework/community-operators/blob/master/docs/best-practices.md + +\[4\] +https://cloud.google.com/blog/products/containers-kubernetes/best-practices-for-building-kubernetes-operators-and-stateful-apps + + +## 미래의 새로운 패턴 + +오퍼레이터의 인기가 높아짐에 따라 모범 사례와 설계 원칙의 현 상태에 도전하는 새로운 사용법과 패턴이 등장하고 있습니다. + +### 오퍼레이터 수명 주기 관리 + +오퍼레이터의 복잡성이 증가하고 버전이 지정된 분산 컨트롤러가 등장하면서 오퍼레이터와 그 리소스의 관리 및 투명성에 대한 필요성이 생겨났습니다. 이 패턴은 발견 가능성, 최소한의 종속성, 선언적 UI 제어를 통해 오퍼레이터의 재사용을 돕습니다[1]. + +추가적으로, 오퍼레이터가 특정 특성과 예상되는 최종 상태를 조정하도록 점점 더 많이 설계됨에 따라, 적절한 관리를 통해 클러스터 내에서 수명 주기를 유지함으로써 새로운 동작에 대한 반복, 실험 및 테스트가 가능해집니다. + +### 정책 인식 오퍼레이터 + +많은 오퍼레이터는 클러스터 내에서 리소스를 조정하기 위해 고정된 역할 기반 권한 집합을 가지고 있습니다. 리소스를 조정하는 데 필요한 동작에 따라 오퍼레이터에 더 동적인 접근 권한을 제공하려는 활동이 계속되고 있습니다. 이는 리소스를 직접 생성하기 위해 일시적으로 권한을 상승시키거나, 사용자 정의 리소스 정의를 쿠버네티스 API 서버에 로드하도록 요청하는 것을 의미할 수 있습니다. + +오퍼레이터가 리소스를 대신하여 특권을 가진 생성 권한을 허용하는 선례가 있으며[2], 이는 새로운 패턴과 운영 모델로 확장됩니다[3]. 이러한 패턴의 미래 가능성은 정책 엔진을 통해 오퍼레이터 권한을 제어할 수 있도록 하는 것입니다. + +### 오퍼레이터 데이터 모델링 + +쿠버네티스의 채택이 계속 증가함에 따라 쿠버네티스 오퍼레이터의 역할도 진화할 가능성이 높습니다. 미래에는 오퍼레이터가 더 지능적이고 자동화되며 다른 쿠버네티스 도구 및 서비스와 더욱 통합될 것으로 기대됩니다. 특히 데이터 모델링을 활용하여 쿠버네티스에서 실행되는 더 복잡하고 동적인 애플리케이션을 지원하는 분야에서 큰 발전이 있을 것으로 보입니다. 데이터 모델링을 사용하여 시스템의 상태를 정의하고 관리함으로써, 오퍼레이터는 복잡한 워크플로, 애플리케이션 및 서비스를 더 쉽게 관리하고 자동화할 수 있습니다. 이러한 접근 방식은 확장성, 유연성 및 유지 관리성을 개선할 뿐만 아니라 자동 스케일링 및 자가 치유와 같은 고급 기능도 가능하게 합니다. 앞으로 쿠버네티스 오퍼레이터는 쿠버네티스 기반 애플리케이션 및 서비스를 위한 고급 데이터 모델링 및 관리 기능을 가능하게 하는 데 중요한 역할을 할 것으로 기대됩니다. + +### 참고자료 + +\[1\] https://olm.operatorframework.io/ + +\[2\] https://github.com/cloud-ark/kubeplus + +\[3\] https://oam.dev/ + +## 결론 +쿠버네티스 오퍼레이터는 쿠버네티스에서 실행되는 복잡한 애플리케이션을 관리하는 데 중요한 도구입니다. 이 문서에서 살펴본 바와 같이, 각각의 장단점을 가진 여러 인기 있는 오퍼레이터 프레임워크가 있습니다. 어떤 오퍼레이터 프레임워크가 귀하의 조직에 적합한지 결정하려면, 특정 요구 사항을 평가하고 개발 복잡성, 배포 확장성, 유지 관리 요구 사항과 같은 요소를 고려하는 것이 중요합니다. + +미래를 내다보면, 쿠버네티스 오퍼레이터는 계속해서 진화하고 더 정교해지며, 다른 쿠버네티스 도구 및 서비스와 더욱 통합될 것으로 기대됩니다. 데이터 모델링의 사용은 이러한 진화에서 중요한 역할을 하여 자동 스케일링 및 자가 치유와 같은 고급 기능을 가능하게 할 수 있습니다. 쿠버네티스의 채택이 계속 증가함에 따라 오퍼레이터는 쿠버네티스 기반 애플리케이션 개발 및 배포의 점점 더 중요한 구성 요소가 될 것입니다. 다양한 오퍼레이터 프레임워크의 장단점을 이해하고 조직의 특정 요구 사항을 평가함으로써, 쿠버네티스 오퍼레이터를 효과적으로 활용하여 애플리케이션을 쉽게 효율적으로 자동화하고 관리할 수 있습니다. + +## 관련 연구 +처음에 오퍼레이터는 CoreOS 블로그의 게시물을 통해 소개되었습니다. 이 글은 오퍼레이터가 무엇인지, 왜 이 개념이 개발되었는지, 그리고 어떻게 구축되는지에 대한 대략적인 개요를 제공합니다. 이 문서에서 오퍼레이터의 정의는 주로 이 글의 통찰을 바탕으로 하고 있습니다. 블로그 포스트는 간략한 개요만 제공했기 때문에, 이 문서에서는 기능, 보안, 추가 개념과 같은 용어를 보다 깊이 있게 설명하고 있습니다. + +오퍼레이터 패턴은 개념으로서 Kubernetes 문서에서 설명되며, 예시 오퍼레이터가 작동 방법에 대한 개요와 오퍼레이터 작성에 대한 출발점을 제공합니다 [1]. + +책 "Kubernetes Operators"[2]는 오퍼레이터에 대한 종합적인 개요를 제공하며, 오퍼레이터가 해결하는 문제와 이를 개발하는 다양한 방법을 설명합니다. 이 책에서 정의된 내용이 이 문서에 반영되었습니다. 또한, "Kubernetes Patterns" (Ibryam, 2019) 책도 마찬가지로 오퍼레이터에 대한 기술적 및 개념적 통찰을 제공합니다. 이들 책에서 정의된 내용은 이 문서에 요약되어, 오퍼레이터에 대한 공통 정의를 제공합니다. + +Michael Hausenblas와 Stefan Schimanski[3]는 client-go, 사용자 정의 리소스 및 오퍼레이터 작성에 대한 심층적인 통찰을 제공하는 "Programming Kubernetes"라는 책을 썼습니다. + +구글은 쿠버네티스 오퍼레이터와 상태 저장 애플리케이션을 구축하기 위한 모범 사례에 대한 블로그 포스트를 제공했습니다. 이 포스트의 일부 권고사항은 이 문서의 모범 사례 섹션에 반영되었습니다 [4]. + +많은 문서들이 오퍼레이터의 기능 수준(성숙도 수준이라고도 함)을 설명하고 있습니다. 모든 기능을 지원하지만 일부 낮은 수준의 기능을 지원하지 않는 오퍼레이터가 있을 수 있기 때문에, 이 문서에서는 "기능 수준" 대신 "기능"을 다루기로 했습니다. 그러나 각 기능 수준에 필요한 기능은 고려됩니다 [5]. + +CNCF TAG Security는 이 문서에 보안 관련 주제를 추가하기 위해 많은 노력을 기울였습니다. 이 문서의 내용이 주로 오퍼레이터 관련 보안 조치를 다루기 때문에, 이들은 클라우드 네이티브 보안 문서를 작성했으며, 클라우드 네이티브 보안을 다룰 때 매우 유용한 자료입니다 [6]. + +### 참고자료 + +\[1\] https://kubernetes.io/docs/concepts/extend-kubernetes/operator/ +\[2\] Dobies, J., & Wood, J. (2020). Kubernetes Operators. O'Reilly. +\[3\] Michael Hausenblas and Stefan Schimanski, Programming Kubernetes: Developing Cloud-Native Applications, First edition. (Sebastopol, CA: O’Reilly Media, 2019). +\[4\] https://cloud.google.com/blog/products/containers-kubernetes/best-practices-for-building-kubernetes-operators-and-stateful-apps +\[5\] Operator Framework. Retrieved 11 2020, 24, from https://operatorframework.io/operator-capabilities/, +https://github.com/cloud-ark/kubeplus/blob/master/Guidelines.md +\[6\] https://github.com/cncf/tag-security/blob/main/security-whitepaper/v2/cloud-native-security-whitepaper.md + + +## 감사의 말 +이 문서는 CNCF TAG App-Delivery Operator Working Group의 커뮤니티 기반 노력입니다. 이 문서에 기여하고, 토론에 참여하고, 문서를 검토한 모든 분들에게 감사드립니다. + +### V1.1 +#### 기여자 + +- Alex Jones (github.com/AlexsJones) + +#### 리뷰어 + +### V1.0 + +#### 기여자 + +- Omer Kahani (github.com/OmerKahani) +- Jennifer Strejevitch (github.com/Jenniferstrej) +- Thomas Schuetz (github.com/thschue) +- Alex Jones (github.com/AlexsJones) +- Hongchao Deng (github.com/hongchaodeng) +- Grzegorz Głąb (github.com/grzesuav) +- Noah Kantrowitz (github.com/coderanger) +- John Kinsella (github.com/jlk) +- Philippe Martin (github.com/feloy) +- Daniel Messer (github.com/dmesser) +- Roland Pellegrini (github.com/friendlydevops) +- Cameron Seader (github.com/cseader) + +#### 리뷰어 + +- Umanga Chapagain (github.com/umangachapagain) +- Michael Hrivnak (github.com/mhrivnak) +- Andy Jeffries (github.com/andyjeffries) +- Daniel Pacak (github.com/danielpacak) +- Bartlomiej Plotka (github.com/bwplotka) +- Phil Sautter (github.com/redeux) +- Roberth Strand (github.com/roberthstrand) +- Anais Urlichs (github.com/AnaisUrlichs)