Skip to content

feat: add namespace allowlist with runtime toleration injection (AIP-2389) - #87

Open
juu-n-oo wants to merge 3 commits into
mainfrom
feat/AIP-2389
Open

feat: add namespace allowlist with runtime toleration injection (AIP-2389)#87
juu-n-oo wants to merge 3 commits into
mainfrom
feat/AIP-2389

Conversation

@juu-n-oo

@juu-n-oo juu-n-oo commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

개요 (AIP-2389)

특정 네임스페이스를 project controller의 동작에서 예외처리(allowlist)하는 기능을 추가합니다. 네임스페이스 라벨 기반이라 런타임에 즉시 추가/해제되며 컨트롤러 재시작이 필요 없습니다.

kubectl label namespace kubevirt project.ten1010.io/allowlisted=true   # 지정
kubectl label namespace kubevirt project.ten1010.io/allowlisted-      # 해제

⚠️ 웹훅 operations 변경(namespaces CREATE/UPDATE 추가)이 있어 aipub-installer#192 와 함께 배포되어야 합니다.

배경

KubeVirt 같은 시스템 컴포넌트는 (1) project managed taint에 대한 toleration을 받지 못해 project managed 노드에 스케줄링될 수 없고, (2) strict isolation 노드에서는 owner가 미등록 타입(VirtualMachineInstance)이라 PodReconciler가 파드를 즉시 삭제합니다. 기존 reconcile-excluded-label-selectors는 웹훅이 건드리지 않게만 할 뿐 toleration 부여와 eviction 방지는 불가능합니다.

동작

allowlist 네임스페이스에 대해:

  • eviction 제외PodReconciler가 해당 네임스페이스 파드를 삭제하지 않음 (UnsupportedControllerException 분기보다 선행 가드)
  • toleration 능동 주입 — Pod/Deployment 웹훅과 6종 워크로드 reconciler가 project.ten1010.io/project-managed 키의 Exists toleration 쌍(NoSchedule+NoExecute)을 주입해 모든 project managed 노드에 스케줄링 가능. 기존 toleration은 재작성 없이 보존(add-only)
  • 관리 reconcile 스킵 — Namespace 라벨/ownerRef 정리, ResourceQuota, 레지스트리 Secret, RBAC(member/aipub) 조기 반환
  • 웹훅 스킵 — 워크로드 라벨/사용자 소유권 주입 웹훅 무패치 통과 (해당 웹훅 manifest는 수정 불필요)

이름 충돌 가드 (양방향 hard block)

allowlist("모두 허용")와 Project("격리")는 의미가 상충하므로, 먼저 부여된 의미를 우선하도록 어드미션에서 양방향으로 봉쇄합니다. 세 경로 모두 system admin 예외 없이 hard block하고 kubectl 응답으로 사유를 반환합니다.

  • allowlist → Project: allowlist 네임스페이스와 동명 Project 생성 거부 (ProjectReviewHandler)
  • Project → allowlist: 동명 Project가 존재하는 네임스페이스에 allowlist 라벨 부착 거부 (NamespaceReviewHandler, namespaces 웹훅 CREATE/UPDATE). terminating Project도 거부 — namespace가 Project 소유(ownerReference)라 함께 GC 삭제되므로 라벨링이 무의미
  • reserved → Project: reserved 이름 Project 생성의 system-admin escape hatch 제거. quota/RBAC/Secret 리컨실러엔 reserved 가드가 없어, 통과 시 인프라 네임스페이스(aipub 등)에 관리 리소스가 실제로 생성되는 것을 확인 → 어드미션이 유일 방어선이므로 구멍을 막음
  • 런타임 backstop: 웹훅 우회(컨트롤러 다운/informer 레이스)로 동명 Project + allowlist 상태가 생기면 NamespaceReconciler가 allowlist 우선 + warn 로그

런타임 전파

워크로드 팩토리 6종 + PodControllerFactory에 namespace watch를 추가해, allowlist 라벨 변경 시 해당 네임스페이스의 워크로드들이 재조정됩니다(템플릿 갱신 → 롤아웃).

판정 방식

  • namespace informer 캐시 실시간 조회 (NamespaceAllowlistResolver)
  • 캐시에 없는 네임스페이스는 allowlist 아님(fail-closed) — 격리 우회 방지
  • namespaces 웹훅 failurePolicyIgnore 유지: 클러스터 전역 네임스페이스 웹훅이라 컨트롤러 다운 시 모든 네임스페이스 쓰기를 막으면 위험 → fail-open, 런타임 backstop이 보완

