Kubernetes:集成外部服务与运行机器学习的指南
1. 跨Kubernetes集群集成服务
1.1 基本步骤
要实现两个Kubernetes集群间服务的发现与连接,可按以下步骤操作:
1.
暴露第一个集群的服务
:在支持内部负载均衡器的云环境中,获取内部负载均衡器的虚拟IP地址,假设为10.1.10.1。
2.
集成虚拟IP到第二个集群
:创建一个无选择器的服务,并将其IP地址设置为10.1.10.1,就像将外部应用导入Kubernetes一样。
1.2 自动化集成
上述步骤较为手动,对于小型静态服务集可能可行。若要实现更紧密或自动的集群间服务集成,可编写一个集群守护进程,在两个集群中运行以执行集成操作。该守护进程会监控第一个集群中带有特定注解(如myco.com/exported-service)的服务,并将这些服务通过无选择器的服务导入第二个集群。同时,它会清理那些已导出到第二个集群但在第一个集群中不再存在的服务。
1.3 第三方工具
有多种第三方工具和项目可用于互连Kubernetes内的服务以及任意应用和机器。这些工具功能强大,但操作上比前面介绍的方法复杂得多。如果构建的网络互连越来越多,可探索服务网格领域,它们大多有开源组件,也提供商业支持以减少运行额外基础设施的操作开销。
1.4 连接集群与外部服务的最佳实践
- 建立网络连接 :确保集群和本地环境之间的网络连通性,保证Pod能与本地机器通信,反之亦然。
-
访问集群外服务
:
- 可使用无选择器的服务,直接指定要通信的机器(如数据库)的IP地址。
- 若没有固定IP地址,可使用CNAME服务重定向到DNS名称。
- 若既没有DNS名称也没有固定服务,可能需要编写动态操作符,定期将外部服务的IP地址与Kubernetes服务端点同步。
- 导出Kubernetes服务 :使用内部负载均衡器或NodePort服务。在公共云环境中,内部负载均衡器通常更容易使用,可绑定到Kubernetes服务本身;当负载均衡器不可用时,NodePort服务可在集群的所有机器上暴露服务。
- 实现集群间连接 :结合上述两种方法,将一个集群的服务外部暴露,然后在另一个集群中作为无选择器的服务使用。
以下是一个简单的流程示意图:
graph LR
A[第一个Kubernetes集群] -->|暴露服务| B(获取虚拟IP: 10.1.10.1)
B -->|集成到第二个集群| C[第二个Kubernetes集群]
C -->|创建无选择器服务| D(设置IP: 10.1.10.1)
2. Kubernetes用于机器学习
2.1 为何Kubernetes适合机器学习
Kubernetes为深度学习的快速创新提供了理想环境,主要因其具备以下特性:
| 特性 | 描述 |
| ---- | ---- |
| 无处不在 | 所有主要公共云都支持,也有适用于私有云和基础设施的发行版,可在任何地方运行深度学习工作负载。 |
| 可扩展 | 深度学习工作流通常需要大量计算资源,Kubernetes的原生自动扩展功能使数据科学家能轻松实现和微调模型训练所需的扩展级别。 |
| 可扩展 | 允许集群管理员快速轻松地向调度器暴露新类型的硬件,无需更改Kubernetes源代码,还能无缝集成自定义资源和控制器以支持专门的工作流。 |
| 自助服务 | 数据科学家无需深入了解Kubernetes,即可按需执行自助式机器学习工作流。 |
| 可移植 | 基于Kubernetes API的工具可使机器学习模型在任何地方运行,实现工作负载在不同Kubernetes提供商之间的可移植性。 |
2.2 机器学习工作流
机器学习开发工作流主要包括以下阶段:
-
数据集准备
:涉及用于训练模型的数据集的存储、索引、编目和元数据。需考虑能满足需求的存储方式,通常需要大规模的块存储和对象存储,可通过Kubernetes原生存储抽象或直接访问的API访问。
-
机器学习算法开发
:数据科学家在此阶段编写、共享和协作机器学习算法。像JupyterHub这样的开源工具在Kubernetes上易于安装,其运行方式与其他工作负载类似。
-
训练
:模型使用数据集学习执行设计任务的过程,训练结果通常是训练模型状态的检查点。此过程会同时利用Kubernetes的调度、访问专用硬件、数据集卷管理、扩展和网络等功能。
-
服务
:使训练好的模型能够响应客户端的服务请求,根据客户端提供的数据进行预测。
以下是机器学习工作流的流程图:
graph LR
A[数据集准备] --> B[机器学习算法开发]
B --> C[训练]
C --> D[服务]
2.3 集群管理员在Kubernetes上运行机器学习的注意事项
2.3.1 模型训练
- 资源需求 :在Kubernetes上训练机器学习模型需要传统CPU和GPU,通常资源越多,训练完成得越快。多数情况下,可在具有所需资源的单台机器上完成模型训练。建议在考虑分布式训练之前,先将虚拟机垂直扩展到4 - 8个GPU。
- 超参数调优 :数据科学家在训练模型时会使用超参数调优技术,即通过运行多个相同的训练作业,使用不同的超参数集,找到模型训练的最佳超参数组合。
2.3.2 首次在Kubernetes上训练模型示例
以使用MNIST数据集训练图像分类模型为例:
1.
确认GPU可用性
:
$ kubectl get nodes -o yaml | grep -i nvidia.com/gpu
nvidia.com/gpu: "1"
nvidia.com/gpu: "1"
nvidia.com/gpu: "1"
nvidia.com/gpu: "1"
- 创建训练作业文件mnist-demo.yaml :
apiVersion: batch/v1
kind: Job
metadata:
labels:
app: mnist-demo
name: mnist-demo
spec:
template:
metadata:
labels:
app: mnist-demo
spec:
containers:
- name: mnist-demo
image: lachlanevenson/tf-mnist:gpu
args: ["--max_steps", "500"]
imagePullPolicy: IfNotPresent
resources:
limits:
nvidia.com/gpu: 1
restartPolicy: OnFailure
- 创建资源 :
$ kubectl create -f mnist-demo.yaml
job.batch/mnist-demo created
- 检查作业状态 :
$ kubectl get jobs
NAME COMPLETIONS DURATION AGE
mnist-demo 0/1 4s 4s
- 查看Pod状态 :
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mnist-demo-hv9b2 1/1 Running 0 3s
- 查看训练日志 :
$ kubectl logs mnist-demo-hv9b2
# 此处省略大量日志输出
- 确认训练完成 :
$ kubectl get jobs
NAME COMPLETIONS DURATION AGE
mnist-demo 1/1 27s 112s
- 清理训练作业 :
$ kubectl delete -f mnist-demo.yaml
job.batch "mnist-demo" deleted
2.3.3 分布式训练
分布式训练仍处于起步阶段,难以优化。通常,在具有八个GPU的单台机器上训练比在两台各有四个GPU的机器上训练更快。只有当模型无法在最大可用机器上运行时,才考虑使用分布式训练。若确定要进行分布式训练,需了解其架构,如分布式TensorFlow架构。
2.3.4 资源约束
机器学习工作负载对集群的各个方面都有非常具体的配置要求,训练阶段是最消耗资源的。机器学习算法训练通常是批处理式工作负载,有开始和结束时间,训练完成时间取决于满足模型训练资源需求的速度。虽然扩展可能是加快训练速度的有效方法,但扩展也有其自身的瓶颈。
2.3.5 专用硬件
训练和服务模型在专用硬件上通常更高效,如通用GPU。Kubernetes通过设备插件使GPU资源可被调度器识别,供应商无需修改Kubernetes核心代码即可实现特定设备。以NVIDIA设备插件为例,运行后可创建如下Pod,Kubernetes会确保其被调度到具有相应资源的节点上:
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
containers:
- name: digits-container
image: nvidia/digits:6.0
resources:
limits:
nvidia.com/gpu: 2 # 请求2个GPU
设备插件不仅适用于GPU,还可用于需要专用硬件的场景,如现场可编程门阵列(FPGA)或InfiniBand。
2.3.6 调度特性
Kubernetes只能对其已知的资源做出决策。在训练时,可能会发现GPU未达到满负荷运行,无法实现理想的利用率。例如,当前的配置只暴露了GPU核心数量,未暴露每个核心可运行的线程数,也未表明GPU核心所在的总线,这可能导致需要相互访问或共享内存的作业被分配到同一节点。此外,不能请求部分GPU(如0.1个GPU),即使特定GPU支持并发运行多个线程,也无法充分利用其容量。
2.3.7 库、驱动和内核模块
访问专用硬件通常需要专门的库、驱动和内核模块,需将它们挂载到容器运行时,以便容器内的工具可以使用。不能简单地将它们添加到容器镜像中,因为这些工具需要与底层主机的版本匹配,并针对特定系统进行适当配置。一些容器运行时(如NVIDIA Docker)可减轻将主机卷映射到每个容器的负担;若没有专用的容器运行时,也可以构建准入Webhook来提供相同的功能。同时,访问某些专用硬件可能需要特权容器,这会影响集群的安全配置文件。Kubernetes设备插件也可促进相关库、驱动和内核模块的安装,许多设备插件会在每台机器上进行检查,确保所有安装完成后才向Kubernetes调度器通告可调度的GPU资源。
2.3.8 存储
存储是机器学习工作流中最关键的方面之一,直接影响以下两个部分:
-
训练期间的数据集存储和分发
:训练期间,每个工作节点都必须能够检索数据集,存储需求为只读,通常磁盘速度越快越好。数据集的大小几乎完全决定了存储磁盘的类型,数百兆字节或千兆字节的数据集适合块存储,而数TB或数百TB的数据集可能更适合对象存储。根据存储数据集的磁盘大小和位置,网络性能可能会受到影响。
-
检查点和模型保存
:在模型训练过程中会创建检查点,保存模型以便用于服务。在这两种情况下,都需要在每个工作节点上附加存储来存储这些数据。数据通常存储在单个目录下,每个工作节点会写入特定的检查点或保存文件。大多数工具期望存储具有特定的配置。
2.3.9 存储方式对比
| 存储类型 | 适用数据集大小 | 特点 |
|---|---|---|
| 块存储 | 数百兆字节或千兆字节 | 读写性能较高,适合对数据访问速度要求较高的场景,但扩展性相对较差。 |
| 对象存储 | 数TB或数百TB | 扩展性强,适合存储大规模数据集,但读写性能可能相对较慢,需要考虑网络延迟。 |
以下是存储在机器学习工作流中的作用示意图:
graph LR
A[数据集] -->|存储| B(块存储/对象存储)
B -->|训练时分发| C[工作节点]
C -->|训练过程| D(生成检查点和模型)
D -->|保存| B
3. 总结
在现实世界中,并非所有应用都是云原生的,构建应用往往需要将现有系统与新应用连接起来。本文介绍了如何将Kubernetes与遗留应用集成,以及如何集成跨多个不同Kubernetes集群运行的不同服务。除非有条件构建全新的云原生应用,否则云原生开发始终需要进行遗留集成,文中描述的技术将有助于实现这一目标。
同时,Kubernetes为机器学习提供了理想的运行环境,其无处不在、可扩展、可定制等特性满足了机器学习工作流的各种需求。对于集群管理员来说,在准备集群进行机器学习工作负载时,需要考虑模型训练、资源约束、专用硬件、存储等多个方面的问题。通过合理配置和使用Kubernetes,数据科学家可以更高效地进行机器学习模型的开发、训练和部署。
3.1 关键要点回顾
- 跨集群服务集成 :通过暴露服务、集成虚拟IP等步骤实现Kubernetes集群间的服务发现与连接,也可借助第三方工具和自动化守护进程提高集成效率。
- 连接外部服务 :遵循建立网络连接、合理选择访问和导出服务的方式等最佳实践,确保集群与外部服务的有效连接。
- 机器学习应用 :利用Kubernetes的特性支持机器学习工作流,包括数据集准备、算法开发、训练和服务等阶段,同时注意模型训练的资源需求、分布式训练的适用场景、专用硬件的使用和存储的配置等问题。
3.2 未来展望
随着技术的不断发展,Kubernetes在集成外部服务和支持机器学习方面将不断完善和创新。例如,分布式训练技术可能会更加成熟,调度算法可能会更好地适应专用硬件的特性,服务网格工具可能会提供更强大的功能和更简单的操作方式。对于开发者和数据科学家来说,持续关注这些发展趋势,不断学习和应用新的技术,将有助于构建更高效、更强大的应用系统。
3.3 实践建议
- 动手实践 :通过实际操作,如在Kubernetes上运行模型训练作业、配置集群与外部服务的连接等,加深对文中技术的理解和掌握。
- 持续学习 :关注Kubernetes和机器学习领域的最新动态和研究成果,不断更新知识体系。
- 社区交流 :参与相关的技术社区,与其他开发者和数据科学家交流经验和心得,共同解决遇到的问题。
以下是按照重要性和操作难度对上述要点的一个简单排序表格:
| 要点 | 重要性 | 操作难度 |
|---|---|---|
| 跨集群服务集成 | 高 | 中 |
| 连接外部服务 | 高 | 中 |
| 机器学习资源管理 | 高 | 高 |
| 分布式训练 | 中 | 高 |
| 专用硬件使用 | 中 | 中 |
| 存储配置 | 高 | 中 |
希望本文能为你在Kubernetes环境中集成外部服务和运行机器学习提供有价值的参考和指导,帮助你更好地应对实际开发中的挑战。
超级会员免费看
75

被折叠的 条评论
为什么被折叠?



