Kubernetes 2026.06.04 10 min read

RCA 플랫폼에 인증과 드릴다운을 붙이면서 배운 것

RCA 파이프라인에 로그인과 RBAC, webhook 인증, report drilldown을 붙였다. Collector가 읽지 못한 정보와 실제 runtime 장애를 구분하는 실패 처리도 정리했다.

보라색 배경에서 네 방향의 블록이 중앙 큐브로 연결되는 주제용 일러스트
Photo by Growtika / Unsplash

Kubernetes Cluster Infra RCA Platform 개발 기록 2편

지난 글에서는 프로젝트를 시작한 이유와 RCA 파이프라인의 초기 구성을 적었다.

처음에는 알림에서 Backend의 evidence request, Agent 수집, RCA report 생성까지 이어지는 흐름을 만들었다.

Alertmanager webhook
  -> evidence request
  -> Node Agent evidence
  -> RCA report
  -> policy decision

이 흐름이 잡힌 뒤에는 결과에 접근할 사람과 권한을 정해야 했다.

RCA report에는 노드 이름, 클러스터 정보, kubelet과 runtime 상태, 네트워크 문제, 시스템 로그 요약, 원인 후보가 포함될 수 있었다.

두 번째 단계에서는 인증, 권한, webhook 보호, report drilldown을 정리했다.


RCA 플랫폼에서 보안이 중요한 이유

처음에는 report 생성부터 구현했지만, 조회 기능에는 접근 제어가 필요했다.

report에서 노출될 수 있는 운영 정보는 다음과 같았다.

  • 어떤 클러스터가 등록되어 있는지
  • 어떤 노드에서 문제가 발생했는지
  • kubelet이나 containerd 상태가 어떤지
  • 네트워크나 CNI 쪽에 어떤 이상이 있는지
  • 어떤 조치가 필요하다고 판단했는지
  • 자동 조치가 가능한지, 승인 후 조치가 필요한지

권한 없이 이 정보를 조회하면 클러스터 내부 상태가 외부에 드러날 수 있었다.

누가 어떤 정보에 접근할 수 있는지부터 정했다.

이를 기준으로 인증과 권한 구조를 붙였다.


처음에는 admin token으로 시작했다

초기에는 관리자 토큰으로 API를 보호했다.

Backend 요청에서 X-Admin-Token 같은 값을 확인하는 방식이었다.

MVP에서는 로그인 시스템을 먼저 만들지 않고 접근을 제한할 수 있었다.

하지만 같은 토큰으로는 사용자별 권한을 나누기 어려웠다.

문제:
admin token 하나로 모든 사용자가 같은 권한을 가짐

결과:
누가 조회만 해야 하는지,
누가 cluster를 등록할 수 있는지,
누가 위험한 조치를 승인할 수 있는지 구분하기 어려움

report 조회, cluster 등록, evidence 요청, webhook 관리, 조치 승인에 서로 다른 권한이 필요했다.

그래서 admin token 다음으로 로그인과 역할 구분을 추가했다.


로그인 세션과 RBAC 추가

로그인 세션과 RBAC를 붙였다.

RBAC는 Role-Based Access Control, 역할 기반 접근 제어다.

당시에는 역할을 세 가지로 나눴다.

admin
operator
viewer

권한은 다음과 같이 잡았다.

  • admin: 클러스터 등록, 삭제, 설정 변경 같은 관리 작업 가능
  • operator: report 확인, evidence 요청, 운영 판단 가능
  • viewer: report 조회 중심의 읽기 권한

조회만 필요한 사용자에게 관리 권한까지 주지 않으려는 구분이었다.

report를 보는 사람이 cluster 삭제나 위험 조치 승인도 할 수 있는 구조는 피해야 했다.

API를 추가할 때 허용할 역할을 함께 정했다.

GET /api/rca/reports
  -> viewer 이상 가능

POST /api/clusters
  -> admin 또는 operator 필요

DELETE /api/clusters
  -> admin만 가능

위험 조치 승인
  -> 최소 operator 이상 필요

