# Deploying a highly available MySQL cluster on top of Google Kubernetes Engine ## Let's get started! This guide will show you how to deploy MySQL highly available cluster on top Google Kubernetes Engine. The uses 3 MySQL instances behind MySQL-proxy which is responsible to route traffic to active instance. During this guide you will deploy a new GKE cluster, MySQL database and you will connect to database to check its connectivity. **Time to complete**: About 30 minutes **Prerequisites**: A GCP Project with billing enabled **Estimated cost**: $10/day Click the **Start** button to move to the next step. ## Create or select a project ## Create GKE autopilot cluster 1. Create a new `terraform.tfvars` file ```sh touch autopilot-cluster/terraform.tfvars ``` 2. Open autopilot-cluster/terraform.tfvars file. 3. Paste the following content into the file and adapt for your needs if necessary ```hcl project_id = "" cluster_name = "gke-patterns-cluster" cluster_create = { deletion_protection = false labels = { pattern = "mysql" } } region = "europe-west4" vpc_create = { enable_cloud_nat = true } ``` MySQL cluster images are downloaded from Oracle repository, thus cluster network requires Internet connectivity. This is provided by provisioning Cloud NAT instance. 4. Initialize terraform ```sh cd autopilot-cluster/ terraform init ``` 5. Deploy GKE Autopilot cluster ```sh terraform apply ```` Once finished successfully (this should take around 10 minutes) you should see following output at the end: ```terminal Apply complete! Resources: 26 added, 0 changed, 0 destroyed. Outputs: created_resources = { "cloud_nat" = "projects/wns-gke-cloudshell/regions/europe-west8/routers/default-nat" "cluster" = "projects/wns-gke-cloudshell/locations/europe-west8/clusters/cluster-00" "node_service_account" = "jump-0@.gserviceaccount.com" "registry" = "europe-west8-docker.pkg.dev//jump-0" "router" = "/europe-west8/default-nat/default" "subnet_id" = "projects//regions/europe-west8/subnetworks/jump-0-default" "vpc_id" = "projects//global/networks/jump-0" } credentials_config = { "fleet_host" = "https://connectgateway.googleapis.com/v1/projects//locations/global/gkeMemberships/cluster-00" } fleet_host = "https://connectgateway.googleapis.com/v1/projects//locations/global/gkeMemberships/cluster-00" get_credentials = { "direct" = "gcloud container clusters get-credentials cluster-00 --project --location europe-west8" "fleet" = "gcloud container fleet memberships get-credentials cluster-00 --project " } region = "europe-west4" ``` ## Prepare configuration for MySQL deployment To deploy MySQL you need to provide a few references to already created GKE cluster. The module used provides outputs which helps to create those references. 1. Change directory to mysql ```sh cd ../mysql ``` 2. Create a new `terraform.tfvars` for MySQL deployment ```sh touch terraform.tfvars ``` 3. Open mysql/terraform.tfvars file. 4. Paste the following content into the file and adapt for your needs if necessary ```tfvars created_resources = { vpc_id = "jump-0" subnet_id = "projects//regions/europe-west4/subnetworks/jump-0-default" } credentials_config = { kubeconfig = { path = "~/.kube/config" } } mysql_config = { ip_address = "10.0.0.20" # db_cpu = "500m" # db_database_size = "10Gi" # db_memory = "1Gi" # db_replicas = 3 # router_replicas = 2 # cannot be higher than number of the zones in region # router_cpu = "500m" # router_memory = "2Gi" # version = "8.0.34" } namespace = "mysql-ha" project_id = "" region = "europe-west4" # use the same region as for autopilot-cluster ``` 5. Get credentials for created cluster ```sh gcloud container fleet memberships get-credentials cluster-00 --project ``` ## Deploy 1. Initialize terraform ```sh terraform init ``` 2. Deploy MySQL ```sh terraform apply ```` 3. Wait until deployment is ready ```sh kubectl get statefulset -n mysql-ha mycluster -w ``` You should see following response, when all nodes are ready: ```terminal NAME READY AGE mycluster 0/3 118s mycluster 1/3 3m39s mycluster 2/3 3m54s mycluster 3/3 4m5s ``` It takes 4-5 minutes time, as cluster needs to create new nodes to accommodate this workload. Once all nodes are ready, press ctrl-c to return to the command line. ## Check connectivity 1. Get password to MySQL user ```sh echo $(terraform output -raw mysql_password) ``` 2. Login to bastion host: ```sh gcloud compute ssh --project bastion ``` 3. Install mysql-client: ```sh sudo apt update sudo apt install -y mariadb-client ``` 4. Connect to database ```sh mysql --ssl -h 10.0.0.20 -P 6446 -u root -p ``` And paste copied password. 5. Create a sample table ```sh use mysql create table ha_test(id INT NOT NULL AUTO_INCREMENT, data varchar(64), PRIMARY KEY (id)); insert into ha_test(data) values('123'); select * from ha_test; ``` ## Congratulations You're all set! **Don't forget to clean up after yourself**: If you created test projects, be sure to delete them to avoid unnecessary charges. Use `gcloud projects delete `. To remove MySQL resources: ```sh terraform destroy ``` And then remove the cluster: ```sh cd ../autopilot-cluster terraform destroy ```