banner
Bathe

Bathe

KubernetesによるRayのマルチテナンシーとオートスケーリングを有効にする

背景#

Ray は、分散コンピューティングを可能にする統一フレームワークであり、単一のサーバーでは重い計算タスクを処理できない場合があります。この記事では、Ray の 2 つの重要な機能、すなわちマルチテナンシーとオートスケーリングについての詳細な分析を提供します。マルチテナンシーは、異なるユーザーに対して CPU やメモリなどの異なるリソースを割り当てることを可能にします。一方、オートスケーリングは、トラフィックや利用レベルに基づいてインスタンスの追加や削除を容易にします。

Kubernetes を選ぶ理由#

Ray はリソース要求に応じて Ray クラスターをスケールする公式のオートスケーリングソリューションを提供していますが、私たちの特定のシナリオではメモリ使用量に基づくオートスケーリングが必要です。その結果、私たちは 2 つの潜在的なソリューションを開発しました。最初のソリューションは、Ray リソースモニターを利用して各タスクとアクターのリソース使用量を監視することです。各ユーザーに異なるクォータを割り当てているため、各タスクとアクターのリソース使用量を集計する必要があります。さらに、メモリ使用量に基づいてオートスケーリングをトリガーするタイミングを決定するメカニズムを確立しなければなりません。2 番目のソリューションは、Kubernetes Horizontal Pod Autoscaler を利用してメモリ使用量に基づいてレプリカの数を自動的に調整することです。したがって、ここでは主に 2 番目のソリューションを選択します。

Ray クラスターの構築#

Kubernetes と Harbor 環境を既に設定していると仮定すると、次のステップは Ray クラスターをインストールすることです。特定の構成に合わせてイメージを変更する必要があることに注意してください。

# Rayヘッドノードサービス、ワーカーポッドがヘッドノードを発見して双方向通信を行うことを許可します。
# 詳細なコンテキストは[ポート構成ドキュメント](https://docs.ray.io/en/latest/ray-core/configure.html#ports-configurations)で確認できます。
apiVersion: v1
kind: Service
metadata:
  name: service-ray-cluster
  labels:
    app: ray-cluster-head
spec:
  clusterIP: None
  ports:
  - name: client
    protocol: TCP
    port: 10001
    targetPort: 10001
  - name: dashboard
    protocol: TCP
    port: 8265
    targetPort: 8265
  - name: gcs-server
    protocol: TCP
    port: 6380
    targetPort: 6380
  selector:
    app: ray-cluster-head
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-ray-head
  labels:
    app: ray-cluster-head
spec:
  # これを変更しないでください - Rayは現在、クラスターごとに1つのヘッドノードのみをサポートしています。
  replicas: 1
  selector:
    matchLabels:
      component: ray-head
      type: ray
      app: ray-cluster-head
  template:
    metadata:
      labels:
        component: ray-head
        type: ray
        app: ray-cluster-head
    spec:
      # ヘッドノードがダウンすると、クラスター全体(すべてのワーカーノードを含む)もダウンします。
      # この場合、Kubernetesが新しいヘッドノードを立ち上げるようにしたい場合は、これを「Always」に設定し、そうでない場合は「Never」に設定します。
      restartPolicy: Always

      # このボリュームは、Rayがそのプラズマオブジェクトストアに使用するための共有メモリを割り当てます。
      # これを提供しない場合、Rayは/tmpにフォールバックし、共有メモリボリュームでない場合は遅延が発生します。
      # volumes:
      # - name: dshm
        # emptyDir:
        #   medium: Memory
      containers:
        - name: ray-head
          image: rayproject/ray:2.3.0
          imagePullPolicy: Always
          command: [ "/bin/bash", "-c", "--" ]
          # Redisにパスワードがない場合は、--redis-password=''を設定します
          args:
            - "ray start --head --port=6380 --num-cpus=$MY_CPU_REQUEST --dashboard-host=0.0.0.0 --object-manager-port=8076 --node-manager-port=8077 --dashboard-agent-grpc-port=8078 --dashboard-agent-listen-port=52365 --redis-password='123456' --block"
          ports:
            - containerPort: 6380 # GCSサーバー
            - containerPort: 10001 # Rayクライアントによって使用される
            - containerPort: 8265 # Rayダッシュボードによって使用される
          # このボリュームは、Rayがそのプラズマオブジェクトストアに使用するための共有メモリを割り当てます。
          # これを提供しない場合、Rayは/tmpにフォールバックし、共有メモリボリュームでない場合は遅延が発生します。
          # volumeMounts:
          #   - mountPath: /dev/shm
          #     name: dshm
          env:
            # RAY_REDIS_ADDRESSは、Rayが外部Redisを使用して障害耐性を持つことを許可します
            - name: RAY_REDIS_ADDRESS
              value: redis:6379 # 外部RedisのIPアドレス、この例では「redis:6379」
            # これはray startコマンドで使用され、Rayが正しい数のプロセスを生成できるようにします。
            # これを省略すると、パフォーマンスが低下する可能性があります。
            - name: MY_CPU_REQUEST
              valueFrom:
                resourceFieldRef:
                  resource: requests.cpu
          resources:
            limits:
              cpu: "2"
              memory: "5G"
            requests:
              # 生産用途の場合、整数のCPU要求と制限を指定することをお勧めします。
              # また、CPUとメモリの両方の要求を制限と等しく設定することをお勧めします。
              # この例では、KinDやminikubeなどのリソース制約のあるローカルKubernetesテスト環境に対応するために、500mのCPU要求を使用します。
              cpu: "500m"
              # Rayヘッドノードの残りの状態メモリ使用量は約1Gbです。Rayヘッドポッドに2Gb未満のメモリを割り当てることはお勧めしません。
              # 生産用途の場合、各Rayコンテナに少なくとも8Gbのメモリを割り当てることをお勧めします。
              memory: "2G"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-ray-worker
  labels:
    app: ray-cluster-worker
