Skip to content

Commit a638662

Browse files
authored
Merge pull request #8 from converged-computing/add-global-token
add support for global token and kind example
2 parents e09b003 + abe625e commit a638662

File tree

16 files changed

+644
-29
lines changed

16 files changed

+644
-29
lines changed

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
rainbow.db
2+
env

cmd/server/server.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,41 @@ import (
1010
)
1111

1212
var (
13-
address string
13+
host string
1414
name = "rainbow"
1515
sqliteFile = "rainbow.db"
1616
environment = "development"
1717
cleanup = false
1818
secret = "chocolate-cookies"
19+
globalToken = ""
1920
)
2021

2122
func main() {
22-
flag.StringVar(&address, "address", ":50051", "Server address (host:port)")
23+
flag.StringVar(&host, "host", ":50051", "Server address (host:port)")
2324
flag.StringVar(&name, "name", name, "Server name (default: rainbow)")
2425
flag.StringVar(&sqliteFile, "db", sqliteFile, "sqlite3 database file (default: rainbow.db)")
26+
flag.StringVar(&globalToken, "global-token", name, "global token for cluster access (not recommended)")
2527
flag.StringVar(&secret, "secret", secret, "secret to validate registration (default: chocolate-cookies)")
2628
flag.StringVar(&environment, "environment", environment, "environment (default: development)")
2729
flag.BoolVar(&cleanup, "cleanup", cleanup, "cleanup previous sqlite database (default: false)")
2830
flag.Parse()
2931

3032
// create server
3133
log.Print("creating 🌈️ server...")
32-
s, err := server.NewServer(name, types.Version, environment, sqliteFile, cleanup, secret)
34+
s, err := server.NewServer(name, types.Version, environment, sqliteFile, cleanup, secret, globalToken)
3335
if err != nil {
3436
log.Fatalf("error while creating server: %v", err)
3537
}
3638
defer s.Stop()
3739

40+
// Give a warning if the globalToken is set
41+
if globalToken != "" {
42+
log.Printf("⚠️ WARNING: global-token is set, use with caution.")
43+
}
44+
3845
// run server
3946
log.Printf("starting scheduler server: %s", s.String())
40-
if err := s.Start(context.Background(), address); err != nil {
47+
if err := s.Start(context.Background(), host); err != nil {
4148
log.Fatalf("error while running scheduler server: %v", err)
4249
}
4350
log.Printf("🌈️ done 🌈️")

docs/examples/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
Examples coming soon:
44

55
- [docker-compose](docker-compose): Simple setup to run a scheduler and two clusters with local docker images
6-
- Kubernetes in Docker (kind)
6+
- [kind](kind): Kubernetes in Docker (kind)

docs/examples/docker-compose/docker-compose-demo.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ services:
77
container_name: scheduler
88
image: ghcr.io/converged-computing/rainbow-scheduler:latest
99
entrypoint: rainbow-scheduler
10-
command: --address :8080 --name rainbow --secret peanutbuttajellay
10+
command: --host :8080 --name rainbow --secret peanutbuttajellay
1111
volumes:
1212
- ./data:/data
1313
ports:

docs/examples/docker-compose/docker-compose.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ services:
77
container_name: scheduler
88
image: ghcr.io/converged-computing/rainbow-scheduler:latest
99
entrypoint: rainbow-scheduler
10-
command: --address :8080 --name rainbow --secret peanutbuttajellay
10+
command: --host :8080 --name rainbow --secret peanutbuttajellay
1111
volumes:
1212
- ./data:/data
1313
ports:

docs/examples/kind/README.md

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# Kubernetes in Docker (kind)
2+
3+
This example shows using the [rainbow docker images](https://github.com/orgs/converged-computing/packages?repo_name=rainbow) locally via kind, which is Kubernetes in docker. These same manifests (the YAML files) will likely work in production Kubernetes as well.
4+
5+
## Usage
6+
7+
## 1. Create Cluster
8+
9+
This cluster is going to allow us to create ingress.
10+
11+
```bash
12+
kind create cluster --config ./kind-config.yaml
13+
```
14+
15+
## 2. Load Images
16+
17+
This step is optional, but if you want to load your images in before creating Kubernetes objects, you can.
18+
This mostly helps if you have a local image (otherwise it will pull from the remote registry directory)
19+
20+
```bash
21+
kind load docker-image ghcr.io/converged-computing/rainbow-flux:latest
22+
kind load docker-image ghcr.io/converged-computing/rainbow-scheduler:latest
23+
```
24+
25+
## 3. Create Service and Ingress
26+
27+
Let's next create the service. While we don't technically need this (communication happens within the network of pods) we anticipate some case when we will want to interact from outside of that space and thus show you how to set it up.
28+
29+
```bash
30+
kubectl create -f ./service.yaml
31+
kubectl create -f ./ingress.yaml
32+
```
33+
34+
## 4. Create Rainbow Scheduler
35+
36+
Let's create the rainbow scheduler deployment.
37+
38+
```bash
39+
kubectl create -f ./scheduler.yaml
40+
```
41+
42+
And ensure it is running OK:
43+
44+
```bash
45+
kubectl logs scheduler-798ddccf-pxfxx
46+
```
47+
```console
48+
2024/02/14 20:53:37 creating 🌈️ server...
49+
2024/02/14 20:53:37 ✨️ creating rainbow.db...
50+
2024/02/14 20:53:37 rainbow.db file created
51+
2024/02/14 20:53:37 create cluster table...
52+
2024/02/14 20:53:37 cluster table created
53+
2024/02/14 20:53:37 create jobs table...
54+
2024/02/14 20:53:37 jobs table created
55+
2024/02/14 20:53:37 ⚠️ WARNING: global-token is set, use with caution.
56+
2024/02/14 20:53:37 starting scheduler server: rainbow v0.1.0-draft
57+
2024/02/14 20:53:37 server listening: [::]:8080
58+
```
59+
60+
Importantly, we give the scheduler a predictable hostname.
61+
62+
```bash
63+
kubectl exec -it scheduler-798ddccf-pxfxx -- cat /etc/hosts
64+
```
65+
```console
66+
# Kubernetes-managed hosts file.
67+
127.0.0.1 localhost
68+
::1 localhost ip6-localhost ip6-loopback
69+
fe00::0 ip6-localnet
70+
fe00::0 ip6-mcastprefix
71+
fe00::1 ip6-allnodes
72+
fe00::2 ip6-allrouters
73+
10.244.0.5 scheduler.rainbow.default.svc.cluster.local scheduler
74+
```
75+
76+
## 5. Start Clusters
77+
78+
We are going to cheat a bit and create multiple "clusters" (pods) via an indexed job.
79+
The names of the pods (hostnames) will correspond with the names of the clusters. We also
80+
are using a `--global-token` so a shared filesystem is not needed - the scheduler will assign
81+
the same token to all newly registered clusters. This is of course not intended for a production
82+
setup.
83+
84+
```bash
85+
kubectl apply -f ./clusters.yaml
86+
```
87+
88+
Four pods should be running now! You can watch the scheduler logs, and ultimately see logs of a cluster to see what is happening.
89+
90+
```console
91+
👋️ Hello, I'm clusters-0!
92+
📜️ Registering clusters-0...
93+
token: "jellaytime"
94+
secret: "e2342db8-1c0b-40dd-9b42-e49e56480916"
95+
status: REGISTER_SUCCESS
96+
97+
🥳️ All 3 clusters are registered.
98+
status: SUBMIT_SUCCESS
99+
100+
status: SUBMIT_SUCCESS
101+
102+
status: SUBMIT_SUCCESS
103+
104+
Status: REQUEST_JOBS_SUCCESS
105+
Received 2 jobs for inspection!
106+
Accepting 2 jobs...
107+
[5, 1]
108+
Submit job ['echo', 'hello', 'from', 'clusters-1,', 'a', 'new', 'word', 'is', 'perfume']: ƒCYGUnZd
109+
Submit job ['echo', 'hello', 'from', 'clusters-2,', 'a', 'new', 'word', 'is', 'sn']: ƒCYraW3Z
110+
Ran job ƒCYGUnZd hello from clusters-1, a new word is perfume
111+
112+
Ran job ƒCYraW3Z hello from clusters-2, a new word is sn
113+
114+
status: SUBMIT_SUCCESS
115+
116+
status: SUBMIT_SUCCESS
117+
118+
status: SUBMIT_SUCCESS
119+
120+
Status: REQUEST_JOBS_SUCCESS
121+
Received 2 jobs for inspection!
122+
Accepting 2 jobs...
123+
[16, 14]
124+
Submit job ['echo', 'hello', 'from', 'clusters-2,', 'a', 'new', 'word', 'is', 'world']: ƒH7VNJbZ
125+
Submit job ['echo', 'hello', 'from', 'clusters-0,', 'a', 'new', 'word', 'is', 'essex']: ƒH86x1Mq
126+
Ran job ƒH86x1Mq hello from clusters-0, a new word is essex
127+
128+
Ran job ƒH7VNJbZ hello from clusters-2, a new word is world
129+
130+
status: SUBMIT_SUCCESS
131+
132+
status: SUBMIT_SUCCESS
133+
134+
status: SUBMIT_SUCCESS
135+
136+
status: SUBMIT_SUCCESS
137+
138+
status: SUBMIT_SUCCESS
139+
140+
Status: REQUEST_JOBS_SUCCESS
141+
Received 5 jobs for inspection!
142+
Accepting 5 jobs...
143+
[27, 23, 20, 29, 22]
144+
Submit job ['echo', 'hello', 'from', 'clusters-0,', 'a', 'new', 'word', 'is', 'resorts']: ƒMetzhd1
145+
Submit job ['echo', 'hello', 'from', 'clusters-1,', 'a', 'new', 'word', 'is', 'puzzles']: ƒMfY4Pfd
146+
Submit job ['echo', 'hello', 'from', 'clusters-1,', 'a', 'new', 'word', 'is', 'mean']: ƒMg9e6Ru
147+
Submit job ['echo', 'hello', 'from', 'clusters-0,', 'a', 'new', 'word', 'is', 'jamie']: ƒMgnhnUX
148+
Submit job ['echo', 'hello', 'from', 'clusters-1,', 'a', 'new', 'word', 'is', 'final']: ƒMhNoVxT
149+
Ran job ƒMhNoVxT hello from clusters-1, a new word is final
150+
151+
Ran job ƒMg9e6Ru hello from clusters-1, a new word is mean
152+
153+
Ran job ƒMgnhnUX hello from clusters-0, a new word is jamie
154+
155+
Ran job ƒMfY4Pfd hello from clusters-1, a new word is puzzles
156+
157+
Ran job ƒMetzhd1 hello from clusters-0, a new word is resorts
158+
159+
status: SUBMIT_SUCCESS
160+
161+
status: SUBMIT_SUCCESS
162+
163+
status: SUBMIT_SUCCESS
164+
165+
status: SUBMIT_SUCCESS
166+
167+
status: SUBMIT_SUCCESS
168+
169+
Status: REQUEST_JOBS_SUCCESS
170+
Received 2 jobs for inspection!
171+
Accepting 2 jobs...
172+
[33, 35]
173+
Submit job ['echo', 'hello', 'from', 'clusters-1,', 'a', 'new', 'word', 'is', 'goal']: ƒSDXnWB1
174+
Submit job ['echo', 'hello', 'from', 'clusters-1,', 'a', 'new', 'word', 'is', 'during']: ƒSE9NCwH
175+
Ran job ƒSE9NCwH hello from clusters-1, a new word is during
176+
177+
Ran job ƒSDXnWB1 hello from clusters-1, a new word is goal
178+
179+
status: SUBMIT_SUCCESS
180+
181+
status: SUBMIT_SUCCESS
182+
183+
Status: REQUEST_JOBS_SUCCESS
184+
Received 1 jobs for inspection!
185+
Accepting 1 jobs...
186+
[41]
187+
Submit job ['echo', 'hello', 'from', 'clusters-2,', 'a', 'new', 'word', 'is', 'manufacture']: ƒWjQTeHm
188+
Ran job ƒWjQTeHm hello from clusters-2, a new word is manufacture
189+
190+
💤️ Cluster clusters-0 is finished! Shutting down.
191+
```
192+
193+
194+
And that's it! Clean up when you are done:
195+
196+
```bash
197+
kind delete cluster
198+
```

docs/examples/kind/clusters.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
apiVersion: batch/v1
2+
kind: Job
3+
metadata:
4+
name: clusters
5+
spec:
6+
completions: 3
7+
parallelism: 3
8+
completionMode: Indexed
9+
template:
10+
spec:
11+
restartPolicy: Never
12+
containers:
13+
- name: cluster
14+
image: ghcr.io/converged-computing/rainbow-flux:latest
15+
command: ["flux"]
16+
17+
# Note that --host defaults to scheduler.rainbow.default.svc.cluster.local:8080
18+
args: ["start", "python3",
19+
"/code/docs/examples/kind/scripts/run-demo.py",
20+
"--peer", "clusters-0",
21+
"--peer", "clusters-1",
22+
"--peer", "clusters-2",
23+
"--iters", "5"]
24+
imagePullPolicy: Never

docs/examples/kind/ingress.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
apiVersion: networking.k8s.io/v1
2+
kind: Ingress
3+
metadata:
4+
name: rainbow
5+
spec:
6+
rules:
7+
- host: localhost
8+
http:
9+
paths:
10+
- path: /
11+
pathType: Prefix
12+
backend:
13+
service:
14+
name: rainbow
15+
port:
16+
# TODO look at what wfmanager is doing with mlserver
17+
number: 8080
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
kind: Cluster
2+
apiVersion: kind.x-k8s.io/v1alpha4
3+
nodes:
4+
- role: control-plane
5+
kubeadmConfigPatches:
6+
- |
7+
kind: InitConfiguration
8+
nodeRegistration:
9+
kubeletExtraArgs:
10+
node-labels: "ingress-ready=true"
11+
extraPortMappings:
12+
- containerPort: 8080
13+
hostPort: 8080
14+
protocol: TCP
15+
- containerPort: 80
16+
hostPort: 80
17+
protocol: TCP
18+
- containerPort: 443
19+
hostPort: 443
20+
protocol: TCP

docs/examples/kind/scheduler.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: scheduler
5+
spec:
6+
selector:
7+
matchLabels:
8+
app: rainbow
9+
replicas: 1
10+
template:
11+
metadata:
12+
labels:
13+
# Matches the headless service
14+
app: rainbow
15+
spec:
16+
subdomain: rainbow
17+
hostname: scheduler
18+
containers:
19+
- name: scheduler
20+
image: ghcr.io/converged-computing/rainbow-scheduler:latest
21+
22+
# Note that we are setting a global token (not recommended)! So that
23+
# we don't need a shared filesystem.
24+
command: ["rainbow-scheduler"]
25+
args: ["--host", ":8080", "--name", "rainbow", "--secret", "peanutbutta", "--global-token", "jellaytime"]
26+
imagePullPolicy: Never

0 commit comments

Comments
 (0)