跳转至

0. 前提条件

在开始之前,请确保您的本地环境满足以下要求:

  • 操作系统(OS): Windows、GNU/Linux 或 macOS
  • 处理器架构: macOS 版本支持 x86_64arm64WindowsGNU/Linux 版本目前仅支持 x86_64
  • 云服务: 拥有一个带有有效访问密钥(Access Key)和秘密访问密钥(Access Secret Key)的 AWS 账户。该账户应具有管理员权限。最低权限必须涵盖对各种资源类型的完全访问权限,例如:VPC、EC2、EBS、Eventbridge、Cloudwatch、IAM。为确保 ScaleX 正常运行,我们强烈建议使用管理员账户。

1. 架构

1.1 高级架构

Local CLI --- AWS APIs (EC2, VPC, S3, IAM, Lambda ...)

1.2 详细架构

CLI-+---Cluster-1---+--VPC---------------------------------------+
    |               |  +-Pubnet---+   +-Subnet-1--------------+  | 
    |               |  | nat      |   | workers in groups     |  |
    |               |  | master   |   | route to nat          |  |
    |               |  +----------+   +-----------------------+  |
    |               |                 +-Subnet-2--------------+  |
    |               |                 | workers in groups     |  |
    |               |                 | route to nat          |  |
    |               |                 +-----------------------+  |
    |               |                 ...                        |
    |               +--------------------------------------------+
    |               +-Events----+---->+-Lambdas----+----+-Bucket-+
    |               | rules     |---->| delete     |    | info   |
    |               | schedules |---->| replace    |    | logs   |
    |               +-----------+---->+------------+    +--------+
    |
    +---Cluster-2---+---Stack-2
    |
    +---...
    |
    +---Cluster-N---+---Stack-N

2. 使用说明

2.1 安装

从以下链接下载软件压缩包:

将压缩包解压到本地目录。本地目录结构如下:

ROOT_DIR/
        +---cloud_functions/    *不要修改
        +---cluster_scripts/    *不要修改
        +---examples/           *不要修改
        +---README.md           *本文件
        +---cluster_config.json *可修改:集群配置
        +---scalex              *可执行文件:主程序

ROOT_DIR/scalex(在 POSIX 系统上)或 ROOT_DIR\scalex.exe(在 Windows 上)是主程序。

2.2 配置

如上所述,ScaleX 需要您的 AWS 凭证(access_key_id 和 secret_access_key)才能运行。

重要提示:

  • ScaleX 不会将除了云 API 请求之外的任何信息(如凭证)从您的本地环境传输出去。config 命令仅读取您的凭证并将其存储到 $HOME/.aws/config。请在本地机器上妥善保护您的凭证。
  • ScaleX 不会覆盖您当前的 AWS 配置。相反,它会将一个名为 scalex 的配置文件追加到您的本地 AWS 配置中。

打开终端(在 POSIX 系统上)或命令提示符窗口(在 Windows 上)。

切换到 ScaleX 的 ROOT_DIR。假设 ROOT_DIR/home/my/scalex_root

运行以下命令:

  • my@ubuntu:~$ cd /home/my/scalex_root
  • my@ubuntu:~/scalex_root$ ./scalex config --ak your_access_key --sk your_secret_key

如果一切顺利,您的本地 AWS 配置文件将被更新。控制台输出类似于:

Scalex (Scale-X): Scale Your Cloud and Save Your Cost. [Version: 0.0.1]
Updated the config profile [profile scalex] to: /home/my/.aws/config.

请保持终端或 CMD 窗口打开以进行下一步操作。

2.3 运行

ScaleX 提供了一个带有多个命令和相应选项的命令行界面。详情如下:

用法:./scalex 命令 参数 ...

命令         参数
config  配置云凭证。
                --ak 'your_access_key'
                --sk 'your_access_secret'
                --force
create  创建一个 Kubernetes 集群。
                --config /your/config/file.json
                --functions-root /your/functions/root/path
                --scripts-root /your/scripts/root/path
