LabHub

CNPE — 클라우드 네이티브 플랫폼 엔지니어 (전문가) · 모의고사 · 실습

CNPE 모의고사 A

LabHub 에서 이어서 보기

목표

실제 CNPE 와 같은 조건에서 과제 17개를 120분 안에 풉니다. 합격선은 64% 이고
부분 점수제이므로, 17개 중 11개를 통과하면 완료로 처리됩니다.

모의고사입니다. 힌트와 정답지를 보지 말고 먼저 끝까지 풀어 보십시오.
막힌 과제는 표시해 두고 넘어갔다가 남은 시간에 돌아오는 편이 낫습니다.
채점은 언제든 눌러도 되고, 여러 번 눌러도 결과가 달라지지 않습니다.

왜 중요한가

CNPE 는 전문가 등급이고, 묻는 것이 조작법이 아니라 판단입니다. 같은 규칙을
파이프라인에서 막을지 API 서버에서 막을지, 사고가 났을 때 제약을 지울지
만족시킬지, 테넌트에게 무엇을 열어 주고 무엇을 닫아 둘지를 정하는 자리가
과제마다 하나씩 들어 있습니다. 도구는 여러 개가 나오지만 어느 것도 깊게
묻지 않습니다. 대신 어느 도구를 어디에 놓을 것인가를 묻습니다.

시험 환경 (실제 시험에서 확인된 사실)

이 모의고사 환경에서 다른 점

이 실습의 클러스터는 파드 안에서 도는 1인용 클러스터입니다. kube-apiserver 와
컨트롤러 매니저와 스케줄러는 진짜라서 스키마 검증, 승인 정책, RBAC 판정, 쿼터,
스케줄링, 집계 ClusterRole, 축출 API 는 실제로 동작하고 실제로 거부합니다.
다만 컨테이너를 실제로 돌리는 런타임이 없으므로 다음이 다릅니다.

노드는 3대이고 각각 CPU 8코어, 메모리 32Gi 이며 존은 zone-0, zone-1,
zone-2 로 하나씩 다릅니다.

단계

GitOps and Continuous Delivery

1. /root/exam/chart 에 Helm 차트를 만드십시오. 차트 이름은 paved-app 이고
템플릿은 Deployment 하나이며 그 이름은 paved-app 입니다. 컨테이너 이름은
app, 레플리카 수는 .Values.replicas, 이미지는
.Values.image.repository.Values.image.digest@ 로 이은 것입니다.
values.schema.json 으로 replicas 는 2 이상 10 이하의 정수, tier
bronze, silver, gold 중 하나, image.digestsha256: 뒤에 16진수
64자리인 문자열만 허용하고 세 값 모두 필수로 만드십시오. 기본값은 각각 3,
silver, 그리고 임의의 유효한 다이제스트입니다.
2. /root/exam/portal 에 kustomize 디렉터리를 만드십시오. Deployment portal
은 레플리카 2, 컨테이너 이름 app, 이미지는 다이제스트 고정이며,
envFrom 으로 ConfigMap portal-config 를 통째로 읽습니다. 그 ConfigMap 은
파일로 두지 말고 configMapGenerator 로 만들되 LOG_LEVEL=info
FEATURE_FLAGS=beta 두 항목을 담고, 이름 해시 접미사를 끄지 마십시오.
렌더 결과에서 Deployment 가 참조하는 이름과 생성된 ConfigMap 의 이름이 같아야
합니다.
3. /root/exam/gitops/appproject.yaml 에 Argo CD AppProject platform
쓰십시오. 네임스페이스는 argocd 입니다. sourceRepos 에는 실제 저장소
주소를 적고 * 를 쓰지 마십시오. destinations 는 서버와 네임스페이스를
모두 못박고 네임스페이스에 * 를 쓰지 마십시오. clusterResourceWhitelist
는 비워 두고, namespaceResourceBlacklist 에는 코어 그룹의 ResourceQuota
LimitRange 를 넣으십시오.
4. /root/exam/promote 를 git 저장소로 만드십시오. envs/staging/deployment.yaml
envs/prod/deployment.yaml 두 파일이 있고 둘 다 Deployment ledger 이며
컨테이너 이름은 app, 이미지는 다이제스트로 고정합니다. 첫 커밋에서는 두
다이제스트가 서로 다릅니다. 그다음 스테이징의 다이제스트를 운영으로 올리는
승격 커밋 하나 를 더 쌓으십시오. 그 커밋에서 스테이징 파일은 바뀌지
않아야 하고, 커밋 메시지에 올린 다이제스트가 들어가야 하며, 작업 트리는
깨끗해야 합니다.

