커스텀 리소스와 컨트롤러
- 12.1 CRD (Custom Resource Definition)
- 12.2 커스텀 컨트롤러와 컨트롤러 패턴
쿠버네티스 생태계가 폭발적으로 성장할 수 있었던 핵심이 뭐냐면, 자신만의 리소스 타입을 정의하고 그에 맞는 컨트롤러를 만들어서 기능을 확장할 수 있기 때문이야. 기본 내장된 파드, 디플로이먼트, 서비스 말고도 뭐든 추가할 수 있거든.
**CRD(Custom Resource Definition)**로 쿠버네티스에 새로운 리소스 타입을 등록할 수 있어. Certificate, VirtualService, PostgresCluster 같은 리소스를 추가할 수 있지:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: mycaches.example.com
spec:
group: example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
size:
type: integer
image:
type: string
scope: Namespaced
names:
plural: mycaches
singular: mycache
kind: MyCache
shortNames:
- mc
이 CRD를 apply하면 이제 MyCache라는 새로운 리소스 타입을 사용할 수 있어:
apiVersion: example.com/v1
kind: MyCache
metadata:
name: production-cache
spec:
size: 3
image: redis:7
kubectl apply -f mycache.yaml
kubectl get mycaches
kubectl get mc # shortName 사용
CRD 자체는 데이터를 저장하는 것만 해. etcd에 커스텀 리소스 오브젝트를 저장하고, kubectl로 CRUD가 가능해지지. 하지만 이 리소스를 기반으로 실제로 뭔가를 하려면(예: Redis 클러스터를 배포) 커스텀 컨트롤러가 필요해. CRD에 **스키마 검증(openAPIV3Schema)**을 정의하면 잘못된 값이 들어오는 걸 막을 수 있어. required 필드, 값의 범위(minimum, maximum), 열거형(enum) 같은 것들을 설정 가능하지.
CRD의 scope는 두 가지야:
- Namespaced: 네임스페이스에 속하는 리소스 (대부분의 경우)
- Cluster: 클러스터 전체 범위의 리소스 (네임스페이스 없이 존재)
쿠버네티스의 핵심 설계 철학은 선언적 상태 관리야. 사용자가 "원하는 상태(desired state)"를 선언하면, 컨트롤러가 현재 상태를 원하는 상태에 맞추려고 지속적으로 동작하지. 이걸 제어 루프(control loop) 또는 **조정 루프(reconciliation loop)**라고 불러:
1. 현재 상태(actual state) 관찰
2. 원하는 상태(desired state)와 비교
3. 차이가 있으면 조치(reconcile)
4. 1로 돌아감
기본 내장 컨트롤러 예시를 보면:
- ReplicaSet 컨트롤러: 현재 파드 수를 확인하고, 원하는 replicas 수와 비교해서 파드를 추가/삭제
- Deployment 컨트롤러: 디플로이먼트의 spec이 바뀌면 새 레플리카셋을 만들어서 롤링 업데이트 수행
- Service 컨트롤러: LoadBalancer 타입 서비스가 생기면 클라우드 LB를 프로비저닝
커스텀 컨트롤러는 이 패턴을 CRD에 적용한 거야. MyCache CRD가 생성되면 Redis 파드 3개를 배포하고, spec.size가 변경되면 파드 수를 조절하는 식이지.
커스텀 컨트롤러를 만드는 도구들이 있어:
- client-go: Go 언어로 쿠버네티스 API를 직접 사용해. 가장 저수준이지만 유연하지.
- Kubebuilder: 커스텀 컨트롤러의 보일러플레이트를 자동 생성해주는 프레임워크야.
- Operator SDK: Red Hat이 만든 도구인데, Kubebuilder 기반이고 Ansible/Helm 기반 오퍼레이터도 지원해.
CRD + 커스텀 컨트롤러를 합쳐서 **오퍼레이터(Operator)**라고 불러. 복잡한 애플리케이션(데이터베이스, 메시지 큐 등)의 운영 로직을 코드로 자동화하는 패턴이야.
실제로 많이 쓰이는 오퍼레이터들이 있지:
- cert-manager: 인증서 발급/갱신 자동화 (
CertificateCRD) - Prometheus Operator: 프로메테우스 배포/설정 관리 (
Prometheus,ServiceMonitorCRD) - ArgoCD: GitOps 기반 배포 관리 (
ApplicationCRD) - CloudNativePG: PostgreSQL 클러스터 운영 자동화
오퍼레이터 패턴은 쿠버네티스 위에서 도메인 전문가의 운영 지식을 코드로 구현하는 거야. 이 패턴 덕분에 쿠버네티스는 단순한 컨테이너 오케스트레이터를 넘어서 범용 인프라 플랫폼이 될 수 있었지.
정리
12장 읽고 기억할 거 세 가지:
- CRD로 쿠버네티스에 새로운 리소스 타입을 추가할 수 있다. etcd에 저장되고 kubectl로 관리 가능.
- 컨트롤러 패턴은 "원하는 상태와 현재 상태의 차이를 지속적으로 조정"하는 것이다. 쿠버네티스의 모든 내장 기능이 이 패턴으로 동작함.
- CRD + 커스텀 컨트롤러 = 오퍼레이터다. 복잡한 애플리케이션의 운영 로직을 코드로 자동화하는 핵심 패턴.