Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
---
title: Install and validate Helm on Google Cloud C4A Arm-based VMs

minutes_to_complete: 45
minutes_to_complete: 60

who_is_this_for: This is an introductory topic intended for developers who want to get hands-on experience using Helm on Linux Arm64 systems, specifically Google Cloud C4A virtual machines powered by Axion processors.


learning_objectives:
- Provision an Arm-based SUSE Linux Enterprise Server (SLES) virtual machine on Google Cloud (C4A with Axion processors)
- Install Helm and kubectl on a SUSE Arm64 (C4A) instance
- Create and validate a local Kubernetes cluster (KinD) on Arm64
- Verify Helm functionality by performing install, upgrade, and uninstall workflows
- Install and configure Helm and kubectl on a SUSE Arm64 (C4A) instance
- Create and connect to a Google Kubernetes Engine (GKE) cluster running on Arm-based nodes
- Deploy PostgreSQL, Redis, and NGINX on GKE using official Helm charts
- Validate Helm workflows by performing install, upgrade, rollback, and uninstall operations
- Verify application readiness and service access for PostgreSQL, Redis, and NGINX on GKE
- Observe Helm behavior under concurrent CLI operations on an Arm64-based Kubernetes cluster

prerequisites:
Expand All @@ -32,8 +34,11 @@ armips:
tools_software_languages:
- Helm
- Kubernetes
- KinD
- kubectl
- GKE
- PostgreSQL
- Redis
- NGINX

operatingsystems:
- Linux
Expand All @@ -57,6 +62,11 @@ further_reading:
link: https://kubernetes.io/docs/
type: documentation

- resource:
title: Bitnami Helm Charts
link: https://github.com/bitnami/charts
type: documentation

weight: 1
layout: "learningpathall"
learning_path_main_page: "yes"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Benchmark Helm concurrency on a Google Axion C4A virtual machine
weight: 6
weight: 10

### FIXED, DO NOT MODIFY
layout: learningpathall
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
title: Prepare GKE Cluster for Helm Deployments
weight: 6

### FIXED, DO NOT MODIFY
layout: learningpathall
---

## Overview
This section explains how to prepare a **Google Kubernetes Engine (GKE) cluster** for deploying Helm charts.
The prepared GKE cluster is used to deploy the following services using custom Helm charts:

- PostgreSQL
- Redis
- NGINX

This setup differs from the earlier KinD-based local cluster, which was intended only for local validation.

## Prerequisites

Before starting, ensure the following are already completed:

- Docker installed
- kubectl installed
- Helm installed
- Google Cloud account available

If Helm and kubectl are not installed, complete the **Install Helm** section first.

### Verify kubectl Installation
Confirm that kubectl is available:

```console
kubectl version --client
```
You should see an output similar to:
```output
Client Version: version.Info{Major:"1", Minor:"26+", GitVersion:"v1.26.15-dispatcher", GitCommit:"5490d28d307425a9b05773554bd5c037dbf3d492", GitTreeState:"clean", BuildDate:"2024-04-18T22:39:37Z", GoVersion:"go1.21.9", Compiler:"gc", Platform:"linux/arm64"}
Kustomize Version: v4.5.7
```

### Install Google Cloud SDK (gcloud)
The Google Cloud SDK is required to create and manage GKE clusters.

**Download and extract:**

```console
wget https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-460.0.0-linux-arm.tar.gz
tar -xvf google-cloud-sdk-460.0.0-linux-arm.tar.gz
```

**Install gcloud:**

```console
./google-cloud-sdk/install.sh
```
Restart the shell or reload the environment if prompted.

### Initialize gcloud
Authenticate and configure the Google Cloud CLI:

```console
./google-cloud-sdk/bin/gcloud init
```

During initialization:

- Log in using a Google account
- Select the correct project
- Choose default settings when unsure

### Set the Active Project
Ensure the correct GCP project is selected:

```console
gcloud config set project YOUR_PROJECT_ID
```

### Enable Kubernetes API
Enable the required API for GKE:

```console
gcloud services enable container.googleapis.com
```

### Create a GKE Cluster
Create a Kubernetes cluster that will host Helm deployments.

```console
gcloud container clusters create helm-arm64-cluster \
--zone us-central1-a \
--machine-type c4a-standard-4 \
--num-nodes 2
```

- This creates a standard GKE cluster
- Node count and machine type can be adjusted later
- Arm64 compatibility depends on available node types in the region

