요약

Important

쿠버네티스는 컨테이너 관리를 위한 오픈소스 플랫폼으로, 컨테이너 기반 애플리케이션을 관리하는 데 탁월하지만 그에 따르는 비용 요소와 학습 곡선이 존재한다.

1. 서론

처음 쿠버네티스의 존재를 알게 되었을 때는 막연히 ‘도커만으로도 충분히 애플리케이션 서비스가 가능한데 컨테이너 오케스트레이션이 왜 필요하지?‘라고 생각했다. 공식 문서나 책을 읽어봐도 내용이 낯설기만 했다. 그래서 좀처럼 해소되지 않던 궁금증은 쿠버네티스 클러스터를 직접 구성해보면서 해소할 수 있었다.

링크를 확인해보면, 쿠버네티스는 구글에서 약 15년 이상에 걸쳐 리눅스 컨테이너를 관리하기 위한 시스템을 연구하면서 내부적으로만 사용되다가, 퍼블릭 인프라 사업을 목적으로 오픈소스화되었다고 한다. 너무 간략한 요약이라 비약이 심했을 수 있지만, 위 문장만 읽어봐도 쿠버네티스가 분산 자원을 효율적으로 관리하는 목적을 가지고 구글에서 자랑스럽게 내놓은 시스템이라는 점을 유추해볼 수 있다.

본 글에서는 쿠버네티스가 필요한 이유와 쿠버네티스 도입이 실제로 적합한지에 대해, 짧게나마 쿠버네티스를 경험해 본 내용을 토대로 개인적인 생각을 적는다.

2. 쿠버네티스란?

Important

‘쿠버네티스란?‘이라는 섹션 제목을 달았지만, 실제로는 ‘(짧은 기간 동안) 쿠버네티스를 접하며 (개인적으로) 느낀 점’이 좀 더 정확할 것 같다.

쿠버네티스가 필요한 이유에 대한 예시를 들어 보았다.

한 대의 서버에 도커를 활용해 애플리케이션을 구동하는 서버가 있다고 가정해보자. 서버 외부에서 컨테이너를 모니터링하거나 설정을 관리하기 위해서는 SSH 등의 원격 접속이 제일 먼저 떠오른다. 그런데 보안상의 문제나 네트워크 구성 등에 따라서 SSH 접속이 불가하다면 문제가 조금 복잡해진다. 현재 동작중인 컨테이너와 별도로 서비스와 서버를 관리할 수 있는 API 를 생성해야하고, https 프로토콜을 사용하기 위해서 인증서가 필요할 것이며 보안을 위해서 접근 권한을 관리하는 인증/인가 모듈을 추가적으로 구성해야할 것이다. 여기까지만 해도 복잡한데 리소스가 부족하여 서버를 더 추가한다면? 추가적으로 컨테이너 배치, 상태 체크, 로드 밸런싱, failover 등 고려해야할 사항이 훨씬 늘어나게 된다. 이러한 설정을 통합적으로 관리할 수 있는 솔루션이 절실해지는 순간이다.

쿠버네티스는 예시에서 언급한 여러 복잡한 설정을 자체 기능 또는 플러그인 요소로 구성할 수 있다. 쿠버네티스는 분산된 여러 리소스를 활용하고 필요에 따라 애플리케이션을 스케일링하며, 로드밸런싱과 안정적인 배포를 위한 옵션을 제공하는 등 분산 서버에서 애플리케이션을 운영하는 데 필요한 다양한 기능을 구성할 수 있다. 그리고 셸 CLI인 kubectl을 통해서 쿠버네티스 클러스터의 API를 호출하여 클러스터 상태를 확인하고 오브젝트를 관리할 수 있다.

아래는 쿠버네티스에 대한 내용을 간략하게 정리한 것이다.

장점

  • 분산 리소스 활용 : 여러 노드의 리소스를 효율적으로 사용할 수 있고, 관리와 배포(CICD), 스케일 업/다운을 설정할 수 있다.

  • 스케일링 : 필요에 따라 애플리케이션을 스케일 업/다운 하는 것을 자동으로 수행할 수 있다.

  • 고가용성 : 애플리케이션에 실패(Fail)가 발생하더라도 계속 사용할 수 있도록 구축된 기능을 제공한다.

  • 유연성 : 온프레미스, 클라우드, 하이브리드 환경 등 다양한 인프라에서 실행될 수 있다.

  • 커뮤니티 : 쿠버네티스와 관련된 다양한 커뮤니티와 오픈소스 개발이 진행되고 있어 문제해결이나 지원 도구를 찾기에 용이하다.

단점

  • 복잡성과 러닝커브 : 쿠버네티스를 전문적으로 사용하려면 충분한 기술 지식이 필요하기 때문에, 기존 시스템에서 쿠버네티스 환경으로 전환하는 데 많은 시간이 소요될 수 있다.

  • 자원 요구 사항 : 클러스터를 구축하기 위해 자원이 상대적으로 많이 필요할 수 있어 비용측면에서 고려할 필요성이 존재한다.

운영시 필요 사양

