---
# System prepended metadata

title: CAPG setup in the GCP VM

---

# CAPG setup in the GCP VM
---------------------------

### Create the VM instance

In this post we are going to setup the management cluster in the GCP VM. First create a VM(Compute Instance) in the GCP either from the console or by the below command.

```bash
gcloud compute instances create capg-test-snadbox --image-family ubuntu-2004-lts --image-project ubuntu-os-cloud --zone us-central1-a
```

### Install all the neccesary software

1. **Install Docker(Latest)**

    ```bash
    sudo apt update
    
    sudo apt install apt-transport-https ca-certificates curl software-properties-common
    
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    
    sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
    
    sudo apt update
    
    sudo apt install docker-ce
    ```
    
2. **Install Kind(v0.14.0)**
    
    ```bash
    curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.14.0/kind-linux-amd64
    
    chmod +x ./kind
    
    mv ./kind /usr/local/bin/
    ```
    
3. **Install Kubectl(Latest)**

    ```bash
    curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
    
    chmod +x ./kubectl
    
    sudo mv ./kubectl /usr/local/bin/kubectl
    ```
    
4. **Install Clusterctl(v1.1.4)**

    ```bash
    curl -L https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.1.4/clusterctl-linux-amd64 -o clusterctl
    
    chmod +x ./clusterctl
    
    sudo mv ./clusterctl /usr/local/bin/clusterctl
    ```
    
### Auth gcloud

```
gcloud auth application-default login
```

It will give you a command to run the command in a separate local terminal then login and copy the output back into the VM terminal.


### Export the Env Vars

**Note-** Always use the Kubernetes version same as the version of our OS image created by the image builder. You can check from [kubernetes.json](https://github.com/kubernetes-sigs/image-builder/blob/master/images/capi/packer/config/kubernetes.json).

```bash
export GCP_PROJECT_ID=<YOUR PROJECT ID>
export GOOGLE_APPLICATION_CREDENTIALS=<PATH TO GCP CREDENTIALS>
export GCP_B64ENCODED_CREDENTIALS=$( cat /path/to/gcp-credentials.json | base64 | tr -d '\n' )

export CLUSTER_TOPOLOGY=true
export GCP_REGION="us-east4"
export GCP_PROJECT="<YOU GCP PROJECT NAME>"
export KUBERNETES_VERSION=1.22.9
export IMAGE_ID=projects/$GCP_PROJECT/global/images/<IMAGE ID>
export GCP_CONTROL_PLANE_MACHINE_TYPE=n1-standard-2
export GCP_NODE_MACHINE_TYPE=n1-standard-2
export GCP_NETWORK_NAME=default
export CLUSTER_NAME=test
```

### Setup the network

setup the network in this example we are using the default network so we will create some router/nats for our workload cluster to have internet access.

```bash
gcloud compute routers create "${CLUSTER_NAME}-myrouter" --project="${GCP_PROJECT}" --region="${GCP_REGION}" --network="default"

gcloud compute routers nats create "${CLUSTER_NAME}-mynat" --project="${GCP_PROJECT}" --router-region="${GCP_REGION}" --router="${CLUSTER_NAME}-myrouter" --nat-all-subnet-ip-ranges --auto-allocate-nat-external-ips
```

### Initialize the Infrastructure, generate the workload cluster config and apply it

```bash
clusterctl init --infrastructure gcp

clusterctl generate cluster $CLUSTER_NAME --kubernetes-version v1.22.9 > workload-test.yaml

kubectl apply -f workload-test.yaml
```

wait for few minutes & view the cluster and its resources

```bash
$ clusterctl describe cluster $CLUSTER_NAME
NAME                                                               READY  SEVERITY  REASON                 SINCE  MESSAGE
/test                                                              False  Info      WaitingForKubeadmInit  5s
├─ClusterInfrastructure - GCPCluster/test
└─ControlPlane - KubeadmControlPlane/test-control-plane            False  Info      WaitingForKubeadmInit  5s
  └─Machine/test-control-plane-x57zs                               True                                    31s
    └─MachineInfrastructure - GCPMachine/test-control-plane-7xzw2
```

Check the status of the control plane

```bash
$ kubectl get kubeadmcontrolplane
NAME                 CLUSTER   INITIALIZED   API SERVER AVAILABLE   REPLICAS   READY   UPDATED   UNAVAILABLE   AGE    VERSION
test-control-plane   test                                           1                  1         1             2m9s   v1.22.9
```

**Note –** The controller plane won’t be ready until the next step when I install the CNI (Container Network Interface).

### Get the kubeconfig for the workload cluster & apply the CNI

```bash
clusterctl get kubeconfig $CLUSTER_NAME > workload-test.kubeconfig

kubectl --kubeconfig=./workload-test.kubeconfig \
  apply -f https://docs.projectcalico.org/v3.20/manifests/calico.yaml
```

### Edit the Machine Deployment

Edit the MachineDeployment in the workload-test.yaml it has 0 replicas add the replicas you want to have your nodes, in this case, we used 2. Apply the workload-test.yaml

```bash
kubectl apply -f workload-test.yaml
```

After a few minutes, you should see something like this –

```bash
$ clusterctl describe cluster $CLUSTER_NAME
NAME                                                               READY  SEVERITY  REASON  SINCE  MESSAGE
/test                                                              True                     15m
├─ClusterInfrastructure - GCPCluster/test
├─ControlPlane - KubeadmControlPlane/test-control-plane            True                     15m
│ └─Machine/test-control-plane-x57zs                               True                     19m
│   └─MachineInfrastructure - GCPMachine/test-control-plane-7xzw2
└─Workers
  └─MachineDeployment/test-md-0                                    True                     10m
    └─2 Machines...                                                True                     13m    See test-md-0-68bd55744b-qpk67, test-md-0-68bd55744b-tsgf6

$ kubectl get nodes --kubeconfig=./workload-test.kubeconfig
NAME                       STATUS   ROLES                  AGE   VERSION
test-control-plane-7xzw2   Ready    control-plane,master   21m   v1.22.9
test-md-0-b7766            Ready    <none>                 17m   v1.22.9
test-md-0-wsgpj            Ready    <none>                 17m   v1.22.9
```

Yaaa! Now we have a Kubernetes cluster in the GCP with 1 control pannel with 2 worker nodes.


### Delete what you have created –

```bash
kubectl delete cluster $CLUSTER_NAME

gcloud compute routers nats delete "${CLUSTER_NAME}-mynat" --project="${GCP_PROJECT}" \
    --router-region="${GCP_REGION}" --router="${CLUSTER_NAME}-myrouter"

gcloud compute routers delete "${CLUSTER_NAME}-myrouter" --project="${GCP_PROJECT}" \
    --region="${GCP_REGION}"

kind delete cluster
```