SMALL

IT 162

ValidatingAdmissionPolicy vs Kyverno, 정책 일부를 옮기고 나서

작년쯤 Kubernetes 1.30이 풀리고 ValidatingAdmissionPolicy(이하 VAP)가 정식으로 GA되었을 때, 솔직히 의심이 좀 있었다. CEL로 정책을 쓴다는 발상 자체는 깔끔한데, Kyverno 같은 PaC(Policy-as-Code) 엔진이 이미 잘 돌아가는 클러스터에서 굳이 또 한 겹을 더 얹을 필요가 있나 싶었다. 그러다 작년 말쯤 우리 팀에서도 일부 정책을 VAP로 옮기는 실험을 시작했고, 6개월쯤 지난 지금 시점에 정리해두면 좋겠다는 생각이 들었다.결론부터 적자면, 모든 걸 VAP로 옮길 일은 없다. 그럼에도 옮길 가치가 있는 정책이 분명히 있다. 그 경계가 어디에 있는지가 이 글의 본론이다.왜 VAP를 썼나원래 우리 클러스터에서는 Kyverno 하나로 모든 admiss..

IT/Kubernets 2026.05.01

pg_stat_io로 새벽 3시에 vacuum I/O 폭탄 잡은 이야기

지난주 화요일 새벽 3시, 슬랙 알림이 미친 듯이 울렸다. 결제 DB의 P99 레이턴시가 평소 12ms에서 280ms로 튀어 올랐다. 폰을 더듬어 잡고 일어나면서 머리가 멍했다. 트래픽은 한산한 시간대인데 왜?처음엔 단순한 락 경합인 줄 알았다. pg_stat_activity 봤는데 long-running 쿼리도 없고, pg_locks도 깨끗했다. 근데 디스크 IOPS는 평소 대비 4배. 뭔가 백그라운드에서 디스크를 갈아먹고 있는 게 분명한데 보이질 않았다. 멘탈이 살짝 나갔다.pg_stat_io를 켰다작년에 PG16으로 올리면서 pg_stat_io 뷰를 알게 됐었는데, 평상시엔 잘 안 보던 거였다. 이번 같은 상황에서 진가를 발휘하는 뷰다. context 컬럼에 bulkread, bulkwrite, v..

IT/DB 운영 2026.05.01

ingress-nginx EOL 이후, ingress2gateway로 Gateway API 옮기기

3월 20일자로 ingress-nginx가 공식 EOL이 됐다. 같은 날 ingress2gateway 1.0이 GA로 풀렸다. 두 이벤트가 같은 날 풀린 게 우연이 아니다 — 업스트림에서 "이제 진짜 옮길 때다"라고 못박은 거다.EOL 전부터 우리 팀도 마이그레이션을 시도했는데, 0.x 시절 ingress2gateway는 ingress-nginx 어노테이션을 3개밖에 못 바꿨다. 그래서 일단 미뤄두고 있었는데 1.0이 나오면서 30개 이상 지원으로 확 늘었다. 마침 옮길 만한 시점이다 싶어서, 지난 2주간 스테이징 → 프로덕션 일부 클러스터까지 옮겨봤다. 그 과정 정리.옮기기 전에 알아둘 것Gateway API는 Ingress 리소스 하나에 다 욱여넣었던 라우팅 + 어노테이션 정글을 두 단계로 쪼갠다. ..

IT/Kubernets 2026.05.01

새벽 2시, Loki 인덱스가 터졌다

지난주 화요일 새벽 2시였다. 핸드폰이 울렸다. 처음엔 무시했다. 두 번째 울렸을 때 눈이 번쩍 떠졌다. 화면에는 loki-write Pod 절반이 OOMKill로 죽고 있다는 알림이 떠 있었다. 멘탈이 나갔다.우리 팀이 Loki를 도입한 건 2년 전이고, 그동안 큰 사고는 없었다. 노드 40대 정도 클러스터에서 하루에 약 1.2TB 로그가 들어오는 규모다. 그런데 그날 밤 갑자기 인덱스가 비정상적으로 커지면서 ingester가 메모리를 다 잡아먹었다. 새벽 4시까지 PC 앞에 있었다. 이 글은 그때 무슨 일이 있었고, 결국 어떻게 푼 건지에 대한 회고다.사고 시작 — 시리즈 수가 갑자기 30배처음 본 건 Grafana에 띄워둔 Loki 자체 모니터링 대시보드였다. loki_ingester_memory_..

IT/모니터링 2026.05.01

Cilium Hubble로 Network Policy 디버깅하기

NetworkPolicy를 처음 도입할 때 가장 답답한 게 뭐냐고 물으면, 나는 망설임 없이 "왜 막혔는지 모르겠다"고 답한다. kubectl logs를 봐도 connection timeout만 보이고, 정작 어느 정책이 그 트래픽을 끊었는지는 알려주지 않는다. 예전엔 cilium monitor를 노드 단위로 띄워서 한참을 들여다봤는데, Hubble이 들어오고 나서는 이 과정이 꽤 깔끔해졌다.이 글은 Cilium 1.19.x 환경에서 Hubble을 가지고 네트워크 정책을 디버깅하는 워크플로우를 정리한 거다. 우리 팀에서 정책을 새로 추가할 때마다 반복적으로 쓰는 절차이고, 신규 입사자한테도 이 순서대로 보여준다.Hubble flow를 보기 전에 확인할 것먼저 Hubble이 활성화돼 있어야 한다. 의외로 ..