이처럼 API별 접근 권한을 구분하는 방향으로 구성했다.


webhook도 보호해야 했다

Alertmanager webhook에도 인증이 필요했다.

초기에는 알림을 받아 evidence request를 만드는 흐름부터 확인했다.

인증 없이 열어 두면 외부에서 가짜 alert를 보낼 수 있었다.

그 경우 다음 흐름이 발생할 수 있었다.

가짜 alert 전송
  -> evidence request 생성
  -> Agent가 불필요한 수집 수행
  -> RCA report 생성
  -> 운영자가 잘못된 장애로 오인

반복 입력으로 불필요한 수집과 report가 쌓일 수도 있었다.

webhook 요청에도 인증을 붙였다.

Alertmanager에서 보낸 유효한 요청만 수집으로 연결하려는 처리다.

문제:
webhook endpoint가 열려 있으면 가짜 alert가 들어올 수 있음

수정:
webhook secret 또는 인증 헤더를 확인하고,
유효한 요청만 evidence request로 연결

MVP에서 먼저 연결한 webhook 경로에 접근 검증을 추가한 것이다.


report drilldown이 필요했던 이유

초기 report는 원인 후보와 필요한 조치를 요약해서 보여줬다.

판단에 사용한 근거도 확인할 수 있어야 했다.

예를 들어 다음 원인 후보만으로는 확인할 내용이 남는다.

Possible root cause:
container runtime degradation

이 결과를 검토하려면 다음 질문에 답할 수 있어야 했다.

  • 어떤 노드에서 발생했는가?
  • containerd socket 접근이 실패했는가?
  • 실제로 containerd가 죽은 것인가?
  • 단순 permission 문제인가?
  • kubelet log에는 어떤 내용이 있었는가?
  • CNI나 DNS 증상도 같이 있었는가?

원인 후보에서 사용한 evidence까지 따라가도록 report drilldown을 추가했다.


drilldown에서 보여주고 싶었던 것

drilldown에서는 RCA 판단에 영향을 준 정보를 연결하려고 했다.

다음 항목을 더 자세히 확인하는 방향으로 잡았다.

  • evidence request 정보
  • 수집 대상 cluster와 node
  • collector별 수집 결과
  • 주요 metric
  • 감지된 signal
  • root cause candidate
  • recommendation
  • policy classification
  • raw evidence 요약

운영자가 원인 후보와 그 근거를 대조할 수 있도록 했다.

보여주려던 흐름은 다음과 같다.

이런 evidence가 있었고,
이런 signal이 감지됐고,
이런 rule 또는 analyzer가 판단했고,
그래서 이런 원인 후보와 조치가 나왔다

실제 노드 증거 수집으로 넘어가면서 보인 문제

초기 파이프라인은 fake evidence로 검증했다.

다음에는 실제 노드의 evidence가 필요했다.

Kubernetes evidence collector와 node collector를 붙이면서 실행 환경의 차이도 검토했다.

먼저 확인한 항목은 접근 권한이었다.

Agent가 읽어야 할 경로와 시스템 정보는 다음과 같았다.

  • /proc
  • /var/log
  • /run/containerd/containerd.sock
  • kubelet 관련 log
  • CNI 설정 파일
  • systemd 상태
  • kernel log

이 항목을 모든 노드에서 항상 읽을 수 있다고 가정할 수는 없었다.

권한 부족, 경로 차이, 컨테이너의 hostPath mount 누락이 각각 발생할 수 있었다.

Collector의 실패 결과에 이 차이를 남기기로 했다.


permission denied를 장애로 착각하면 안 된다

수집 권한 문제를 서비스 장애와 구분하려고 했다.

예를 들어 containerd socket 접근에서 permission denied가 발생할 수 있다.

이 응답만으로 containerd 중단이나 runtime 장애라고 판단하면 안 됐다.

containerd는 정상인데 Agent의 socket 접근 권한이 없는 경우도 있기 때문이다.

잘못된 판단:
containerd socket 접근 실패
  -> container runtime 장애로 판단