Platform APIs and Self-Service Capabilities

5. /root/exam/api/environment-crd.yaml 에 CRD 를 쓰고 apply 하십시오. 그룹은
platform.labhub.io, 종류는 Environment, 복수형은 environments, 짧은
이름은 env, 범위는 Namespaced 입니다. 버전은 둘입니다. v1 은 served 이자
저장 버전이고, spec.owner 는 필수 문자열, spec.tierbronze,
silver, gold 중 하나이며 기본값이 bronze, spec.retentionDays 는 1
이상 90 이하의 정수이며 기본값이 7 입니다. v1alpha1 은 served 이지만 저장
버전이 아니고 spec.owner 만 가지며, 폐기 표시를 하고 폐기 경고 문구를 직접
적으십시오. 스키마에 없는 필드는 서버가 거절해야 합니다.
6. /root/exam/api/env-defaults.yaml 에 Kyverno ClusterPolicy env-defaults
쓰십시오. Environment 리소스에만 적용되는 변형(mutate) 규칙으로, 라벨
platform.labhub.io/ownerspec.owner 값으로, 애너테이션
platform.labhub.io/requested-tierspec.tier 값으로 채웁니다. 값을
고정해 적지 말고 요청에서 읽어 채워야 합니다.
7. /root/exam/api/env-rbac.yaml 에 집계 권한을 쓰고 apply 하십시오. ClusterRole
platform-env-author 는 자체 규칙 없이 라벨
platform.labhub.io/aggregate-to-env-author: "true" 가 붙은 ClusterRole 을
모읍니다. ClusterRole platform-env-author-base 에 그 라벨을 붙이고
Environment 에 대해 get, list, watch, create, update, patch 를 허용하되
delete 는 주지 마십시오. 네임스페이스 tenant-amber 와 ServiceAccount
env-author 를 만들고 RoleBinding env-author 로 그 집계 ClusterRole 을
묶으십시오. 어느 규칙에도 * 를 쓰지 마십시오.
8. /root/exam/api/env-status-rbac.yaml 에 spec 과 status 의 권한을 나누십시오.
tenant-amber 에 ServiceAccount env-controller, Role env-controller,
RoleBinding env-controller 를 만듭니다. 이 계정은 Environment 를 읽고
environments/status 를 update, patch 할 수 있지만 Environment 자체를
create, update, patch, delete 할 수는 없습니다. 반대로 7번의 env-author
environments/status 를 update 할 수 없어야 합니다.

Observability and Operations

9. /root/exam/ops/platform-rules.yaml 에 Prometheus 규칙을 쓰십시오. 그룹
이름은 platform-api 이고, 기록 규칙 platform:request_error:ratio5m
나눗셈과 5분 구간을 쓰며, 알림 규칙 PlatformApiErrorBudgetBurn 에는 for,
labels.severity, annotations.summary, annotations.runbook_url
있어야 합니다. 그리고 /root/exam/ops/platform-rules-test.yaml 에 규칙
유닛 테스트를 쓰십시오. rule_files 에는 상대 이름
platform-rules.yaml 만 적고, alert_rule_test 를 두 개 이상 두되 하나는
알림이 울리는 시각을, 다른 하나는 울리지 않는 시각(exp_alerts: [])을
확인해야 합니다. promtool check rulespromtool test rules 가 모두
통과해야 합니다.
10. 네임스페이스 platform-system 을 만들고
/root/exam/ops/servicemonitor.yaml 에 ServiceMonitor platform-api 를 써서
적용하십시오. 대상 선택자는 app: platform-api, namespaceSelector
platform-system 입니다. 엔드포인트는 하나이고 포트 이름은 metrics,
수집 주기는 30s, 수집 제한 시간은 주기보다 짧아야 합니다.
metricRelabelings 에는 __name__ 을 보고 특정 지표를 drop 하는 규칙과,
고카디널리티 라벨을 labeldrop 으로 떨어뜨리는 규칙이 각각 하나 이상
있어야 합니다.
11. 네임스페이스 tenant-ochre 를 만들어 라벨
platform.labhub.io/tenant: ochre 를 붙이고, ResourceQuota ochre-quota
requests.cpu 를 2, requests.memory 를 4Gi 로 제한하십시오. 그 안에
Deployment search 를 레플리카 4로 만드십시오. 컨테이너 이름은 app,
이미지는 다이제스트 고정, 요청은 CPU 700m 과 메모리 512Mi 입니다. 이 시점에
파드는 다 뜨지 못합니다. 그다음 /root/exam/ops/triage.txt
quota_cpu_hard, quota_memory_hard, desired_replicas,
max_cpu_per_pod 네 줄을 키=값 형식으로 적으십시오. CPU 는 밀리코어
정수로, 메모리는 Mi 정수로, 마지막 값은 이 쿼터 안에서 레플리카가 전부 뜨려면
파드 하나의 CPU 요청이 얼마 이하여야 하는지를 밀리코어 정수로 적습니다.
단위 문자는 붙이지 마십시오.
12. 쿼터를 올리지 말고 search 의 파드 4개가 모두 Running 이 되게
하십시오. 레플리카 수와 메모리 요청은 그대로 두고, CPU 요청만 11번에서
계산한 값으로 내립니다. 옛 요청값을 쓰는 파드가 남아 있으면 안 됩니다.