IT/Kubernets 2026.04.30

VPC Lattice 6개월 써보니 보이는 것들

처음에 기대했던 것작년 가을, 우리 팀은 VPC를 5개 운영 중이었다. 메인 워크로드 VPC, 데이터 분석 VPC, 사내 도구 VPC, 보안 격리 VPC, 그리고 신규 사업 VPC. 각 VPC끼리 서비스를 호출해야 하는 케이스가 슬슬 늘어나면서 PrivateLink와 Transit Gateway가 거미줄처럼 얽혀 있었다. 어떤 서비스가 어디에 노출돼 있는지 추적하는 게 자체로 일이었다. 이 시점에 VPC Lattice를 도입하기로 결정했고, 지금은 약 6개월째 운영 중이다. 잘한 결정인지 묻는다면 솔직히 반반이다.이 글은 칭찬도 비판도 섞인 후기다. 도입을 검토 중인 분이라면 좀 도움이 될 것 같다.마케팅 페이지만 보면 정말 끌린다. VPC끼리 서비스를 노출하는데 NLB나 PrivateLink Endpo..

IT/AWS 2026.04.30

Pod이 OOMKill 되기 직전, kernel과 kubelet이 보는 것

들어가며OOMKill은 K8s 운영하면서 가장 자주 마주치는 종류의 죽음 중 하나다. 그런데 막상 "왜 죽었냐"고 물으면 Last State: OOMKilled 로그 한 줄 외엔 잘 못 말하는 경우가 많다. 사실 나도 그랬다. 우리 팀 내부 논의에서 "메모리 limit 부족이지" 정도로 넘기던 게 한 90% 였고, 정작 그 직전 kernel과 kubelet이 어떤 신호를 주고 받았는지는 들여다본 적이 별로 없었다.이번 글에서는 cgroup v2 환경에서 Pod의 메모리가 limit 근처까지 차오를 때 노드 안에서 어떤 흐름이 도는지를 정리한다. K8s 1.28부터 cgroup v2 동작이 한 단계 정리됐고, 1.34에서 PSI 메트릭이 Beta로 올라오면서 이 영역의 운영 가시성이 꽤 좋아진 시점이다.m..

IT/Kubernets 2026.04.30

GitHub Actions의 concurrency, 배포 race 막는 한 줄

오늘 알게 된 건 아니고, 어제 팀 PR 리뷰하다가 "어 이거 아직도 모르는 분들 꽤 많은데" 싶어서 짧게 정리해둔다. 우리 팀에서도 작년 한 분기 동안 같은 사고를 두 번 냈다. 똑같은 워크플로가 동시에 두 개 뜨면서 한쪽이 helm release를 절반쯤 적용한 상태에서 다른 한쪽이 덮어쓰는 그림. 새벽 3시에 슬랙 알림으로 깨면 진짜 멘탈이 묘하게 무너진다.한 줄이면 끝난다concurrency: group: deploy-${{ github.ref }} cancel-in-progress: false이게 전부다. 같은 브랜치에서 deploy 워크플로가 한 번에 하나만 돌게 만든다. PR 빌드용 워크플로면 cancel-in-progress: true로 바꿔서 새 커밋이 들어올 때 진행 중인 빌드를 죽..

IT/CI CD 2026.04.29

KEDA SQS scaler 도입했다가 thrashing에 한참 데인 이야기

지난달에 SQS 기반 워커 파드를 KEDA로 옮겼다. HPA의 CPU 메트릭만으로는 큐가 쌓일 때 늦게 반응하는 게 계속 거슬려서, 큐 길이로 직접 스케일하는 게 자연스러워 보였다. KEDA는 2.19가 최근에 떨어졌고(2026-02), SQS scaler에 scaleOnDelayed 같은 옵션도 정리돼 있어서 큰 고민 없이 시작했는데, 정작 일주일 동안 새벽에 두 번 호출되고 나서야 정신을 차렸다. 그 과정 정리.시작은 정상이었다워크로드는 단순하다. 외부 이벤트 → SQS → 워커 파드(Go 단일 바이너리)가 메시지 하나씩 받아 처리. 평소엔 큐가 비어 있고, 1시간 단위로 큐가 수만 건씩 쌓이는 burst 패턴이다. 한 메시지 처리에 평균 2초, P99 8초.처음 달았던 ScaledObject는 거의..

IT/Kubernets 2026.04.29

PgBouncer transaction 모드에서 prepared statement 제대로 쓰는 법

왜 굳이 켜야 하나PgBouncer 1.21에서 transaction pooling 모드에서도 prepared statement를 쓸 수 있게 된 게 벌써 2년 가까이 됐다. 우리 팀도 작년 가을에 1.22로 올리고 max_prepared_statements를 켰는데, 그동안 마주친 함정 몇 개가 있어서 정리해둔다. 비슷한 마이그레이션을 앞두고 있는 분들에게 도움이 됐으면 한다.이 글은 "PgBouncer는 뭔가요"부터 시작하지 않는다. 이미 transaction 모드로 PgBouncer를 운영 중이고, 애플리케이션이 prepared statement를 쓰고 있거나 쓰고 싶은 상황을 가정한다.JDBC, asyncpg, pgx, psycopg3 같은 모던 드라이버는 기본적으로 Parse/Bind/Execu..

IT/DB 운영 2026.04.29
BIG