delete  删除一个 Kubernetes 集群。
                --stack-id stack_id_string
                --region region_name
                --stack-data /your/stack/data/file.json
                --delete-logs
list    列出您的集群(堆栈)或集群中的组。
                --type clusters | groups
                --regions region_name_a,region_name_b 或 --regions all
                --groups group_name_a,group_name_b 或 --groups all
status  获取集群的状态。
                --stack-id stack_id_string
                --region region_name
                --stack-data /your/stack/data/file.json
                --summary
start   启动集群中的节点。
                --all/--groups all
                --groups group_name_a,group_name_b
                --stack-id stack_id_string
                --region region_name
                --stack-data /your/stack/data/file.json
stop    停止集群中的节点。
                --all
                --groups all 或 --groups group_name_a,group_name_b
                --stack-id stack_id_string
                --region region_name
                --stack-data /your/stack/data/file.json

3. 教程

3.1 概念:

  • 堆栈/集群: 由 ScaleX 在您的 AWS 账户上管理的 Kubernetes 集群。
  • *每个堆栈/集群都有一个唯一的堆栈 ID。
  • 工作节点组: 具有相同规格和实例类型的工作节点组。
  • *在堆栈/集群中,每个工作节点组都有一个唯一的名称。
  • 工作节点: 集群中作为 Kubernetes 工作节点运行的实例。有几种类型:
  • fixed_od: 一个在堆栈生命周期内不会切换到竞价实例的按需实例。
  • od: 一个动态的按需实例,可能会被 ScaleX 自动切换到竞价实例。
  • spot: 一个可能会被中断的竞价实例。ScaleX 会自动处理中断。
  • nat: 堆栈中为私有子网提供互联网访问的实例。
  • 主节点: Kubernetes 堆栈中运行控制平面的实例。
  • 自动扩展: 应用于工作节点组的功能,可根据工作负载扩展或缩减节点数量。有几种选项:
  • full: 组可以扩展(添加节点)或缩减(删除节点)。
  • up: 组只允许扩展(添加节点)。
  • down: 组只允许缩减(删除节点)。
  • off: 关闭自动扩展。
  • schedule_priority: 当竞价实例失败时,'region' 优先级会更频繁地触发跨可用区迁移,而 'az' 优先级会更频繁地触发竞价实例到按需实例的切换。

3.2 创建您的第一个堆栈

3.2.1 准备 SSH 密钥对

我们建议使用 OpenSSH 工具来生成 SSH 密钥对。通常,OpenSSH 已预装在您的操作系统中(Windows、macOS 或 GNU/Linux)。

  • 打开终端(在 POSIX 系统上)或命令提示符窗口(在 Windows 上)。
  • 输入命令:ssh-keygen -t ed25519 -N '' -f ./scalex_ssh_ed25519 -q。此命令仅供参考,您可以根据需要调整。
  • -t: 密钥对的类型(算法)。您可以指定 -t rsa 或 -t ed25519。
  • -N: 指定一个密码短语,通常留空即可。
  • -f: 密钥对输出的路径。
  • 将生成两个文件。如果您使用上面的示例命令,它们将位于您的当前路径中:
  • scalex_ssh_ed25519: 私钥。请务必谨慎管理此密钥,切勿将其传输给任何不可信的第三方。
  • scalex_ssh_ed25519.pub: 公钥,稍后您可以将它注入到您的集群中。
  • 更改您的私钥的权限。SSH 要求权限模式为 600。
  • 在 Windows 上:右键单击私钥文件 -> 属性 -> 安全 -> 从权限列表中移除其他用户。
  • 在 POSIX 系统(GNU/Linux 或 macOS)上:chmod 600 ./scalex_ssh_ed25519。

完成上述步骤后,您的 SSH 密钥对应该就可以使用了。

3.2.2 定义并创建堆栈

每个堆栈/集群都由一个 JSON 格式的文件预定义。请参考示例 cluster_config.json

