forked from keyteki/keyteki
-
Notifications
You must be signed in to change notification settings - Fork 0
124 lines (107 loc) · 5.11 KB
/
deploy-node.yml
File metadata and controls
124 lines (107 loc) · 5.11 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
name: Deploy Game Nodes
on:
workflow_dispatch:
inputs:
environment:
type: environment
description: Select the environment
default: Production
jobs:
deploy:
runs-on: self-hosted
environment: ${{ inputs.environment }}
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Deploy Game Nodes
run: |
ENV=$(echo "${{ github.event.inputs.environment }}" | tr '[:upper:]' '[:lower:]')
if [ "${{ github.event.inputs.environment }}" = "Production" ]; then
NAMESPACE="keyteki"
REPLICAS=2
SCALE_INCREMENT=2
ENV_SUBDOMAIN="production"
elif [ "${{ github.event.inputs.environment }}" = "Development" ]; then
NAMESPACE="keyteki-development"
REPLICAS=1
SCALE_INCREMENT=1
ENV_SUBDOMAIN="dev"
else
NAMESPACE="keyteki-$ENV"
REPLICAS=1
SCALE_INCREMENT=1
ENV_SUBDOMAIN="$ENV"
fi
echo "Deploying to $NAMESPACE ($REPLICAS replicas)"
DEPLOY_TIME=$(date +%s)
echo "Deployment timestamp: $DEPLOY_TIME"
cat > /tmp/node-secrets.yaml <<EOF
nodeConfig:
env: "production"
sentryDsn: "${{ secrets.SENTRY_DSN }}"
redisKeyPrefix: "keyteki:$ENV"
redisUrl: "${{ secrets.REDIS_URL }}"
gameNode:
host: null
socketioPort: 80
secret: "${{ secrets.SECRET }}"
EOF
helm upgrade --install game-node ./infrastructure/node \
--set namespace=$NAMESPACE \
--set replicaCount=$REPLICAS \
--set updatePartition=$REPLICAS \
--set environment=$ENV_SUBDOMAIN \
--set deployTime=$DEPLOY_TIME \
-f /tmp/node-secrets.yaml \
-n $NAMESPACE
echo "Starting graceful rollout..."
NEW_REPLICAS=$((REPLICAS + SCALE_INCREMENT))
echo "Scaling up to $NEW_REPLICAS replicas..."
kubectl scale statefulset node -n $NAMESPACE --replicas=$NEW_REPLICAS
for i in $(seq $REPLICAS $((NEW_REPLICAS - 1))); do
NEW_POD="node-$i"
echo "Waiting for $NEW_POD to become ready..."
kubectl wait --for=condition=ready pod/$NEW_POD -n $NAMESPACE --timeout=30m
echo "$NEW_POD is ready."
done
OLD_PODS=$(kubectl get pods -n $NAMESPACE -l app=game-node -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | sort | head -n $REPLICAS)
echo "Old pods: $OLD_PODS"
echo "Sending SIGTERM to all old pods to start draining..."
for POD in $OLD_PODS; do
echo "Signaling $POD..."
kubectl exec -n $NAMESPACE $POD -- /bin/sh -c "kill -TERM \$(pidof node)" || true
done
echo "Waiting for all old pods to drain..."
for POD in $OLD_PODS; do
echo "Monitoring $POD..."
ATTEMPTS=0
while [ $ATTEMPTS -lt 540 ]; do
GAMES=$(kubectl exec -n $NAMESPACE $POD -- wget -q -O- http://localhost:9000/health/games 2>/dev/null || echo "error")
if [ "$GAMES" = "error" ]; then
echo "$POD: Health check failed; assuming node shutting down."
break
fi
if [ "$GAMES" = "0" ]; then
echo "$POD: All games finished."
break
fi
echo "$POD: Still running $GAMES games... ($ATTEMPTS/540)"
ATTEMPTS=$((ATTEMPTS + 1))
sleep 10
done
done
echo "Updating old pods to new version..."
helm upgrade --install game-node ./infrastructure/node \
--set namespace=$NAMESPACE \
--set replicaCount=$NEW_REPLICAS \
--set updatePartition=0 \
--set environment=$ENV_SUBDOMAIN \
--set deployTime=$DEPLOY_TIME \
-f /tmp/node-secrets.yaml \
-n $NAMESPACE
echo "Waiting for rollout to complete..."
kubectl rollout status statefulset/node -n $NAMESPACE --timeout=30m
rm /tmp/node-secrets.yaml
echo "Scaling back down to $REPLICAS replicas..."
kubectl scale statefulset node -n $NAMESPACE --replicas=$REPLICAS
echo "Graceful rollout complete!"