IT 363

새벽 3시, CoreDNS NXDOMAIN 폭주로 잠을 못 잤다

처음엔 외부 API를 의심했다새벽 3시 12분. 슬랙 알림이 한 번에 17개 쌓였다. P99 외부 API 호출 latency가 평소 80ms에서 4초까지 튀었다. 처음엔 SaaS 벤더 쪽 장애인가 싶었는데, 우리 쪽 다른 서비스들도 다 같이 느려지고 있었다. 멘탈이 한번 나가고, 노트북을 켰다.결론부터 말하면 CoreDNS NXDOMAIN 폭주였다. 솔직히 DNS 문제는 항상 의심해야 한다는 걸 머리로는 알았는데, 실제로 새벽에 당해보니 또 한 번 새겼다. 우리 팀이 운영하는 EKS 클러스터, 노드 38대, 워크로드 약 400개 정도 되는 규모다.알림 내용은 단순했다. httpClient.get 호출 P99가 폭증 중이라는 거. 외부 결제 SaaS 호출이 대부분이라 벤더 status 페이지부터 봤다. 다..

IT/기타 2026.06.20

Terraform 1.10 ephemeral resources로 시크릿 상태 노출 줄이기

Terraform 쓰면서 가장 찜찜한 게 뭐였냐고 물으면, 솔직히 나는 terraform.tfstate에 시크릿이 평문으로 박히는 거였다. RDS 마스터 패스워드, API 토큰, OAuth 클라이언트 시크릿. data 블록으로 Secrets Manager에서 가져온 값조차 state에 그대로 기록된다.그동안은 state 백엔드(S3 + KMS)에 의존하거나, write-only 패턴을 억지로 끼워넣거나, 아예 Terraform 밖에서 처리하는 식으로 우회했다. 그런데 작년 말 1.10에서 나온 ephemeral resources가 1년 좀 넘게 실무에서 굴려보니 꽤 쓸 만하다. 최근 6월 기준 AWS, Azure, Vault, Kubernetes, random, 그리고 GCP 프로바이더까지 지원이 거의 ..

IT/IaC 2026.06.19

Tekton vs Argo Workflows, 6개월 굴려보고 우리 팀이 내린 결론

작년 말부터 우리 팀은 GitHub Actions 한 곳에 모든 파이프라인을 몰아넣던 구조를 깨기 시작했다. 빌드/배포는 Actions에 두고, 데이터 파이프라인과 K8s 안에서 도는 무거운 잡들은 클러스터 안에서 돌리자는 결정이었다. 후보는 Tekton Pipelines와 Argo Workflows 두 개. 결정을 못 내려서 결국 둘 다 6개월씩 굴려봤다.올해 들어 두 프로젝트 모두 큰 릴리즈가 있었다. Tekton Pipelines는 작년 5월에 v1.0 GA 찍고 올 2월에 v1.9.0 LTS를 냈고, Argo Workflows는 v4.0.0이 2월 4일에 떨어졌다. 둘 다 안정성과 운영 편의 쪽으로 방향이 잡혀가는 시점이라 비교하기 딱 좋았다.우리가 본 워크로드비교가 의미 있으려면 어떤 잡을 돌렸..

IT/CI CD 2026.06.19

사실 내부적으로는 — Istio ambient mode ztunnel과 waypoint가 동작하는 방식

ambient mode가 Istio 1.24에서 GA된 게 2024년 말이다. 지난주에 우리 팀도 일부 네임스페이스를 sidecar에서 ambient로 옮기는 작업을 마무리했다. 옮기고 나서 가장 많이 받은 질문이 "그래서 mTLS는 누가 거는 거냐", "L7 정책은 어디서 검사되냐"였다. 문서를 봐도 그림 한 장으로 퉁쳐버리니까 막상 트러블슈팅을 시작하면 답답하다.그래서 이 글은 패킷이 Pod A에서 떠나서 Pod B에 도착할 때까지, 정확히 어떤 컴포넌트가 어떤 순서로 끼어드는지를 우리 팀이 확인하면서 정리한 내용이다. Istio 공식 문서가 적당히 추상화한 부분을 한 단계 더 내려가서 본다.sidecar 없는 데이터플레인이라는 말의 진짜 의미ambient mode의 가장 큰 광고 문구는 "sidec..

IT/기타 2026.06.19

Karpenter NodePool weight, 함정이 하나 있다

