# Prepare a GKE cluster for Helm deployments

## In this learning path

- [Introduction](https://learn.arm.com/learning-paths/servers-and-cloud-computing/helm-on-gcp/)
- [Get started with Helm on Google Axion C4A (Arm-based)](https://learn.arm.com/learning-paths/servers-and-cloud-computing/helm-on-gcp/background/)
- [Create a Google Axion C4A virtual machine on Google Cloud](https://learn.arm.com/learning-paths/servers-and-cloud-computing/helm-on-gcp/instance/)
- [Install Helm](https://learn.arm.com/learning-paths/servers-and-cloud-computing/helm-on-gcp/installation/)
- [Validate Helm workflows on a Google Axion C4A virtual machine](https://learn.arm.com/learning-paths/servers-and-cloud-computing/helm-on-gcp/baseline/)
- [Prepare a GKE cluster for Helm deployments](https://learn.arm.com/learning-paths/servers-and-cloud-computing/helm-on-gcp/gke-cluster-for-helm/)
- [PostgreSQL Deployment Using Custom Helm Chart](https://learn.arm.com/learning-paths/servers-and-cloud-computing/helm-on-gcp/postgresql-helm/)
- [Deploy Redis on GKE](https://learn.arm.com/learning-paths/servers-and-cloud-computing/helm-on-gcp/redis-helm/)
- [Deploy NGINX with public access](https://learn.arm.com/learning-paths/servers-and-cloud-computing/helm-on-gcp/nginx-helm/)
- [Benchmark Helm concurrency on a Google Axion C4A virtual machine](https://learn.arm.com/learning-paths/servers-and-cloud-computing/helm-on-gcp/benchmarking/)
- [Next Steps](https://learn.arm.com/learning-paths/servers-and-cloud-computing/helm-on-gcp/_next-steps/)

## Set up your GKE environment
In this section you’ll prepare a Google Kubernetes Engine (GKE) cluster for deploying Helm charts. The GKE cluster hosts the following services:

- PostgreSQL
- Redis
- NGINX

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

## Prerequisites
Ensure that Docker, kubectl, and Helm are installed, and that you have a Google Cloud account available. If Helm and kubectl aren’t installed, complete the previous section first.

### Verify kubectl installation
Confirm that kubectl is available:
```bash
kubectl version --client
```
You should see an output similar to:
```
__output__
Client Version: v1.30.1
__output__
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
```

### Install Python 3.11
Install Python 3.11:
```bash
sudo zypper install -y python311
which python3.11
```

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

Download and extract:
```bash
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:
```bash
./google-cloud-sdk/install.sh
```
After installation completes, exit and reconnect to apply the PATH changes:
```bash
exit
```

### Initialize gcloud
Authenticate and configure the Google Cloud CLI:
```bash
gcloud init
```
During initialization, select **Login with a new account**. You’ll be prompted to authenticate using your browser and receive an auth code to copy back. Select the project you want to use and choose default settings when unsure.

### Get the list of Google project IDs
Retrieve the list of project IDs:
```bash
gcloud projects list
```
The output is similar to:
```
__output__
PROJECT_ID              NAME             PROJECT_NUMBER
__output__
arm-lp-test             arm-lp-test      834184475014
```
Note the **PROJECT_ID** for use in the next step.

### Set the active project
Ensure the correct GCP project is selected:
```bash
gcloud config set project <YOUR_PROJECT_ID>
```
Replace `<YOUR_PROJECT_ID>` with your actual project ID from the previous step.

### Install the auth plugin for gcloud
```bash
gcloud components install gke-gcloud-auth-plugin
```

### Enable Kubernetes API
Enable the required API for GKE:
```bash
gcloud services enable container.googleapis.com
```

### Create a GKE cluster
Create a Kubernetes cluster to host Helm deployments:
```bash
gcloud container clusters create helm-arm64-cluster \
  --zone us-central1-a \
  --machine-type c4a-standard-4 \
  --num-nodes 2 \
  --no-enable-ip-alias
```

### Configure kubectl access to GKE
Fetch cluster credentials:
```bash
gcloud container clusters get-credentials helm-arm64-cluster \
  --zone us-central1-a
```

### Verify cluster access
Confirm Kubernetes access:
```bash
kubectl get nodes
```
You should see an output similar to:
```
__output__
NAME                                                STATUS   ROLES    AGE     VERSION
__output__
gke-helm-arm64-cluster-default-pool-f4ab8a2d-5h6f   Ready    <none>   5h54m   v1.33.5-gke.1308000
__output__
gke-helm-arm64-cluster-default-pool-f4ab8a2d-5ldp   Ready    <none>   5h54m   v1.33.5-gke.1308000
```
All nodes should be in **Ready** state and the Kubernetes control plane should be accessible.

### Remove the taint on the cluster nodes for arm64 support
Remove the taint on the nodes to ensure proper scheduling on arm64 VMs. For each node starting with **gke**, run the following taint command. For example using the node IDs in the output above:
> Note the required “-” at the end… its needed!
```bash
kubectl taint nodes gke-helm-arm64-cluster-default-pool-f4ab8a2d-5h6f kubernetes.io/arch=arm64:NoSchedule-
kubectl taint nodes gke-helm-arm64-cluster-default-pool-f4ab8a2d-5ldp kubernetes.io/arch=arm64:NoSchedule-
```
Replace the node names with your actual node names from the previous command output.

The output should be similar to:
```
__output__
node/gke-helm-arm64-cluster-default-pool-f4ab8a2d-5h6f untainted
__output__
node/gke-helm-arm64-cluster-default-pool-f4ab8a2d-5ldp untainted
```

### Create hyperdisk storage class for our cluster
In order to use the c4a architecture with our cluster, a new storage class must be created.

Create a new file, `hyperdisk.yaml`, with this content:
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: my-hyperdisk-sc
provisioner: pd.csi.storage.gke.io
parameters:
  type: hyperdisk-balanced # Or hyperdisk-ssd, etc.
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
```
Apply the `hyperdisk.yaml` file to the cluster:
```bash
kubectl apply -f ./hyperdisk.yaml
```
Confirm that the new storage class has been added:
```bash
kubectl get storageclass
```
The output should contain the new **my-hyperdisk-sc** storage class:
```
__output__
NAME                     PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
__output__
my-hyperdisk-sc          pd.csi.storage.gke.io   Delete          WaitForFirstConsumer   false                  7m27s
__output__
premium-rwo              pd.csi.storage.gke.io   Delete          WaitForFirstConsumer   true                   20m
__output__
standard                 kubernetes.io/gce-pd    Delete          Immediate              true                   20m
__output__
standard-rwo (default)   pd.csi.storage.gke.io   Delete          WaitForFirstConsumer   true                   20m
```
The new storage class will be used in the next section.

## What you’ve accomplished and what’s next
You’ve successfully prepared your GKE environment by installing and configuring the Google Cloud SDK, creating a GKE cluster, connecting kubectl to the cluster, and verifying cluster access. Your environment is now ready to deploy applications using Helm charts.

Next, you’ll deploy PostgreSQL on your GKE cluster using a custom Helm chart with persistent storage and secure credentials.
