banner
Bathe

Bathe

在 Kubernetes 中啟用 Ray 的多租戶和自動擴展

背景#

Ray 是一個統一的框架,能夠實現分散式計算,因為單一伺服器可能無法處理繁重的計算任務。在本文中,我們對 Ray 的兩個重要特性進行深入分析,即多租戶和自動擴展。多租戶允許將不同的資源(如 CPU 和內存)分配給不同的用戶。另一方面,自動擴展根據流量和利用率水平促進實例的增加或移除。

選擇 Kubernetes 的原因#

雖然 Ray 提供了一個官方的自動擴展解決方案,根據資源請求來擴展 Ray 集群,但我們的特定場景需要根據內存使用情況進行自動擴展。因此,我們開發了兩個潛在的解決方案。第一個解決方案涉及利用 Ray 資源監控器來監控每個任務和演員的資源使用情況。考慮到我們已經為每個用戶分配了不同的配額,有必要累積每個任務和演員的資源使用情況。此外,我們必須建立一個機制,以確定何時根據內存使用情況觸發自動擴展。第二個解決方案涉及利用 Kubernetes 水平 Pod 自動擴展器自動調整副本數量,根據內存使用情況。因此,我們在這裡主要選擇第二個解決方案。

建立 Ray 集群#

假設您已經設置了 Kubernetes 和 Harbor 環境,下一步將是安裝 Ray 集群。需要注意的是,您需要修改映像以匹配您的具體配置。

# Ray 頭節點服務,允許工作者 Pod 發現頭節點以進行雙向通信。
# 更多上下文可以在 [端口配置文檔](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 目前只支持每個集群一個頭節點。
  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 分配共享內存以用於其 plasma 對象存儲。如果您不提供此項,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 分配共享內存以用於其 plasma 對象存儲。如果您不提供此項,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 和內存的限制相等。
              # 在此示例中,我們使用 500m CPU 請求以適應資源受限的本地 Kubernetes 測試環境,例如 KinD 和 minikube。
              cpu: "500m"
              # Ray 頭節點的剩餘狀態內存使用量約為 1Gb。我們不建議為 Ray 頭 Pod 分配少於 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 分配共享內存以用於其 plasma 對象存儲。如果您不提供此項,Ray 將回退到 /tmp,這會導致速度變慢,如果它不是共享內存卷。
          # volumeMounts:
          #   - mountPath: /dev/shm
          #     name: dshm
          env:
            # 這在 ray start 命令中使用,以便 Ray 可以生成正確數量的進程。省略此項可能會導致性能下降。
            - name: MY_CPU_REQUEST
              valueFrom:
                resourceFieldRef:
                  resource: requests.cpu
            # 此配置中的資源請求和限制對於生產來說太小了!
            # 使用幾個大型 Ray Pod 比使用許多小型 Pod 更好。
            # 對於生產,理想情況下是將每個 Ray Pod 的大小設置為佔用其調度的整個 Kubernetes 節點。
          resources:
            limits:
              cpu: "1"
              memory: "1G"
              # 對於生產用例,我們建議指定整數 CPU 請求和限制。
              # 我們還建議將請求設置為 CPU 和內存的限制相等。
              # 在此示例中,我們使用 500m CPU 請求以適應資源受限的本地 Kubernetes 測試環境,例如 KinD 和 minikube。
            requests:
              cpu: "500m"
              memory: "1G"

一旦您在伺服器上創建了 ray-dev.yaml 文件,您可以繼續安裝 Ray 頭和工作者。如果您想在 ns 命名空間中安裝 Ray 集群,可以通過執行以下命令來實現:

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

在伺服器上創建 ray-dev.yaml 文件並安裝 Ray 頭和工作者後,下一步是為工作者啟用水平 Pod 自動擴展(HPA)。

要為工作者啟用 HPA,您需要在伺服器上創建另一個名為 ray-autoscaler.yaml 的文件。該文件將包含 Kubernetes HPA 對象的配置,該對象將根據 CPU 利用率自動調整工作 Pod 的數量。以下是 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%。

要在 ns 命名空間中應用此 HPA,請執行以下命令:

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

監控和可觀察性#

下一步是啟用 集群監控。Ray 在頭節點上自動生成一個名為 prom_metrics_service_discovery.json 的 Prometheus 服務發現文件,這有助於指標代理的服務發現。要使用默認的 Kubernetes Prometheus 為您的 Ray 集群啟用監控,您需要將此文件映射出來並將其添加到 Prometheus 配置中。

我們可以更新 ray-dev.yaml 配置文件,以使用持久卷聲明(PVC)來映射 /tmp/ray 目錄(請參閱文檔以獲取更多詳細信息)。這涉及將以下配置添加到 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
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。