Maybe You Don't Need Kubernetes

Matthias Endler

어쩌면 Kubernetes는 필요하지 않을지도 모릅니다

스쿠터를 타는 여성
스쿠터를 타는 여성
출처: 일러스트 제작 freepik, Nomad 로고 HashiCorp.

Kubernetes는 컨테이너 오케스트레이션 분야의 절대 강자입니다.
전 세계에서 가장 큰 배포 중 다수를 뒷받침하고 있지만, 그만큼 대가도 따릅니다.

특히 작은 팀에게는 유지 관리에 많은 시간이 들고 학습 곡선도 가파릅니다. trivago에서 4명으로 구성된 우리 팀이 이루고자 했던 일에 비하면 오버헤드가 너무 컸습니다. 그래서 대안을 찾아봤고, Nomad와 사랑에 빠졌습니다.

위시리스트

우리 팀은 모니터링과 성능 분석을 위한 여러 전형적인 서비스를 운영합니다. Go로 작성된 메트릭용 API 엔드포인트, Prometheus 익스포터, Logstash나 Gollum 같은 로그 파서, InfluxDB나 Elasticsearch 같은 데이터베이스가 그 예입니다. 각 서비스는 저마다의 컨테이너에서 실행됩니다. 우리는 이 작업들을 계속 실행해 줄 단순한 시스템이 필요했습니다.

컨테이너 오케스트레이션에 대한 요구사항 목록부터 정리했습니다.

  • 여러 머신에 걸쳐 서비스 플릿을 실행할 것.
  • 실행 중인 서비스 현황을 한눈에 볼 수 있을 것.
  • 서비스 간 통신을 허용할 것.
  • 서비스가 죽으면 자동으로 재시작할 것.
  • 작은 팀이 관리할 수 있을 것.

여기에 더해 있으면 좋지만 필수는 아닌 항목들은 다음과 같았습니다.

  • 머신의 역량에 따라 태그를 지정할 수 있을 것(예: I/O 집약적인 서비스를 위해 빠른 디스크를 탑재한 머신에 라벨 지정).
  • 오케스트레이터와 무관하게 서비스를 실행할 수 있을 것(예: 개발 환경에서).
  • 설정과 시크릿을 공유할 수 있는 공통 공간이 있을 것.
  • 메트릭과 로깅을 위한 엔드포인트를 제공할 것.

왜 Kubernetes는 우리에게 맞지 않았나

Kubernetes로 프로토타입을 만들면서, 서비스를 운영하기 위해 점점 더 복잡한 로직을 계속 추가하고 있다는 사실을 깨달았습니다. 그리고 우리는 그 로직에 암묵적으로 의존하게 됐습니다.

예를 들어 Kubernetes는 ConfigMaps를 이용해 서비스 설정을 임베드할 수 있게 해 줍니다. 여러 설정 파일을 합치거나 파드에 서비스를 추가할 때 이는 금세 꽤 혼란스러워질 수 있습니다. Kubernetes나 helm은 외부 설정을 동적으로 주입해 관심사를 분리하도록 해 줍니다. 하지만 이는 프로젝트와 Kubernetes 사이에 단단하고 암묵적인 결합을 만들 수 있습니다. Helm과 ConfigMaps는 선택 기능이므로 굳이 쓸 필요는 없습니다. 그냥 설정을 Docker 이미지에 복사해도 됩니다. 하지만 그 길로 가고 싶은 유혹이 들고, 불필요한 추상화를 만들었다가 나중에 발목을 잡힐 수 있습니다.

거기에 더해 Kubernetes 생태계는 여전히 빠르게 진화하고 있습니다. 모범 사례와 최신 툴링을 따라잡는 데도 상당한 시간과 에너지가 듭니다. kubectl, minikube, kubeadm, helm, tiller, kops, oc 등 목록은 끝도 없이 이어집니다. Kubernetes를 시작하는 데 모든 툴이 필요한 건 아니지만, 어떤 것이 필요한지 알기 어려우니 적어도 각각이 무엇인지는 알아야 합니다. 그래서 학습 곡선이 꽤 가파릅니다.

언제 Kubernetes를 사용해야 할까

trivago 내에서도 많은 팀이 Kubernetes를 사용하고 있고 만족도도 높습니다. 다만 이런 환경은 이를 감당할 역량을 갖춘 Google이나 Amazon이 관리합니다.

Kubernetes에는 대규모 컨테이너 오케스트레이션을 더 관리하기 쉽게 만드는 놀라운 기능들이 있습니다.

  • 세분화된 권한 관리
  • 커스텀 컨트롤러를 이용해 클러스터에 로직을 넣을 수 있습니다. 이는 그저 Kubernetes API와 통신하는 프로그램일 뿐입니다.
  • 오토스케일링! Kubernetes는 필요에 따라 서비스를 자동으로 확장·축소할 수 있습니다. 수동 개입 없이 서비스 메트릭을 이용해 이를 수행합니다.

문제는 이런 기능이 정말 필요한가 하는 점입니다. 이런 추상화가 그냥 동작한다고 믿을 수만은 없습니다. 내부에서 무슨 일이 일어나는지 직접 배워야 합니다.

특히 trivago의 핵심 인프라와 밀접하게 연결되어 있어 대부분의 서비스를 온프레미스에서 운영하는 우리 팀으로서는, 자체 Kubernetes 클러스터를 운영하는 데 비용을 들이고 싶지 않았습니다. 우리는 서비스를 배포하고 싶었을 뿐입니다.

핵폭탄급 견해: 5년 후에는 아무도 Kubernetes에 신경 쓰지 않을 것이다. - Corey Quinn의 트윗

