volcano

 

1 volcano 调度架构简介

主要概念及解释:

  • volcano 调度对象是 vcjob(volcano 创建的 CRD),即上图的 JobInfo(这是 scheduler 组件内定义的类)。

  • 一个 vcjob 包含一个或者多个 pod,每个 pod 声明各自的资源要求(如 cpu 多少个 core,memory 多少 GB,gpu 多少卡)

  • 每个 vcjob 对应一个 PodGroup 概念, 描述整个 vcjob 的状态,最低资源要求,资源队列等信息。

 

当我们向 kube-apisever 创建一个 vcjob 之后,scheduler 组件会将其记录到 Cache 中。scheduler 组件每隔(默认)1 秒循环执行如下调度过程:

  • OpenSession()初始化本次调度:加载所有 plugins,并调用每个 plugin 的 OnSessionOpen()方法

  • 依次调用每个 action(默认是 enqueue,allocate,backfill)

  • 每个 action 会遍历所有的 JobInfo,分别对其进行处理

  • enqueu 过滤 JobInfo 是否需要进入下一轮 allocate

  • allocate 是资源调度的主要过程,主要概念与 kubernetes 原生调度器相似,首先 predicate 过滤 node 节点,然后 priority 排序 node 节点,最后(如有则)绑定 pod 到一个 node。

  • CloseSession()结束本次调度:调用每个 plugin 的 OnSessionClose()方法

2 volcano 组件及 vcjob 创建过程

前面我们看到 scheduler 内部如何对 vcjob 做资源调度,但是 pod 和 PodGroup 是如何被创建的,以及 volcano 组件在整个 vcjob 的创建过程中的作用是如何?

2.1 volcano 组件

首先,我们看下图,volcano 组件及 vcjob 创建过程

当我们部署 volcano 完成后,可以看到在 kubernetes 机器上,主要创建了以上三个 service:

  • webhook-manager 服务:通过向 kubernetes 服务注册 MutatingWebhookConfigurations 和 ValidatingWebhookConfigurations,修改及校验 vcjob。主要职责包括如下:

  • mutate:设置 schedulerName,queue,taskName 等

  • validate:检查 jobSpec 参数,tasks,plugins 等合法性检查

  • controller-manager 服务:监听 kube-apiserver 上的所有 vcjob,pod,PodGroup 等资源,主要管理整个 vcjob 的生命周期,包括其相关的 pod 和 PodGroup 的创建,修改(如状态和事件),以及销毁。

  • scheduler 服务:pod 资源调度及绑定

2.2 vcjob 创建过程:webhook-manager 校验

 

从零开始运行Volcano作业:

1)用户创建一个 Volcano 作业

2)Volcano Admission 拦截作业的创建请求,并进行合法性校验

3)Kubernetes 持久化存储 Volcano Job 到 ETCD

4)ControllerManager 通过 List-Watch 机制观察到Job 资源的创建,创建任务(Pod)

5)Scheduler 负责任务的调度,绑定 Node

6)Kubelet Watch 到 Pod的创建,接管 Pod 的运行

7)ControllerManager 监控所有任务的运行状态,保证所有的任务在期望的状态下运行

首先,我们看官方示例 vcjob 定义:

 

apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
  name: job-1
spec:
  minAvailable: 1
  schedulerName: volcano
  queue: test
  policies:
    - event: PodEvicted
      action: RestartJob
  tasks:
    - replicas: 1
      name: nginx
      policies:
      - event: TaskCompleted
        action: CompleteJob
      template:
        spec:
          containers:
            - command:
              - sleep
              - 10m
              image: nginx:latest
              name: nginx
              resources:
                requests:
                  cpu: 1
                limits:
                  cpu: 1
          restartPolicy: Never

 

通过如下方式想 kubernetes 集群创建 vcjob

kubectl create vcjob demo.yaml

 

该命令在执行过程中,kube-apiserver 服务将调用 webhook-manager 服务注册的 webhook 操作,如下:

  • webhook-manager 将对 vcjob 做如下修改:

  • 如果 schedulerName 未设置,则使用默认值 volcano。这是用于指定使用哪个调度器,对 pod 资源进行调度。这个很关键,vcjob 关联的 pod 将沿用该 schedulerName 值,否则该值如果为 default 或者未设置,则 kubernetes 调度服务将会处理该 pod,这将导致冲突。

  • 如果 queue 未设置,则使用默认值 default,即使用默认的资源队列。注,volcano 支持多个资源队列(queue),每个 queue 可配置资源大小及优先级

  • 如果 taskName 未设置,则使用 index 创建默认名称。注:vcjob 内的每个 task 定义,根据 replica 数量,对应到 kubernetes 内的多个 pod。

  • webhook-mananger 对 vcjob 信息做如下校验:

  • vcjob spec 基本信息是否合法,包括 MinAvailable,MaxRetry

  • spec.Tasks 信息:名称,Replicas, Policies

  • spec.Plugins:是否合法,是被支持的

  • spec.Queue:是否存在,且状态是 Open

