Kubernetes + Helm 속의 Trino

Kubernetes + Helm 속의 Trino (Trino on Kubernetes with Helm)

Kubernetes는 컨테이너 오케스트레이션 플랫폼으로, Trino와 다른 애플리케이션을 다양한 인프라 위에 반복 가능한 방식으로 배포할 수 있게 해줘요. 가장 빠른 방법은 Trino Helm 차트를 사용하는 거예요.

출처: 문서

본문

Kubernetes는 컨테이너 오케스트레이션 플랫폼으로, kind 같은 도구로 노트북에 배포하는 것부터 Amazon Elastic Kubernetes Service, Google Kubernetes Engine, Azure Kubernetes Service 같은 클라우드의 관리형 Kubernetes 서비스에 이르기까지 다양한 인프라 위에 Trino와 다른 애플리케이션을 반복 가능하게 배포하게 해줘요.

Kubernetes에서 Trino를 실행하는 가장 빠른 방법은 Trino Helm 차트를 쓰는 거예요. Helm은 Kubernetes 애플리케이션용 패키지 매니저로, Kubernetes 설정 파일을 템플릿화해 더 간단한 설치와 버전 관리를 제공해요. 로컬 또는 사내(on-premise) 클러스터에서 프로토타입을 만들고, 같은 배포 메커니즘으로 클라우드에 배포해 확장할 수 있어요.

요구 사항 (Requirements)

  • 지원되는 Kubernetes 버전의 클러스터
  • Kubernetes 클러스터가 없다면 kind로 로컬에서 실행할 수 있어요
  • Kubernetes 배포를 관리하는 머신에 Kubernetes 버전 스큐 정책을 따르는 kubectl
  • Kubernetes 배포를 관리하는 머신에 Helm 버전 스큐 정책을 따르는 helm

Helm으로 Trino 실행 (Running Trino using Helm)

helmkubectl이 설치되어 실행 중인 Kubernetes 클러스터에 연결되도록 구성된 시스템에서 다음 명령을 실행해요.

  1. 다음 명령으로 kubectl이 올바른 클러스터를 가리키는지 확인해요.

    kubectl cluster-info
    

    올바른 Kubernetes 컨트롤 플레인 주소를 보여 주는 출력이 보여야 해요.

  2. 아직 추가하지 않았다면 Trino Helm 차트 저장소를 Helm에 추가해요. 이렇게 하면 Helm이 Trino 차트를 어디서 찾을지 알게 돼요. 저장소 이름은 자유롭게 정할 수 있고, trino가 좋은 선택이에요.

    helm repo add trino https://trinodb.github.io/charts
    
  3. Helm 차트를 사용해 Kubernetes 클러스터에 Trino를 설치해요. 모든 기본값을 사용하고 example-trino-cluster라는 클러스터를 만들려면 install 명령부터 실행해요.

    helm install example-trino-cluster trino/trino
    

    이 명령은 헬름 템플릿에 프로퍼티를 삽입해 Kubernetes 설정 파일을 생성해요. Helm 차트에는 YAML 파일로 덮어쓸 수 있는 기본값들이 포함돼 있어요.

  4. (선택) 기본값을 덮어쓰려면 배포의 파라미터를 정의하는 나만의 YAML 설정을 만들어요. example.yaml을 사용해 install 명령을 실행하려면 install 명령에 -f 파라미터를 추가해요. 설정 파일의 모범 사례와 명명 규칙을 따르는 것이 좋아요.

    helm install -f example.yaml example-trino-cluster trino/trino
    

    다음과 같은 출력이 보여야 해요.

    NAME: example-trino-cluster
    LAST DEPLOYED: Tue Sep 13 14:12:09 2022
    NAMESPACE: default
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    NOTES:
    Get the application URL by running these commands:
      export POD_NAME=$(kubectl get pods --namespace default --selector "app.kubernetes.io/name=trino,app.kubernetes.io/instance=example-trino-cluster,app.kubernetes.io/component=coordinator" --output name)
      echo "Visit http://127.0.0.1:8080 to use your application"
      kubectl port-forward $POD_NAME 8080:8080
    

    이 출력은 설정과 클러스터 이름에 따라 달라져요. 예를 들어 포트 8080example.yaml.service.port가 정해요.

  5. 모든 pod, deployment, service가 제대로 실행되는지 확인하려면 다음 명령을 실행해요.

    kubectl get all
    

    실행 중인 pod, deployment, replica set을 보여 주는 출력을 기대할 수 있어요. 모든 pod가 READY 컬럼에서 ready 상태를 반환하는 것이 정상 동작의 좋은 지표예요.

    NAME                                               READY   STATUS    RESTARTS   AGE
    pod/example-trino-cluster-coordinator-bfb74c98d-rnrxd   1/1     Running   0          161m
    pod/example-trino-cluster-worker-76f6bf54d6-hvl8n       1/1     Running   0          161m
    pod/example-trino-cluster-worker-76f6bf54d6-tcqgb       1/1     Running   0          161m
    
    NAME                       TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
    service/example-trino-cluster   ClusterIP   10.96.25.35   <none>        8080/TCP   161m
    
    NAME                                           READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/example-trino-cluster-coordinator   1/1     1            1           161m
    deployment.apps/example-trino-cluster-worker        2/2     2            2           161m
    
    NAME                                                     DESIRED   CURRENT   READY   AGE
    replicaset.apps/example-trino-cluster-coordinator-bfb74c98d   1         1         1       161m
    replicaset.apps/example-trino-cluster-worker-76f6bf54d6       2         2         2       161m
    

    이 출력은 실제 Trino 컨테이너를 포함한 실행 중인 pod들을 보여 줘요. 이 출력을 더 잘 이해하려면 kubectl get 명령 레퍼런스와 예시, Kubernetes 디버깅 문서를 참고하세요.

    모든 pod, deployment, replica set이 실행되고 ready 상태라면 Trino가 성공적으로 배포된 거예요.

