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
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。