diff --git a/.github/PULL_REQUEST_TEMPLATE/bug_fix_template.md b/.github/PULL_REQUEST_TEMPLATE/bug_fix_template.md new file mode 100644 index 00000000..00835e84 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/bug_fix_template.md @@ -0,0 +1,9 @@ +- [ ] clear title +- [ ] docs/README updated +- [ ] no secrets/large temp files + +## Bug(s) + +## Changes + +## Testing diff --git a/.github/PULL_REQUEST_TEMPLATE/feature_template.md b/.github/PULL_REQUEST_TEMPLATE/feature_template.md new file mode 100644 index 00000000..5bfa2bf7 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/feature_template.md @@ -0,0 +1,13 @@ +- [ ] clear title +- [ ] docs/README updated +- [ ] no secrets/large temp files + +## Goals + +## Description +Summary... +New Dependencies... + +## Changes + +## Testing diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..975ad533 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,4 @@ +Please go to the `Preview` tab and select the appropriate sub-template: + +* [Bug Fixes](?expand=1&template=bug_fix_template.md) +* [Features](?expand=1&template=feature_template.md) diff --git a/.github/workflows/github-actions-demo.yml b/.github/workflows/github-actions-demo.yml new file mode 100644 index 00000000..b677974f --- /dev/null +++ b/.github/workflows/github-actions-demo.yml @@ -0,0 +1,23 @@ +name: GitHub Actions Demo +run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 +on: [push, workflow_dispatch] +jobs: + Explore-GitHub-Actions: + runs-on: ubuntu-latest + steps: + - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." + - name: SYSTEM INFO + run: | + echo "OS ${{ runner.os }}" + echo "Arch ${{ runner.arch }}" + echo "Details: " + cat /etc/os-release + - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." + - name: Check out repository code + uses: actions/checkout@v5 + - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." + - run: echo "🖥️ The workflow is now ready to test your code on the runner." + - name: List files in the repository + run: | + ls ${{ github.workspace }} + - run: echo "🍏 This job's status is ${{ job.status }}." diff --git a/labs/lab12/config.toml.backup b/labs/lab12/config.toml.backup new file mode 100644 index 00000000..94003c7e --- /dev/null +++ b/labs/lab12/config.toml.backup @@ -0,0 +1,31 @@ +# Copyright 2018-2022 Docker Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +disabled_plugins = ["cri"] + +#root = "/var/lib/containerd" +#state = "/run/containerd" +#subreaper = true +#oom_score = 0 + +#[grpc] +# address = "/run/containerd/containerd.sock" +# uid = 0 +# gid = 0 + +#[debug] +# address = "/run/containerd/debug.sock" +# uid = 0 +# gid = 0 +# level = "info" diff --git a/labs/lab12/containerd-shim-wasmtime-v1 b/labs/lab12/containerd-shim-wasmtime-v1 new file mode 100755 index 00000000..d7f39135 Binary files /dev/null and b/labs/lab12/containerd-shim-wasmtime-v1 differ diff --git a/labs/lab12/main.wasm b/labs/lab12/main.wasm new file mode 100755 index 00000000..50b4159f Binary files /dev/null and b/labs/lab12/main.wasm differ diff --git a/labs/lab12/moscow-time-traditional b/labs/lab12/moscow-time-traditional new file mode 100755 index 00000000..613de7bf Binary files /dev/null and b/labs/lab12/moscow-time-traditional differ diff --git a/labs/lab12/moscow-time-wasm.oci b/labs/lab12/moscow-time-wasm.oci new file mode 100644 index 00000000..fde9420f Binary files /dev/null and b/labs/lab12/moscow-time-wasm.oci differ diff --git a/labs/resources/12/image-1.png b/labs/resources/12/image-1.png new file mode 100644 index 00000000..b01d99ba Binary files /dev/null and b/labs/resources/12/image-1.png differ diff --git a/labs/resources/12/image-10.png b/labs/resources/12/image-10.png new file mode 100644 index 00000000..5c57e835 Binary files /dev/null and b/labs/resources/12/image-10.png differ diff --git a/labs/resources/12/image-11.png b/labs/resources/12/image-11.png new file mode 100644 index 00000000..910249b7 Binary files /dev/null and b/labs/resources/12/image-11.png differ diff --git a/labs/resources/12/image-2.png b/labs/resources/12/image-2.png new file mode 100644 index 00000000..0dfe17f1 Binary files /dev/null and b/labs/resources/12/image-2.png differ diff --git a/labs/resources/12/image-3.png b/labs/resources/12/image-3.png new file mode 100644 index 00000000..135fe30d Binary files /dev/null and b/labs/resources/12/image-3.png differ diff --git a/labs/resources/12/image-4.png b/labs/resources/12/image-4.png new file mode 100644 index 00000000..ca54c737 Binary files /dev/null and b/labs/resources/12/image-4.png differ diff --git a/labs/resources/12/image-5.png b/labs/resources/12/image-5.png new file mode 100644 index 00000000..5399f48b Binary files /dev/null and b/labs/resources/12/image-5.png differ diff --git a/labs/resources/12/image-6.png b/labs/resources/12/image-6.png new file mode 100644 index 00000000..e82bb660 Binary files /dev/null and b/labs/resources/12/image-6.png differ diff --git a/labs/resources/12/image-7.png b/labs/resources/12/image-7.png new file mode 100644 index 00000000..132799dd Binary files /dev/null and b/labs/resources/12/image-7.png differ diff --git a/labs/resources/12/image-8.png b/labs/resources/12/image-8.png new file mode 100644 index 00000000..47e152c4 Binary files /dev/null and b/labs/resources/12/image-8.png differ diff --git a/labs/resources/12/image-9.png b/labs/resources/12/image-9.png new file mode 100644 index 00000000..ef3c1dbf Binary files /dev/null and b/labs/resources/12/image-9.png differ diff --git a/labs/resources/12/image.png b/labs/resources/12/image.png new file mode 100644 index 00000000..6ebc49c0 Binary files /dev/null and b/labs/resources/12/image.png differ diff --git a/labs/submission12.md b/labs/submission12.md new file mode 100644 index 00000000..8ff1a843 --- /dev/null +++ b/labs/submission12.md @@ -0,0 +1,132 @@ +# Lab 12 — WebAssembly Containers vs Traditional Containers +### Task 1 — Create the Moscow Time Application +##### CLI output +```bash +MODE=once go run main.go +``` + +![modeOnce](resources/12/image.png) + +##### How it works in 3 contexts +- `isWagi()` function detects if running under Spin by checking for `REQUEST_METHOD` env var +- `runWagiOnce()` handles a single HTTP request by printing headers and body to STDOUT (CGI/WAGI style) +- Falls back to standard `net/http` server if not in CLI or WAGI mode + +### Task 2 — Build Traditional Docker Container +##### Binary size +```bash +ls -lh moscow-time-traditional +``` + +![traditionalBinSize](resources/12/image-1.png) + +##### Image size +```bash +docker image inspect moscow-time-traditional --format '{{.Size}}' | \ + awk '{print $1/1024/1024 " MB"}' +``` +![traditionalImgSize](resources/12/image-3.png) + +##### Startup time +```bash +for i in {1..5}; do + /usr/bin/time -f "%e" docker run --rm -e MODE=once moscow-time-traditional 2>&1 | tail -n 1 +done | awk '{sum+=$1; count++} END {print "Average:", sum/count, "seconds"}' +``` + +![alt traditionalStartupTime](resources/12/image-11.png) + +##### Memory usage (server mode) +In one terminal: +```bash +docker run --rm --name test-traditional -p 8080:8080 moscow-time-traditional +``` + +In another: +```bash +docker stats test-traditional --no-stream +``` + +![traditionalMemUsage](resources/12/image-4.png) + +##### Screenshot of application in browser +![appInBrowser](resources/12/image-5.png) + +### Task 3 — Build WASM Container (ctr-based) +##### TinyGo version +![tinygoVersion](resources/12/image-6.png) + +##### Verification of WASM binary +```bash +ls -lh main.wasm +file main.wasm +``` +![wasmBinary](resources/12/image-7.png) + +##### Image size +```bash +sudo ctr images ls | awk 'NR>1 && $1 ~ /moscow-time-wasm/ {print "IMAGE:", $1, "SIZE:", $4}' +``` +![wasmImgSize](resources/12/image-8.png) + +##### Startup time +```bash +for i in {1..5}; do + NAME="wasi-$(date +%s%N | tail -c 6)-$i" + /usr/bin/time -f "%e" sudo ctr run --rm \ + --runtime io.containerd.wasmtime.v1 \ + --platform wasi/wasm \ + --env MODE=once \ + docker.io/library/moscow-time-wasm:latest "$NAME" 2>&1 | tail -n 1 +done | awk '{sum+=$1; n++} END{printf("Average: %.4f seconds\n", sum/n)}' +``` + +![wasmStartupTime](resources/12/image-9.png) + +##### Confirmation of using ctr for WASM execution +![wasmConfirm](resources/12/image-10.png) +- Note: used same source code as traditional build + +##### Server Mode Limitation +Plain WASI (Preview1) modules do not support TCP sockets. Server mode under ctr is **not supported** for the standard `main.wasm` just built, because WASI Preview1 lacks networking capabilities. +- Note: server mode can be demonstrated via Spin using the same main.wasm + +##### Memory reporting +Memory reporting is **N/A via ctr**. +WASM runs in a sandboxed runtime with **different resource accounting mechanisms** than traditional Linux containers. +The wasmtime runtime manages WASM memory internally, and traditional container metrics (cgroups) don't apply. + +### Task 4 — Performance Comparison & Analysis +#### Comprehensive comparison table + +| Metric | Traditional Container | WASM Container | Improvement | Notes | +|--------|----------------------|----------------|-------------|-------| +| **Binary Size** | 4.5 MB | 2.4 MB | 46.67% smaller | From `ls -lh` | +| **Image Size** | 1.9772 MiB | 0.8 MiB | 59.54% smaller | From `docker image inspect` | +| **Startup Time (CLI)** | 0.932 ms | 0.574 ms | 1.63x faster | Average of 5 runs | +| **Memory Usage** | 1.367 MiB | N/A | N/A | From `docker stats` | +| **Base Image** | scratch | scratch | Same | Both minimal | +| **Source Code** | main.go | main.go | Identical | ✅ Same file! | +| **Server Mode** | ✅ Works (net/http) | ❌ Not via ctr
âś… Via Spin (WAGI) | N/A | WASI Preview1 lacks sockets;
Spin provides HTTP abstraction | + +#### Analysis questions + +Answer the following in your submission: + +1. **Binary Size Comparison:** + - Why is the WASM binary so much smaller than the traditional Go binary? + - TinyGo targets constrained environments and aggressively strips unused parts of the Go runtime, GC, reflection, and large standard‑library helpers that the regular Go toolchain always links in + - What did TinyGo optimize away? + - It performed whole‑program optimization (via LLVM), dead‑code elimination, simpler runtime, and can avoid heavy packages like `fmt` + +2. **Startup Performance:** + - Why does WASM start faster? + - A WASM module is just a compiled sandboxed binary loaded into an existing runtime — no OS boot, no container filesystem, no separate process + - What initialization overhead exists in traditional containers? + - A traditional container has to create a process namespace, set up cgroups, mount or prepare a filesystem layer, configure networking, and start a full user‑space runtime + +3. **Use Case Decision Matrix:** + - When would you choose WASM over traditional containers? + - When needing very fast cold starts, high instance density, small binary size or network transfer, while able to live within the WASI/runtime capability surface (limited direct OS access, more constrained I/O model) + - When would you stick with traditional containers? + - When needing full Linux/OS compatibility, rich system calls, mature ecosystem or heavily dependent on the filesystem \ No newline at end of file