📌 참고: 작은 pod를 여러 개 두는 게 더 좋은 일부 Kubernetes 애플리케이션과 달리, Trino는 각각 더 많은 자원을 가진 더 적은 pod가 가장 잘 동작해요. 단일 물리 호스트에 여러 Trino pod를 두어 자원 경쟁이 생기지 않도록 하는 것을 강력히 권장해요.

쿼리 실행 (Executing queries)

Trino 컨테이너를 실행하는 pod들은 모두 Kubernetes 내부의 사설 네트워크에서 돌아요. 특히 코디네이터에 접근하려면 코디네이터 pod와 컴퓨터 사이에 터널을 만들어야 해요. 설living할 때 생성된 명령으로 이 작업을 할 수 있어요.

  1. 클라이언트에서 코디네이터 서비스로의 터널을 만들어요.

    kubectl port-forward svc/trino 8080:8080
    

    이제 http://localhost:8080에서 Trino 코디네이터에 연결할 수 있어요.

  2. Trino에 연결하려면 커맨드라인 인터페이스, JDBC 클라이언트, 또는 다른 클라이언트 중 하나를 사용할 수 있어요. 이 예시에서는 커맨드라인 인터페이스를 설치해 새 콘솔 세션에서 Trino에 연결해요.

    trino --server http://localhost:8080
    
  3. tpch 카탈로그의 샘플 데이터를 사용해 tiny 스키마의 nation 테이블에 쿼리를 입력하고 실행해요.

    trino> select count(*) from tpch.tiny.nation;
     _col0
    -------
      25
    (1 row)
    
    Query 20181105_001601_00002_e6r6y, FINISHED, 1 node
    Splits: 21 total, 21 done (100.00%)
    0:06 [25 rows, 0B] [4 rows/s, 0B/s]
    

    다른 SQL 쿼리로 데이터셋을 탐색하고 클러스터를 테스트해 보세요.

  4. 탐색을 마치면 CLI에 quit 명령을 입력해요.

  5. 코디네이터 pod로의 터널을 종료해요. 이 터널은 kubectl 프로세스가 실행되는 동안에만 유효하므로, 포트를 포워딩하는 kubectl 프로세스를 종료하면 돼요. 대부분 CTRL + C를 누르면 엔 돼요.

구성 (Configuration)

Helm 차트는 Trino 컨테이너 이미지를 사용해요. Docker 이미지에는 시작할 수 있는 기본 설정과 Trino를 탐색할 수 있는 몇몇 카탈로그가 이미 포함돼 있어요. Kubernetes는 YAML 파일에 설정을 제공해 기존 배포를 흉내 낼 수 있게 해줘요. 값을 바꾸기 전에 Trino 설정, JVM, 다양한 카탈로그 프로퍼티 같은 파일들이 Trino에서 어떻게 구성되는지 이해하는 게 중요해요.

나만의 YAML 설정 만들기 (Creating your own YAML configuration)

자체 YAML Kubernetes 설정을 사용하면 지정한 값만 덮어써요. 나머지 프로퍼티는 기본값을 사용해요. 다음 설정으로 example.yaml을 추가해요.

image:
  tag: "483"
server:
  workers: 3
coordinator:
  jvm:
    maxHeapSize: "8G"
worker:
  jvm:
    maxHeapSize: "8G"

이 값들은 기본값보다 커서 Trino가 더 많은 메모리를 쓰고 더 까다로운 쿼리를 실행하게 해줘요. 값이 너무 높으면 이 클러스터에 배포된 다른 애플리케이션과 클러스터 노드 크기에 따라 Kubernetes가 일부 Trino pod를 스케줄하지 못할 수 있어요.

  • .image.tag는 현재 버전인 483으로 설정돼요. 특정 Trino 버전을 사용해야 할 때 이 값을 설정해요. 기본값은 latest인데, 권장되지 않아요. latest를 쓰면 각 릴리스와 그 다음 Kubernetes 배포 때마다 새 버전의 Trino가 배포되거든요.
  • .server.workers3으로 설정돼요. 워커 수를 정하는 값으로, 이 경우 코디네이터 한 대와 워커 3대가 배포돼요.
  • .coordinator.jvm.maxHeapSize8GB로 설정돼요. 코디네이터 JVM의 최대 힙 크기를 정해요. JVM 설정 문서를 참고하세요.
  • .worker.jvm.maxHeapSize8GB로 설정돼요. 워커 JVM의 최대 힙 크기를 정해요. JVM 설정 문서를 참고하세요.

