diff options
| author | Paul Buetow <paul@buetow.org> | 2026-01-15 21:31:45 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-01-15 21:31:45 +0200 |
| commit | 7abd6361ddd487ded8baee5f3812af0135964abf (patch) | |
| tree | 71856dc85bf1c856c99db3dee0ed20947654aec9 | |
| parent | e5e6a3baa70cab02360779079ed431607ea42f89 (diff) | |
feat: add automated demo scripts for Argo Rollouts
| -rw-r--r-- | f3s/tracing-demo/Justfile | 18 | ||||
| -rwxr-xr-x | f3s/tracing-demo/demo-abort-rollout.sh | 106 | ||||
| -rwxr-xr-x | f3s/tracing-demo/demo-canary-rollout.sh | 171 | ||||
| -rwxr-xr-x | f3s/tracing-demo/demo-menu.sh | 95 | ||||
| -rwxr-xr-x | f3s/tracing-demo/demo-reset.sh | 63 |
5 files changed, 453 insertions, 0 deletions
diff --git a/f3s/tracing-demo/Justfile b/f3s/tracing-demo/Justfile index b3b1eae..2d5620e 100644 --- a/f3s/tracing-demo/Justfile +++ b/f3s/tracing-demo/Justfile @@ -136,6 +136,24 @@ rollout-abort: rollout-history: kubectl argo rollouts history tracing-demo-frontend -n {{NAMESPACE}} +# === Automated Demo Scripts === + +# Run full automated canary rollout demo +demo-canary: + @./demo-canary-rollout.sh + +# Run abort/rollback demo +demo-abort: + @./demo-abort-rollout.sh + +# Reset rollout to clean state +demo-reset: + @./demo-reset.sh + +# Interactive demo menu +demo-menu: + @./demo-menu.sh + # Start demo (requires manual rollout trigger in another terminal) rollout-demo: @echo "Starting Argo Rollouts demo..." diff --git a/f3s/tracing-demo/demo-abort-rollout.sh b/f3s/tracing-demo/demo-abort-rollout.sh new file mode 100755 index 0000000..55c0c7f --- /dev/null +++ b/f3s/tracing-demo/demo-abort-rollout.sh @@ -0,0 +1,106 @@ +#!/bin/bash +# Argo Rollouts Abort Demo - Test rollback behavior + +NAMESPACE="services" +ROLLOUT="tracing-demo-frontend" + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +BOLD='\033[1m' +NC='\033[0m' + +info() { echo -e "${BLUE}ℹ${NC} $1"; } +success() { echo -e "${GREEN}✓${NC} $1"; } +step() { echo -e "\n${BOLD}=== $1 ===${NC}"; } + +step "Rollout Abort Demo" +echo "" +echo "This will:" +echo " 1. Trigger a new canary rollout" +echo " 2. Wait 20 seconds for canary to become ready" +echo " 3. Abort the rollout mid-canary" +echo " 4. Show that old version continues running" +echo "" + +read -p "Start? (y/n) " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 0 +fi + +# Trigger rollout +step "Step 1: Triggering canary rollout..." +TRIGGER_VALUE="$(date +%s)" +kubectl patch rollout "$ROLLOUT" -n "$NAMESPACE" \ + --type='json' \ + -p='[{"op":"add","path":"/spec/template/spec/containers/0/env/-","value":{"name":"ROLLOUT_ABORT_TEST","value":"'$TRIGGER_VALUE'"}}]' \ + > /dev/null + +success "Rollout triggered" +echo "" + +# Wait for canary to start +step "Step 2: Waiting for canary pod to become ready..." +echo "Monitoring..." + +WAITED=0 +MAX_WAIT=30 +while [ $WAITED -lt $MAX_WAIT ]; do + READY=$(kubectl get rollout "$ROLLOUT" -n "$NAMESPACE" -o jsonpath='{.status.readyReplicas}') + UPDATED=$(kubectl get rollout "$ROLLOUT" -n "$NAMESPACE" -o jsonpath='{.status.updatedReplicas}') + STEP=$(kubectl get rollout "$ROLLOUT" -n "$NAMESPACE" -o jsonpath='{.status.currentStep}') + + printf "\r[%02ds] Ready: %s, Updated: %s, Step: %s " $WAITED "$READY" "$UPDATED" "$STEP" + + # Check if canary is ready (4 total ready = 3 stable + 1 canary) + if [ "$READY" = "4" ]; then + echo "" + success "Canary pod ready!" + break + fi + + sleep 1 + WAITED=$((WAITED + 1)) +done +echo "" + +# Abort the rollout +step "Step 3: Aborting rollout..." +kubectl argo rollouts abort "$ROLLOUT" -n "$NAMESPACE" > /dev/null +success "Rollout aborted" +echo "" + +# Show status +step "Step 4: Checking status after abort" +sleep 2 +kubectl argo rollouts status "$ROLLOUT" -n "$NAMESPACE" +echo "" + +# Show pods +step "Pod Status After Abort" +echo "Notice: Canary pod is gone, 3 stable pods still running" +echo "" +kubectl get pods -n "$NAMESPACE" -l app="$ROLLOUT" -o wide --no-headers | awk '{print $1, $3, $4}' +echo "" + +step "Summary" +cat << 'EOF' +What happened: + ✓ Canary started (4 pods: 3 stable + 1 canary) + ✓ Abort command issued while in canary phase + ✓ Canary pods immediately terminated + ✓ Old 3 stable pods continue serving traffic + ✓ Status: Degraded (RolloutAborted) + +Benefits of abort: + • Zero downtime - old version never interrupted + • Safe to stop at any point + • No manual cleanup needed + • Can retry with different version + +To retry: + ./demo-canary-rollout.sh +EOF +echo "" diff --git a/f3s/tracing-demo/demo-canary-rollout.sh b/f3s/tracing-demo/demo-canary-rollout.sh new file mode 100755 index 0000000..ce570db --- /dev/null +++ b/f3s/tracing-demo/demo-canary-rollout.sh @@ -0,0 +1,171 @@ +#!/bin/bash +# Argo Rollouts Canary Demo - Fully Automated +# Simulates a complete canary rollout with monitoring + +set -e + +NAMESPACE="services" +ROLLOUT="tracing-demo-frontend" +KUBE_CTX="$(kubectl config current-context)" + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +BOLD='\033[1m' +NC='\033[0m' + +info() { echo -e "${BLUE}ℹ${NC} $1"; } +success() { echo -e "${GREEN}✓${NC} $1"; } +error() { echo -e "${RED}✗${NC} $1"; exit 1; } +step() { echo -e "\n${BOLD}=== $1 ===${NC}"; } + +# Check prerequisites +step "Checking Prerequisites" + +info "Cluster: $KUBE_CTX" + +if ! kubectl get pods -n cicd -l app.kubernetes.io/name=argo-rollouts &>/dev/null; then + error "Argo Rollouts controller not found. Install: cd argo-rollouts && just install" +fi +success "Argo Rollouts controller running" + +if ! kubectl get rollout "$ROLLOUT" -n "$NAMESPACE" &>/dev/null; then + error "Rollout $ROLLOUT not found in $NAMESPACE" +fi +success "Rollout $ROLLOUT found" + +if ! kubectl argo rollouts version &>/dev/null; then + error "kubectl argo rollouts plugin not installed" +fi +success "kubectl argo rollouts plugin available" + +# Current state +step "Current Rollout State" +kubectl argo rollouts status "$ROLLOUT" -n "$NAMESPACE" +echo "" + +# Demo plan +step "Demo Plan" +cat << 'EOF' +Timeline: + 0-15s: Canary pod starting (Step 0/3, SetWeight 33%) + 15-60s: Canary observing (Step 1/3, paused) + 60-90s: Auto-promoting (Step 2/3, SetWeight 100%) +~90s: Complete (Status Healthy) + +What will be shown: + • Real-time rollout progress + • Pod replica counts + • Canary vs Stable pods + • Step progression +EOF +echo "" + +read -p "Start demo? (y/n) " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + info "Cancelled" + exit 0 +fi + +# Show initial pod state +step "Initial Pod State" +kubectl get pods -n "$NAMESPACE" -l app="$ROLLOUT" -o wide --no-headers | awk '{print $1, $3, $4}' +echo "" + +# Trigger rollout +step "Triggering Canary Rollout" +info "Triggering rollout by adding env var..." + +TRIGGER_VALUE="$(date +%s)" +kubectl patch rollout "$ROLLOUT" -n "$NAMESPACE" \ + --type='json' \ + -p='[{"op":"add","path":"/spec/template/spec/containers/0/env/-","value":{"name":"ROLLOUT_DEMO_V","value":"'$TRIGGER_VALUE'"}}]' \ + > /dev/null + +success "Rollout triggered (v=$TRIGGER_VALUE)" +echo "" + +# Monitor rollout +step "Monitoring Rollout Progress" +echo "Watching rollout for ~100 seconds..." +echo "" + +START_TIME=$(date +%s) +MAX_WAIT=120 +COMPLETE=0 + +while true; do + ELAPSED=$(($(date +%s) - START_TIME)) + + # Get status + STATUS=$(kubectl argo rollouts status "$ROLLOUT" -n "$NAMESPACE" 2>/dev/null || echo "Error") + ROLLOUT_INFO=$(kubectl get rollout "$ROLLOUT" -n "$NAMESPACE" -o jsonpath='{.status.phase},{.status.currentStep},{.spec.strategy.canary.steps | length},{.status.canary.weights.canary.weight // 0},{.status.replicas},{.status.updatedReplicas},{.status.readyReplicas}' 2>/dev/null || echo "Unknown,0,3,0,0,0,0") + + IFS=',' read -r PHASE STEP TOTAL_STEPS WEIGHT CURRENT UPDATED READY <<< "$ROLLOUT_INFO" + + # Print progress line + printf "\r[%02d:%02ds] %s | Step %s/%s | Weight %s%% | Replicas: %s (updated:%s ready:%s) " \ + $((ELAPSED / 60)) $((ELAPSED % 60)) "$PHASE" "$STEP" "$TOTAL_STEPS" "$WEIGHT" "$CURRENT" "$UPDATED" "$READY" + + # Check if complete + if [ "$PHASE" = "Healthy" ] && [ "$STEP" = "$TOTAL_STEPS" ]; then + echo "" + COMPLETE=1 + break + fi + + # Check if exceeded max wait + if [ $ELAPSED -ge $MAX_WAIT ]; then + echo "" + error "Timeout waiting for rollout to complete" + fi + + sleep 2 +done + +echo "" + +if [ $COMPLETE -eq 1 ]; then + success "Rollout completed successfully!" + echo "" +fi + +# Show final state +step "Final Rollout State" +kubectl argo rollouts get rollout "$ROLLOUT" -n "$NAMESPACE" +echo "" + +# Show final pods +step "Final Pod State" +kubectl get pods -n "$NAMESPACE" -l app="$ROLLOUT" -o wide --no-headers | awk '{print $1, $3, $4}' +echo "" + +# Summary +step "Demo Summary" +echo "Total time: ${ELAPSED}s" +echo "" +cat << 'EOF' +What happened: + 1. ✓ Canary pod created with new revision + 2. ✓ 1 canary pod + 3 stable pods = 33% traffic to new version + 3. ✓ Paused for 1 minute to observe metrics + 4. ✓ Auto-promoted to 100% (all 3 pods = new version) + 5. ✓ Old pods terminated + +This is progressive delivery: + • Zero downtime + • Validated before full rollout + • Automatic promotion if healthy + • Easy rollback if issues + +To test more: + • Run again: ./demo-canary-rollout.sh + • Abort: kubectl argo rollouts abort tracing-demo-frontend -n services + • Check logs: kubectl logs -n services -l app=tracing-demo-frontend -f + • View history: kubectl argo rollouts history tracing-demo-frontend -n services +EOF +echo "" +success "Demo complete!" diff --git a/f3s/tracing-demo/demo-menu.sh b/f3s/tracing-demo/demo-menu.sh new file mode 100755 index 0000000..73a7f05 --- /dev/null +++ b/f3s/tracing-demo/demo-menu.sh @@ -0,0 +1,95 @@ +#!/bin/bash +# Argo Rollouts Demo Menu - Choose demo scenario + +BOLD='\033[1m' +BLUE='\033[0;34m' +GREEN='\033[0;32m' +NC='\033[0m' + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +show_menu() { + clear + echo -e "${BOLD}Argo Rollouts Demo Menu${NC}" + echo "" + echo "Choose a demo:" + echo "" + echo " 1) Run full canary rollout demo" + echo " • Triggers rollout" + echo " • Monitors 0-15s (canary), 15-60s (observe), 60-90s (promote)" + echo " • Shows final state" + echo "" + echo " 2) Abort rollout demo" + echo " • Triggers rollout" + echo " • Waits 20s for canary to be ready" + echo " • Aborts mid-canary" + echo " • Shows rollback behavior" + echo "" + echo " 3) Reset rollout" + echo " • Aborts any in-progress rollout" + echo " • Removes demo env vars" + echo " • Returns to clean state" + echo "" + echo " 4) Check rollout status" + echo " • Shows current state" + echo " • Shows pod replicas" + echo " • Shows recent history" + echo "" + echo " 5) Watch rollout (real-time)" + echo " • Opens live rollout viewer" + echo "" + echo " 0) Exit" + echo "" +} + +check_status() { + echo "" + echo -e "${BOLD}Rollout Status:${NC}" + kubectl argo rollouts status tracing-demo-frontend -n services + echo "" + echo -e "${BOLD}Pod Replicas:${NC}" + kubectl get pods -n services -l app=tracing-demo-frontend -o wide --no-headers | awk '{print $1, $3, $4}' + echo "" + echo -e "${BOLD}Recent Revisions:${NC}" + kubectl argo rollouts history tracing-demo-frontend -n services | head -5 + echo "" + read -p "Press enter to continue..." +} + +watch_live() { + echo "" + echo -e "${BOLD}Live Rollout Viewer (Ctrl+C to exit)${NC}" + echo "" + kubectl argo rollouts get rollout tracing-demo-frontend -n services --watch +} + +while true; do + show_menu + read -p "Select option: " choice + + case $choice in + 1) + bash "$SCRIPT_DIR/demo-canary-rollout.sh" + ;; + 2) + bash "$SCRIPT_DIR/demo-abort-rollout.sh" + ;; + 3) + bash "$SCRIPT_DIR/demo-reset.sh" + ;; + 4) + check_status + ;; + 5) + watch_live + ;; + 0) + echo "Goodbye!" + exit 0 + ;; + *) + echo "Invalid option" + sleep 1 + ;; + esac +done diff --git a/f3s/tracing-demo/demo-reset.sh b/f3s/tracing-demo/demo-reset.sh new file mode 100755 index 0000000..fbfa0bd --- /dev/null +++ b/f3s/tracing-demo/demo-reset.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# Reset rollout to clean state + +NAMESPACE="services" +ROLLOUT="tracing-demo-frontend" + +RED='\033[0;31m' +GREEN='\033[0;32m' +BLUE='\033[0;34m' +BOLD='\033[1m' +NC='\033[0m' + +step() { echo -e "\n${BOLD}=== $1 ===${NC}"; } +success() { echo -e "${GREEN}✓${NC} $1"; } + +step "Resetting Rollout" +echo "" +echo "This will:" +echo " 1. Abort any in-progress rollout" +echo " 2. Remove env vars added by demo scripts" +echo " 3. Return rollout to clean state" +echo "" + +read -p "Reset? (y/n) " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 0 +fi + +step "Step 1: Aborting current rollout" +kubectl argo rollouts abort "$ROLLOUT" -n "$NAMESPACE" 2>/dev/null || true +sleep 2 +success "Aborted" + +step "Step 2: Removing demo env vars" +# Get the current env vars and reconstruct without demo ones +kubectl get rollout "$ROLLOUT" -n "$NAMESPACE" -o json | \ + jq '.spec.template.spec.containers[0].env |= map(select(.name | test("ROLLOUT_") | not))' | \ + kubectl apply -f - > /dev/null + +sleep 2 +success "Demo env vars removed" + +step "Step 3: Verifying clean state" +echo "Waiting for rollout to stabilize..." +sleep 5 + +STATUS=$(kubectl argo rollouts status "$ROLLOUT" -n "$NAMESPACE") +echo "$STATUS" +echo "" + +step "Reset Complete" +cat << 'EOF' +Rollout is now reset to: + • Status: Healthy + • No pending rollouts + • No demo env vars + • Ready for next demo + +To run demo again: + ./demo-canary-rollout.sh +EOF +echo "" |