如果 webhook-manager 校验通过,则 vcjob 被成功创建。可通过如下命令查看到:

 

kubectl get vcjob

 

.3 vcjob 创建过程:controller-manager 创建 pod 及 PodGroup

当 vcjob 被创建后,controller-manager 将监听到该信息,并开始管理整个 vcjob 生命周期的所有相关资源(包括 pod 及 PodGroup),主要操作如下:

  • 根据 vcjob 的 spec,创建 pod:

  • 设置 schedulerName(默认使用 vcjob 的 schedulerName),这样该 pod 就不会被其他 scheduler 处理了。

  • 设置 annotations 信息,主要包含 GroupName 信息,即将 pod 关联到 PodGroup

  • pod 名称:使用 job 名称,task 名称及 index(task 可能包含多个 replicas)

  • 设置 labels

  • 创建 PodGroup:先有 pod 被创建,再有 PodGroup 被创建

  • 设置 annotations 信息:从 pod 复制 annotations 信息

  • 设置 OwnerReferences:关联到 pod

  • 设置 queue

当 pod 和 PodGroup 被创建之后,可以通过如下命令查看到:

root@ubuntu:~# kubectl get pods -o wide --all-namespaces | grep job
default          test-job-default-nginx-0                   1/1     Running            0          41h     10.244.29.15     bogon     <none>           <none>
default          test-job-default-nginx-1                   1/1     Running            0          41h     10.244.29.16     bogon     <none>           <none>
default          test-job-default-nginx-2                   1/1     Running            0          41h     10.244.29.11     bogon     <none>           <none>
default          test-job-default-nginx-3                   1/1     Running            0          41h     10.244.29.14     bogon     <none>           <none>
default          test-job-default-nginx-4                   1/1     Running            0          41h     10.244.29.12     bogon     <none>           <none>
default          test-job-default-nginx-5                   1/1     Running            0          41h     10.244.29.13     bogon     <none>           <none>
root@ubuntu:~# kubectl get podgroup  --all-namespaces
No resources found
root@ubuntu:~# 

 

 

2.4 vcjob 创建过程:scheduler 调度 pod

当 pod 创建完成之后,scheduler 服务将监听到该信息,并根据 pod 和 PodGroup 信息,对 pod 进行资源调度和绑定(bind),过程如第一节所述。

当绑定完成后,再通过 kubect get pod 查看时,可以看到 pod 状态已变成 ContainerCreating 或者 Running,即相应 node 节点的 kubelet 服务已监听到该 bind 信息,并为该 pod 创建相应的 Container。

3 小结

以上是从 vcjob 创建到 pod 运行的简略过程,由此我们可以了解 volcano 三个组件的主要职责,以及关键节点。这将有利于使用过程中的问题排查及效率优化。

不足之处,本文略过了很多其他细节信息,包括 volume 信息,queue,metrics 等。这些将在后续文章补充。

 

 

For x86_64:
kubectl apply -f https://raw.githubusercontent.com/volcano-sh/volcano/master/installer/volcano-development.yaml

For arm64:
kubectl apply -f https://raw.githubusercontent.com/volcano-sh/volcano/master/installer/volcano-development-arm64.yaml

 

 

 

root@ubuntu:~# kubectl get pods -n volcano-system -o wide
NAME                                   READY   STATUS      RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
volcano-admission-6cc49fdc5-5zgzs      1/1     Running     0          34m   10.244.29.8   bogon   <none>           <none>
volcano-admission-init-qgh9b           0/1     Completed   0          34m   10.244.29.6   bogon   <none>           <none>
volcano-controllers-5f5c4f4785-8dbgl   1/1     Running     0          34m   10.244.29.7   bogon   <none>           <none>
volcano-scheduler-7f48dddb8f-8g6b5     1/1     Running     0          34m   10.244.29.5   bogon   <none>           <none>
root@ubuntu:~# kubectl get services -n volcano-system
NAME                        TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
volcano-admission-service   ClusterIP   10.103.9.198   <none>        443/TCP   35m

 

cat <<EOF >job.yaml    
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
  name: test-job
spec:
  minAvailable: 3
  schedulerName: volcano
  policies:
    - event: PodEvicted
      action: RestartJob
  plugins:
    ssh: []
    env: []
    svc: []
  maxRetry: 5
  queue: default
  # Comment out the following section to enable volumes for job input/output.
  #volumes:
  #  - mountPath: "/myinput"
  #  - mountPath: "/myoutput"
  #    volumeClaimName: "testvolumeclaimname"
  #    volumeClaim:
  #      accessModes: [ "ReadWriteOnce" ]
  #      storageClassName: "my-storage-class"
  #      resources:
  #        requests:
  #          storage: 1Gi
  tasks:
    - replicas: 6
      name: "default-nginx"
      template:
        metadata:
          name: web
        spec:
          containers:
            - image: nginx
              imagePullPolicy: IfNotPresent
              name: nginx
              resources:
                requests:
                  cpu: "1"
          restartPolicy: OnFailure
