Volcano Job Plugin -- SVC User Guide
Background
SVC Plugin is designed for the communication for pods within a volcano job, which is essential for workloads such as
TensorFlow and MPI. For example, it is necessary for
tensorflow job to contact with each other between ps and worker. Volcano job plugin svc enable pods within a job
to visit each other by domain.
Key Points
- Once
svcplugin is configured, value of fieldhostnameunderspecwill be filled out to be the pod name for all pods under the job automatically. Namely,pod.spec.hostnameispod.metadata.name. - Once
svcplugin is configured, value of fieldsubdomainunderspecwill be filled out to be the job name for all pods under the job automatically. Namely,pod.spec.subdomainisjob.metadata.name. - Once
svcplugin is configured, environment variablesVC_%s_NUMwill be registered to all the containers(including initContainers) under the job automatically.%swill be replaced by the task name which the pod belongs to. The value of the environment variable is the task replicas. The number of the environment variables depends on the number of tasks, which is usually2for most AI and Big Data jobs contains 2 roles. For example, a Spark job containsdriverandexecutor. - Once
svcplugin is configured, environment variablesVC_%s_HOSTSwill be registered to all the containers(including initContainers) under the job automatically.%swill be replaced by the task name which the pod belongs to. The value of the environment variable are the domains of all the pods under the task. The number of the environment variables depends on the number of tasks, which is usually2for most AI and Big Data jobs contains 2 roles. For example, a TensorFlow job containspsandworker. - A configmap whose name joins job-name and
svcwith-will be created automatically, which contains replicas of all tasks and domains of all pods under the task. It will be mounted as a volume for all pods under the job and serves as the host files under the directory/etc/volcano/. - A headless service whose name is the same with job will be created.
- If
disable-network-policyis set to be false, aNetworkPolicyobject with the typeIngresswill be created for the job.
Arguments
| ID | Name | Value | Default Value | Required | Description | Example |
|---|---|---|---|---|---|---|
| 1 | publish-not-ready-addresses | true/false | false | N | whether publish the pod address when it is not ready | svc: ["--publish-not-ready-addresses=true"] |
| 2 | disable-network-policy | true/false | false | N | whether disable network policy for the job | svc: ["--disable-network-policy=true"] |
Examples
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: tensorflow-dist-mnist
spec:
minAvailable: 3
schedulerName: volcano
plugins:
env: []
svc: [
"--publish-not-ready-addresses=false",
"--disable-network-policy=false",
] ## SVC plugin register
policies:
- event: PodEvicted
action: RestartJob
queue: default
tasks:
- replicas: 1
name: ps
template:
spec:
containers:
- command:
- sh
- -c
- |
PS_HOST=`cat /etc/volcano/ps.host | sed 's/$/&:2222/g' | sed 's/^/"/;s/$/"/' | tr "\n" ","`; ## Get host domain from host files generated
WORKER_HOST=`cat /etc/volcano/worker.host | sed 's/$/&:2222/g' | sed 's/^/"/;s/$/"/' | tr "\n" ","`;
export TF_CONFIG={\"cluster\":{\"ps\":[${PS_HOST}],\"worker\":[${WORKER_HOST}]},\"task\":{\"type\":\"ps\",\"index\":${VK_TASK_INDEX}},\"environment\":\"cloud\"};
python /var/tf_dist_mnist/dist_mnist.py
image: volcanosh/dist-mnist-tf-example:0.0.1
name: tensorflow
ports:
- containerPort: 2222
name: tfjob-port
resources: {}
restartPolicy: Never
- replicas: 2
name: worker
policies:
- event: TaskCompleted
action: CompleteJob
template:
spec:
containers:
- command:
- sh
- -c
- |
PS_HOST=`cat /etc/volcano/ps.host | sed 's/$/&:2222/g' | sed 's/^/"/;s/$/"/' | tr "\n" ","`;
WORKER_HOST=`cat /etc/volcano/worker.host | sed 's/$/&:2222/g' | sed 's/^/"/;s/$/"/' | tr "\n" ","`;
export TF_CONFIG={\"cluster\":{\"ps\":[${PS_HOST}],\"worker\":[${WORKER_HOST}]},\"task\":{\"type\":\"worker\",\"index\":${VK_TASK_INDEX}},\"environment\":\"cloud\"};
python /var/tf_dist_mnist/dist_mnist.py
image: volcanosh/dist-mnist-tf-example:0.0.1
name: tensorflow
ports:
- containerPort: 2222
name: tfjob-port
resources: {}
restartPolicy: Never
Note:
- Fields
hostnameandsubdomainhave been added to the pods under jobtensorflow-dist-mnist. The following is part yaml of thepspod.
apiVersion: v1
kind: Pod
metadata:
annotations:
scheduling.k8s.io/group-name: tensorflow-dist-mnist
volcano.sh/job-name: tensorflow-dist-mnist
volcano.sh/job-version: "0"
volcano.sh/queue-name: default
volcano.sh/task-spec: ps
volcano.sh/template-uid: tensorflow-dist-mnist-ps
labels:
volcano.sh/job-name: tensorflow-dist-mnist
volcano.sh/job-namespace: default
volcano.sh/queue-name: default
volcano.sh/task-spec: ps
name: tensorflow-dist-mnist-ps-0
namespace: default
ownerReferences:
- apiVersion: batch.volcano.sh/v1alpha1
blockOwnerDeletion: true
controller: true
kind: Job
name: tensorflow-dist-mnist
uid: 52c98cc2-4791-490f-8572-22df2c16ef8f
resourceVersion: "855403"
uid: 1b9e834b-de7e-4760-9b23-2a673d38e5d9
spec:
containers:
- command:
- sh
- -c
- |
PS_HOST=`cat /etc/volcano/ps.host | sed 's/$/&:2222/g' | sed 's/^/"/;s/$/"/' | tr "\n" ","`; ## Get host domain from host files generated
WORKER_HOST=`cat /etc/volcano/worker.host | sed 's/$/&:2222/g' | sed 's/^/"/;s/$/"/' | tr "\n" ","`;
export TF_CONFIG={\"cluster\":{\"ps\":[${PS_HOST}],\"worker\":[${WORKER_HOST}]},\"task\":{\"type\":\"ps\",\"index\":${VK_TASK_INDEX}},\"environment\":\"cloud\"};
python /var/tf_dist_mnist/dist_mnist.py
env:
- name: VK_TASK_INDEX
value: "0"
- name: VC_TASK_INDEX
value: "0"
- name: VC_PS_HOSTS ## Environment variable `VC_PS_HOSTS` contains the domains of all the `ps` hosts.
valueFrom:
configMapKeyRef:
key: VC_PS_HOSTS
name: tensorflow-dist-mnist-svc
- name: VC_PS_NUM ## Environment variable `VC_PS_NUM` contains the number of `ps` hosts.
valueFrom:
configMapKeyRef:
key: VC_PS_NUM
name: tensorflow-dist-mnist-svc
- name: VC_WORKER_HOSTS ## Environment variable `VC_WORKER_HOSTS` contains the domains of all the `worker` hosts.
valueFrom:
configMapKeyRef:
key: VC_WORKER_HOSTS
name: tensorflow-dist-mnist-svc
- name: VC_WORKER_NUM ## Environment variable `VC_WORKER_NUM` contains the number of `worker` hosts.
valueFrom:
configMapKeyRef:
key: VC_WORKER_NUM
name: tensorflow-dist-mnist-svc
image: volcanosh/dist-mnist-tf-example:0.0.1
name: tensorflow
ports:
- containerPort: 2222
name: tfjob-port
protocol: TCP
resources: {}
volumeMounts: ## Mount the configmap generated for the job under `/etc/volcano`, which contains all host files.
- mountPath: /etc/volcano
name: tensorflow-dist-mnist-svc
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-wflz5
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
hostname: tensorflow-dist-mnist-ps-0 ## Add `hostname` field
nodeName: volcano-control-plane
restartPolicy: Never
schedulerName: volcano
subdomain: tensorflow-dist-mnist ## Add `subdomain` field
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- configMap: ## Configmap generated for the job
defaultMode: 420
name: tensorflow-dist-mnist-svc
name: tensorflow-dist-mnist-svc
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2022-04-13T02:08:17Z"
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2022-04-13T02:08:18Z"
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2022-04-13T02:08:18Z"
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2022-04-13T02:08:17Z"
status: "True"
type: PodScheduled
hostIP: x.x.x.x
phase: Running
podIP: x.x.x.x
podIPs:
- ip: x.x.x.x
qosClass: BestEffort
startTime: "2022-04-13T02:08:17Z"
- Host information is registered to all pods under the job. The following are registered environment variables for
pspod.
[root@tensorflow-dist-mnist-ps-0 /] env | grep VC
VC_PS_NUM=1
VC_PS_HOSTS=tensorflow-dist-mnist-ps-0.tensorflow-dist-mnist ## ps pod domain
VC_WORKER_NUM=2
VC_WORKER_HOSTS=tensorflow-dist-mnist-worker-0.tensorflow-dist-mnist,tensorflow-dist-mnist-worker-1.tensorflow-dist-mnist ## worker pods domains
- The host files added under
/etc/volcanoare as follows.
[root@tensorflow-dist-mnist-ps-0 /] ls /etc/volcano/
VC_PS_HOSTS VC_PS_NUM VC_WORKER_HOSTS VC_WORKER_NUM ps.host worker.host
[root@tensorflow-dist-mnist-ps-0 /]# cat /etc/volcano/ps.host
tensorflow-dist-mnist-ps-0.tensorflow-dist-mnist
[root@tensorflow-dist-mnist-ps-0 /]# cat /etc/volcano/worker.host
tensorflow-dist-mnist-worker-0.tensorflow-dist-mnist
tensorflow-dist-mnist-worker-1.tensorflow-dist-mnist
- The headless service
tensorflow-dist-mnistgenerated for the job is as follows.
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2022-04-13T02:08:15Z"
name: tensorflow-dist-mnist
namespace: default
ownerReferences:
- apiVersion: batch.volcano.sh/v1alpha1
blockOwnerDeletion: true
controller: true
kind: Job
name: tensorflow-dist-mnist
uid: 52c98cc2-4791-490f-8572-22df2c16ef8f
resourceVersion: "855341"
uid: a77cb081-72ae-442f-96da-e36974dfed48
spec:
clusterIP: None
clusterIPs:
- None
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
selector:
volcano.sh/job-name: tensorflow-dist-mnist
volcano.sh/job-namespace: default
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
- The configmap
tensorflow-dist-mnist-svcgenerated for the job is as follows.
apiVersion: v1
data:
VC_PS_HOSTS: tensorflow-dist-mnist-ps-0.tensorflow-dist-mnist
VC_PS_NUM: "1"
VC_WORKER_HOSTS: tensorflow-dist-mnist-worker-0.tensorflow-dist-mnist,tensorflow-dist-mnist-worker-1.tensorflow-dist-mnist
VC_WORKER_NUM: "2"
ps.host: tensorflow-dist-mnist-ps-0.tensorflow-dist-mnist
worker.host: |-
tensorflow-dist-mnist-worker-0.tensorflow-dist-mnist
tensorflow-dist-mnist-worker-1.tensorflow-dist-mnist
kind: ConfigMap
metadata:
creationTimestamp: "2022-04-13T02:08:15Z"
name: tensorflow-dist-mnist-svc
namespace: default
ownerReferences:
- apiVersion: batch.volcano.sh/v1alpha1
blockOwnerDeletion: true
controller: true
kind: Job
name: tensorflow-dist-mnist
uid: 52c98cc2-4791-490f-8572-22df2c16ef8f
resourceVersion: "855340"
uid: c4f3db21-6857-451f-b8b8-bbd5aa8b06ec
- The networkpolicy
tensorflow-dist-mnistgenerated for the job is as follows.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
creationTimestamp: "2022-04-13T02:08:15Z"
name: tensorflow-dist-mnist
namespace: default
ownerReferences:
- apiVersion: batch.volcano.sh/v1alpha1
blockOwnerDeletion: true
controller: true
kind: Job
name: tensorflow-dist-mnist
uid: 52c98cc2-4791-490f-8572-22df2c16ef8f
resourceVersion: "855343"
uid: ddf8aada-51d7-47c1-99a0-5e0d8a913a4d
spec:
ingress:
- from:
- podSelector:
matchLabels:
volcano.sh/job-name: tensorflow-dist-mnist
volcano.sh/job-namespace: default
podSelector:
matchLabels:
volcano.sh/job-name: tensorflow-dist-mnist
volcano.sh/job-namespace: default
policyTypes:
- Ingress
Note
- DNS plugin is required in your Kubernetes cluster such as
corndns. - Kubernetes version >= v1.14