SMALL

kubernetes 82

ArgoCD app-of-apps에서 sync-wave 잘못 짜서 새벽에 깬 이야기

지난주 화요일 새벽 3시쯤. 휴대폰이 울렸다. 온콜 알림이었다. prod의 메인 API가 503을 뱉고 있다는. 솔직히 그날따라 몸이 너무 무거워서 한 5분쯤은 침대에서 멍하니 알림을 봤다. 그 5분이 정말 길었다.원인을 미리 말하자면, 전날 머지된 PR에서 ArgoCD argocd.argoproj.io/sync-wave 값을 한 줄 바꾼 게 문제였다. app-of-apps 패턴을 쓰는 우리 클러스터에서, 그 한 줄이 컨트롤 플레인 컴포넌트보다 워크로드를 먼저 띄우게 만들었다. 결과적으로 cert-manager가 뜨기 전에 ingress webhook이 호출돼서 발급이 꼬였고, 그게 ALB target health check를 흔들었고, 503이 떴다.새벽 3시반에 침대에서 일어나면서 든 생각: "syn..

IT/CI CD 2026.05.17

Velero로 EKS 백업/복구 자동화하기

EKS를 몇 년째 운영하다 보면 한 번쯤은 이런 순간이 온다. 누군가 kubectl delete ns prod-something을 잘못 쳤거나, GitOps 동기화가 꼬여서 ConfigMap이 통째로 날아갔거나. 우리 팀에서는 작년에 한 번 비슷한 사고가 났다. ArgoCD가 잘못된 브랜치를 source로 잡아서 네임스페이스 하나를 prune 해버린 거다. 다행히 ETCD 덤프가 있었지만, 복구하는 데 반나절을 썼다.그 사건 이후로 Velero를 정식으로 도입했다. 이번 글은 EKS 환경에서 Velero를 0에서부터 세팅하고 운영하는 실전 가이드다. 공식 문서에 나오는 기본 설치 말고, 실제 운영 들어갔을 때 부딪히는 부분 위주로 적었다.왜 Velero인가EKS 백업 옵션은 몇 가지가 있다. AWS Ba..

IT/Kubernets 2026.05.16

kubectl debug --target 플래그, 이거 모르는 분 꽤 많더라

오늘 알게 된 건 아니지만, 최근에 팀 내부 트러블슈팅 가이드 다듬다가 다시 한 번 짚어둘 만하다 싶어서 짧게 적는다. kubectl debug로 ephemeral container 띄울 때 --target 빠뜨리고 쓰는 분들이 의외로 많다. 1.25부터 EphemeralContainers feature gate가 GA로 켜진 게 벌써 한참 됐는데도.무슨 문제냐면distroless 이미지를 쓰는 파드에 들어가서 curl이나 netstat 한 번 쳐보고 싶을 때 보통 이렇게 쓴다.kubectl debug -it my-pod -n prod --image=nicolaka/netshoot이걸로 컨테이너는 잘 붙는다. 근데 막상 들어가서 ps를 쳐보면 본인 프로세스만 보인다. 본 컨테이너의 PID가 안 보인다는 ..

IT/Kubernets 2026.05.16

Cilium vs Calico — 6개월 검토하고 우리가 내린 결론

CNI 갈아탈까 말까 하는 고민은 누구나 한 번쯤 한다. 우리 팀도 작년 말부터 "Cilium 한번 가보자" 분위기가 있었고, 결국 6개월 가까이 PoC와 운영 시뮬레이션을 돌렸다. 결론부터 말하면, 메인 워크로드는 Calico에 남겼고 새로 구축한 ML 추론 클러스터만 Cilium으로 갔다. 같은 회사 안에서 CNI를 두 개 쓰게 된 셈인데, 이 글은 왜 그런 결정을 했는지에 대한 정리다.왜 갈아타고 싶었나우리 메인 EKS 클러스터는 노드 80대 규모. Calico를 3년 넘게 써왔고 큰 문제는 없었다. 그런데 최근 1년 사이 두 가지 가려운 부분이 생겼다.하나는 kube-proxy iptables 룰이 너무 길어진 거다. Service 수가 1,200개를 넘기면서 노드당 iptables 룰이 4만 줄..

IT/Kubernets 2026.05.16

HPA behavior 필드 잘못 만지다가 P99 튀어버린 이야기

지난주에 HPA behavior 필드를 손댄 적이 있다. 정확히 말하면 손댄 게 아니라, 누군가 친절하게 PR로 올려준 "스케일 다운 빠르게 하자"는 변경을 별생각 없이 머지한 게 시작이었다. 그날 오후부터 P99 레이턴시가 평소 80ms에서 320ms를 찍었고, 새벽 1시쯤 알람이 한 번 더 울리고 나서야 우리 팀은 이게 비용 최적화가 아니라 자해였다는 걸 인정했다.이 글은 그 삽질 회고다. 비슷한 PR 들어오면 한 번만 더 생각해 보시라는 의미에서 적어둔다.사건의 시작서비스는 API 트래픽이 출퇴근 시간대에 몰리는 전형적인 패턴이다. 노드 12대짜리 EKS 클러스터에서 Deployment 3개가 HPA로 묶여 있었고, 평소 replica가 8~30 사이를 왔다 갔다 했다. 비용을 줄이려면 트래픽이 빠..