EOF    

 

 kubectl create -f job.yaml

root@ubuntu:~#  kubectl get pods -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
test-job-default-nginx-0   1/1     Running   0          14s   10.244.29.15   bogon   <none>           <none>
test-job-default-nginx-1   1/1     Running   0          14s   10.244.29.16   bogon   <none>           <none>
test-job-default-nginx-2   1/1     Running   0          14s   10.244.29.11   bogon   <none>           <none>
test-job-default-nginx-3   1/1     Running   0          14s   10.244.29.14   bogon   <none>           <none>
test-job-default-nginx-4   1/1     Running   0          14s   10.244.29.12   bogon   <none>           <none>
test-job-default-nginx-5   1/1     Running   0          14s   10.244.29.13   bogon   <none>           <none>
root@ubuntu:~# 

 

root@ubuntu:~# kubectl get pods -o wide --all-namespaces | grep job
default          test-job-default-nginx-0                   1/1     Running            0          41h     10.244.29.15     bogon     <none>           <none>
default          test-job-default-nginx-1                   1/1     Running            0          41h     10.244.29.16     bogon     <none>           <none>
default          test-job-default-nginx-2                   1/1     Running            0          41h     10.244.29.11     bogon     <none>           <none>
default          test-job-default-nginx-3                   1/1     Running            0          41h     10.244.29.14     bogon     <none>           <none>
default          test-job-default-nginx-4                   1/1     Running            0          41h     10.244.29.12     bogon     <none>           <none>
default          test-job-default-nginx-5                   1/1     Running            0          41h     10.244.29.13     bogon     <none>           <none>
root@ubuntu:~# 

 

 

root@ubuntu:~# kubectl get  vcjob
NAME       AGE
test-job   41h
root@ubuntu:~# kubectl describe vcjob
Name:         test-job
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  batch.volcano.sh/v1alpha1
Kind:         Job
Metadata:
  Creation Timestamp:  2021-07-05T09:39:59Z
  Generation:          1
  Managed Fields:
    API Version:  batch.volcano.sh/v1alpha1
    Fields Type:  FieldsV1
    fieldsV1:
      f:spec:
        .:
        f:maxRetry:
        f:minAvailable:
        f:plugins:
          .:
          f:env:
          f:ssh:
          f:svc:
        f:policies:
        f:queue:
        f:schedulerName:
    Manager:      kubectl
    Operation:    Update
    Time:         2021-07-05T09:39:59Z
    API Version:  batch.volcano.sh/v1alpha1
    Fields Type:  FieldsV1
    fieldsV1:
      f:spec:
        f:tasks:
      f:status:
        .:
        f:controlledResources:
          .:
          f:plugin-env:
          f:plugin-ssh:
          f:plugin-svc:
        f:minAvailable:
        f:running:
        f:state:
          .:
          f:lastTransitionTime:
          f:phase:
    Manager:         vc-controller-manager
    Operation:       Update
    Time:            2021-07-05T09:40:11Z
  Resource Version:  938444
  Self Link:         /apis/batch.volcano.sh/v1alpha1/namespaces/default/jobs/test-job
  UID:               3df22478-aac7-4185-8a8b-dfc4ce9944ec
Spec:
  Max Retry:      5
  Min Available:  3
  Plugins:
    Env:
    Ssh:
    Svc:
  Policies:
    Action:        RestartJob
    Event:         PodEvicted
  Queue:           default
  Scheduler Name:  volcano
  Tasks:
    Name:      default-nginx
    Replicas:  6
    Template:
      Metadata:
        Name:  web
      Spec:
        Containers:
          Image:              nginx
          Image Pull Policy:  IfNotPresent
          Name:               nginx
          Resources:
            Requests:
              Cpu:       1
        Restart Policy:  OnFailure
Status:
  Controlled Resources:
    Plugin - Env:  env
    Plugin - Ssh:  ssh
    Plugin - Svc:  svc
  Min Available:   3
  Running:         6
  State:
    Last Transition Time:  2021-07-05T09:40:10Z
    Phase:                 Running
Events:                    <none>
root@ubuntu:~# 

 

 

root@ubuntu:~# kubectl get podgroup  --all-namespaces
No resources found
root@ubuntu:~# 

 

posted on 2021-07-05 16:26  tycoon3  阅读(2102)  评论(0)    收藏  举报

导航