오늘 알게 된 건데, Karpenter NodePool의 weight 가지고 spot 우선 + on-demand fallback 구성한 분들 꽤 많을 거다. 우리 팀도 그렇게 쓰고 있었고. 근데 이게 생각만큼 매끄럽게 fallback이 안 되는 케이스가 있다.며칠 전에 다른 팀 슬랙에서 "spot이 깨졌는데 on-demand로 안 넘어와요" 하는 글을 봤다. 처음엔 NodePool 매칭이 안 맞나 싶었는데, GitHub 이슈를 따라가다 보니 karpenter-provider-aws#8885라는 게 있더라. 올해 1월 말부터 올라온 이슈인데, 아직 진행 중이다.무슨 상황이냐면대충 이런 구성을 떠올리면 된다.# 우선순위 높은 spot 풀apiVersion: karpenter.sh/v1kind: NodePoo..

IT/AWS 2026.06.18

Gateway API v1.5 ListenerSet으로 멀티팀 Gateway 정리하기

기존 Gateway 모델의 한계올해 2월에 Gateway API v1.5가 나왔고, ListenerSet이 드디어 Standard 채널로 올라왔다. 우리 팀에서는 v1.4 시절부터 Experimental로 깔짝거리며 써봤는데, 이제 GA니까 본격적으로 도입했다. 막상 옮겨보니 단순한 기능 추가가 아니라 멀티팀 환경에서 Gateway 관리 모델 자체가 바뀌는 변화였다.이 글은 ListenerSet이 뭔지, 왜 필요한지, 그리고 기존 Gateway에서 어떻게 갈아끼는지 정리한 가이드다. Istio나 Envoy Gateway 같은 구현체에 따라 세부 동작이 다르긴 한데, 기본 개념은 동일하다.Gateway API에서 Gateway 리소스 하나는 보통 플랫폼 팀이 소유한다. Listener를 여러 개 박아두고,..

IT/Kubernets 2026.06.18

Cilium kube-proxy replacement, 내부에서는 무슨 일이 벌어지나

kube-proxy를 Cilium으로 교체한 지 1년이 좀 넘었다. 처음엔 단순히 "iptables 룰이 많아져서 느려지니까 eBPF로 바꾸자" 정도의 인식이었는데, 운영하면서 보니 동작 모델 자체가 완전히 다르다. ClusterIP 패킷이 어디서 어떻게 처리되는지, 왜 socket-level LB가 그렇게 강조되는지, DSR은 왜 켰을 때 갑자기 응답이 안 오는지 — 이런 걸 제대로 알아야 디버깅이 가능했다.이번 글은 우리 팀에서 KubeCon EU 2026 직후 사내 발표용으로 정리한 내용을 다시 풀어쓴 거다. 코드 예제보다는 패킷이 흐르는 경로를 추적하는 데 집중했다.kube-proxy의 한계, 그리고 왜 eBPF가 답이 됐나kube-proxy iptables 모드는 Service 하나당 여러 개의..

IT/Kubernets 2026.06.17

pgbouncer transaction mode에서 prepared statement 깨진 새벽 사건

지난주 새벽에 또 깼다. 4시쯤 핸드폰이 미친 듯이 울리는데, 화면을 보니 prepared statement "S_42" does not exist 에러가 분당 수천 건씩 쌓이고 있었다. 결제 API 쪽이었는데, 그날따라 더 짜증났던 건 — 두 시간 전에 내가 직접 머지한 PR 때문이라는 게 거의 확실했기 때문이다.결론부터 말하면 pgbouncer transaction pooling 모드 + 새 JDBC 드라이버 조합이 문제였다. 근데 거기까지 가는 과정이 정말 길었다.새벽 4시, 일단 롤백부터운영 룰은 단순하다. 새벽에 깨면 일단 의심되는 배포부터 롤백. 두 시간 전 머지한 PR이 두 개 있었다 — 하나는 pgbouncer 버전 업(1.18 → 1.23), 다른 하나는 백엔드 서비스의 PostgreSQ..

IT/DB 운영 2026.06.17

GitHub Actions concurrency 그룹과 matrix, 무심코 쓰면 서로를 죽인다

이거 모르는 분 꽤 많더라. 우리 팀도 작년 말까지 모르고 있었고, 우연히 디플로이 파이프라인 디버깅하다가 발견했다.concurrency: 블록을 workflow 레벨에 걸어 둔 상태에서 matrix strategy로 OS 3개를 동시에 돌리면 어떻게 될까. 정답은 3개가 서로를 취소시킨다.name: teston: [push]concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: truejobs: test: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} ..

IT/CI CD 2026.06.17