164 lines
6.2 KiB
Bash
Executable File
164 lines
6.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# Tank War Server — one-shot K8s deploy
|
|
#
|
|
# Mirrors the style of WarmCheck's run-deploy.sh:
|
|
# 1) sync source to master
|
|
# 2) build docker image on master
|
|
# 3) distribute image tarball to all worker nodes and `ctr` import
|
|
# 4) apply K8s manifests and restart the deployment
|
|
# =============================================================================
|
|
set -euo pipefail
|
|
|
|
# ---------- Configurable ------------------------------------------------------
|
|
# Host that the LOCAL developer machine can reach (uses your ssh_config alias).
|
|
MASTER_HOST="${MASTER_HOST:-host_172.16.16.16}"
|
|
# Intranet IPs that the MASTER uses to reach workers (no alias on the CVMs).
|
|
WORKER_INTRANET_IPS=(
|
|
"10.1.0.6"
|
|
"172.16.32.10"
|
|
"172.16.32.16"
|
|
)
|
|
|
|
NAMESPACE="tankwar"
|
|
IMAGE_NAME="tankwar-server"
|
|
IMAGE_TAG="${IMAGE_TAG:-latest}"
|
|
REMOTE_WORKDIR="/root/tankwar"
|
|
SSH_USER="root"
|
|
SSH_OPTS="-o StrictHostKeyChecking=no -o ConnectTimeout=10"
|
|
|
|
# ---------- Paths -------------------------------------------------------------
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
|
|
SERVER_DIR="${PROJECT_ROOT}/server"
|
|
K8S_DIR="${PROJECT_ROOT}/deploy/k8s"
|
|
|
|
# ---------- Helpers -----------------------------------------------------------
|
|
log() { printf "\033[1;36m[deploy]\033[0m %s\n" "$*"; }
|
|
ok() { printf "\033[1;32m[ ok ]\033[0m %s\n" "$*"; }
|
|
warn() { printf "\033[1;33m[warn]\033[0m %s\n" "$*"; }
|
|
die() { printf "\033[1;31m[fail]\033[0m %s\n" "$*" >&2; exit 1; }
|
|
|
|
ssh_master() { ssh ${SSH_OPTS} "${SSH_USER}@${MASTER_HOST}" "$@"; }
|
|
ssh_host() { local h="$1"; shift; ssh ${SSH_OPTS} "${SSH_USER}@${h}" "$@"; }
|
|
|
|
# =============================================================================
|
|
# Step 1 — sync server source code & k8s manifests to master
|
|
# =============================================================================
|
|
step_sync() {
|
|
log "1/5 Syncing source to master (${MASTER_HOST}) ..."
|
|
ssh_master "mkdir -p ${REMOTE_WORKDIR}/server ${REMOTE_WORKDIR}/deploy/k8s"
|
|
|
|
rsync -az --delete \
|
|
--exclude '.git' \
|
|
--exclude '.DS_Store' \
|
|
-e "ssh ${SSH_OPTS}" \
|
|
"${SERVER_DIR}/" \
|
|
"${SSH_USER}@${MASTER_HOST}:${REMOTE_WORKDIR}/server/"
|
|
|
|
rsync -az --delete \
|
|
-e "ssh ${SSH_OPTS}" \
|
|
"${K8S_DIR}/" \
|
|
"${SSH_USER}@${MASTER_HOST}:${REMOTE_WORKDIR}/deploy/k8s/"
|
|
|
|
ok "source synced"
|
|
}
|
|
|
|
# =============================================================================
|
|
# Step 2 — build docker image on master
|
|
# =============================================================================
|
|
step_build() {
|
|
log "2/5 Building image ${IMAGE_NAME}:${IMAGE_TAG} on master ..."
|
|
ssh_master "cd ${REMOTE_WORKDIR}/server && \
|
|
docker build --pull -t ${IMAGE_NAME}:${IMAGE_TAG} -t ${IMAGE_NAME}:latest ."
|
|
ok "image built"
|
|
}
|
|
|
|
# =============================================================================
|
|
# Step 3 — distribute image to every worker via containerd (ctr import)
|
|
#
|
|
# The cluster uses containerd directly (not docker-shim). Each node must
|
|
# have the image in the "k8s.io" namespace to be usable by kubelet.
|
|
# =============================================================================
|
|
step_distribute() {
|
|
log "3/5 Distributing image to workers ..."
|
|
|
|
# Export once on master
|
|
local remote_tar="/tmp/${IMAGE_NAME}-${IMAGE_TAG}.tar"
|
|
ssh_master "docker save ${IMAGE_NAME}:${IMAGE_TAG} -o ${remote_tar} && ls -lh ${remote_tar}"
|
|
|
|
# Import on master's containerd (k8s.io ns) so the scheduler can use it locally too
|
|
ssh_master "ctr -n k8s.io images import ${remote_tar} && \
|
|
ctr -n k8s.io images tag --force docker.io/library/${IMAGE_NAME}:${IMAGE_TAG} \
|
|
docker.io/library/${IMAGE_NAME}:latest"
|
|
ok "master imported"
|
|
|
|
# Fan-out to workers — executed FROM the master using intranet IPs.
|
|
for ip in "${WORKER_INTRANET_IPS[@]}"; do
|
|
log " -> ${ip}"
|
|
ssh_master "scp ${SSH_OPTS} ${remote_tar} ${SSH_USER}@${ip}:${remote_tar} && \
|
|
ssh ${SSH_OPTS} ${SSH_USER}@${ip} 'ctr -n k8s.io images import ${remote_tar} && \
|
|
ctr -n k8s.io images tag --force docker.io/library/${IMAGE_NAME}:${IMAGE_TAG} \
|
|
docker.io/library/${IMAGE_NAME}:latest && \
|
|
rm -f ${remote_tar}'"
|
|
ok " ${ip} imported"
|
|
done
|
|
|
|
ssh_master "rm -f ${remote_tar}"
|
|
ok "distribution done"
|
|
}
|
|
|
|
# =============================================================================
|
|
# Step 4 — apply manifests & roll the deployment
|
|
# =============================================================================
|
|
step_apply() {
|
|
log "4/5 Applying K8s manifests ..."
|
|
ssh_master "kubectl apply -f ${REMOTE_WORKDIR}/deploy/k8s/namespace.yaml"
|
|
ssh_master "kubectl apply -f ${REMOTE_WORKDIR}/deploy/k8s/service.yaml"
|
|
ssh_master "kubectl apply -f ${REMOTE_WORKDIR}/deploy/k8s/deployment.yaml"
|
|
|
|
# Force a new rollout so we pick up the newly-imported image even
|
|
# when the tag stays :latest.
|
|
ssh_master "kubectl -n ${NAMESPACE} set image deploy/tankwar-server \
|
|
tankwar-server=${IMAGE_NAME}:${IMAGE_TAG} --record=false || true"
|
|
|
|
log " waiting for rollout ..."
|
|
ssh_master "kubectl -n ${NAMESPACE} rollout status deploy/tankwar-server --timeout=180s"
|
|
ok "deployment is live"
|
|
}
|
|
|
|
# =============================================================================
|
|
# Step 5 — sanity check
|
|
# =============================================================================
|
|
step_verify() {
|
|
log "5/5 Verifying ..."
|
|
ssh_master "kubectl -n ${NAMESPACE} get pods,svc -o wide"
|
|
echo
|
|
ssh_master "kubectl -n ${NAMESPACE} logs deploy/tankwar-server --tail=20 || true"
|
|
echo
|
|
ok "all done. NodePort: 30081"
|
|
cat <<EOF
|
|
|
|
------------------------------------------------------------
|
|
Public endpoints (after DNS on www.igeek.site takes effect):
|
|
wss://www.igeek.site:30081/ (via NodePort)
|
|
|
|
Direct CVM access for smoke test:
|
|
wscat -c ws://43.139.80.61:30081/
|
|
|
|
Remember to allow TCP/30081 in the CVM security group.
|
|
------------------------------------------------------------
|
|
EOF
|
|
}
|
|
|
|
main() {
|
|
log "Tank War Server deploy — tag=${IMAGE_TAG}"
|
|
step_sync
|
|
step_build
|
|
step_distribute
|
|
step_apply
|
|
step_verify
|
|
}
|
|
|
|
main "$@"
|