### Configure kubectl Access to GKE
Fetch cluster credentials:

```console
gcloud container clusters get-credentials helm-arm64-cluster \
--zone us-central1-a
```

### Verify Cluster Access
Confirm Kubernetes access:

```console
kubectl get nodes
```

You should see an output similar to:
```output
NAME STATUS ROLES AGE VERSION
gke-helm-arm64-cluster-default-pool-f4ab8a2d-5h6f Ready <none> 5h54m v1.33.5-gke.1308000
gke-helm-arm64-cluster-default-pool-f4ab8a2d-5ldp Ready <none> 5h54m v1.33.5-gke.1308000
```

- Nodes in Ready state
- Kubernetes control plane accessible

### Outcome
At this point:

- Google Cloud SDK is installed and configured
- GKE cluster is running
- kubectl is connected to the cloud cluster
- Helm is ready to deploy applications on GKE

The environment is now prepared to deploy Helm charts.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
---
title: NGINX Deployment Using Custom Helm Chart
weight: 9

### FIXED, DO NOT MODIFY
layout: learningpathall
---

## NGINX Deployment Using Custom Helm Chart
This document explains how to deploy NGINX as a frontend service on Kubernetes using a custom Helm chart.

## Goal
After completing this guide, the environment will include:

- NGINX deployed using Helm
- Public access using a LoadBalancer service
- External IP available for browser access
- Foundation for connecting backend services (Redis, PostgreSQL)

### Create Helm Chart
Generates a Helm chart skeleton that will be customized for NGINX.

```console
helm create my-nginx
```

### Resulting structure

```text
my-nginx/
├── Chart.yaml
├── values.yaml
└── templates/
```

### Configure values.yaml
Defines configurable parameters such as:

- NGINX image
- Service type
- Public port

Replace the contents of `my-nginx/values.yaml` with:
```yaml
image:
repository: nginx
tag: latest

service:
type: LoadBalancer
port: 80
```

That matters

- Centralizes configuration
- Allows service exposure without editing templates
- Simplifies future changes

### Deployment Definition (deployment.yaml)
Defines how the NGINX container runs inside Kubernetes, including:

- Container image
- Pod labels
- Port exposure

Replace `my-nginx/templates/deployment.yaml` completely:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-nginx.fullname" . }}

spec:
replicas: 1
selector:
matchLabels:
app: {{ include "my-nginx.name" . }}

template:
metadata:
labels:
app: {{ include "my-nginx.name" . }}

spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
```

### Service Definition (service.yaml)
Exposes NGINX to external traffic using a Kubernetes LoadBalancer.

Replace `my-nginx/templates/service.yaml` with:

```yaml
apiVersion: v1
kind: Service
metadata:
name: {{ include "my-nginx.fullname" . }}
spec:
type: LoadBalancer
ports:
- port: 80
selector:
app: {{ include "my-nginx.name" . }}
```

Why LoadBalancer:

- Provides a public IP
- Required for browser access
- Common pattern for frontend services

### Install & Access

```console
helm install nginx ./my-nginx
```

```output
NAME: nginx
LAST DEPLOYED: Tue Jan 6 07:55:52 2026
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch its status by running 'kubectl get --namespace default svc -w nginx-my-nginx'
export SERVICE_IP=$(kubectl get svc --namespace default nginx-my-nginx --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")
echo http://$SERVICE_IP:80
```

### Access NGINX from Browser
Get External IP

```console
kubectl get svc
```

Wait until EXTERNAL-IP is assigned.

```output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 34.118.224.1 <none> 443/TCP 3h22m
nginx-my-nginx LoadBalancer 34.118.239.19 34.63.103.125 80:31501/TCP 52s
postgres-app-my-postgres ClusterIP 34.118.225.2 <none> 5432/TCP 13m
redis-my-redis ClusterIP 34.118.234.155 <none> 6379/TCP 6m53s
```

**Open in browser:**

```bash
http://<EXTERNAL-IP>
```

You should see the default NGINX welcome page as shown below:

![NGINX default welcome page in a web browser on an GCP VM alt-text#center](images/nginx-browser.png)

### Outcome
This deployment achieves the following:

- NGINX deployed using a custom Helm chart
- Public access enabled via LoadBalancer
- External IP available for frontend access
- Ready to route traffic to backend services

Loading