Hi! I'm Niran. This is a test project with Google Cloud
The main highlights of the application are as follows:
- Dockerized Angular 7 App with Angular Material in One Kubernetes Cluster
- Dockerized Java API (Spring Boot, JPA, Hibernate Restful CRUD API) on another Kubernetes Cluster
- Cloud SQL (around 1,00,000 records)
- Logs will be stored in StackDriver
- Jenkins for CI
- Spinnaker for CD
- Helm for setting up environments for Jenkins & Spinnaker
Detailed Steps:
- Developer do the code changes and adding some “tags” (say v1.0.1) and commits it
- Code is getting pushed into “GitHub” (Can be changed to Bit Bucket or Cloud Source Repositories)
- “Container Builder” will detect the new Git tag and trigger an automated build which creates a Docker image and run Unit Tests – This can be replaced with Jenkins
- Docker image will be pushed into “Container Registry” (Currently Google Container Registry)
- This will add a message into “Cloud Pub Sub” with the details about the new image
- “Spinnaker” running on the Kubernetes cluster will detect the new image via Pub Sub Subscription (This can be changed to directly monitor the container registry)
- “Spinnaker” will do an Automated Deployment to the “Staging” environment, which is running on Kubernetes
- Admin can check approve the deployment to “Canary” Environment after doing some rounds of checks via “Spinnaker”. This will do a the rolling update on a small set of Canary testers
- Admin will monitor the Canary builds and approve the deployment to the “Production” via “Spinnaker”.
- Requests coming to the Server will be routed based on the Load Balancer provided by Kubernetes
- Modify "dispatch.yaml" in root with the new domain
- run
gcloud app deploy dispatch.yaml
Created based on google code labs
cd gae-std-java\gae-standard-example
- Add App Engine Plugin in pom.xml add the below:
<plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>appengine-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <version>1</version> </configuration> </plugin>
- Add App Engine Descriptor at "src/main/webapp/WEB-INF/appengine-web.xml"
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> <threadsafe>true</threadsafe> <runtime>java8</runtime> </appengine-web-app>
- Run locally:
./mvnw -DskipTests spring-boot:run
gcloud app create --region us-central
./mvnw -DskipTests appengine:deploy
npm install -g @angular/cli@latest
npm install -g http-server
cd InfiniteScroll
ng build --prod
- Test Prod Build
http-server ./dist
gcloud app deploy
gcloud config set compute/zone us-central1-a
gcloud container clusters create [CLUSTER-NAME]
Ex:
gcloud beta container --project "$GOOGLE_CLOUD_PROJECT" clusters create "niran-poc-cluster" --zone "us-central1-a" --username "admin" --cluster-version "1.11.8-gke.6" --machine-type "n1-standard-1" --image-type "COS" --disk-type "pd-standard" --disk-size "20" --scopes "https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/trace.append" --num-nodes "2" --enable-cloud-logging --enable-cloud-monitoring --no-enable-ip-alias --network "projects/$GOOGLE_CLOUD_PROJECT/global/networks/default" --subnetwork "projects/$GOOGLE_CLOUD_PROJECT/regions/us-central1/subnetworks/default" --enable-autoscaling --min-nodes "1" --max-nodes "3" --addons HorizontalPodAutoscaling,HttpLoadBalancing,KubernetesDashboard --enable-autoupgrade --enable-autorepair
gcloud container clusters get-credentials niran-poc-cluster
- (Not Required as per latest Dockerfile)
./mvnw -DskipTests spring-boot:run
(Not Required as per latest Dockerfile) Package the Java application as a Docker container [Option 1 - using Jib]
- Package the app:
./mvnw -DskipTests package
- Use Jib to create the container image and push it to the Container Registry:
./mvnw -DskipTests com.google.cloud.tools:jib-maven-plugin:build -Dimage=gcr.io/$GOOGLE_CLOUD_PROJECT/employee-java-api:v1
- Test the image locally with the following command which will run a Docker container
as a daemon on port 8080 from your newly-created container image
docker run -ti --rm -p 8080:8080 gcr.io/$GOOGLE_CLOUD_PROJECT/employee-java-api:v1
- Deploy your application to Kubernetes
kubectl run employee-java-api-server --image=gcr.io/$GOOGLE_CLOUD_PROJECT/employee-java-api:v1 --port=8080
kubectl get deployments
kubectl get pods
kubectl expose deployment employee-java-api-server --type=LoadBalancer
- (Not Required as per latest Dockerfile) Package:
mvn package
& Runjava -jar target/employee-0.0.1-SNAPSHOT.war
Alternatively, you can run the app without packaging it using:mvn spring-boot:run
- (Not Required as per latest Dockerfile)
docker image build -t employee-java-api:v1.0.1 .
- (Not Required as per latest Dockerfile)
docker tag employee-java-api:v1.0.1 gcr.io/$GOOGLE_CLOUD_PROJECT/employee-java-api:v1.0.1
- (Not Required as per latest Dockerfile)
docker images
- (Not Required as per latest Dockerfile)
docker push gcr.io/$GOOGLE_CLOUD_PROJECT/employee-java-api:v1.0.1
- (Not Required as per latest Dockerfile)
docker stop $(docker ps -q)
- (Not Required as per latest Dockerfile)
docker rm $(docker ps -aq)
gcloud config set compute/zone us-central1-a
gcloud container clusters get-credentials niran-poc-cluster
kubectl run employee-java-api-server --image=gcr.io/$GOOGLE_CLOUD_PROJECT/employee-java-api:v1.0.1 --port 8080
kubectl expose deployment employee-java-api-server --type="LoadBalancer"
gcloud config set compute/zone us-central1-a
gcloud container clusters get-credentials niran-poc-cluster
kubectl set image deployment employee-java-api-server employee-java-api-server=gcr.io/$GOOGLE_CLOUD_PROJECT/employee-java-api:v1.0.1
kubectl rollout status deployment employee-java-api-server
kubectl get deployments
docker stop $(docker ps -q)
docker rm $(docker ps -aq)
docker rmi employee-java-api:v1.0.1 gcr.io/$GOOGLE_CLOUD_PROJECT/employee-java-api employee-java-api:v1.0.1
docker rmi openjdk:8-jre-alpine
docker rmi $(docker images -aq) --force # remove remaining images
docker images
docker pull gcr.io/$GOOGLE_CLOUD_PROJECT/employee-java-api:v1.0.1
docker run -p 8080:8080 -d gcr.io/$GOOGLE_CLOUD_PROJECT/employee-java-api:v1.0.1
curl http://localhost:8080
- Config details are available here
- On Google Kubernetes Engine, you must add the logging.write access scope when creating the cluster:
gcloud container clusters create example-cluster-name --scopes https://www.googleapis.com/auth/logging.write
- (Not Required as per latest Dockerfile)
npm install -g @angular/cli@latest
- (Not Required as per latest Dockerfile)
npm install -g http-server
- (Not Required as per latest Dockerfile)
cd InfiniteScroll/
- (Not Required as per latest Dockerfile)
ng build --prod
- (Not Required as per latest Dockerfile) To Test Prod Build
http-server ./dist
- (Not Required as per latest Dockerfile)
docker image build -t employee-angular-web:v1.0.1 .
- (Not Required as per latest Dockerfile)
docker image ls
- (Not Required as per latest Dockerfile)
docker run -p 3000:80 --rm employee-angular-web:v1.0.1
ORdocker run -d -p 8080:8080 employee-angular-web:v1.0.1
- (Not Required as per latest Dockerfile)
docker ps
- (Not Required as per latest Dockerfile)
docker history employee-angular-web:v1.0.1
- (Not Required as per latest Dockerfile)
docker stop [container_id]
- (Not Required as per latest Dockerfile)
docker tag employee-angular-web:v1.0.1 gcr.io/$GOOGLE_CLOUD_PROJECT/employee-angular-web:v1.0.1
- (Not Required as per latest Dockerfile)
docker images
- (Not Required as per latest Dockerfile)
docker push gcr.io/$GOOGLE_CLOUD_PROJECT/employee-angular-web:v1.0.1
- (Not Required as per latest Dockerfile)
docker stop $(docker ps -q)
- (Not Required as per latest Dockerfile)
docker rm $(docker ps -aq)
gcloud config set compute/zone us-central1-a
gcloud container clusters get-credentials niran-poc-cluster
kubectl run employee-angular-web-server --image=gcr.io/$GOOGLE_CLOUD_PROJECT/employee-angular-web:v1.0.1 --port 80
kubectl expose deployment employee-angular-web-server --type="LoadBalancer"
gcloud config set compute/zone us-central1-a
gcloud container clusters get-credentials niran-poc-cluster
kubectl set image deployment employee-angular-web-server employee-angular-web-server=gcr.io/$GOOGLE_CLOUD_PROJECT/employee-angular-web:v1.0.1
kubectl rollout status deployment employee-angular-web-server
kubectl get deployments
Ref: https://codelabs.developers.google.com/codelabs/cloud-spinnaker-kubernetes-cd/#0
- Enable Required APIs
cd spinnaker
- Modify Cluster Name "GKE_CLUSTER" & "ZONE"
./setup.sh
./connect.sh
- Preview on Port 8080 on Cloud Shell
Ref https://www.qwiklabs.com/focuses/552?parent=catalog
gcloud config set compute/zone us-central1-f
gcloud container clusters create spinnaker-tutorial --machine-type=n1-standard-2 --enable-legacy-authorization
gcloud iam service-accounts create spinnaker-storage-account --display-name spinnaker-storage-account
export SA_EMAIL=$(gcloud iam service-accounts list --filter="displayName:spinnaker-storage-account" --format='value(email)')
export PROJECT=$(gcloud info --format='value(config.project)')
- Bind the storage.admin role to your service account:
gcloud projects add-iam-policy-binding $PROJECT --role roles/storage.admin --member serviceAccount:$SA_EMAIL
- Download the service account key. In a later step, you will install Spinnaker and upload this key to Kubernetes Engine:
gcloud iam service-accounts keys create spinnaker-sa.json --iam-account $SA_EMAIL
wget https://storage.googleapis.com/kubernetes-helm/helm-v2.5.0-linux-amd64.tar.gz
tar zxfv helm-v2.5.0-linux-amd64.tar.gz
cp linux-amd64/helm .
- Initialize Helm to install Tiller, the server side of Helm, in your cluster:
./helm init
./helm repo update
- Ensure that Helm is properly installed by running the following command. If Helm is correctly installed, v2.5.0 appears for both client and server.
./helm version
- In Cloud Shell, create a bucket for Spinnaker to store its pipeline configuration:
export PROJECT=$(gcloud info \
--format='value(config.project)')
export BUCKET=$PROJECT-spinnaker-config
gsutil mb -c regional -l us-central1 gs://$BUCKET
- Create your configuration file by executing the following:
export SA_JSON=$(cat spinnaker-sa.json)
cat > spinnaker-config.yaml <<EOF
storageBucket: $BUCKET
gcs:
enabled: true
project: $PROJECT
jsonKey: '$SA_JSON'
# Disable minio the default
minio:
enabled: false
# Configure your Docker registries here
accounts:
- name: gcr
address: https://gcr.io
username: _json_key
password: '$SA_JSON'
email: 1234@5678.com
EOF
./helm install -n cd stable/spinnaker -f spinnaker-config.yaml --timeout 600 --version 0.3.1
Note: You will see a warning here about a listener not getting created - you can ignore it. The installation will proceed after a few minutes.
- After the command completes, run the following command to set up port forwarding to Spinnaker from Cloud Shell:
export DECK_POD=$(kubectl get pods --namespace default -l "component=deck" \
-o jsonpath="{.items[0].metadata.name}")
kubectl port-forward --namespace default $DECK_POD 8080:9000 >> /dev/null &
- To open the Spinnaker user interface, click the Web Preview icon at the top of the Cloud Shell window and select Preview on port 8080
- In the Cloud Platform Console, click Navigation menu > Cloud Build > Triggers. Click Create trigger.
mvn compile
mvn package
./mvnw clean package
ormvn clean package
./mvnw spring-boot:run
ormvn spring-boot:run
java -jar target/java-api-0.1.0.jar
docker build . -t java-api:0.1
docker tag java-api:0.1 gcr.io/$GOOGLE_CLOUD_PROJECT/java-api:0.1
docker push gcr.io/$GOOGLE_CLOUD_PROJECT/java-api:0.1
gcloud config set compute/zone us-central1-a
gcloud container clusters get-credentials my-cluster
kubectl run java-api --image=gcr.io/$GOOGLE_CLOUD_PROJECT/java-api:0.1 --port 8080
kubectl expose deployment java-api --type="LoadBalancer"
chmod +x mvnw