⚠️ 경고: 일부 메모리 설정은 주의해서 튜닝해야 해요. 최대 힙 크기 범위를 벗어난 값을 설정하면 Trino 시작이 실패할 수 있거든요. Resource management properties 문서의 경고를 참고하세요. Helm 차트에서 덮어쓸 수 있는 전체 프로퍼티 목록도 참조하세요.

📌 참고: 이 문서에서는 example.yaml이라는 이름으로 Kubernetes 설정 파일을 가리키지만, 관리하는 클러스터와 배포에 대해 명확한 명명 지침을 쓰는 것이 좋아요. 예를 들어 cluster-example-trino-etl.yamlexample Kubernetes 클러스터에 배포된, 주로 extract-transform-load 쿼리를 위한 클러스터의 Trino 배포를 가리킬 수 있어요. Kubernetes 배포 구성 팁은 Configuration Best Practices 문서를 참고하세요.

카탈로그 추가 (Adding catalogs)

일반적인 사용 사례는 커스텀 카탈로그를 추가하는 거예요. example.yaml 파일의 catalogs 프로퍼티에 값을 추가하면 돼요.

catalogs:
  lakehouse: |-
    connector.name=iceberg
    hive.metastore.uri=thrift://example.net:9083
  rdbms: |-
    connector.name=postgresql
    connection-url=jdbc:postgresql://example.net:5432/database
    connection-user=root
    connection-password=secret
  tpch: |-
    connector.name=tpch
    tpch.splits-per-node=4

이렇게 하면 lakehouserdbms 카탈로그가 Kubernetes 배포 구성에 추가돼요.

kind로 로컬 Kubernetes 클러스터 실행 (Running a local Kubernetes cluster with kind)

로컬 배포에는 kind(Kubernetes in Docker)를 사용할 수 있어요. 다음 단계로 시스템에서 kind를 실행해 봐요.

  1. kind는 Docker 위에서 돌아요. 먼저 Docker가 설치되어 있는지 확인해요.

    docker --version
    

    이 명령이 실패하면 Docker 설치 지침을 따라 Docker를 설치해요.

  2. kind 설치 지침을 따라 kind를 설치해요.

  3. kind에서 Kubernetes 클러스터를 실행해요.

    kind create cluster --name trino
    

    📌 참고: name 파라미터는 선택이지만, 이후 명령에서 네임스페이스가 어떻게 적용되는지 보여 주는 데 쓰여요. 파라미터를 추가하지 않으면 클러스터 이름은 기본적으로 kind가 돼요. 이 클러스터의 애플리케이션이 분명해지도록 trino를 사용하세요.

  4. kubectl이 올바른 Kubernetes 클러스터에서 실행되는지 확인해요.

    kubectl cluster-info --context kind-trino
    

    ~/.kube/config에 이미 여러 Kubernetes 클러스터가 구성되어 있다면, 로컬 kind 클러스터에서 작업하려면 kubectl 명령에 context 파라미터를 넘겨야 해요. 이 파라미터를 주지 않으면 kubectl은 기본 context를 사용해요. context는 클러스터 이름에 kind- 접두사가 붙은 이름이란 점을 기억하세요. 이제 kind 클러스터에서 실행 중인 모든 Kubernetes 객체를 볼 수 있어요.

  5. "Running Trino using Helm" 단계를 따라 Trino를 설정해요. kubectl get all 명령을 실행할 때 context 파라미터를 추가해요.

    kubectl get all --context kind-trino
    
  6. "Executing queries" 단계를 따라 몇몇 쿼리를 실행해요.

  7. kind로 작업을 마치면 클러스터를 삭제할 수 있어요.

    kind delete cluster -n trino
    

정리 (Cleaning up)

Kubernetes 클러스터에서 Trino를 제거하려면 다음 명령을 실행해요.

helm uninstall my-trino-cluster

다음과 같은 출력이 보여야 해요.

release "my-trino-cluster" uninstalled

제대로 됐는지 확인하려면 다음 kubectl 명령으로 Trino 클러스터와 관련된 Kubernetes 객체가 남아 있지 않은지 확인해요.

kubectl get all

더 알아보기 (Learn more)

Kubernetes에서 Trino를 운영하는 방법을 배웠어요. 이어서 Trino의 확장 구조를 다루는 플러그인(Plugins)을 살펴보면 좋아요.