The Hello World UI service project is designed to deploy a Node.js web application using Google Kubernetes Engine (GKE) and manage it with Prometheus and Grafana for monitoring. The project utilizes Docker for containerization and Google Artifact Registry (GAR) for storing Docker images. It integrates with Kubernetes for application deployment and uses Helm for managing Prometheus and Grafana installations.
- Deploy Node.js Application: Containerize and deploy a Node.js web application to a GKE cluster.
- Manage Docker Images: Use Google Artifact Registry to store and manage Docker images.
- Enable Monitoring: Implement Prometheus and Grafana for monitoring application metrics and visualizing data.
- Secure Access: Configure Kubernetes secrets for database credentials and Docker image access.
- Reason for Choice: Docker is used for containerizing the Node.js application, ensuring consistent deployment across different environments.
- Advantages:
- Encapsulates application dependencies and environment.
- Facilitates reproducible builds and deployment.
- Reason for Choice: GAR is used to store and manage Docker images securely.
- Advantages:
- Integration with GCP services for seamless authentication and authorization.
- Supports immutable tags to prevent overwriting of images.
- Reason for Choice: GKE provides a managed Kubernetes environment, simplifying the deployment and scaling of containerized applications.
- Advantages:
- Managed Kubernetes service with automated updates and scaling.
- Integration with GCP’s security, logging, and monitoring services.
- Reason for Choice: Prometheus is used for collecting and storing metrics from the Node.js application and Kubernetes components.
- Advantages:
- Powerful querying language (PromQL) for metric analysis.
- Integration with Kubernetes for service discovery and monitoring.
- Reason for Choice: Grafana provides a flexible platform for visualizing metrics from Prometheus.
- Advantages:
- Customizable dashboards for visualizing a wide range of metrics.
- Supports various data sources, including Prometheus.
- Reason for Choice: Helm is used for managing Kubernetes applications, making it easier to deploy and configure Prometheus and Grafana.
- Advantages:
- Simplifies the management of Kubernetes resources with pre-configured charts.
- Facilitates version control and updates.
Clone the repository to your local machine:
git clone https://github.com/thunderbirdgit/hw-ui-service.git
If you don't have a Google Artifact Registry, create one and ensure immutable tags are enabled to prevent overwriting the same image.
Authenticate Docker with Google Artifact Registry, then build, tag, and push the Docker image:
gcloud auth configure-docker us-central1-docker.pkg.dev
docker build -t hello-world-fe-ab12n1o-develop:latest .
docker tag hello-world-fe-ab12n1o-develop:latest us-central1-docker.pkg.dev/nonprod-app-cluster/nonprod/hello-world-fe-ab12n1o-develop:latest
docker push us-central1-docker.pkg.dev/nonprod-app-cluster/nonprod/hello-world-fe-ab12n1o-develop:latest
Enable GitGuardian checks to monitor and alert if any sensitive information is committed to the repository.
Ensure your Docker images are correctly pushed to Google Artifact Registry.
Create a service account to pull Docker images during deployments and avoid using credentials directly in configuration files:
$ gcloud iam service-accounts create app-docker-image-puller --description="Service account for pulling Docker images" --display-name="Docker Image Puller"
$ gcloud projects add-iam-policy-binding nonprod-app-cluster --member="serviceAccount:app-docker-image-puller@nonprod-
app-cluster.iam.gserviceaccount.com" --role="roles/artifactregistry.reader"
Generate a key for the service account and create a Kubernetes secret for Docker registry access:
$ gcloud iam service-accounts keys create app-docker-read-key.json --iam-account=app-docker-image-puller@nonprod-app-cluster.iam.gserviceaccount.com
$ kubectl create secret docker-registry regcred --docker-server=us-central1-docker.pkg.dev --docker-username=_json_key --docker-password="$(cat app-docker-read-key.json)" --docker-email=<email>
$ gcloud projects add-iam-policy-binding nonprod-app-cluster --member="serviceAccount:app-docker-image-puller@nonprod-app-cluster.iam.gserviceaccount.com" --role="roles/secretmanager.secretAccessor"
- Create VPC Peering to connect to postgres database. Since postgres DB is installed on a different VPC network, you need to connect GKE cluster with postgres DB cluster
gcloud services enable servicenetworking.googleapis.com servicemanagement.googleapis.com iamcredentials.googleapis.com
gcloud compute addresses create cloudsql-peer --global --purpose=VPC_PEERING --prefix-length=16 --description="Peering range for Cloud SQL" --network=default --project=<gke_project_id>
gcloud sql connect <db_host>
- Connect to default postgres database
psql "host=db_host port=5432 sslmode=disable user=dev_api_db_creds dbname=postgres"
Password for user dev_api_db_creds:
psql (16.3 (Ubuntu 16.3-1.pgdg22.04+1), server 14.12)
Type "help" for help.
postgres=>
- Create hello_world_db database, messages table and insert record into the database
postgres=> \c hello_world_db;
psql (16.3 (Ubuntu 16.3-1.pgdg22.04+1), server 14.12)
You are now connected to database "hello_world_db" as user "dev_api_db_creds".
hello_world_db=> CREATE TABLE messages (
id SERIAL PRIMARY KEY,
message TEXT NOT NULL
);
CREATE TABLE
hello_world_db=> INSERT INTO messages (message) VALUES ('Hello World');
INSERT 0 1
hello_world_db=> SELECT * FROM messages;
id | message
----+-------------
1 | Hello World
(1 row)
Store database credentials in Kubernetes secrets for runtime access:
kubectl create secret generic dev-db-credentials --from-literal=host=<DATABASE_SERVER_IP> --from-literal=port=5432 --from-literal=user=<DB_USERNAME> --from-literal=password=<DB_PASSWORD> --from-literal=database=<DB_NAME>
Prepare Kubernetes manifests for deployment:
- deployment.yaml: Contains deployment details, including image, container ports, resource configuration, and DB secrets.
- service.yaml: Configures a LoadBalancer service for the application with HTTP port 3080 and metrics port 3081.
- ingress.yaml: Configures Ingress to host dev.helloworld.com with path prefixes for the application and metrics server.
- prometheus-service.yaml: Service file to access the Prometheus monitoring server.
- servicemonitor.yaml: Configuration to monitor metrics server endpoints.
- prometheus/: Contains Prometheus monitoring server installation files with configurations for LoadBalancer and scrape_configs.
- grafana/: Contains Grafana monitoring dashboard installation files with LoadBalancer configuration.
- Connect to Kubernetes dev cluster
gcloud container clusters get-credentials dev-gke-cluster --region=us-central1
Fetching cluster endpoint and auth data.
kubeconfig entry generated for dev-gke-cluster.
- Apply the manifest files to create the deployment, service, Ingress, ServiceMonitor, and other resources:
kubectl apply -f manifests/
Ensure that the services are using LoadBalancer instead of ClusterIP to enable traffic routing through the Ingress Controller.
In real world, dev.helloworld.com will be registered through the Domain registration providers. For the purposes of this exercise, modify the /etc/hosts
file on your laptop or other device to access http://dev.helloworld.com
through Ingress IP.
Ingress access logs can be accessed by running kubectl logs -f <ingress_controller> --namespace ingress-nginx
Metrics can be accessed from the /metrics endpoint of your application. This data can be integrated with Prometheus and Grafana for monitoring and analytics.
Install Prometheus using Helm:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.52.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml --force-conflicts=true --server-side
helm install prometheus prometheus-community/prometheus
helm pull prometheus-community/prometheus --untar # Pull prometheus installation folder
# Modify values.yaml file from ClusterIP to LoadBalancer
helm upgrade prometheus prometheus-community/prometheus -f values.yaml
Prometheus can be accessed from the LoadBalancer IP.
Add scrape configurations to values.yaml and restart Prometheus to scrape metrics from the hello-world-fe service:
scrape_configs:
- job_name: 'hello-world-fe'
scrape_interval: 15s
static_configs:
- targets: ['hello-world-fe:3081']
After applying the changes and restarting prometheus server, hello-world-fe metrics data can be accessed from Prometheus server
helm upgrade prometheus prometheus-community/prometheus -f values.yaml
kubectl rollout restart deployment prometheus-server
Display HTTP Requests Total
Although Promotheus can be used for monitoring and alerting, Grafana can be the best tool for data visualization. Data from Prometheus can be used as a data source for Grafana to create dashboards
Install Grafana using Helm:
helm repo add grafana https://grafana.github.io/helm-charts
helm install grafana grafana/grafana
helm pull grafana/grafana --untar
# Change from ClusterIP to LoadBalancer in values.yaml and reapply
helm upgrade grafana grafana/grafana -f values.yaml
- Access Grafana Grafana can be accessed from the LoadBalancer IP. Add Prometheus as a data source and configure dashboards.
Ensure all pods are healthy:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
grafana-846f7fdf6-g2n25 1/1 Running 0 45m
hello-world-fe-5f49c88f84-bsgx9 1/1 Running 0 106m
prometheus-alertmanager-0 1/1 Running 0 98m
prometheus-kube-state-metrics-6b6cdbf965-b4r4r 1/1 Running 0 98m
prometheus-operator-755897dcb6-mnxmm 1/1 Running 0 92m
prometheus-prometheus-node-exporter-4cqgh 1/1 Running 0 98m
prometheus-prometheus-node-exporter-5mr4v 1/1 Running 0 98m
prometheus-prometheus-node-exporter-nj7d2 1/1 Running 0 98m
prometheus-prometheus-pushgateway-57c548bd6f-qrgzk 1/1 Running 0 98m
prometheus-server-7cb8cd8fd5-mfrz8 2/2 Running 0 98m
Now Grafana is ready to display dashboards with visualizations based on the metrics collected from Prometheus.
# Example Dashboard Creation Steps
# 1. Navigate to Grafana web UI
# 2. Create a new dashboard
# 3. Add Prometheus as a data source
# 4. Create panels for different metrics
kubectl delete service hello-world-fe
kubectl delete ingress hello-world-fe
kubectl delete deployment hello-world-fe
- Effective Containerization: Docker streamlined the deployment process, making it easy to manage and deploy the application consistently.
- Integration Challenges: Configuring Prometheus and Grafana required careful attention to service discovery and metric scraping configurations.
- Security and Access Control: Proper management of Kubernetes secrets and IAM roles was crucial for maintaining security and access control.