Skip to content

Commit db0fd8e

Browse files
authored
Kannon quick starter (#17)
* Define file organization * Update example srcs * Create quick starter doc * Format * Fix ns * Update volume name * Fix volume name * Add temp pod yaml * Update quick starter * Update README * Update CI * Fix lint ignore * Annotate types * Change filename * Update python version * Shorten the duration * Fix parent class * Update task figure
1 parent 18889a5 commit db0fd8e

File tree

16 files changed

+479
-4
lines changed

16 files changed

+479
-4
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ Kannon can be installed via `pip`.
99
pip install kannon
1010
```
1111

12+
# [Quick Starter](./example/README.md)
13+
An easy and self-contained tutorial can be found in [here](./example/README.md)!
14+
1215
# Usage
1316
It is required for users to prepare following two scripts and copy them into a docker container:
1417
- A script to start task pipeline on master job.

example/Dockerfile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM python:3.10.11
2+
3+
WORKDIR /usr/src/app
4+
5+
COPY requirements.txt .
6+
RUN pip install --no-cache-dir -r requirements.txt
7+
8+
COPY . .

example/README.md

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# Quick Starter
2+
This is a easy and self-contained tutorial of `kannon`.
3+
4+
## Requirements
5+
### Install Docker
6+
Install docker from [Get Docker](https://docs.docker.com/get-docker/).
7+
8+
### Install minikube
9+
Install minikube following the instruction on the [minikube start](https://minikube.sigs.k8s.io/docs/start/) document. Make sure the whole setup completed successfully.
10+
11+
12+
13+
## Steps
14+
### 1. Start minikube
15+
Make sure the docker daemon is running.
16+
```bash
17+
$ minikube start
18+
```
19+
20+
### 2. Build docker image
21+
Enable to push a local docker image to the docker daemon within the minikube cluster.
22+
The detail is given [here](https://minikube.sigs.k8s.io/docs/handbook/pushing/#1-pushing-directly-to-the-in-cluster-docker-daemon-docker-env).
23+
```bash
24+
$ eval $(minikube docker-env)
25+
```
26+
27+
Build a docker image from `example/Dockerfile`.
28+
```bash
29+
$ cd ./example
30+
$ docker build -t kannon_quick_starter .
31+
```
32+
33+
Now, the docker image is available within the cluster.
34+
35+
### 3. Create the required Kubernetes resources
36+
Create a new namespace `kannon-quick-starter`.
37+
```bash
38+
$ minikube kubectl -- apply -f k8s/ns.yaml
39+
namespace/kannon-quick-starter created
40+
```
41+
42+
Create a new service account, role, and role-biding.
43+
```bash
44+
$ minikube kubectl -- apply -f k8s/sa.yaml
45+
serviceaccount/job-manager created
46+
role.rbac.authorization.k8s.io/job-manager-role created
47+
rolebinding.rbac.authorization.k8s.io/job-manager-rolebinding created
48+
```
49+
50+
Create a new persistent volume and persistent volume claim, which is used as a common cache for multiple k8s jobs.
51+
```bash
52+
$ minikube kubectl -- apply -f k8s/pv.yaml
53+
persistentvolume/kannon-cache created
54+
persistentvolumeclaim/kannon-cache-claim created
55+
```
56+
57+
58+
### 4. Check task definition
59+
gokart tasks to be run are defined in `example/tasks.py`.
60+
61+
In this quick starter, the following tasks will be run.
62+
Each block represents a single task, `TaskName (duration)`
63+
64+
<div align="center">
65+
66+
![](./image/quick_starter_task.jpeg)
67+
68+
</div>
69+
70+
In `tasks.py`, `TaskC`, `TaskD`, and `TaskD` inherits `kannon.TaskOnBullet` instead of `gokart.TaskOnKart`, so Task C0-C2, D0-D2, and E0-E2 are run on different jobs in parallel.
71+
72+
```python
73+
# example/tasks.py
74+
class TaskC(kannon.TaskOnBullet):
75+
...
76+
77+
class TaskD(kannon.TaskOnBullet):
78+
...
79+
80+
class TaskE(kannon.TaskOnBullet):
81+
...
82+
```
83+
84+
Since Task C, D, and E are tasks that will take longer time than other tasks and they can be run in parallel, `kannon` will be very effective! Let's check it.
85+
86+
87+
### 5. Run master job
88+
Run the master job!
89+
```bash
90+
$ minikube kubectl -- apply -f k8s/master-job.yaml
91+
job.batch/master-job-quick-starter created
92+
```
93+
94+
Let's check running jobs. You can see 3 child tasks are running on multiple jobs in parallel.
95+
```bash
96+
$ minikube kubectl -- get jobs -n kannon-quick-starter
97+
NAME COMPLETIONS DURATION AGE
98+
# C0-C2 are done in parallel
99+
master-job-quick-starter 0/1 65s 65s
100+
quick-starter-taskc-069-20230416142331 1/1 35s 51s
101+
quick-starter-taskc-169-20230416142334 1/1 35s 48s
102+
quick-starter-taskc-191-20230416142337 1/1 35s 45s
103+
# now, D0-D2 are running in parallel
104+
quick-starter-taskd-014-20230416142415 0/1 7s 7s
105+
quick-starter-taskd-036-20230416142406 0/1 16s 16s
106+
quick-starter-taskd-079-20230416142417 0/1 5s 5s
107+
```
108+
109+
### 6. Check the result
110+
Let's check the final result.
111+
```bash
112+
$ minikube kubectl -- get jobs -n kannon-quick-starter
113+
NAME COMPLETIONS DURATION AGE
114+
master-job-quick-starter 1/1 2m28s 3m13s
115+
# C0-C2 are done in parallel
116+
quick-starter-taskc-069-20230416142331 1/1 35s 2m59s
117+
quick-starter-taskc-169-20230416142334 1/1 35s 2m56s
118+
quick-starter-taskc-191-20230416142337 1/1 35s 2m53s
119+
# D0-D2 are done in parallel
120+
quick-starter-taskd-014-20230416142415 1/1 36s 2m15s
121+
quick-starter-taskd-036-20230416142406 1/1 35s 2m24s
122+
quick-starter-taskd-079-20230416142417 1/1 36s 2m13s
123+
# E0-E2 are done in parallel
124+
quick-starter-taske-118-20230416142442 1/1 34s 108s
125+
quick-starter-taske-143-20230416142455 1/1 34s 95s
126+
quick-starter-taske-146-20230416142456 1/1 34s 94s
127+
```
128+
129+
All jobs are completed successfully!
130+
Duration for the master job to be completed is `2m28s`.
131+
Compared to the case without `kannon`, it is almost **2x** faster!
132+
133+
|using kannon? | duration |
134+
|---|---|
135+
|yes | **2m28s**|
136+
|no | 5m09s|
137+
138+
139+
### (Optional) Clear the cache to rerun the tasks
140+
```bash
141+
$ minikube kubectl -- apply -f k8s/temp-pod.yaml
142+
pod/temp-pod created
143+
144+
$ minikube kubectl -- exec -it temp-pod -n kannon-quick-starter -- /bin/sh
145+
```
146+
147+
Within `temp-pod`, execute the following commands.
148+
```
149+
/ #
150+
/ # ls cache/
151+
log tasks
152+
/ # rm -rf cache/*
153+
```
154+
Now, all caches saved on the persistent volume `kannon-cache` are cleared.
155+
156+
### (Optional) Clean up
157+
```bash
158+
# Delete namespace
159+
$ minikube kubectl -- delete ns kannon-quick-starter
160+
# Delete persistent volume
161+
$ minikube kubectl -- delete pv kannon-cache
162+
```

example/conf/base.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[TaskOnKart]
2+
workspace_directory=${TASK_WORKSPACE_DIRECTORY}
17.7 KB
Loading

example/k8s/master-job.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
apiVersion: batch/v1
2+
kind: Job
3+
metadata:
4+
name: master-job-quick-starter
5+
namespace: kannon-quick-starter
6+
spec:
7+
template:
8+
spec:
9+
serviceAccountName: job-manager
10+
containers:
11+
- name: job
12+
image: kannon_quick_starter
13+
command: ["python", "./run_batch.py"]
14+
imagePullPolicy: IfNotPresent
15+
volumeMounts:
16+
- name: kannon-cache
17+
mountPath: /cache
18+
env:
19+
- name: TASK_WORKSPACE_DIRECTORY
20+
value: /cache
21+
restartPolicy: Never
22+
volumes:
23+
- name: kannon-cache
24+
persistentVolumeClaim:
25+
claimName: kannon-cache-claim

example/k8s/ns.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
apiVersion: v1
2+
kind: Namespace
3+
metadata:
4+
name: kannon-quick-starter

example/k8s/pv.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
apiVersion: v1
2+
kind: PersistentVolume
3+
metadata:
4+
name: kannon-cache
5+
spec:
6+
storageClassName: manual
7+
capacity:
8+
storage: 1Gi
9+
accessModes:
10+
- ReadWriteMany
11+
hostPath:
12+
path: /cache
13+
---
14+
apiVersion: v1
15+
kind: PersistentVolumeClaim
16+
metadata:
17+
name: kannon-cache-claim
18+
namespace: kannon-quick-starter
19+
spec:
20+
storageClassName: manual
21+
accessModes:
22+
- ReadWriteMany
23+
resources:
24+
requests:
25+
storage: 1Gi

example/k8s/sa.yaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
apiVersion: v1
3+
kind: ServiceAccount
4+
metadata:
5+
name: job-manager
6+
namespace: kannon-quick-starter
7+
---
8+
apiVersion: rbac.authorization.k8s.io/v1
9+
kind: Role
10+
metadata:
11+
name: job-manager-role
12+
namespace: kannon-quick-starter
13+
rules:
14+
- apiGroups: ["batch"]
15+
resources: ["jobs"]
16+
verbs: ["create", "get", "list", "watch", "delete"]
17+
- apiGroups: ["batch"]
18+
resources: ["jobs/status"]
19+
verbs: ["get", "watch", "list"]
20+
---
21+
apiVersion: rbac.authorization.k8s.io/v1
22+
kind: RoleBinding
23+
metadata:
24+
name: job-manager-rolebinding
25+
namespace: kannon-quick-starter
26+
subjects:
27+
- kind: ServiceAccount
28+
name: job-manager
29+
namespace: kannon-quick-starter
30+
roleRef:
31+
kind: Role
32+
name: job-manager-role
33+
apiGroup: rbac.authorization.k8s.io

example/k8s/temp-pod.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: temp-pod
5+
namespace: kannon-quick-starter
6+
spec:
7+
containers:
8+
- name: busybox
9+
image: busybox
10+
command: ["sleep", "3600"]
11+
volumeMounts:
12+
- mountPath: /cache
13+
name: kannon-cache
14+
volumes:
15+
- name: kannon-cache
16+
persistentVolumeClaim:
17+
claimName: kannon-cache-claim
18+
restartPolicy: Never

0 commit comments

Comments
 (0)