Kubernetes와 운영 성숙도에 대한 잘못된 느낌
Source: Dev.to
위에 제공된 텍스트를 번역하려면 실제 번역할 내용이 필요합니다. 번역하고 싶은 전체 텍스트(마크다운 형식 포함)를 알려주시면 한국어로 번역해 드리겠습니다.
소개
Kubernetes는 실제 필요성 때문에 작은 프로젝트에 거의 들어가지 않는다. 시스템이 성장하고, 확장에 대한 논의가 등장하거나, 누군가가 “이제는 더 견고한 것을 써야 할 때다”라고 느낄 때 등장한다. 문제는 Kubernetes가 기술 성숙도의 인증서처럼 취급되는 경우가 많은데, 실제로는 문제 발생 지점을 단지 옮겨줄 뿐이다.
Kubernetes에서 애플리케이션을 실행한다고 해서 시스템이 스스로 더 신뢰성이 높아지는 것은 아니다. 오히려 나쁜 결정이 더 오래 살아남고 좋은 결정이 필수가 되는 환경을 만든다. 이 두 시나리오의 차이는 보통 첫 번째 심각한 사고가 발생한 뒤에야 명확해진다.
클러스터는 애플리케이션을 해결하지 않는다
가장 처음 깨지는 기대 중 하나는 Kubernetes가 애플리케이션을 “돌봐준다”는 생각이다. Kubernetes는 pod, 컨테이너, 노드, 스케줄링을 관리한다. 나머지는 팀의 책임이다. 애플리케이션이 재시작을 잘 처리하지 못하고, 상태를 잃지 않고 올라가고 내려가는 방법을 모른다면, 명확한 헬스 신호를 제공하지 못한다면, 클러스터는 이를 보완하지 않는다. 클러스터는 단지 깨진 것을 더 효율적으로 재시작할 뿐이다.
운영 환경에서는 이것이 특이한 패턴으로 나타난다: Kubernetes 관점에서는 모든 것이 정상으로 보이지만, 시스템은 전혀 가치를 제공하지 않는다. Pod는 실행 중이고, 레플리카는 정상이며, 자동 스케일링도 동작하지만, 사용자 입장에서는 느려지거나 일관성이 없다고 느낀다. 클러스터는 정상이다. 애플리케이션은 아니다.
‘건강한 인프라’와 ‘건강한 제품’ 사이의 이러한 구분은 인프라 장애와 애플리케이션 장애가 거의 동일했던 더 단순한 환경에서 온 사람들에게 충격을 주는 경우가 많다.
Configuração vira código… e dívida
Kubernetes는 모든 것을 코드로 다루도록 장려합니다. 이는 동시에 옳고 위험한 아이디어입니다. 옳은 이유는 추적 가능성을 제공하기 때문이며, 위험한 이유는 조용한 복잡성이 쉽게 쌓이게 만들기 때문입니다. YAML 파일은 커지고, 중복되며, 프로젝트 간에 복사되고, 금세 누구도 특정 옵션이 왜 존재하는지 정확히 이해하지 못하게 됩니다.
운영 중인 클러스터의 대부분은 아무도 건드리기 두려워하는 결정들을 가지고 있습니다. “항상 그래왔기 때문에” 정의된 요청(request)과 제한(limit), 오래된 문제를 우회하기 위해 조정된 프로브(probe), 누가 작성했는지 기억조차 못하는 차트에서 물려받은 어노테이션(annotation) 등이 그것입니다. 모든 것이 작동하던 날이 지나면 더 이상 작동하지 않게 되고, 시스템을 이해하려면 고고학적인 작업이 필요합니다.
Kubernetes 자체가 이 부채를 만들지는 않지만, 그 부채가 숨을 수 있는 편안한 장소를 제공할 뿐입니다.
확장은 부하를 견디는 것과 동일하지 않다
다른 흔한 혼동 포인트는 자동 스케일링을 트래픽 증가에 실제로 대응할 수 있는 능력과 연관 짓는 것이다. 클러스터는 빠르게 스케일링할 수 있지만 애플리케이션이 이를 따라가지 못할 수 있다. 외부 연결, 콜드 캐시, 느린 의존성 및 무거운 초기화는 더 많은 파드가 있다고 해서 사라지지 않는다.
많은 경우 HPA는 문제를 단순히 퍼뜨릴 뿐이다. 더 많은 인스턴스가 동일한 잘못된 작업을 병렬로 수행하면서 데이터베이스, 큐 또는 외부 API에 더 큰 압력을 가한다. 시스템은 “스케일”하지만 동작은 예측하기 어려운 방식으로 악화된다.
이때 Kubernetes가 인프라를 스케일링하고, 아키텍처를 스케일링하는 것이 아니라는 것이 명확해진다. 설계가 부하를 견디지 못한다면, 클러스터는 한계에 더 빨리 도달하도록 도울 뿐이다.
관찰 가능성은 이제 필수, 사치가 아니다
소규모 환경에서는 기본 로그와 약간의 직감으로 살아남을 수 있다. 쿠버네티스에서는 이것이 오래가지 못한다. 파드의 일시적인 특성과 클러스터의 동적 특성 때문에 명확하고 정의된 신호 없이는 사고를 이해하기가 불가능하다.
괜찮은 메트릭이 없으면 모든 조정이 시도와 오류가 된다. 트레이스가 없으면 시간이 어디에 쓰이고 있는지 알기 어렵다. 구조화된 로그가 없으면 문제를 조사할 때 이미 존재하지 않는 정보 조각들을 모아야 한다. 쿠버네티스는 변화 속도를 가속화하고, 이는 관찰 가능성 부족을 더욱 비용이 많이 들게 만든다.
팀이 kubectl을 능숙하게 다루면서도 애플리케이션의 실제 동작에 대해 전혀 모르는 경우가 드물지 않다.
Kubernetes 운영은 지속적인 작업입니다
Kubernetes가 “설정하고 잊어버리는” 것이라는 기대도 있습니다. 실제로는 지속적인 유지보수가 필요합니다. 버전이 바뀌고, API가 폐기되며, 미묘한 동작이 업그레이드 사이에 변경됩니다. 애플리케이션이 변하지 않아도 클러스터는 노후됩니다.
이를 무시하면 위험이 누적됩니다. 많은 심각한 문제는 새로운 버그 때문이 아니라, 서로 다른 속도로 진화한 구성 요소 버전 간의 조용한 호환성 문제 때문에 발생합니다. Kubernetes는 정적인 제품이 아니며, 이를 그렇게 취급하면 나중에 큰 대가를 치르게 됩니다.
결론
Kubernetes는 강력하지만 관대하지 않다. 잘 설계된 시스템에 보상을 주고, 운이나 행운에 의존하는 사람들을 빠르게 드러낸다. 그것을 사용한다고 해서 팀이 자동으로 더 성숙해지는 것은 아니며, 유연성을 통제된 혼돈으로 변질시키지 않기 위해 성숙함이 요구된다.
잘 이해한다면, Kubernetes는 성장의 견고한 기반이 된다. 전문성을 위한 지름길로 사용될 때, 그것은 단지 같은 문제가 발생할 무대를 바꿀 뿐이다 — 이제는 더 많은 추상화, 더 많은 계층, 그리고 즉흥에 대한 여지가 적어진다.