공식 사이트에서는 최소 사양이나 권장 사양에 대한 명확한 가이드를 제공하지 않지만, 링크를 참고했을 때 아래 사양 이상이 필요한 것으로 보인다.

  • 클러스터 구성 : 마스터 3식 이상, 워커 2개 이상
  • 노드 당 최소 사양 : 2코어 cpu, 2기가 ram

그리고 워커 노드는 서비스하려는 애플리케이션의 사양에 맞춰 스펙을 높여야 한다.

쿠버네티스를 저해하는 요소

  • 단일 또는 소규모 리소스
  • 구성원들의 쿠버네티스에 대한 낮은 이해도
  • 오프라인 환경 (폐쇄망)

에 해당하는 내용이 있다면 도입 과정에서 많은 어려움이 따를 수 있으니, 쿠버네티스 도입을 좀 더 신중하게 검토하는 것이 어떨까 싶다.

  • 이유 (펼치기/접기)
    • 단일 또는 소규모 리소스
      리소스가 부족하면 고가용성과 Failover 구성이 오히려 복잡해진다. 워커 노드가 2개일 경우에는 서버 1대만 다운되더라도 가용 자원의 50%를 잃는다. 단순히 생각하면 예기치 못한 서버 장애에 대비하기 위해서 각 서버마다 여유 자원을 50% 이상 남겨두어야 성공적으로 Drain 된다는 의미다. 실제 운영에서 어떤 방식으로 Failover 전략을 사용하는지는 잘 모르겠지만, 확실히 리스크가 크다고 생각한다. 또한 고가용성을 위해서 3개 이상의 노드가 기본적으로 필요한 플러그인도 존재한다.
      서버 숫자가 작다고 해서 설정 작업이 줄어드는 것도 아니다. 결국 클러스터 구성 요소는 모두 갖추어야 한다는 뜻인데, 그 결과로 불필요하게 도커 시스템에 비해서 복잡성만 증가하는 결과를 초래할 수도 있다.

    • 구성원들의 쿠버네티스에 대한 낮은 이해도
      구성원들이 파드를 배포하고 로그를 확인하는 데 어려움이 있다면, 매번 인프라 담당자가 과정을 대신 처리하거나 관련 가이드와 스크립트를 공유해야 하는 상황이 발생할 수 있다. 이 과정에서 업무 병목이 발생할 수 있으므로, 개발자가 기본적인 쿠버네티스 기능을 활용할 수 있는지가 중요하다.

    • 오프라인 환경 (폐쇄망)
      필요한 패키지 파일, 도커 이미지, 바이너리 파일을 온라인으로 내려받지 못하고 직접 준비해서 오프라인 서버로 옮겨야 하므로, 클러스터링 단계에서 복잡성이 매우 증가한다. 게다가 회사 내부에서 작업하는 것이 아니라 고객사에 설치하는 경우에는, 고객사 보안 규정에 따라 클러스터링 단계에서 IaC(Infrastructure as Code)를 활용할 수 있는지 여부도 불투명하다. 결국 직접 명령어를 입력하거나 쉘 스크립트로 모든 작업을 해결해야 할 수도 있다.

3. 결론

쿠버네티스를 미지의 생태계라고 표현하는 것이 적절할 것 같다. 컨테이너가 외부에서 정상적으로 동작하도록 만들기 위해서는 최소한 네트워크(CNI, ingress, service, kube-dns, kube-proxy) 정도는 갖추어져야 한다. 그리고 좀 더 쿠버네티스답게 사용하기 위해서는 추가로 스토리지(CSI, StorageClass, PersistentVolume, PersistentVolumeClaim), 컨피그맵(ConfigMap), 시크릿(Secret), 서비스 어카운트와 롤바인딩(ServiceAccount, RoleBinding), 레플리카셋과 스테이트풀셋(ReplicaSet, StatefulSet) 등 다양한 오브젝트에 대한 이해가 필요하다. 그만큼 학습 곡선이 필요하다는 의미다.

다만 학습 곡선을 어느 정도 극복하고 나면 편의성이 확실히 증가한다. yaml 파일을 작성하여 api-server에 전달하는 동작만으로 리소스의 생성과 관리를 쿠버네티스에 맡길 수 있으며, 이 과정도 helm 같은 패키지 매니저를 활용하면 훨씬 간소화할 수 있다.

그리고 이러한 편의성은 클러스터 규모가 어느 정도 이상일 때 두드러진다. 애플리케이션당 0~1개의 복제본만 존재하거나 워커 노드 2대로 고가용성을 목적으로 클러스터를 구성하는 경우에는, 쿠버네티스 도입이 상황에 따라 도커만으로 구성하는 것과 큰 차이가 없거나 복잡성만 증가시켜 작업자의 부담만 키울 수 있다고 느꼈다.

쿠버네티스는 익히고 나면 강력하고 편한 시스템이다. 다만 그 과정까지가 매우 험난할 수 있으니, 도입을 검토하는 단계라면 현재 상황이 실제로 적합한지부터 따져보는 것이 맞겠다.

참고