Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added autoscaling/README.md
Empty file.
31 changes: 31 additions & 0 deletions autoscaling/api/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/bash

# Deploy infrastructure using the raw Unikraft Cloud REST API
# Usage: ./api/deploy.sh

TOKEN="${UKC_TOKEN}"
METRO="${UKC_METRO:-fra}"
API_URL="https://api.${METRO}.unikraft.cloud/v1"
GROUP_NAME="my-scaling-group"

if [ -z "$TOKEN" ]; then
echo "[-] Error: UKC_TOKEN is not set. Please export it before running."
exit 1
fi

echo "[+] Creating service group '$GROUP_NAME' via Unikraft Cloud API..."
curl -s -X POST "${API_URL}/services" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"name\": \"${GROUP_NAME}\",
\"services\": [
{
\"port\": 443,
\"destination_port\": 8080,
\"handlers\": [\"http\", \"tls\"]
}
]
}"

echo -e "\n[+] Service group deployment request sent successfully."
Comment on lines +16 to +31
45 changes: 45 additions & 0 deletions autoscaling/api/scale.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/bash

# Configure autoscale policy using the raw Unikraft Cloud REST API
# Usage: ./api/scale.sh

TOKEN="${UKC_TOKEN}"
METRO="${UKC_METRO:-fra}"
API_URL="https://api.${METRO}.unikraft.cloud/v1"
GROUP_NAME="my-scaling-group"
TEMPLATE_NAME="my-first-instance"

if [ -z "$TOKEN" ]; then
echo "[-] Error: UKC_TOKEN is not set. Please export it before running."
exit 1
fi

echo "[+] Configuring autoscale policy for '$GROUP_NAME' via API..."
# Changed the identifier key to "name" to match the root properties of the cloud resource
curl -s -X POST "${API_URL}/services/autoscale" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"name\": \"${GROUP_NAME}\",
\"min_size\": 0,
\"max_size\": 1,
\"create_args\": {
\"template\": {
\"name\": \"${TEMPLATE_NAME}\"
}
},
\"policies\": [
{
\"name\": \"my-cpu-policy\",
\"type\": \"step\",
\"metric\": \"cpu\",
\"adjustment_type\": \"percent\",
\"steps\": [
{ \"lower_bound\": 600, \"upper_bound\": 800, \"adjustment\": 50 },
{ \"lower_bound\": 800, \"adjustment\": 100 }
]
}
]
}"
Comment on lines +19 to +43

echo -e "\n[+] Autoscale policy configuration request sent successfully."
11 changes: 11 additions & 0 deletions autoscaling/app/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Stage 1: Build the Go server
FROM golang:1.21 as builder
WORKDIR /src
COPY main.go .
# Unikraft requires a dynamically linked binary (PIE - Position Independent Executable)
RUN CGO_ENABLED=0 GOOS=linux go build -buildmode=pie -a -installsuffix cgo -o /autoscaling-test main.go

# Stage 2: Final image
# We use debian-slim instead of scratch to provide the dynamic linker (ld-linux.so) required by the PIE binary above
FROM debian:bookworm-slim
Comment on lines +8 to +10
COPY --from=builder /autoscaling-test /autoscaling-test
9 changes: 9 additions & 0 deletions autoscaling/app/Kraftfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
spec: v0.6
name: autoscaling-test
runtime: base:latest
rootfs: ./Dockerfile
# The command executed automatically when the unikernel starts
cmd: ["/autoscaling-test"]
# Set the internal port expected by the platform
env:
PORT: "8080"
20 changes: 20 additions & 0 deletions autoscaling/app/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package main

import (
"fmt"
"net/http"
"os"
)

// The handler responds with the current instance's hostname.
// Under heavy load, when the autoscaler creates clones, we will see different hostnames here.
func handler(w http.ResponseWriter, r *http.Request) {
hostname, _ := os.Hostname()
fmt.Fprintf(w, "Hello from KraftCloud! Responding instance: %s\n", hostname)
}

func main() {
http.HandleFunc("/", handler)
fmt.Println("Server starting on port 8080...")
http.ListenAndServe(":8080", nil)
}
Comment on lines +1 to +20
16 changes: 16 additions & 0 deletions autoscaling/kraft/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash

# Deploy an instance and assign it to a service group.
# Usage: ./deploy.sh <instance-name> <service-group>
# Example: ./deploy.sh my-first-instance my-scaling-group

NAME=${1:-my-first-instance}
GROUP=${2:-my-scaling-group}

echo "[+] Creating service group $GROUP (if it doesn't exist)..."
# Create the service group. We use '|| true' so the script doesn't fail if the group already exists.
kraft cloud service create -n $GROUP 443:8080/http+tls || true

echo "[+] Deploying instance $NAME to service group $GROUP..."
# We append ./app at the end to explicitly tell KraftKit where the Kraftfile and Dockerfile are located.
kraft cloud deploy -M 512M -g $GROUP --name $NAME ./app
Comment on lines +7 to +16
20 changes: 20 additions & 0 deletions autoscaling/kraft/scale.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

# Configure the autoscaling policy for a service group.
# Usage: ./scale.sh <service-group> <template-instance>
# Example: ./scale.sh my-scaling-group my-first-instance

GROUP=${1:-my-scaling-group}
TEMPLATE=${2:-my-first-instance}

echo "[+] Initializing autoscale configuration for service group $GROUP using template $TEMPLATE..."
# The template was already successfully created, so we just ensure the autoscaler is initialized
kraft cloud scale init $GROUP --min-size 0 --max-size 1 --template $TEMPLATE || true

echo "[+] Configuring CPU autoscaling policy..."
kraft cloud scale add $GROUP \
--name my-cpu-policy \
--metric cpu \
--adjustment percent \
--step 600:800/50 \
--step 800:/100 || true
Comment on lines +7 to +20
Empty file added autoscaling/unikraft/deploy.sh
Empty file.
Empty file added autoscaling/unikraft/scale.sh
Empty file.