Kubernetes
提供可拓展的容器调度功能:
- 用户可以对接不同的
container runtime
, 其中最常用的是docker
。 - 用户可以在
docker
内封装隔离各类进程应用 。
因此,kubernetes
可以调度和部署一系列web
服务等app
, 也可以部署分布式应用, 计算密集型应用如Spark和Tensorflow等,这取决于开发者的部署配置和docker
镜像内容等。
下文记录一些实践经验,不深入配置层面。
Kubernetes 部署web服务
web
服务config
配置用config map方案比较方便。- 集群管理工具用Rancher比较方便, 用户可以在其
UI
管理多个k8s
集群,避免编写yam
l等和kubectl
等繁琐操作。Rancher
在namespace
的基础上也引入了project
的概念, 即project
内可包含多个 k8snamespace
. 但是kubectl get ns
仍会发现所有project
下的namespace
,Rancher
的这个做法只是方便用户管理集群。另外Rancher
对k8s
内资源的变化响应也是很不错的, 即在Rancher
前端UI
能很及时地看到deployment
等的状态刷新情况。另外Rancher
提供部署回滚功能,降低误操作带来的开销。 - 使用
Rancher
的时候注意其与K8s的兼容关系。 web
服务间通信配置参考service。k8s
集群所有服务上免费可用的tls
参考
Kubernetes 部署计算密集型服务
计算密集型服务与web
服务有区别:
- 计算密集型服务注重计算性能, 容器环境会有损耗(内存/cpu虚拟化开销)
- 计算密集型服务偏向批量启动和批量删除等操作, 如启动深度学习集群,大数据集群等, 计算完毕后
deployment/pods
等即删除。 - 计算密集型服务对实例间带宽要求高,在K8s环境下要考虑CNI损耗
- 不同计算业务的容器运行环境配置不同,运行依赖不同,调度配置(
workers/masters
)等较复杂
实践:
-
优化计算和存储性能:
- 引入统一存储和本地固态硬盘等
- 选用开销较少的
CNI
- 增加计算业务并行化部分, 用并行度淡化虚拟化开销
- 容器中使用
GPU
计算有较好的性能
-
计算密集型服务的调度的简单做法可以依赖原生
k8s
的deployment
等概念,利用k8s
的client,编写简单的创建服务, 如将spark master
设置为deployment A
, 为其配置service A
等, 再将spark worker
等设置为deployment B
, 为其配置service B
, 二者通过service A/B
通信。 -
计算密集型服务的调度的更佳做法具体开发可以参考k8s operator,
开发operator
的做法会更规范, 对管理复杂的计算密集型服务调度实现起来更有效。对比之下,单纯依靠k8s的client去组织分布式服务会显得低效且会引入很多琐碎问题,例如需要修改spark
镜像, 插入指定的启动程序, 用于收集spark
节点的信息等。