forked from calfonso/rusternetes
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathquickstart.html
More file actions
528 lines (463 loc) · 18.9 KB
/
Copy pathquickstart.html
File metadata and controls
528 lines (463 loc) · 18.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quick Start - Rūsternetes</title>
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
<link rel="stylesheet" href="../style.css">
</head>
<body>
<nav class="nav">
<div class="nav-inner">
<a href="../index.html" class="nav-logo">
<img src="../favicon-colored.svg" width="22" height="22" alt="" style="vertical-align: middle;"> rūsternetes
</a>
<div class="nav-links">
<a href="index.html" style="color: var(--walle-yellow);">Docs</a>
</div>
</div>
</nav>
<div class="doc-layout">
<aside class="doc-sidebar">
<div class="doc-search">
<input type="text" class="doc-search-input" placeholder="Search docs... ( / )">
</div>
<div class="doc-search-results"></div>
<div class="sidebar-section">
<div class="sidebar-heading">Getting Started</div>
<ul class="sidebar-links">
<li><a href="quickstart.html" class="active">Quick Start</a></li>
<li><a href="installation.html">Installation</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-heading">Deployment</div>
<ul class="sidebar-links">
<li><a href="deployment.html">Overview</a></li>
<li><a href="all-in-one.html">All-in-One Binary</a></li>
<li><a href="docker-cluster.html">Compose + etcd</a></li>
<li><a href="sqlite-cluster.html">Compose + SQLite</a></li>
<li><a href="high-availability.html">High Availability</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-heading">Cluster Setup</div>
<ul class="sidebar-links">
<li><a href="bootstrap.html">Bootstrap</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-heading">Configuration</div>
<ul class="sidebar-links">
<li><a href="api-server-config.html">API Server</a></li>
<li><a href="kubelet-config.html">Kubelet</a></li>
<li><a href="scheduler-config.html">Scheduler</a></li>
<li><a href="controller-manager-config.html">Controller Manager</a></li>
<li><a href="kube-proxy-config.html">Kube-Proxy</a></li>
<li><a href="storage-config.html">Storage Backends</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-heading">Features</div>
<ul class="sidebar-links">
<li><a href="workloads.html">Workloads</a></li>
<li><a href="networking.html">Networking</a></li>
<li><a href="storage-volumes.html">Storage & Volumes</a></li>
<li><a href="security.html">Security</a></li>
<li><a href="crds.html">Custom Resources</a></li>
<li><a href="scheduling.html">Scheduling</a></li>
<li><a href="containers.html">Container Runtime</a></li>
<li><a href="kubectl.html">kubectl</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-heading">Operations</div>
<ul class="sidebar-links">
<li><a href="authentication.html">Authentication</a></li>
<li><a href="monitoring.html">Monitoring</a></li>
<li><a href="troubleshooting.html">Troubleshooting</a></li>
<li><a href="cloud-providers.html">Cloud Providers</a></li>
</ul>
</div>
<div class="sidebar-section">
<div class="sidebar-heading">Reference</div>
<ul class="sidebar-links">
<li><a href="api-reference.html">API Reference</a></li>
<li><a href="conformance.html">Conformance</a></li>
</ul>
</div>
</aside>
<div class="doc-overlay"></div>
<main class="doc-content">
<h1>Quick Start</h1>
<p class="lead">
Get a fully functional Rūsternetes cluster running in 5 minutes using Podman or Docker Compose.
No Rust toolchain required.
</p>
<h2>Prerequisites</h2>
<table>
<thead>
<tr>
<th>Platform</th>
<th>Requirement</th>
</tr>
</thead>
<tbody>
<tr>
<td>macOS</td>
<td><a href="https://podman-desktop.io/">Podman Desktop</a> or <a href="https://www.docker.com/products/docker-desktop/">Docker Desktop</a></td>
</tr>
<tr>
<td>Linux</td>
<td>Rootful Podman 4+ or <a href="https://docs.docker.com/engine/install/">Docker Engine</a> 24+</td>
</tr>
</tbody>
</table>
<p>
You also need <code>kubectl</code> installed on your host machine. Any recent version works —
Rūsternetes is compatible with the standard Kubernetes CLI.
</p>
<div class="admonition tip">
<div class="admonition-title">Rust is optional</div>
<p>
The compose setup builds everything inside containers. You only need Rust installed
if you want to <a href="installation.html">build from source</a> outside of containers.
</p>
</div>
<h2>Step-by-Step Setup</h2>
<h3>1. Clone the repository</h3>
<pre>
<div class="code-header">
<span class="code-dot red"></span>
<span class="code-dot yellow"></span>
<span class="code-dot green"></span>
<span class="code-title">terminal</span>
</div>
<code>git clone <repository-url>
cd rusternetes</code>
</pre>
<h3>2. Set the volumes path</h3>
<p>
The kubelet needs a shared directory to mount ConfigMaps, Secrets, and other volumes into
pod containers. This path must be absolute and accessible to both Docker and the kubelet container.
</p>
<pre>
<div class="code-header">
<span class="code-dot red"></span>
<span class="code-dot yellow"></span>
<span class="code-dot green"></span>
<span class="code-title">terminal</span>
</div>
<code>export KUBELET_VOLUMES_PATH=$(pwd)/.rusternetes/volumes
mkdir -p $KUBELET_VOLUMES_PATH</code>
</pre>
<div class="admonition warning">
<div class="admonition-title">Podman on macOS</div>
<p>
If using Podman Machine on macOS, <code>/tmp</code> is not shared between host and VM.
Use a path under your home directory (which is automatically mounted).
The <code>$(pwd)/.rusternetes/volumes</code> path works correctly.
</p>
</div>
<h3>3. Build the container images</h3>
<p>
This compiles each Rūsternetes component inside a container build stage. The first build takes
10–15 minutes; subsequent builds use the layer cache and are much faster.
</p>
<pre>
<div class="code-header">
<span class="code-dot red"></span>
<span class="code-dot yellow"></span>
<span class="code-dot green"></span>
<span class="code-title">terminal</span>
</div>
<code>podman compose -f compose.yml build <span class="comment"># or: docker compose -f docker-compose.yml build</span></code>
</pre>
<h3>4. Start the cluster</h3>
<pre>
<div class="code-header">
<span class="code-dot red"></span>
<span class="code-dot yellow"></span>
<span class="code-dot green"></span>
<span class="code-title">terminal</span>
</div>
<code>podman compose -f compose.yml up -d <span class="comment"># or: docker compose -f docker-compose.yml up -d</span></code>
</pre>
<p>
This starts all seven services. The API server waits for etcd to be healthy before accepting
connections.
</p>
<h3>5. Bootstrap the cluster</h3>
<p>
The bootstrap script generates TLS certificates, creates system namespaces
(<code>kube-system</code>, <code>kube-public</code>, <code>default</code>),
deploys CoreDNS, creates ServiceAccounts, and sets up the <code>kubernetes</code> service.
</p>
<pre>
<div class="code-header">
<span class="code-dot red"></span>
<span class="code-dot yellow"></span>
<span class="code-dot green"></span>
<span class="code-title">terminal</span>
</div>
<code>bash scripts/bootstrap-cluster.sh</code>
</pre>
<h3>6. Configure kubectl</h3>
<pre>
<div class="code-header">
<span class="code-dot red"></span>
<span class="code-dot yellow"></span>
<span class="code-dot green"></span>
<span class="code-title">terminal</span>
</div>
<code>export KUBECONFIG=~/.kube/rusternetes-config</code>
</pre>
<p>
The bootstrap script writes this kubeconfig file automatically. It points to
<code>https://localhost:6443</code> with the generated TLS credentials.
</p>
<h3>7. Verify the cluster</h3>
<pre>
<div class="code-header">
<span class="code-dot red"></span>
<span class="code-dot yellow"></span>
<span class="code-dot green"></span>
<span class="code-title">terminal</span>
</div>
<code>kubectl get nodes</code>
</pre>
<p>You should see two nodes in <code>Ready</code> status:</p>
<pre>
<div class="code-header">
<span class="code-dot red"></span>
<span class="code-dot yellow"></span>
<span class="code-dot green"></span>
<span class="code-title">output</span>
</div>
<code>NAME STATUS ROLES AGE VERSION
node-1 Ready <none> 30s v1.35.0-rusternetes
node-2 Ready <none> 30s v1.35.0-rusternetes</code>
</pre>
<p>Try deploying a workload:</p>
<pre>
<div class="code-header">
<span class="code-dot red"></span>
<span class="code-dot yellow"></span>
<span class="code-dot green"></span>
<span class="code-title">terminal</span>
</div>
<code>kubectl create deployment nginx --image=nginx
kubectl get pods -w</code>
</pre>
<h2>What You Get</h2>
<p>
The compose cluster runs seven services that mirror a real Kubernetes cluster:
</p>
<table>
<thead>
<tr>
<th>Service</th>
<th>Container</th>
<th>Role</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>etcd</code></td>
<td><code>rusternetes-etcd</code></td>
<td>Distributed key-value store for all cluster state</td>
</tr>
<tr>
<td><code>api-server</code></td>
<td><code>rusternetes-api-server</code></td>
<td>HTTPS REST API on port 6443 (TLS)</td>
</tr>
<tr>
<td><code>scheduler</code></td>
<td><code>rusternetes-scheduler</code></td>
<td>Assigns pods to nodes using filter/score plugins</td>
</tr>
<tr>
<td><code>controller-manager</code></td>
<td><code>rusternetes-controller-manager</code></td>
<td>Runs 31 reconciliation controllers</td>
</tr>
<tr>
<td><code>kubelet</code></td>
<td><code>rusternetes-kubelet</code></td>
<td>Node agent on node-1, manages containers via Docker</td>
</tr>
<tr>
<td><code>kubelet2</code></td>
<td><code>rusternetes-kubelet2</code></td>
<td>Node agent on node-2, same as above</td>
</tr>
<tr>
<td><code>kube-proxy</code></td>
<td><code>rusternetes-kube-proxy</code></td>
<td>iptables-based service routing (host network mode)</td>
</tr>
</tbody>
</table>
<p>
After bootstrapping, the cluster also runs <strong>CoreDNS</strong> as a pod in the
<code>kube-system</code> namespace, providing in-cluster DNS resolution at
<code>10.96.0.10</code>.
</p>
<h2>Common Operations</h2>
<h3>View logs</h3>
<pre>
<div class="code-header">
<span class="code-dot red"></span>
<span class="code-dot yellow"></span>
<span class="code-dot green"></span>
<span class="code-title">terminal</span>
</div>
<code><span class="comment"># All services</span>
podman compose -f compose.yml logs -f
<span class="comment"># Single service</span>
podman compose -f compose.yml logs -f api-server
podman compose -f compose.yml logs -f kubelet
podman compose -f compose.yml logs -f scheduler</code>
</pre>
<h3>Rebuild after code changes</h3>
<pre>
<div class="code-header">
<span class="code-dot red"></span>
<span class="code-dot yellow"></span>
<span class="code-dot green"></span>
<span class="code-title">terminal</span>
</div>
<code><span class="comment"># Rebuild and restart a single service</span>
podman compose -f compose.yml build api-server
podman compose -f compose.yml up -d api-server
<span class="comment"># Rebuild everything</span>
podman compose -f compose.yml build
podman compose -f compose.yml up -d</code>
</pre>
<h3>Stop the cluster</h3>
<pre>
<div class="code-header">
<span class="code-dot red"></span>
<span class="code-dot yellow"></span>
<span class="code-dot green"></span>
<span class="code-title">terminal</span>
</div>
<code><span class="comment"># Stop containers (preserves data)</span>
podman compose -f compose.yml down
<span class="comment"># Stop and delete all data (clean restart)</span>
podman compose -f compose.yml down -v</code>
</pre>
<h3>Clean restart</h3>
<p>
If you need to wipe the cluster completely and start fresh:
</p>
<pre>
<div class="code-header">
<span class="code-dot red"></span>
<span class="code-dot yellow"></span>
<span class="code-dot green"></span>
<span class="code-title">terminal</span>
</div>
<code><span class="comment"># Remove containers, volumes, and orphan pod containers</span>
podman compose -f compose.yml down -v
podman rm -f $(podman ps -aq --filter "label=rusternetes") 2>/dev/null || true
<span class="comment"># Start fresh</span>
podman compose -f compose.yml up -d
bash scripts/bootstrap-cluster.sh</code>
</pre>
<h2>Troubleshooting</h2>
<h3>Port 6443 already in use</h3>
<p>
Another process (often a real Kubernetes or minikube) is listening on port 6443.
Stop it or change the port mapping in the compose file:
</p>
<pre>
<div class="code-header">
<span class="code-dot red"></span>
<span class="code-dot yellow"></span>
<span class="code-dot green"></span>
<span class="code-title">compose.yml</span>
</div>
<code><span class="comment"># Change the host port (left side) to any free port</span>
ports:
- <span class="value">"7443:6443"</span></code>
</pre>
<p>Then update your kubeconfig to use the new port:</p>
<pre>
<div class="code-header">
<span class="code-dot red"></span>
<span class="code-dot yellow"></span>
<span class="code-dot green"></span>
<span class="code-title">terminal</span>
</div>
<code>kubectl config set-cluster rusternetes --server=https://localhost:7443</code>
</pre>
<h3>Cannot connect to API server</h3>
<p>
If <code>kubectl get nodes</code> returns a connection error:
</p>
<ul>
<li>Check that the API server is running: <code>podman compose -f compose.yml ps</code></li>
<li>Check the API server logs: <code>podman compose -f compose.yml logs api-server</code></li>
<li>Verify etcd is healthy: <code>podman compose -f compose.yml logs etcd</code></li>
<li>Make sure <code>KUBECONFIG</code> is set: <code>echo $KUBECONFIG</code></li>
<li>Confirm the kubeconfig file exists: <code>cat ~/.kube/rusternetes-config</code></li>
</ul>
<h3>First build is slow</h3>
<p>
The initial <code>podman compose -f compose.yml build</code> compiles the entire Rust workspace from scratch,
which takes 10–15 minutes depending on your hardware. Subsequent builds use the
layer cache and only recompile changed crates. To speed things up:
</p>
<ul>
<li>Allocate more CPUs and memory to your container runtime (Settings → Resources)</li>
<li>Rebuild only the service you changed: <code>podman compose -f compose.yml build api-server</code></li>
<li>Consider building from source natively for faster iteration (see <a href="installation.html">Installation</a>)</li>
</ul>
<h3>Podman: permission denied</h3>
<p>
On macOS with Podman, you may see permission errors for volume mounts. Ensure:
</p>
<ul>
<li>Podman Machine is running in rootful mode: <code>podman machine set --rootful</code></li>
<li>The volumes path is under your home directory, not <code>/tmp</code></li>
<li>The Podman socket is accessible: <code>podman info</code></li>
</ul>
<h3>Pods stuck in Pending</h3>
<p>
If pods stay in <code>Pending</code> after deployment:
</p>
<ul>
<li>Check the scheduler is running: <code>podman compose -f compose.yml ps scheduler</code></li>
<li>Check scheduler logs: <code>podman compose -f compose.yml logs scheduler</code></li>
<li>Verify nodes are Ready: <code>kubectl get nodes</code></li>
<li>Describe the pod for events: <code>kubectl describe pod <name></code></li>
</ul>
<h2>Next Steps</h2>
<ul>
<li><a href="installation.html">Installation</a> — build from source, feature flags, and platform details</li>
<li><a href="deployment.html">Deployment Overview</a> — compare all-in-one, compose+etcd, and compose+SQLite modes</li>
<li><a href="workloads.html">Workloads</a> — deploy Deployments, StatefulSets, DaemonSets, Jobs, and CronJobs</li>
<li><a href="bootstrap.html">Bootstrap</a> — understand what the bootstrap script creates</li>
</ul>
<div class="doc-pager">
<a href="index.html" class="prev">
<span class="pager-label">Previous</span>
← Docs Home
</a>
<a href="installation.html" class="next">
<span class="pager-label">Next</span>
Installation →
</a>
</div>
</main>
</div>
<footer class="doc-footer">
<p><a href="../index.html">Rūsternetes</a> — Kubernetes reimplemented in Rust. Apache-2.0 License.</p>
</footer>
<button class="sidebar-toggle" aria-label="Toggle navigation">☰</button>
<script src="search.js"></script>
</body>
</html>