더 나은 판단:
containerd socket 접근 실패
  -> permission denied 여부 확인
  -> runtime 장애와 수집 권한 문제를 분리

runtime 장애와 Agent 권한 부족은 확인할 대상과 조치가 다르다.

수집 실패를 구체적인 signal로 남기는 방향을 잡았다.

containerd_socket_permission_denied: true
runtime_unhealthy: false 또는 unknown

Report에서 읽지 못한 항목과 확인된 장애를 구분할 수 있도록 했다.


collector 실패도 evidence다

수집 실패 자체도 분석에 사용할 정보로 남기기로 했다.

무엇을 읽지 못했는지와 실패 이유를 알아야 추가 확인을 할 수 있었다.

다음 세 경우를 구분하려고 했다.

case 1:
containerd socket에 접근했지만 응답이 없음
  -> runtime 문제 가능성

case 2:
containerd socket에 접근하려 했지만 permission denied
  -> Agent 권한 또는 mount 설정 문제 가능성

case 3:
containerd socket 경로 자체가 없음
  -> runtime 종류가 다르거나 경로 설정 문제 가능성

모두 containerd 확인 실패로 묶으면 어느 부분부터 확인할지 알기 어렵다.

Collector의 실패 유형을 구조화해서 남기기로 했다.


Codex를 어떻게 활용했는가

보안 모델과 접근 권한의 구분은 직접 정했다.

webhook 보호와 Collector 실패를 evidence로 남기는 기준도 직접 검토했다.

이 설계에 따라 반복 구현과 테스트 확장에는 Codex를 활용했다.

대상은 다음과 같았다.

  • 로그인 세션 관련 반복 코드 보강
  • API별 권한 체크 패턴 정리
  • webhook 인증 처리 테스트 확장
  • report drilldown 응답 구조 정리
  • collector permission case 테스트 추가
  • 에러 응답 형식 정리
  • README와 개발 문서 정리

민감한 정보의 범위와 자동화하면 안 되는 동작은 직접 검토했다.

작업 범위는 다음과 같다.

사람:
설계 방향, 보안 기준, 운영 위험 판단, 최종 검토

Codex:
반복 구현, 테스트 확장, 문서 초안, 코드 패턴 보강

반복 코드를 작성하는 시간을 줄이고 권한과 실패 처리 결과를 확인하는 데 집중했다.


이 단계에서 가장 중요했던 점

조회 권한을 제한하면서도, 허용된 운영자는 판단 근거를 충분히 확인할 수 있도록 했다.

작업 기준은 다음과 같았다.

  1. RCA report는 민감한 운영 정보로 본다
  2. 사용자 역할에 따라 접근 가능한 API를 나눈다
  3. webhook은 외부 입력이므로 반드시 인증한다
  4. report는 결론뿐 아니라 근거까지 따라갈 수 있어야 한다
  5. collector 실패는 단순 에러가 아니라 분석 가능한 evidence로 남긴다
  6. permission 문제와 실제 장애를 구분한다
  7. Codex는 구현 보조로 쓰되, 운영 위험 판단은 사람이 한다

특히 6번을 확인했다.

권한 부족으로 수집하지 못한 것을 장애로 표시하면 잘못된 조치로 이어질 수 있었다.

알 수 없는 상태는 그대로 표시하고, 실패 이유를 구분해 보여주려고 했다.


마무리

인증과 역할, webhook 보호, report drilldown을 추가했다.

실제 노드 수집에서 발생할 수 있는 permission 문제도 별도 signal로 다루기 시작했다.

허용된 운영자가 근거를 검토하고 수집 공백을 확인할 수 있는 구조를 정리한 단계였다. 위험 조치의 실행은 정책과 승인 흐름으로 구분했다.

다음 글에서는 Agent의 Helm chart, DaemonSet, 로컬 검증과 smoke test 구성을 다룬다.

SEARCH JOURNAL

기록 검색

글 제목, 요약, 태그에서 찾습니다.

검색을 준비하고 있어요.

검색어를 입력해 주세요.

    Ctrl/⌘ K 검색 Esc 닫기 결과 이동