배터리는 미포함

Nomad는 서비스 오케스트레이션의 20%로 80%를 해내는 도구입니다. 하는 일은 배포를 관리하는 것뿐입니다. 롤아웃을 처리하고 오류가 발생하면 컨테이너를 재시작합니다. 그게 전부입니다.

Nomad의 핵심은 더 적게 하는 데 있습니다. 세분화된 권한 관리나 고급 네트워크 정책을 포함하지 않으며, 이는 의도된 설계입니다. 그런 구성 요소는 엔터프라이즈 서비스로, 서드파티를 통해 제공되거나 아예 제공되지 않습니다.

Nomad는 사용 편의성과 표현력 사이에서 적절한 균형점을 찾았다고 생각합니다. 작고 대체로 독립적인 서비스에 적합합니다. 더 많은 제어가 필요하다면 직접 만들거나 다른 방식을 써야 합니다. Nomad는 말 그대로 오케스트레이터일 뿐입니다.

Nomad의 가장 큰 장점은 교체하기 쉽다는 점입니다. 제공하는 기능이 서비스를 관리하는 다른 시스템에 쉽게 통합될 수 있기 때문에 벤더 종속성이 거의 없습니다. 클러스터의 모든 머신에서 평범한 단일 바이너리로 실행될 뿐입니다. 그게 다입니다!

느슨하게 결합된 컴포넌트들의 Nomad 생태계

Nomad의 진정한 힘은 생태계에 있습니다. Consul(키-값 저장소)이나 Vault(시크릿 관리) 같은 완전히 선택적인 다른 제품들과 매우 잘 통합됩니다. Nomad 파일 안에서는 이런 서비스들로부터 데이터를 가져오는 섹션을 넣을 수 있습니다.

template {
  data = <<EOH
LOG_LEVEL="{{key \"service/geo-api/log-verbosity\"}}"
API_KEY="{{with secret \"secret/geo-api-key\"}}{{.Data.value}}{{end}}"
EOH

  destination = "secrets/file.env"
  env         = true
}

이 설정은 Consul에서 service/geo-api/log-verbosity 키를 읽어 작업 안의 LOG_LEVEL 환경 변수로 노출합니다. Vault의 secret/geo-api-keyAPI_KEY로 노출합니다. 단순하지만 강력합니다!

매우 단순하기 때문에 Nomad는 API를 통해 다른 서비스와도 쉽게 확장할 수 있습니다. 예를 들어 서비스 디스커버리를 위해 작업에 태그를 지정할 수 있습니다. trivago에서는 메트릭을 노출하는 모든 서비스에 trv-metrics 태그를 붙입니다. 이렇게 하면 Prometheus가 Consul을 통해 서비스를 찾아 /metrics 엔드포인트를 주기적으로 스크랩해 새로운 데이터를 수집합니다. 로그도 마찬가지로 Loki를 통합해 같은 방식으로 처리할 수 있습니다.

확장 가능성의 다른 예는 다음과 같습니다.

  • 웹훅과 Consul watch를 이용해 서비스 설정 변경 시 Nomad 작업을 재배포하도록 Jenkins 작업을 트리거하기.
  • Ceph를 이용해 Nomad에 분산 파일 시스템을 추가하기.
  • fabio를 이용해 로드 밸런싱하기.

이 모든 덕분에 큰 초기 투자 없이 인프라를 유기적으로 성장시킬 수 있었습니다.

미리 해 두는 경고

완벽한 시스템은 없습니다. 지금 당장 프로덕션에서 화려한 신기능을 사용하는 것은 권하지 않습니다. 버그빠진 기능이 있는 건 당연합니다. 하지만 이는 Kubernetes도 마찬가지입니다.

Kubernetes와 비교하면 Nomad를 뒷받침하는 모멘텀은 훨씬 작습니다. 지금까지 Kubernetes는 약 75,000개의 커밋과 2,000명의 컨트리뷰터를 기록한 반면, Nomad는 약 14,000개의 커밋과 300명의 컨트리뷰터를 보유하고 있습니다. Nomad가 Kubernetes의 속도를 따라잡기는 어렵겠지만, 어쩌면 그럴 필요도 없습니다! 범위가 훨씬 좁고, 커뮤니티가 작다는 것은 Kubernetes에 비해 풀 리퀘스트가 받아들여지기 더 쉽다는 의미일 수도 있습니다.

정리

핵심은 이겁니다. 모두가 사용한다고 해서 Kubernetes를 사용하지 마십시오. 요구사항을 신중하게 평가하고 어떤 도구가 적합한지 확인하십시오.

대규모 인프라에서 동질적인 서비스 플릿을 배포할 계획이라면 Kubernetes가 좋은 선택일 수 있습니다. 다만 추가적인 복잡성과 운영 비용을 염두에 두십시오. Google Kubernetes Engine이나 Amazon EKS 같은 관리형 Kubernetes 환경을 이용하면 이런 비용 중 일부를 피할 수 있습니다.

유지 관리가 쉽고 확장 가능한 믿을 만한 오케스트레이터를 찾고 있다면, Nomad를 한번 써 보는 건 어떨까요? 기대 이상으로 멀리 갈 수 있다는 사실에 놀랄지도 모릅니다.

Kubernetes가 자동차라면 Nomad는 스쿠터입니다. 때로는 한쪽이, 때로는 다른 쪽이 더 끌립니다. 둘 다 존재할 이유가 있습니다.

원문은 Matthias Endler님이 에 게재했습니다.

이 글은 muse-spark-1.2-contributor 모델을 사용해 번역했습니다.