This project illustrates how to build and deploy a simple app to the Google Kubernetes Engine and with support for canary deployments.
Open the file ./scripts/set-env.sh
and set the correct values for your environment.
./scripts/set-env.sh;
./scripts/gke-setup.sh;
./scripts/build-and-push-image.sh;
./scripts/deploy-version-production.sh;
export VERSION_NUMBER=2.0
./scripts/build-and-push-image.sh;
./scripts/deploy-version-canary.sh;
./scripts/gke-cleanup.sh;
Setup the project:
gcloud config set project <PROJECT_ID>;
gcloud config set compute/zone <ZONE_ID>;
Create the cluster:
export CLUSTER_NAME=<CLUSTER_NAME>;
gcloud container clusters create $CLUSTER_NAME --num-nodes=3;
gcloud container clusters get-credentials $CLUSTER_NAME;
Create namespace:
kubectl create namespace production
Set version number:
export VERSION_NUMBER=1.0;
Build and push images to GCP:
export PROJECT_ID=$(gcloud info --format='value(config.project)');
docker build -t gcr.io/$PROJECT_ID/app:$VERSION_NUMBER .;
gcloud docker -- push gcr.io/$PROJECT_ID/app:$VERSION_NUMBER;
Deploy to GKE:
sed -i.bak "s/PROJECT_ID/$PROJECT_ID/; s/VERSION_NUMBER/$VERSION_NUMBER/;" k8s/app-production.yml;
kubectl --namespace=production apply -f k8s/app-production.yml
kubectl --namespace=production rollout status deployment/kubeapp-production
Make externally accessible:
kubectl --namespace=production apply -f k8s/app-ingress-production.yml
kubectl --namespace=production describe ingress
export SERVICE_IP=$(kubectl --namespace=production get ingress/app-ingress --output=json | jq -r '.status.loadBalancer.ingress[0].ip')
curl http://$SERVICE_IP/
Set version number:
export VERSION_NUMBER=2.0;
Build and push images to GCP:
export PROJECT_ID=$(gcloud info --format='value(config.project)');
docker build -t gcr.io/$PROJECT_ID/app:$VERSION_NUMBER .;
gcloud docker -- push gcr.io/$PROJECT_ID/app:$VERSION_NUMBER;
Deploy to GKE:
sed -i.bak "s/PROJECT_ID/$PROJECT_ID/; s/VERSION_NUMBER/$VERSION_NUMBER/;" k8s/app-canary.yml;
kubectl --namespace=production apply -f k8s/app-canary.yml
kubectl --namespace=production rollout status deployment/kubeapp-canary
Create the ingress:
kubectl --namespace=production apply -f k8s/app-ingress-canary.yml
kubectl --namespace=production describe ingress
export INGRESS_IP=$(kubectl --namespace=production get ing/app-ingress --output=json | jq -r '.status.loadBalancer.ingress[0].ip')
echo "$INGRESS_IP foo.bar canary.foo.bar" | sudo tee -a /etc/hosts
curl http://foo.bar/version
curl http://canary.foo.bar/version
kubectl --namespace=... get services;
kubectl --namespace=... get pods -o wide;
kubectl --namespace=... get events -w;
Delete the service:
kubectl --namespace=production delete service kubeapp-production-service
kubectl --namespace=production delete service kubeapp-canary-service
Wait for the Load Balancer provisioned for the app service to be deleted:
gcloud compute forwarding-rules list
Delete the container cluster:
gcloud container clusters delete $CLUSTER_NAME