주의 사항

  • 워크로드가 이미 있는 네임스페이스를 allowlist하면 toleration 주입으로 일괄 롤아웃 발생 → 컴포넌트 설치 전 라벨링 권장
  • 파드 toleration은 불변이므로 allowlist 이전 파드는 재생성 필요
  • allowlist 해제 시 strict 노드 위 파드는 즉시 eviction 대상
  • 네임스페이스 라벨 권한 보유자는 project 노드 스케줄링 권한을 얻는 셈 (RBAC 참고)

테스트

  • NamespaceAllowlistResolverTest (신규): 라벨 판정·fail-closed·null 안전성
  • ReconciliationServiceTest (신규): Exists 쌍 주입, 기존 toleration 보존, per-node Equal 제거, 멱등성
  • NamespaceReviewHandlerTest (신규): Project → allowlist 라벨 거부(CREATE/UPDATE, terminating 포함), 무충돌 허용
  • ProjectReviewHandlerTest (신규): reserved/allowlist 이름 Project 생성이 system admin에게도 거부됨
  • WorkloadLabelReviewHandlerTest (신규) + UserOwnerReviewHandlerTest 확장: allowlist 네임스페이스 무패치 통과
  • ./gradlew :test 전체 통과 (23개 클래스 132개 테스트)

수동 스모크 테스트(실클러스터)는 미수행: ① 라벨 부여 → Deployment에 Exists 쌍 주입·롤아웃 ② bare pod 생성 → 웹훅 주입 확인 ③ strict 노드 위 파드 미삭제 ④ 라벨 제거 → 원복 ⑤ 동명 Project 있는 ns에 라벨 → 거부

@juu-n-oo
juu-n-oo force-pushed the feat/AIP-2389 branch 4 times, most recently from 180b46d to 4da7062 Compare August 4, 2026 02:42
@juu-n-oo juu-n-oo changed the title feat: add namespace whitelist with runtime toleration injection (AIP-2389) feat: add namespace allowlist with runtime toleration injection (AIP-2389) Aug 4, 2026
…2389)

Add a namespace-level allowlist driven by the label
project.ten1010.io/allowlisted=true, read live from the namespace
informer so changes apply at runtime without restart.

Allowlisted namespaces are excluded from all managing reconcilers
(namespace labels/ownerRefs, ResourceQuota, image registry secret,
RBAC) and PodReconciler never evicts their pods. Instead, admission
webhooks and workload reconcilers inject an Exists toleration pair
for the project.ten1010.io/project-managed taint so pods can schedule
on any project-managed node (e.g. KubeVirt system components).

Namespace label changes are propagated by new namespace watches on
the workload/pod controller factories, and creating a Project named
after an allowlisted namespace is rejected by the webhook.

Guard the namespace/project name conflict in both directions: the
namespaces webhook now also intercepts CREATE/UPDATE and rejects
labeling a namespace as allowlisted while a project of the same name
still exists (mirroring the project-creation guard). The reserved-name
and allowlisted-name project-creation rejections are hard blocks with
no system-admin exception, because such a project would otherwise leak
project management (quota, RBAC, secrets) onto an infrastructure or
allowlisted namespace.
@pranludi pranludi added this to the v5.1.0 milestone Aug 6, 2026
…in namespace deletion guard

Check namespace allowlist before the reconcile-exclusion label in
DeploymentReviewHandler and WorkloadControllerReconciler, matching
PodReviewHandler, so excluded workloads in allowlisted namespaces
still get the Exists toleration pair even when the pod webhook is
unavailable.

Read the namespace name for the reserved-deletion guard from the
admission request instead of the informer cache; a cache miss caused
an NPE that silently disabled the guard under failurePolicy Ignore.
DO NOT MERGE - 논의용 임시 커밋. 논의 종료 후 제거 예정.

allowlist 네임스페이스의 DaemonSet 파드가 Pending에 머무는 원인 분석
문서. project-controller의 toleration 주입은 정상이며, coaster
scheduler webhook이 schedulerName을 coaster로 바꾸지만 해당 파드가
스케줄링 큐에 등록되지 않아 발생하는 문제다. coaster 소관 사안과
allowlist 워크로드의 리소스 회계 정책 논의 항목을 함께 정리했다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants