Kubernetes的架构怎么使用

发布时间:2021-12-20 09:52:25 作者:iii
来源:亿速云 阅读:150

这篇文章主要讲解了“Kubernetes的架构怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Kubernetes的架构怎么使用”吧!

分布式TensorFlow

TensorFlow是一个使用数据流图进行数值计算的开源软件库。图中的节点代表数学运算,而图中的边则代表在这些节点之间传递的多维数组(张量)。这种灵活的架构可让您使用一个 API 将计算工作部署到桌面设备、服务器或者移动设备中的一个或多个 CPU 或 GPU。 关于TensorFlow的基础概念,我就不多介绍了。

单机TensorFlow

下面是一个单机式TensorFlow训练示意图,通过Client提交Session,定义这个worker要用哪个cpu/gpu做什么事。

Kubernetes的架构怎么使用

分布式TensorFlow

2016年4月TensorFlow发布了0.8版本宣布支持分布式计算,我们称之为Distributed TensorFlow。这是非常重要的一个特性,因为在AI的世界里,训练的数据量和模型参数通常会非常大。比如Google Brain实验室今年发表的论文OUTRAGEOUSLY LARGE NEURAL NETWORKS: THE SPARSELY-GATED MIXTURE-OF-EXPERTS LAYER中提到一个680亿个Parameters的模型,如果只能单机训练,那耗时难于接受。通过Distributed TensorFlow,可以利用大量服务器构建分布式TensorFlow集群来提高训练效率,减少训练时间。

通过TensorFlow Replcation机制,用户可以将SubGraph分布到不同的服务器中进行分布式计算。TensorFlow的副本机制又分为两种,In-graph和Between-graph。

In-graph Replication简单来讲,就是通过单个client session定义这个TensorFlow集群的所有task的工作。

Kubernetes的架构怎么使用

与之相对地,Between-graph Replication就是每个worker都有独立的client来定义自己的工作。

Kubernetes的架构怎么使用

下面是抽象出来的分布式TensorFlow Framework如下:

Kubernetes的架构怎么使用

我们先来了解里面的几个概念:

一个TensorFlow Cluster有一个或多个jobs组成,每个job又由一个或多个tasks构成。Cluster的定义是通过tf.train.ClusterSpec来定义的。比如,定义一个由3个worker和2个ps的TensorFlow Cluster的ClusterSpec如下:

tf.train.ClusterSpec({
    "worker": [
        "worker0.example.com:2222",  //主机名也可以使用IP
        "worker1.example.com:2222",
        "worker2.example.com:2222"
    ],
    "ps": [
        "ps0.example.com:2222",
        "ps1.example.com:2222"
    ]})

Client用来build一个TensorFlow Graph,并构建一个tensorflow::Session用来与集群通信。一个Client可以与多个TensorFlow Server交互,一个Server能服务多个Client。

一个Job由tasks list组成,Job分ps和worker两种类型。ps即parameter server,用来存储和更新variables的,而worker可以认为是无状态的,用来作为计算任务的。workers中,一般都会选择一个chief worker(通常是worker0),用来做训练状态的checkpoint,如果有worker故障,那么可以从最新checkpoint中restore。

每个Task对应一个TensorFlow Server,对应一个单独的进程。一个Task属于某个Job,通过一个index来标记它在对应Job的tasks中的位置。每个TensorFlow均实现了Master service和Worker service。Master service用来与集群内的worker services进行grpc交互。Worker service则是用local device来计算subgraph。

关于Distributed TensorFlow的更多内容,请参考官方内容www.tensorflow.org/deplopy/distributed

分布式TensorFlow的缺陷

分布式TensorFlow能利用数据中心所有服务器构成的资源池,让大量ps和worker能分布在不同的服务器进行参数存储和训练,这无疑是TensorFlow能否在企业落地的关键点。然而,这还不够,它还存在一下先天不足:

TensorFlow on Kubernetes架构与原理

TensorFlow的这些不足,正好是Kubernetes的强项:

TensorFlow on Kubernetes架构

Kubernetes的架构怎么使用

TensorFlow on Kubernetes原理

在我们的TensorFlow on Kubernetes方案中,主要用到以下的Kubernetes对象:

我们用Kubernetes Job来部署TensorFlow Worker,Worker训练正常完成退出,就不会再重启容器了。注意Job中的Pod Template restartPolicy只能为Never或者OnFailure,不能为Always,这里我们设定restartPolicy为OnFailure,worker一旦异常退出,都会自动重启。但是要注意,要保证worker重启后训练能从checkpoint restore,不然worker重启后又从step 0开始,可能跑了几天的训练就白费了。如果你使用TensorFlow高级API写的算法,默认都实现了这点,但是如果你是使用底层core API,一定要注意自己实现。

kind: Job
apiVersion: batch/v1
metadata:
  name: {{ name }}-{{ task_type }}-{{ i }}
  namespace: {{ name }}
