LabHub
배우기 러닝패스 코스

CKA — Kubernetes管理者

CRDでAPIを広げる

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

CustomResourceDefinition 을 직접 작성해 쿠버네티스 API 를 넓히고, 스키마 검증이 실제로 요청을 거부하는 것을 확인하고, 새 리소스에 대한 권한을 Aggregated ClusterRole 로 붙입니다.

왜 중요한가

CKA 출제 범위에 CRD 가 들어간 이유는 오퍼레이터를 만들라는 뜻이 아닙니다. 오퍼레이터가 깔린 클러스터를 운영할 수 있느냐를 묻는 것입니다. 현장의 클러스터에는 이미 수십 개의 CRD 가 깔려 있습니다.

여기서 이해해야 할 구조가 있습니다. CRD 를 만들면 apiserver 에 새 엔드포인트가 생기고, 그 엔드포인트는 저장·검증·watch 를 제공합니다. 하지만 그것뿐입니다. 실제로 무언가를 하는 것은 그 CR 을 watch 하는 컨트롤러이고, 그건 별도 소프트웨어입니다. CR 을 만들었는데 아무 일도 안 일어난다면 대개 컨트롤러가 없거나 죽은 것입니다.

스키마도 같은 맥락입니다. apiextensions.k8s.io/v1 에서 schema 는 선택이 아니라 필수입니다. 스키마가 곧 그 API 의 계약이고, 잘못된 값을 컨트롤러가 아니라 apiserver 가 먼저 막아 줍니다.

단계

  1. CRD widgets.labhub.io 를 만든다. group labhub.io, scope Namespaced, kind Widget, plural widgets, singular widget, shortNames 에 wg, 버전은 v1alpha1 하나이며 served 와 storage 모두 true.
  2. 네임스페이스 cka-crd 를 만들고 그 안에 Widget demo 를 만든다. spec.replicas 는 3, spec.tiersmall.
  3. CRD 의 v1alpha1 스키마를 고쳐 검증 규칙을 넣는다. spec.replicas 는 type integer 에 minimum 1, maximum 10. spec.tier 는 type string 에 enum [small, large]. spec 오브젝트의 required 는 [replicas, tier].
  4. spec.replicas 가 99 인 Widget too-big 을 만들어 보고, 거부된 에러 출력을 /root/cka-crd/reject.txt 에 저장한다. too-big 은 생성되지 않아야 한다.
  5. v1alpha1 에 additionalPrinterColumns 두 개를 추가한다. 이름 REPLICAS (type integer, jsonPath .spec.replicas), 이름 TIER (type string, jsonPath .spec.tier).
  6. CRD clusterwidgets.labhub.io 를 만든다. scope Cluster, kind ClusterWidget, plural clusterwidgets, group labhub.io, 버전 v1alpha1. 그리고 ClusterWidget global 을 만든다.
  7. ClusterRole cka-widget-viewer 를 만든다. 라벨 rbac.labhub.io/aggregate-to-widget=true, 규칙은 apiGroups labhub.iowidgets 에 대해 get, list, watch. 그리고 ClusterRole cka-widget-aggregate 를 만들어 aggregationRule 이 그 라벨을 셀렉터로 고르게 한다.

참고

CustomResourceDefinition 만들기

CRD widgets.labhub.io 를 만든다. group labhub.io, scope Namespaced, kind Widget, plural widgets, singular widget, shortNames 에 wg, 버전은 v1alpha1 하나이며 served 와 storage 모두 true.

CRD 의 metadata.name 은 반드시 '복수형.그룹' 형식이어야 합니다. apiextensions.k8s.io/v1 에서는 versions 배열의 각 항목에 schema 가 필수입니다.

커스텀 리소스 만들기

네임스페이스 cka-crd 를 만들고 그 안에 Widget demo 를 만든다. spec.replicas 는 3, spec.tiersmall.

CR 의 apiVersion 은 '그룹/버전' 입니다. 스키마가 느슨하면 임의 필드가 들어가니, 우선 spec 아래에 미지의 필드를 허용해 두면 편합니다.

스키마에 검증 규칙 넣기

CRD 의 v1alpha1 스키마를 고쳐 검증 규칙을 넣는다. spec.replicas 는 type integer 에 minimum 1, maximum 10. spec.tier 는 type string 에 enum [small, large]. spec 오브젝트의 required 는 [replicas, tier].

openAPIV3Schema 안의 properties.spec.properties 아래에 필드별 type 과 minimum/maximum/enum 을 답니다. required 는 값이 아니라 그 오브젝트 레벨의 배열입니다.

검증이 거부하는 순간 확인하기

spec.replicas 가 99 인 Widget too-big 을 만들어 보고, 거부된 에러 출력을 /root/cka-crd/reject.txt 에 저장한다. too-big 은 생성되지 않아야 한다.

에러는 표준출력이 아니라 표준에러로 나갑니다. 리다이렉트할 때 2>&1 을 잊지 마세요. 거부된 리소스는 만들어지지 않아야 정상입니다.

kubectl get 출력에 컬럼 추가하기

v1alpha1 에 additionalPrinterColumns 두 개를 추가한다. 이름 REPLICAS (type integer, jsonPath .spec.replicas), 이름 TIER (type string, jsonPath .spec.tier).

additionalPrinterColumns 는 versions 배열의 각 버전 안에 들어갑니다. name, type, jsonPath 세 필드가 필요하고 jsonPath 는 점으로 시작합니다.

클러스터 스코프 CRD 만들기

CRD clusterwidgets.labhub.io 를 만든다. scope Cluster, kind ClusterWidget, plural clusterwidgets, group labhub.io, 버전 v1alpha1. 그리고 ClusterWidget global 을 만든다.

scope 는 CRD 를 만든 뒤에는 바꿀 수 없습니다. 클러스터 스코프 리소스는 -n 옵션을 받지 않습니다.

Aggregated ClusterRole 로 권한 넓히기

ClusterRole cka-widget-viewer 를 만든다. 라벨 rbac.labhub.io/aggregate-to-widget=true, 규칙은 apiGroups labhub.iowidgets 에 대해 get, list, watch. 그리고 ClusterRole cka-widget-aggregate 를 만들어 aggregationRule 이 그 라벨을 셀렉터로 고르게 한다.

aggregationRule 이 있는 ClusterRole 의 rules 는 직접 쓰지 않습니다. 라벨이 붙은 다른 ClusterRole 을 컨트롤러가 찾아 합쳐 줍니다.