spec:
  # Rayクラスターで開始されるワーカーノードの数をスケールするには、これを変更します。
  selector:
    matchLabels:
      component: ray-worker
      type: ray
      app: ray-cluster-worker
  template:
    metadata:
      labels:
        component: ray-worker
        type: ray
        app: ray-cluster-worker
    spec:
      restartPolicy: Always
      # volumes:
      # - name: dshm
      #   emptyDir:
      #     medium: Memory
      containers:
        - name: ray-worker
          image: rayproject/ray:2.3.0
          imagePullPolicy: Always
          command: ["/bin/bash", "-c", "--"]
          args:
            - "ray start --num-cpus=$MY_CPU_REQUEST --address=service-ray-cluster:6380 --object-manager-port=8076 --node-manager-port=8077 --dashboard-agent-grpc-port=8078 --dashboard-agent-listen-port=52365 --block"

          # このボリュームは、Rayがそのプラズマオブジェクトストアに使用するための共有メモリを割り当てます。
          # これを提供しない場合、Rayは/tmpにフォールバックし、共有メモリボリュームでない場合は遅延が発生します。
          # volumeMounts:
          #   - mountPath: /dev/shm
          #     name: dshm
          env:
            # これはray startコマンドで使用され、Rayが正しい数のプロセスを生成できるようにします。
            # これを省略すると、パフォーマンスが低下する可能性があります。
            - name: MY_CPU_REQUEST
              valueFrom:
                resourceFieldRef:
                  resource: requests.cpu
            # この設定のリソース要求と制限は、生産には小さすぎます!
            # 多くの小さなRayポッドよりも、いくつかの大きなRayポッドを使用する方が良いです。
            # 生産の場合、各RayポッドがスケジュールされたKubernetesノード全体を占有するのが理想的です。
          resources:
            limits:
              cpu: "1"
              memory: "1G"
              # 生産用途の場合、整数のCPU要求と制限を指定することをお勧めします。
              # また、CPUとメモリの両方の要求を制限と等しく設定することをお勧めします。
              # この例では、KinDやminikubeなどのリソース制約のあるローカルKubernetesテスト環境に対応するために、500mのCPU要求を使用します。
            requests:
              cpu: "500m"
              memory: "1G"

サーバー上にray-dev.yamlファイルを作成したら、Ray ヘッドとワーカーをインストールすることができます。ns名前空間に Ray クラスターをインストールしたい場合は、次のコマンドを実行します。

kubectl apply -f ray-dev.yaml -n ns

サーバー上にray-dev.yamlファイルを作成し、Ray ヘッドとワーカーをインストールした後、次のステップはワーカーのために Horizontal Pod Autoscaling(HPA)を有効にすることです。

ワーカーの HPA を有効にするには、サーバー上にray-autoscaler.yamlという別のファイルを作成する必要があります。このファイルには、CPU 利用率に基づいてワーカーポッドの数を自動的にスケールする Kubernetes HPA オブジェクトの設定が含まれます。以下はray-autoscaler.yamlファイルの例です。

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: ray-autoscaler
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: deployment-ray-worker
  minReplicas: 1
  maxReplicas: 2
  targetCPUUtilizationPercentage: 60

この HPA は、指定されたデプロイメントのレプリカ数を CPU 利用率に基づいて自動的に調整し、最小 1 レプリカ、最大 2 レプリカで、CPU 利用率 60% を目指します。

この HPA をns名前空間に適用するには、次のコマンドを実行します。

kubectl apply -f ray-autoscaler.yaml -n ns

監視と可視性#

次のステップは、クラスター監視を有効にすることです。Ray は、メトリクスエージェントのサービスディスカバリーを容易にするために、ヘッドノード上にprom_metrics_service_discovery.jsonという Prometheus サービスディスカバリーファイルを自動生成します。Kubernetes のデフォルトの Prometheus を使用して Ray クラスターの監視を有効にするには、このファイルをマッピングし、Prometheus の設定に追加する必要があります。

ray-dev.yaml設定ファイルを更新して、/tmp/rayディレクトリをマッピングするために永続ボリュームクレーム(PVC)を使用するようにします(詳細についてはドキュメントを参照してください)。これには、YAML ファイルにvolumesvolumeMountsの設定を追加する必要があります。最後に、この PVC を Prometheus インスタンスに関連付けることができます。

spec:
  volumes:
    - name: ray-prom
      persistentVolumeClaim:
        claimName: ray-prom-pvc
  containers:
    - name: ray-head
      volumeMounts:
        - name: ray-prom
          mountPath: /tmp/ray
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。