Amazon EKS+Kubeflow+Karpenter 助力构建弹性机器学习平台

93c3ecf87f9db79c2ad2e444dc98cbb1.jpeg

3c29b40c3f5471a7887f19a03def3810.gif

点击上方入口立即【自由构建 探索无限】

一起共赴年度科技盛宴!

前言

随着机器学习的不断发展和在各个行业的使用,很多企业已经从最初关注构建模型、算法选择到了现在如何构建自己的机器学习平台,在该平台上实现从数据处理、模型训练、模型部署和 CI/CD。现在机器学习平台有很多,比较受欢迎的机器学习平台有亚马逊云科技的托管服务 SageMaker 和开源的 Kubeflow, MLflow 等。本文结合用户的场景,使用 Kubeflow 构建一个弹性可灵活扩展的机器学习平台。

Kubeflow (https://www.kubeflow.org) 是 Kubernetes 的机器学习工具包,目标是利用 Kubernetes 的优点,尽可能简单地扩展机器学习 (ML) 模型并将它们部署到生产环境。在 Kubernetes 部署选择上,我们根据用户的使用情况选择了 Amazon Elastic Kubernetes Service

(https://aws.amazon.com/cn/eks/?nc1=h_ls) (Amazon EKS) ,它是一项托管容器服务,可以在云中和本地运行和扩展 Kubernetes 应用程序。最后我们会选择三剑客中的第三项,Karpenter, Karpenter (https://karpenter.sh) 是使用亚马逊云科技构建的开源、灵活、高性能的 Kubernetes 集群自动扩缩程序。它通过快速启动适当规模的计算资源来响应不断变化的应用程序负载,从而帮助提高应用程序可用性和集群效率。Karpenter 特别适合该用户在机器学习中对于成本优化的需求,在无需配置任何 GPU 节点组情况下,快速的获得 GPU 资源进行模型训练和在训练结束后快速释放 GPU 资源。本方案中,我们会专注于使用这三个服务,构建弹性的机器学习平台。

本方案部署在北京区域进行,本文通过四个部分总结如何在中国区搭建 Kubeflow 1.5.1并利用 Karpenter 进行动态的 GPU 资源的扩展满足 Kubeflow ML 训练的需求。

  • 准备环境

  • 部署 Kubeflow

  • 验证 Kubeflow 的安装,包含实验

  • 利用 Karpenter 进行动态的资源扩展满足 Kubeflow ML 训练的需求

需要的服务和架构如下图:

028e3566db0f2d13c6daf87bd444e9ef.png

准备环境

准备环境主要分为四部分:

  • 安装必要的工具

  • 创建 EKS 集群

  • 下载源码

  • 配置 image 拉取工具

安装必要的工具

在正式安装 Kubeflow 前,需要准备一些必要的工具,具体也可参考 Kubeflow on EKS 

(https://awslabs.github.io/kubeflow-manifests/docs/deployment/prerequisites/) 官网。安装时请一定注意工具版本,Python 3.8 和 Kustomize 3.2.0。

  • Amazon CLI

    (https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)

  • eksctl (https://eksctl.io/introduction/#installation)

  • kubectl (https://kubernetes.io/docs/tasks/tools)

  • yq (https://mikefarah.gitbook.io/yq)

  • jq (https://stedolan.github.io/jq/download/)

  • kustomize version 3.2.0

    (https://github.com/kubernetes-sigs/kustomize/releases/tag/v3.2.0)

  • python 3.8+ (https://www.python.org/downloads/)

  • pip (https://pip.pypa.io/en/stable/installation/)

创建 EKS 集群

创建一个新的集群为Kubeflow使用,关于EKS的版本选择,可以参考 Amazon EKS 和 Kubeflow 兼容性 

(https://awslabs.github.io/kubeflow-manifests/docs/about/eks-compatibility/) 网站。

首先设置环境变量,EKS 集群名称和指定北京 Region。

export CLUSTER_NAME=kubeflow151
export CLUSTER_REGION=cn-north-1

创建集群:

eksctl create cluster --name ${CLUSTER_NAME} --version 1.21 --region ${CLUSTER_REGION} --nodegroup-name kf --node-type m5.xlarge --nodes 4 --nodes-min 4 --nodes-max 8 --managed --with-oidc

左滑查看更多

下载源码

此次实验基于1.5.1 进行,下载1.5.1相关的源码:

export KUBEFLOW_RELEASE_VERSION=v1.5.1
export AWS_RELEASE_VERSION=v1.5.1-aws-b1.0.0
git clone https://github.com/awslabs/kubeflow-manifests.git && cd kubeflow-manifests
git checkout ${AWS_RELEASE_VERSION}
git clone --branch ${KUBEFLOW_RELEASE_VERSION} https://github.com/kubeflow/manifests.git upstream

左滑查看更多

配置 image 拉取工具

在安装 Kubeflow 的时候,比较困难的一个问题是 image 的拉取,例如 k8s.gcr.io (https://k8s.gcr.io), gcr.io (http://gcr.io), quay.io (https://quay.io) 等源的 image 拉取。关于这部分,我们在 Amazon API Gateway Mutating Webhook For K8S (https://github.com/aws-samples/amazon-api-gateway-mutating-webhook-for-k8) 基础上做了一些修改,具体可以参考自动化拉取 image 

(https://github.com/walkingerica/automate-pulling-and-mutating-webhook-for-k8),概括来说,原理是在需要 gcr.io 等镜像的时候,该工具自动通过 Amazon Global 区域的 CodeBuild 拉取镜像并添加到中国区的 ECR 中。

部署 KubeFlow

在部署 KubeFlow on EKS 的时候有多种选择,除了原始安装方法外,Amazon 发行了Kubeflow on EKS 开源版本,允许客户使用现成的 Amazon 服务集成构建机器学习系统并提供安装文档, 包括 RDS 和 S3 安装方法,Cognito, RDS 和 S3 安装方法等。本篇是使用的 RDS 和S3 安装方法。此部署方法用到的服务包含:

  • RDS:代替 KFP 和 Katib 使用的 MySQL pod,用于持久化 KFP 数据(例如实验、pipelines、job 信息等)和 Katib 日志信息。

  • S3:代替 MinIO 存储对象, 例如一些日志文件。

  • Secret Manager:存储 RDS 相关信息,像用户名密码和 Endpoint 等。

准备工作

因为代码中没有考虑对中国区的支持,需要手动修改一些代码。

在 auto-rds-s3-setup.py  文件中需要修改两处:

  • iam_policies 部分,需要把 aws 替换成 aws-cn

  • s3_params 部分,需要把 amazonaws.com 

  • (http://s3.amazonaws.com.cn) 换成 s3.amazonaws.com.cn (http://s3.amazonaws.com.cn)

def create_secrets_iam_service_account():
    print("Creating secrets IAM service account...")
    iam_policies = [
        "arn:aws-cn:iam::aws:policy/AmazonSSMReadOnlyAccess",
        "arn:aws-cn:iam::aws:policy/SecretsManagerReadWrite",
    ]

    create_iam_service_account(
        service_account_name="kubeflow-secrets-manager-sa",
        namespace="kubeflow",
        cluster_name=CLUSTER_NAME,
        region=CLUSTER_REGION,
        iam_policy_arns=iam_policies,
    )

    print("Secrets IAM service account created!")


def setup_kubeflow_pipeline():
    print("Setting up Kubeflow Pipeline...")

    print("Retrieving DB instance info...")
    db_instance_info = get_db_instance_info()

    pipeline_rds_params_env_file = "../../awsconfigs/apps/pipeline/rds/params.env"
    pipeline_rds_secret_provider_class_file = (
        "../../awsconfigs/common/aws-secrets-manager/rds/secret-provider.yaml"
    )

    rds_params = {
        "dbHost": db_instance_info["Endpoint"]["Address"],
        "mlmdDb": "metadb",
    }
    edit_pipeline_params_env_file(rds_params, pipeline_rds_params_env_file)

    update_secret_provider_class(
        pipeline_rds_secret_provider_class_file, RDS_SECRET_NAME
    )

    pipeline_s3_params_env_file = "../../awsconfigs/apps/pipeline/s3/params.env"
    pipeline_s3_secret_provider_class_file = (
        "../../awsconfigs/common/aws-secrets-manager/s3/secret-provider.yaml"
    )

    s3_params = {
        "bucketName": S3_BUCKET_NAME,
        "minioServiceRegion": CLUSTER_REGION,
        "minioServiceHost": "s3.amazonaws.com.cn",
    }

左滑查看更多

在 config 文件中 s3 endpoint 需要修改:

{
artifactRepository:
{
    s3: {
        bucket: $(kfp-artifact-bucket-name),
        keyPrefix: artifacts,
        endpoint: s3.cn-north-1.amazonaws.com.cn,
        insecure: true,
        accessKeySecret: {
            name: mlpipeline-minio-artifact,
            key: accesskey
        },
        secretKeySecret: {
            name: mlpipeline-minio-artifact,
            key: secretkey
        }
    },
    archiveLogs: true
}
}

左滑查看更多

准备 RDS, S3 和 

Secret Manager 环境

1. 首先确保从代码的根目录开始。

export REPO_ROOT=$(pwd)

2. 进入 tests/e2e 目录并安装依赖。

cd tests/e2e
pip install -r requirements.txt

3. 准备需要使用的环境变量。

export CLUSTER_REGION=cn-north-1
export CLUSTER_NAME=kubeflow151
export S3_BUCKET=<YOUR S3 BUCKET>
export MINIO_AWS_ACCESS_KEY_ID=<YOUR ACCESS KEY>
export MINIO_AWS_SECRET_ACCESS_KEY=<YOUR SECRET ACCESS KEY>

左滑查看更多

4. 配置 RDS, S3 和 Secret Manager 环境,安装 auto-rds-s3-setup.py。此步骤包含:

  • RDS 数据库创建

  • S3 桶创建

  • Secret Manager 设置

  • Serviceaccounts 创建

  • Secret Store CSI driver 设置等

PYTHONPATH=.. python utils/rds-s3/auto-rds-s3-setup.py --region $CLUSTER_REGION --cluster $CLUSTER_NAME --bucket $S3_BUCKET --s3_aws_access_key_id $MINIO_AWS_ACCESS_KEY_ID --s3_aws_secret_access_key $MINIO_AWS_SECRET_ACCESS_KEY

左滑查看更多

9ecc50aa5ff2937f078b27e8e8a3b5e2.png

5b5aea674ed46d4859325e1b1ce3af7b.png

Python 脚本执行后,会看到上面的 log 输出,为了确保安装过程成功,可以分别查看 pod 运行的状态、serviceaccounts 和 CSI driver 等。

kubectl get pods —all-namespaces

07dba8f801a7cf832e6f82bb60a3711c.png

kubectl describe serviceaccounts kubeflow-secrets-manager-sa -n kubeflow;

左滑查看更多

d549c1e93f807170a9d42aafb55c0004.png

kubectl get csidriver

1482544f059f8a946318b12b9213d326.png

Kubeflow 安装

执行如下命令安装,安装后也可以建议查看 pod 状态。

cd $REPO_ROOT 
while ! kustomize build deployments/rds-s3 | kubectl apply -f -; do echo "Retrying to apply resources"; sleep 30; done

kubectl get pods --all-namespaces

左滑查看更多

如果各个 Pod 运行没有问题的话,执行如下命令后,就可通过 http://localhost:8080 访问 Kubeflow Dashboard, 默认用户名为 user@example.com,密码为12341234。因为涉及到 RDS 和 S3 的使用,请参考下一步验证安全结果。

kubectl port-forward svc/istio-ingressgateway -n istio-system 8080:80

左滑查看更多

fd400a148566b1a41d732c3ee52ca0ce.png

登陆后,可以看到 Kubeflow 的控制台界面如下。Kubeflow 支持的主要功能可以在界面上找到,用户编程测试工作台  (Jupyter Notebook),超参调优 (Experiment(AutoML)), 机器学习工作流(Pipeline)等。

cc23246d17d00d9ab76d135b04d1c84f.png

验证安装结果

在 Kubeflow 安装之后,我们通过两个方面进行验证,RDS 和 S3 的验证,这两个角度的验证也是在侧面验证超参调优和工作流工作。

验证 RDS数据库

RDS 中会存储

     1. 连接 RDS 数据库。

kubectl run -it —rm —image=mysql:5.7 —restart=Never mysql-client — mysql -h <YOUR RDS ENDPOINT> -u <YOUR LOGIN> -p<YOUR PASSWORD>

左滑查看更多

     2. 连接成功后,查看 kubeflow 和mlpipeline 数据是否存在, 同时查看在mlpipeline中是否有如下的表。

show databases;
use mlpipeline; show tables;

9189633df372f01d31719f60b55374f8.png

     3. 登录进入到 Kubeflow Dashboard,使用此 yaml 

(https://github.com/awslabs/kubeflow-manifests/blob/main/tests/e2e/resources/custom-resource-templates/katib-experiment-random.yaml) 文件(注意需要更改 namespace) 运行一个实验。具体操作为 Dashboard –> Experiments (AutoML) –> New Experiment。

1ffa0b99dfa8ce8f9093bb9bfa501ba3.png

实验成功后,RDS 中表中会有相关的实验执行信息。

e8381d4c2a3af8eff692900391a3ac26.png

验证 S3

在 Kubeflow Dashboard 中,创建一个 Experiment 并运行,运行结束之后,我们可以去到第二步部署的 S3 bucket 中,如果可以查看到 log, S3 部分没有问题。可以参考下图:

705e35c8bc7556dfb4a16851178122b8.png

348f0fa62395652b5c4ac0fbc4a62160.png

利用 Karpenter 进行动态的资源扩展

满足 Kubeflow ML 训练的需求

在 Karpenter 之前,EKS 用户使用 Cluster Autoscaler 动态调整集群的计算容量,他的原理是使用 Amazon EC2 Auto Scaling 组

(https://docs.aws.amazon.com/autoscaling/ec2/userguide/auto-scaling-groups.html)进行扩展底层的 EC2 资源。Karpenter 会观察未调度的一组容器 (pod) 的总资源请求,然后向 Amazon EC2 直接发送命令并作出启动和终止新节点的决策,从而减少调度延迟并降低基础设施成本。在机器学习场景下,用户可以像该文中一样使用一个 EKS 节点组安装和管理 Kubeflow,在提交训练任务时,通过 Karpenter 开启 GPU 资源,在训练结束后终止 GPU 资源。

Karpenter 的安装不在此介绍了,可以参考官方文档安装 (https://karpenter.sh/v0.5.5/getting-started/)。我们主要演示在 Karpenter 部署后,Kubeflow 中如何使用。使用验证 RDS 的例子,在 spec 中添加 resource 为 nvidia.com/gpu 

(https://www.nvidia.com/gpu/), 添加后在 Kubeflow Dashboard 中 Experiments (AutoML) 部分运行修改后的 yaml 文件。

.......
    trialSpec:
      apiVersion: batch/v1
      kind: Job
      spec:
        template:
          metadata:
            annotations:
              sidecar.istio.io/inject: 'false'
          spec:
            containers:
              - name: training-container
                image: docker.io/kubeflowkatib/mxnet-mnist:v1beta1-45c5727
                command:
                  - "python3"
                  - "/opt/mxnet-mnist/mnist.py"
                  - "--batch-size=64"
                  - "--lr=${trialParameters.learningRate}"
                  - "--num-layers=${trialParameters.numberLayers}"
                  - "--optimizer=${trialParameters.optimizer}"
                resources:
                  limits:
                    nvidia.com/gpu: 1
            restartPolicy: Never

左滑查看更多

在提交了这个 Experiment 后,可以通过命令行查看 Karpenter 的日志。我们可以看到 GPU 机器可快速创建起来。

kubectl logs -f -n karpenter -l app.kubernetes.io/name=karpenter -c controller

左滑查看更多

ccf63a25b607b5357b1b3bd809983e43.png

c59b234db56713d2f63699e5a4514276.png

在任务执行完毕后,可以看到创建的 GPU EC2 被删除。通过 Karpenter,我们可以随时扩展资源进行训练,不需要提前配置很多 GPU 资源。

c2b154796253a902ddc98263091ad632.png

256100136b245e2b4d56a2f2d10c236c.png

总结

通过使用 EKS, Kubeflow, Karpenter 可以建立弹性扩展性强的机器学习平台,在安装中需要注意的问题包含:

1. Kubeflow 中使用了很多源是 io 的 image,可通过这个工具自动化拉取Image。

2. 在中国区 Kubeflow 和 Karpenter 安装的时候,需要修改一些服务的 endpoint 和 ARN 像是 amazonaws.com 到 s3.cn-north-1.amazonaws.com.cn。Kubeflow 的配置文件代码量比较大,在部署前通过检索的方式发现需要修改的 endpoint 外。最好的办法是通过查看 Pod 运行状态进行 Troubleshooting,一般这几个配置都在 configmap 中,修改 configmap 即可。

3. 在使用 Karpenter 调度 GPU 资源前,记得安装 NVIDIA 设备的插件,kubectl apply -f 

https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.9.0/nvidia-device-plugin.yml。

参考文档

Kubeflow on Amazon: 

https://awslabs.github.io/kubeflow-manifests/docs/deployment/rds-s3/guide/#42-verify-s3

Karpenter 介绍:

https://aws.amazon.com/cn/blogs/china/karpenter-new-generation-kubernetes-auto-scaling-tools/

Karpenter 安装:

https://karpenter.sh/v0.12.1/getting-started/getting-started-with-eksctl/

本篇作者

ff053bc7ab556bd683faf93be3cb0b6b.jpeg

冯秋爽

亚马逊云科技解决方案架构师,负责跨国企业级客户基于 Amazon 的技术架构设计、咨询和设计优化工作。在加入 Amazon 之前曾就职于 IBM、甲骨文等 IT 企业,积累了丰富的程序开发和数据库的实践经验。

d8cdce9d5d655f499829da78cba97817.jpeg

黄德滨

亚马逊云科技资深解决方案架构师,服务于全球客户销售团队,负责技术架构设计和咨询,致力于企业级应用在 Amazon 云服务的运用和部署,对于大型企业级应用开发和实施拥有近二十年的丰富经验,在云计算领域工作多年,拥有大量帮助各种类型企业上云的经验,在加入 Amazon 之前先后服务于百度、甲骨文等国内外知名 IT 企业。

75c1ac5680276ded370687dddb4293af.jpeg

点击上方【立即报名】

直通大咖云集的亚马逊云科技中国峰会!

7647ee8ba3061f2f8485d104c35bf5d9.gif

876fc103d5aea5c15c094c630c7a59bf.gif

听说,点完下面4个按钮

就不会碰到bug了!

dea55d61cac2222a31e15a0cd78aa80d.gif

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值