CNPE — 클라우드 네이티브 플랫폼 엔지니어 (전문가) · 플랫폼 API 와 셀프서비스 · 이론
CRD 는 기능이 아니라 계약입니다
한 줄 요약
CRD 를 만드는 일의 본체는 필드를 정하는 것이 아니라 약속을 정하는 것입니다. 어떤 값을 받고, 어떤 값을 거절하고, 한 번 정해진 뒤에는 무엇을 바꿀 수 없는지가 그 약속입니다.
왜 스키마가 먼저인가
셀프서비스 API 를 열면 요청은 사람이 아니라 기계가 받습니다. 그래서 잘못된 요청을 거르는 자리가 두 곳뿐입니다. 하나는 API 서버의 스키마 검증이고, 다른 하나는 나중에 컨트롤러가 조정하다가 실패하는 것입니다.
두 번째 자리에서 걸리면 값이 이미 저장돼 있습니다. 사용자는 자기 요청이 접수됐다고 믿고 기다리는데 아무 일도 일어나지 않고, 원인은 컨트롤러 로그 안에만 있습니다. 첫 번째 자리에서 걸리면 kubectl apply 가 즉시 거절하면서 이유를 말합니다. 그래서 거를 수 있는 것은 전부 스키마로 걸러야 합니다.
어떻게 동작하나
세 겹의 검증이 각각 다른 것을 잡습니다
| 장치 | 잡는 것 | 언제 도는가 |
| --- | --- | --- |
| OpenAPI 타입과 enum | 값의 모양과 집합 | 생성과 변경 모두 |
| CEL 검증 규칙(self) | 필드 사이의 관계 | 생성과 변경 모두 |
| CEL 전이 규칙(oldSelf) | 변경 전후의 관계 | 변경할 때만 |
replicas: 9 와 maxReplicas: 4 는 각각은 멀쩡한 값입니다. 둘의 관계가 틀렸을 뿐입니다. 이런 것은 타입으로 못 잡고 CEL 로만 잡습니다.
x-kubernetes-validations: - rule: "self.replicas <= self.maxReplicas" message: "replicas 는 maxReplicas 보다 클 수 없습니다"message 를 성의 없이 쓰면 검증이 있으나 마나 합니다. 사용자가 받는 것은 규칙이 아니라 이 문장이고, 여기에 필드 이름이 없으면 어디를 고쳐야 하는지 알 수 없습니다.
불변 필드는 oldSelf 로만 만들어집니다
규칙이 oldSelf 를 참조하는 순간 그 규칙은 전이 규칙이 되어 변경할 때만 평가됩니다. 생성 때는 비교할 이전 값이 없으므로 건너뜁니다.
- rule: "self.tier == oldSelf.tier" message: "tier 는 발급 후 바꿀 수 없습니다"여기서 자주 나는 실수가 self == oldSelf 를 걸어 버리는 것입니다. 그러면 등급뿐 아니라 레플리카 수도 못 바꾸게 되고, 그것은 불변이 아니라 동결입니다. 불변으로 묶을 필드를 하나씩 이름으로 적어야 합니다.
버전을 둘로 나눌 때 정할 것
served 는 그 버전으로 읽고 쓸 수 있는가이고, storage 는 etcd 에 어떤 모양으로 담기는가입니다. 저장 버전은 언제나 한 버전만 true 입니다. 옛 버전은 served: true, storage: false 로 남겨 두어야 기존 사용자의 매니페스트가 계속 동작합니다.
그리고 subresources.status 를 떼는 것을 잊으면 안 됩니다. status 가 spec 과 같은 문서 안에 있으면 사용자의 apply 가 컨트롤러가 쓴 상태를 덮고, 컨트롤러의 쓰기가 사용자의 요청을 덮습니다. 두 쪽이 같은 문서를 놓고 번갈아 지우는 상태가 되는데, 로그에는 아무것도 안 남습니다.
출력 컬럼은 사용성이 아니라 운영입니다
additionalPrinterColumns 를 넣으면 kubectl get appclaims 한 줄에 등급과 레플리카가 보입니다. 이것이 없으면 상태를 확인할 때마다 -o yaml 을 열어야 하고, 그러면 아무도 확인하지 않게 됩니다.
현장에서 만나는 모습
한 팀이 tier 를 자유 문자열로 두었습니다. 반년 뒤 값의 목록을 세어 보니 gold, Gold, gold 세 가지가 있었습니다. 대시보드의 집계가 셋으로 갈라져 있었고, 아무도 그것을 모르고 있었습니다. 그 사이 요금 계산도 셋으로 갈라져 있었습니다.
enum 한 줄이면 막혔을 일입니다. 셀프서비스 API 의 첫 번째 일은 기능을 늘리는 것이 아니라 값의 집합을 좁히는 것입니다.
그다음 읽을 것
스키마로 좁힌 다음, 누가 무엇을 할 수 있는지와 얼마나 많이 할 수 있는지를 이어서 정합니다.