spec:
  template:
    metadata:
      labels:
        name: {{ name }}
        job: {{ task_type }}
        task: "{{ i }}"
    spec:
      imagePullSecrets:
      - name: harborsecret
      containers:
      - name: {{ name }}-{{ task_type }}-{{ i }}
        image: {{ image }}
        resources:
          requests:
            memory: "4Gi"
            cpu: "500m"
        ports:
        - containerPort: 2222
        command: ["/bin/sh", "-c", "export CLASSPATH=.:/usr/lib/jvm/java-1.8.0/lib/tools.jar:$(/usr/lib/hadoop-2.6.1/bin/hadoop classpath --glob); wget -r -nH  -np --cut-dir=1 -R 'index.html*,*gif'  {{ script }}; cd ./{{ name }}; sh ./run.sh {{ ps_hosts() }} {{ worker_hosts() }} {{ task_type }} {{ i }} {{ ps_replicas }} {{ worker_replicas }}"]
      restartPolicy: OnFailure

TensorFlow PS用Kubernetes Deployment来部署。为什么不像worker一样,也使用Job来部署呢?其实也未尝不可,但是考虑到PS进程并不会等所有worker训练完成时自动退出(一直挂起),所以使用Job部署没什么意义。

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: {{ name }}-{{ task_type }}-{{ i }}
  namespace: {{ name }}
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: {{ name }}
        job: {{ task_type }}
        task: "{{ i }}"
    spec:
      imagePullSecrets:
      - name: harborsecret
      containers:
      - name: {{ name }}-{{ task_type }}-{{ i }}
        image: {{ image }}
        resources:
          requests:
            memory: "4Gi"
            cpu: "500m"
        ports:
        - containerPort: 2222
        command: ["/bin/sh", "-c","export CLASSPATH=.:/usr/lib/jvm/java-1.8.0/lib/tools.jar:$(/usr/lib/hadoop-2.6.1/bin/hadoop classpath --glob); wget -r -nH  -np --cut-dir=1 -R 'index.html*,*gif'  {{ script }}; cd ./{{ name }}; sh ./run.sh {{ ps_hosts() }} {{ worker_hosts() }} {{ task_type }} {{ i }} {{ ps_replicas }} {{ worker_replicas }}"]
      restartPolicy: Always

关于TensorFlow PS进程挂起的问题,请参考https://github.com/tensorflow/tensorflow/issues/4713.我们是这么解决的,开发了一个模块,watch每个TensorFlow集群的所有worker状态,当所有worker对应Job都Completed时,就会自动去删除PS对应的Deployment,从而kill PS进程释放资源。

Headless Service通常用来解决Kubernetes里面部署的应用集群之间的内部通信。在这里,我们也是这么用的,我们会为每个TensorFlow对应的Job和Deployment对象都创建一个Headless Service作为worker和ps的通信代理。

kind: Service
apiVersion: v1
metadata:
  name: {{ name }}-{{ task_type }}-{{ i }}
  namespace: {{ name }}
spec:
  clusterIP: None
  selector:
    name: {{ name }}
    job: {{ task_type }}
    task: "{{ i }}"
  ports:
  - port: {{ port }}
    targetPort: 2222

用Headless Service的好处,就是在KubeDNS中,Service Name的域名解析直接对应到PodIp,而没有service VIP这一层,这就不依赖于kube-proxy去创建iptables规则了。少了kube-proxy的iptables这一层,带来的是性能的提升。

Kubernetes的架构怎么使用

在TensorFlow场景中,这是不可小觑的,因为一个TensorFlow Task都会创建一个service,几万个service是很正常的事,如果使用Normal Service,iptables规则就几十万上百万条了,增删一条iptabels规则耗时几个小时甚至几天,集群早已奔溃。关于kube-proxy iptables模式的性能测试数据,请参考华为PaaS团队的相关分享。

前面提到,每个TensorFlow Task都会创建一个service,都会在KubeDNS中有一条对应的解析规则,但service数量太多的时候,我们发现有些worker的域名解析失败概率很大,十几次才能成功解析一次。这样会影响TensorFlow集群内各个task的session建立,可能导致TensorFlow集群起不来。

为了解决这个问题,我们引入了Kubernetes的孵化项目kubernetes-incubator/cluster-proportional-autoscaler来对KubeDNS进行动态伸缩。关于这个问题的具体的细节,有兴趣的同学可以查看我的博文https://my.oschina.net/jxcdwangtao/blog/1581879。

TensorFlow on Kubernetes实践

基于上面的方案,我们开发一个TaaS平台,已经实现了基本的功能,包括算法管理、训练集群的创建和管理、模型的管理、模型上线(TensorFlow Serving)、一键创建TensorBoard服务、任务资源监控、集群资源监控、定时训练管理、任务日志在线查看和批量打包下载等等,这部分内容可以参考之前在DockOne上分享的文章http://dockone.io/article/3036。

这只是刚开始,我正在做下面的特性:

经验和坑

整个过程中,遇到了很多坑,有TensorFlow的,也有Kubernetes的,不过问题最多的还是我们用的CNI网络插件contiv netplugin,每次大问题基本都是这个网络插件造成的。Kubernetes是问题最少的,它的稳定性比我预期还要好。

感谢各位的阅读,以上就是“Kubernetes的架构怎么使用”的内容了,经过本文的学习后,相信大家对Kubernetes的架构怎么使用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

推荐阅读:
  1. Kubernetes存储架构和接口使用方法
  2. 如何进行Kubernetes架构及组件介绍

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

kubernetes

上一篇:基于Groovy规则脚本引擎的示例分析

下一篇:如何启用Initializers

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》