{
    "region": "us-east-2",          # 一个有效的 AWS 区域名称
    "cpu_arch": "x86_64",           # 管理节点的 CPU 架构
    "ha_flag": "False",             # 是否启用控制节点高可用性(待开发)
    "nfs_init_gb": 100,             # 集群 NFS 共享的初始大小(自动扩展正在开发中)
    "master_ssh_public_key": {      # 注入到控制节点以进行 SSH 连接的公共 SSH 密钥
        "type": "file",
        "content": "./id_rsa.pub"
    },
    "worker_groups": [              # 工作节点组,是一个列表[字典]
        {
            "group_name": "a10_group",  # 组的唯一名称
            "instance_type": "",        # 可选:精确的实例类型,如果指定了实例类型,
                                        # 则下面的 vcpu 等实例参数将被忽略
            "schedule_priority": "",    # AZ 优先级或区域优先级(默认)
            "cpu_arch": "x86_64",       # 工作节点的 CPU 架构
            "cpu_providers": [],        # CPU 提供商,默认为英特尔
            "vcpu_range": {             
                "start": 1,
                "end": 16
            },
            "mem_range": {              # 单位:GiB
                "start": 32,
                "end": 10000
            },
            "mem_per_cpu_range": {      # 单位:GiB
                "start": 0,
                "end": 1000000
            },
            "acc_names": ["a10g"],      # 加速器(GPU)名称
            "acc_count_range": {        # 每个节点的加速器(GPU)数量
                "start": 1,
                "end": 1
            },
            "total_workers": 1,         # 初始总工作节点数
            "od_workers": 1,            # 初始按需工作节点数
            "fixed_workers": 0,         # 固定按需工作节点数
            "os_disk_gb": 16,           # 操作系统卷/磁盘大小
            "container_disk_gb": 100,   # 容器卷/磁盘大小
            "autoscaling_experimental": "full"  # 自动扩展策略
        },
        {
            "group_name": "cpu_group",
            "instance_type": "",
            "schedule_priority": "",
            "cpu_arch": "x86_64",
            "cpu_providers": ["amd"],
            "vcpu_range": {
                "start": 4,
                "end": 4
            },
            "mem_range": {
                "start": 0,
                "end": 10000
            },
            "mem_per_cpu_range": {
                "start": 2,
                "end": 2
            },
            "acc_names": [], 
            "acc_count_range": {
                "start": 1,
                "end": 1
            },
            "total_workers": 1,
            "od_workers": 1,
            "fixed_workers": 0,
            "os_disk_gb": 16,
            "container_disk_gb": 100,
            "autoscaling_experimental": "full"
        }
    ]
}

使用上述 JSON 文件(假设其路径为 /home/my/cluster_config.json),您可以运行以下命令:

./scalex create --config /home/my/cluster_config.json

如果一切顺利,将生成一个初始堆栈。控制台输出类似于:

Checking the ingested request attributes ...
The format of configs is checked and good to go.
Checking the contents of the configs.
Worker group: a10_group will use instance type: g5.xlarge.
Worker group: cpu_group will use instance type: c5a.xlarge.
[*] scalex (scale-x) kubernetes stack started creating ...
Stack id: k8s-lml6uq7wbk5e
...
...
...
Worker group: cpu_group provision summary: spot: 1 | od: 1 | total: 2
Worker group: cpu_group: All planned 2 node(s) provisioned.

Scalex k8s stack summary:
...

Please connect to the cluster: ssh ubuntu@XXX.XXX.XXX.XXX -i /your/private/key
[*] The IP address above is *elastic* and will keep unchanged during the lifecycle of this cluster.
Saved the stack to 'k8s-lml6uq7wbk5e.json'.

3.3 部署您的第一个 AI 模型

注意:在本演示中,我们使用 huggingface 获取演示模型:DeepSeek-R1-Distill-Qwen-7B。如您希望继续按照本教程完成下列步骤,清注册 huggingface 账号并获取一个有效的 Token。