IT/Kubernets 2026.05.16

AWS NLB로 gRPC 라우팅, ALPN 정책 한 줄을 안 넣으면 어떻게 깨지나

ALB의 gRPC 지원은 꽤 알려져 있다. Target group protocol version을 GRPC로 바꾸고, health check 경로를 /grpc.health.v1.Health/Check로 잡으면 끝. 근데 사내에서 ALB를 안 쓰고 NLB로 가야 하는 상황이 생긴다. 클라이언트가 mTLS를 끝단까지 가져가야 하거나, ALB로는 못 받는 별난 트래픽이 섞여 있거나, 비용 문제거나.이 글은 그 NLB + gRPC 조합에서 우리 팀이 며칠 헤맨 얘기를 정리한 거다. 결론부터 말하면 ALPN 정책 한 줄이 빠지면 TLS handshake는 되는데 gRPC만 안 된다. 로그도 별 게 안 남는다.NLB가 gRPC를 "지원"한다는 말의 의미NLB는 L4다. HTTP/2 프레임을 해석하지 않는다. 그래서..

IT/AWS 2026.05.15

CronJob 실패 로그가 증발한 사건

지난주 새벽의 작은 사고지난주에 작은 사고가 있었다. 큰 장애는 아니었는데, 디버깅하면서 내가 너무 기본값을 신뢰하고 있었다는 걸 깨달았다. CronJob failedJobsHistoryLimit 얘기다.상황은 이랬다. 데이터 동기화용 CronJob이 매 5분마다 도는데, 모니터링 대시보드에서 어느 새벽부터 실패 카운트가 슬슬 올라가고 있었다. 한 시간쯤 지나서 PagerDuty가 울렸고, 출근 전이라 자느라 못 봤다. 아침에 일어나서 보니 한 시간 동안 12번 실패한 상태였다.로그를 보러 갔는데당연히 kubectl logs부터 쳤다. Pod가 이미 사라진 상태. 그렇지, CronJob은 Job을 만들고, Job이 Pod를 만든다. Pod는 사라져도 Job 객체는 남아있어야 하니까 그쪽을 보자.$ kub..

IT/Kubernets 2026.05.15

Kubernetes graceful node shutdown, 안에서 도는 것들

스팟 인스턴스를 자주 쓰다 보면 kubelet이 노드 종료 시점에 어떻게 행동하는지가 늘 신경 쓰인다. 사실 nodelifecycle 컨트롤러가 Pod를 옮겨주기는 하지만, 그건 노드가 NotReady가 되고도 한참 뒤의 이야기다. 그 사이에 노드 위에 있던 Pod이 어떻게 끝나느냐는 전적으로 kubelet의 graceful node shutdown 동작에 달려 있다. 이 기능은 1.21에서 알파, 1.28에서 GA가 됐고, 1.24부터는 Pod priority별로 단계화도 가능해졌다. 그런데 막상 운영해보면 "켜 놨는데 안 도는 것 같다"는 케이스가 꽤 있다. 어디서 끊기는지 한번 따라가본다.systemd-inhibitor라는 비밀번호kubelet이 노드 종료를 감지하는 방식은 의외로 단순하다. 부팅 ..

IT/Kubernets 2026.05.15

Karpenter 스케줄러는 어떻게 노드를 결정하는가 — 내부 동작 분석

Karpenter를 1년 넘게 운영하다 보니 "왜 이 인스턴스 타입을 골랐을까" 하는 순간이 종종 생긴다. m5.2xlarge면 충분해 보이는데 c6i.4xlarge를 띄운다거나, 분명히 비슷한 spec인데 어떤 Pod는 한 노드에 몰리고 어떤 Pod는 새 노드를 띄운다. 처음엔 그냥 "알아서 잘 해주겠지" 하고 넘어갔는데, 최근 Karpenter 1.11에서 Application Recovery Controller(ARC) zonal shift 통합이 들어오면서 zone 단위 회복 시나리오를 검토할 일이 생겼다. 이 김에 스케줄러 내부를 한 번 제대로 들여다봤다.사실 Karpenter의 스케줄링 로직은 pkg/controllers/provisioning/scheduling/scheduler.go 한 파..

IT/Kubernets 2026.05.14

startupProbe 모르고 슬로우 스타트 앱 운영하지 마세요

오늘 알게 된 거 아니고, 사실 꽤 됐는데 의외로 모르는 분이 많더라. 지난주에도 동료가 "JVM 앱이 livenessProbe 때문에 자꾸 재시작된다, initialDelaySeconds를 300초로 박았는데도 가끔 죽는다"는 얘길 했다. 그때 startupProbe 얘기를 꺼내면서 "어 진짜? 그런 게 있었어?"라는 반응이 나왔다. 1.20부터 GA였는데도 말이다.근데 이게 한두 명 얘기가 아니라서, 짧게 정리해둔다.initialDelaySeconds로 버티는 게 왜 문제냐흔히 쓰는 패턴이 이거다.livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 180 periodSeconds: 10 failureThresh..

IT/Kubernets 2026.05.13
BIG