Platform Architecture and Infrastructure

13. 노드 정확히 두 대 에 라벨 platform.labhub.io/pool=platform 과 테인트
platform.labhub.io/pool=platform:NoSchedule 을 함께 거십시오. 그리고
platform-system 에 Deployment portal 을 레플리카 3으로 만드십시오.
컨테이너 이름은 app, 이미지는 다이제스트 고정, 요청은 CPU 100m 과 메모리
128Mi 입니다. 이 워크로드는 그 풀만 고르고, 그 테인트를 견디며,
topology.kubernetes.io/zone 을 기준으로 maxSkew: 1
whenUnsatisfiable: DoNotSchedule 로 퍼져야 합니다. 파드 3개가 모두
풀 노드 위에서 Running 이어야 합니다.
14. PriorityClass platform-critical(값 100000 이상)과
tenant-batch(값 1000 이하, preemptionPolicy: Never)를 만드십시오. 둘 다
globalDefault 는 false 입니다. tenant-amber 에 ResourceQuota
amber-priority 를 걸어 platform-critical 우선순위를 쓰는 파드를 그
네임스페이스에서 아예 만들 수 없게 하십시오. 그리고 13번의 portal
platform-critical 을 쓰게 하십시오.
15. platform-system 에 PodDisruptionBudget portal 을 만드십시오. 선택자는
portal 파드를 고르고 minAvailable 은 2 이며 maxUnavailable 은 쓰지
않습니다. 유지보수 때 한 번에 한 대만 비울 수 있어야 합니다.

Security and Policy Enforcement

16. 네임스페이스 tenant-teal 을 만들고 파드 보안 승인의 enforce, audit,
warn 을 모두 restricted 로 걸되 세 모드의 버전 라벨은 latest 가 아니라
v1.31 로 고정하십시오. 그 안에 Deployment checkout 을 레플리카 2로
만드십시오. 컨테이너 이름은 app, 이미지는 다이제스트 고정이며 파드는
restricted 를 통과해야 합니다. 파드 2개가 실제로 Running 이어야 합니다.
17. 규칙 하나를 두 곳에서 집행하십시오. 규칙은 "Deployment 에는 라벨
platform.labhub.io/owner 가 있어야 한다" 입니다.
/root/exam/security/owner-policy.yaml 에 Kyverno ClusterPolicy
require-ownerEnforce 로 쓰십시오. 파이프라인이 kyverno apply
돌릴 게이트입니다. /root/exam/security/owner-vap.yaml 에는
ValidatingAdmissionPolicy require-owner 와 같은 이름의 바인딩을 쓰고
apply 하십시오. validationActionsDeny 이고, 적용 범위는 라벨
platform.labhub.io/gate=owner 가 붙은 네임스페이스뿐입니다. 네임스페이스
delivery 를 만들어 그 라벨을 붙이십시오. 라벨 없는 Deployment 는
delivery 에서 거부되고 default 에서는 통과해야 합니다.

참고

단계 17개

  1. 차트가 잘못된 값을 스스로 거절하게
  2. 설정이 바뀌면 배포도 바뀌게
  3. 프로젝트가 무엇을 허용하는지 못박기
  4. 승격을 커밋 하나로 남기기
  5. 스키마가 계약이 되게
  6. 요청에 빠진 것을 플랫폼이 채우기
  7. 권한을 조각으로 나눠 모으기
  8. 적는 사람과 채우는 사람을 나누기
  9. 알림 규칙을 시험으로 못박기
  10. 무엇을 재지 않을지 정하기
  11. 쿼터 소진을 재현하고 숫자로 적기
  12. 쿼터를 올리지 않고 복구하기
  13. 풀을 나누고 워크로드를 퍼뜨리기
  14. 우선순위를 쓸 수 있는 사람 정하기
  15. 유지보수 중에도 남아 있을 수를 정하기
  16. 테넌트 네임스페이스에 기준선 걸기
  17. 같은 규칙을 두 곳에서 집행하기