步骤 1:连接到您的集群

使用您的私钥登录到您的集群(公共密钥已注入到主节点,并且 IP 地址已回显):

ssh ubuntu@10.10.10.10 -i /my/private/key

请将示例 IP 地址和示例私钥路径更改为实际值。

步骤 2:创建用户命名空间

接下来,您可以创建一个命名空间:

kubectl create namespace deepseek

步骤 3:导入 Huggingface 令牌

将 huggingface 令牌导入到命名空间 deepseek:

kubectl create secret generic huggingface-token --from-literal=HF_TOKEN=hf_xxx.... -n deepseek

请将示例令牌字符串 hf_xxx.... 更改为实际有效的令牌

步骤 4:部署模型

接下来,请在主节点上创建一个 YAML 文件(deepseek.yaml)以部署 DeepSeek-R1-Distill-Qwen-7B。此 YAML 模板将在您的集群中创建一个 3 个副本的部署。

apiVersion: apps/v1  
kind: Deployment  
metadata:  
  name: deepseek-deployment  
  namespace: deepseek  
  labels:  
    app: deepseek  
spec:  
  replicas: 3 
  selector:  
    matchLabels:  
      app: deepseek  
  template:  
    metadata:  
      labels:  
        app: deepseek  
    spec:  
      tolerations:  
        - key: "nvidia.com/gpu"  
          operator: "Exists"  
          effect: "NoSchedule"  
      volumes:  
      - name: cache-volume  
        hostPath:  
          path: /tmp/deepseek  
          type: DirectoryOrCreate  
      - name: shm  
        emptyDir:  
          medium: Memory  
          sizeLimit: "2Gi"  
      containers:  
      - name: deepseek  
        image: vllm/vllm-openai:latest  
        command: ["/bin/sh", "-c"]  
        args: [  
          "vllm serve deepseek-ai/DeepSeek-R1-Distill-Qwen-7B  --trust-remote-code --max_model_len 2048"  
        ]  
        env: 
        - name: HUGGING_FACE_HUB_TOKEN
          valueFrom:
            secretKeyRef:
              name: huggingface-token
              key: HF_TOKEN
        ports:  
        - containerPort: 8000  
        resources:  
          requests:  
            nvidia.com/gpu: "1"  
          limits:  
            nvidia.com/gpu: "1"  
        volumeMounts:  
        - mountPath: /root/.cache/huggingface  
          name: cache-volume  
        - name: shm  
          mountPath: /dev/shm  
---  
apiVersion: v1  
kind: Service  
metadata:  
  name: deepseek-svc  
  namespace: deepseek  
spec:  
  ports:  
  - name: http  
    port: 80  
    protocol: TCP  
    targetPort: 8000
  selector:  
    app: deepseek  
  type: ClusterIP

请根据您的实际堆栈配置调整内容。

接下来,请运行 kubectl apply -f deepseek.yaml。Pod 将被调度到工作节点上。

3.4 自动化管理

ScaleX 集群是完全动态和完全托管的。这意味着,您无需在以下情况下管理资源:

  • 竞价实例在任何时候被中断
  • 竞价实例可用于替换高价的按需实例
  • 新部署被调度但当前资源不足
  • 部署被删除并使一些工作节点闲置

因此,您可以专注于您的应用程序、部署以及其他工作负载,ScaleX 旨在自动处理所有维护工作。为实现这一目标,ScaleX 在您的堆栈下运行多个低成本的 AWS 服务,它们是:

  • Lambda 函数
  • AWS EventBridge 规则
  • CloudWatch 日志
  • AWS EventBridge 调度
  • S3 存储桶

请注意,这些服务可能会产生额外的少量费用。有关计费和费用的详细信息,请参阅 AWS 官方网站

4. 错误报告、问题和故障排除

请通过以下方式向我们报告问题:

  • 电子邮件:wangzr@cloudsway.com
  • 技术支持组