A game where microservices battle each other in a giant real-time bowl.
Run Locally:
./sbt "runMain apps.dev.KafkaApp"
(cd samples/scala-play; ./sbt run)
./sbt "runMain apps.Battle"
./sbt "runMain apps.dev.KafkaConsumerApp"
./sbt "runMain apps.dev.KafkaProducerApp"
You can send commands like
ARENA/create
ARENA/unlist
ARENA/playerjoin
ARENA/playerfill/NUM
ARENA/playerleave/ID
ARENA/viewerjoin
ARENA/scoresreset
./sbt run
Check out the foo arena: http://localhost:9000/foo
Web UI Notes:
Pause the Arena refresh:
document.body.dataset.paused = true;
Create GKE Cluster with Cloud Run
gcloud config set core/project YOUR_PROJECT
gcloud services enable compute.googleapis.com container.googleapis.comcontainer.googleapis.com containerregistry.googleapis.com cloudbuild.googleapis.com
gcloud config set compute/region us-central1
gcloud config set container/cluster cloudbowl
gcloud container clusters create \
--region=$(gcloud config get-value compute/region) \
--addons=HorizontalPodAutoscaling,HttpLoadBalancing,CloudRun \
--machine-type=n1-standard-4 \
--enable-stackdriver-kubernetes \
--enable-ip-alias \
--enable-autoscaling --num-nodes=1 --min-nodes=0 --max-nodes=20 \
--release-channel=stable \
--scopes cloud-platform \
$(gcloud config get-value container/cluster)
Install Strimzi Kafka Operator
kubectl create namespace kafka
curl -L https://github.com/strimzi/strimzi-kafka-operator/releases/download/0.20.0/strimzi-cluster-operator-0.20.0.yaml \
| sed 's/namespace: .*/namespace: kafka/' \
| kubectl apply -f - -n kafka
Setup the Kafka Cluster
kubectl apply -n kafka -f .infra/kafka.yaml
kubectl wait -n kafka kafka/cloudbowl --for=condition=Ready --timeout=300s
Get your IP Address:
export IP_ADDRESS=$(kubectl get svc istio-ingress -n gke-system -o 'jsonpath={.status.loadBalancer.ingress[0].ip}')
echo $IP_ADDRESS
Create a ConfigMap named cloudbowl-config
:
export APPLICATION_SECRET=$(head -c 32 /dev/urandom | base64)
export ADMIN_PASSWORD=PICK_A_PASSWORD # Used for creating / updating arenas
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: cloudbowl-config
data:
WEBJARS_USE_CDN: 'true'
APPLICATION_SECRET: $APPLICATION_SECRET
ADMIN_PASSWORD: $ADMIN_PASSWORD
EOF
Setup Cloud Build with a trigger on master, excluding samples/**
, with Configuration Type set to Cloud Build configuration file, and substitution vars _CLOUDSDK_COMPUTE_REGION
and _CLOUDSDK_CONTAINER_CLUSTER
. Running the trigger will create the Kafka topics, deploy the battle service, and the web app.
Once the service is deployed, setup the domain name:
export IP_ADDRESS=$(kubectl get svc istio-ingress -n gke-system -o 'jsonpath={.status.loadBalancer.ingress[0].ip}')
echo "IP_ADDRESS=$IP_ADDRESS"
gcloud beta run domain-mappings create --service cloudbowl-web --domain $IP_ADDRESS.nip.io --platform=gke --project=$(gcloud config get-value core/project) \
--cluster=$(gcloud config get-value container/cluster) --cluster-location=$(gcloud config get-value compute/region)
gcloud compute addresses create cloudbowl-ip --addresses=$IP_ADDRESS --region=$(gcloud config get-value compute/region)
Turn on TLS support:
kubectl patch cm config-domainmapping -n knative-serving -p '{"data":{"autoTLS":"Enabled"}}'
kubectl get kcert
# Pick a topic:
export TOPIC=viewer-ping
export TOPIC=players-refresh
export TOPIC=arena-update
# Describe a topic:
kubectl -n kafka run kafka-consumer -ti --image=strimzi/kafka:0.17.0-kafka-2.4.0 --rm=true --restart=Never -- bin/kafka-topics.sh --describe --bootstrap-server cloudbowl-kafka-bootstrap.kafka:9092 --topic $TOPIC
# Consume messages on a topic:
kubectl -n kafka run kafka-consumer -ti --image=strimzi/kafka:0.17.0-kafka-2.4.0 --rm=true --restart=Never -- bin/kafka-console-consumer.sh --bootstrap-server cloudbowl-kafka-bootstrap.kafka:9092 --topic $TOPIC --from-beginning --property print.key=true --property key.separator=":"