This tutorial focuses on setting up a single-replica WordPress deployment on GKE (Google Kubernetes Engine) using a MySQL database. Instead of installing MySQL, users can use Cloud SQL, which provides a managed version of MySQL. WordPress uses PersistentVolumeClaims (PVC) and PersistentVolumes (PV) to store data.
A PersistentVolumes (PV) represents storage volume in the cluster that an administrator provision, or dynamically provisioned by Kubernetes, to fulfill a request made in a PersistentVolumeClaims (PVC). A PersistentVolumeClaims (PVC) is a request for storage of a particular storage class by a user that can be fulfilled by a PersistentVolumes (PV). Both PVCs and PVs are independent from the Pod lifecycles and preserve data through rescheduling, restarting, and even deleting Pods. In Google Kubernetes Engine (GKE), WordPress uses Persistent Disk as storage to back the PersistentVolumes (PV).
WordPress is a blogging engine that uses a relational database to store the blog articles and their related metadata and objects and the local file system to store assets, such as pictures and videos in a blog post. We use the official WordPress Docker image from the Docker Hub in this tutorial to deploy the WordPress.
A container’s root file system isn’t fit to store persistent data in general. The containers we run on GKE (Google Kubernetes Engine) are typically disposable entities. The cluster manager can evict, delete, or reschedule any containers that become unavailable due to node failures or other causes. The user will also lose all data stored in a container’s root file system when a node fails.
WordPress requires PersistentVolumes (PV) to store data. Using PVs backed by Persistent Disk lets the user keep their platform data outside the containers. Even if the containers are deleted, their data will persist in this way. User’s Persistent Disk (and hence their data) doesn’t move with their Pod if the Pod is rescheduled to another node with the default storage class. This tutorial will use the default storage class to create a Persistent Disk and create a PersistentVolumeClaims (PVC) for the deployment.
Before we Begin
- If the user is new to Google Cloud, create an account.
- In the Google Cloud Console, go to the project selector page and select or create a Google Cloud project.
- Make sure to enable the billing for the Google Cloud project.
- In the Google Cloud Console, activate Cloud Shell.
- Enable the Google Kubernetes Engine (GKE) and Cloud SQL Admin APIs in the Cloud Shell:
gcloud services enable container.googleapis.com sqladmin.googleapis.com
Set Up the Environment
1. In Cloud Shell, set the default zone for the gcloud command-line tool by executing the below command:
gcloud config set compute/zone zone
2. After that, replace the following section with the zone closest to the user:
3. Then, set the PROJECT_ID environment variable to the Google Cloud project ID. Replace project-id in the below command with the actual Cloud project ID.
4. Download the application manifest files from the GitHub repository:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
5. Switch to the directory with the wordpress-persistent-disks file, such as:
6. Finally, set the WORKING_DIR environment variable:
For this tutorial, we will create Kubernetes objects using manifest files in YAML format.
Create a Google Kubernetes Engine (GKE) Cluster
To create a GKE cluster to host the user’s WordPress app container, follow the below step:
- Create a cluster (persistent-disk-tutorial) that has three nodes in the Cloud Shell:
CLUSTER_NAME=persistent-disk-tutorial gcloud container clusters create $CLUSTER_NAME \ --num-nodes=3 --enable-autoupgrade --no-enable-basic-auth \ --no-issue-client-certificate --enable-ip-alias --metadata \ disable-legacy-endpoints=true
Creating a PVC and a PV Backed by Persistent Disk
Create a PersistentVolumeClaims (PVC) as the storage required for WordPress. Google Kubernetes Engine (GKE) has a default StorageClass resource installed that lets the user dynamically provision PersistentVolume backed by Persistent Disk. Users can use the wordpress-volumeclaim.yaml file to create the PVCs required for the deployment. This manifest file describes a PersistentVolumeClaims (PVC) that requests 200 GB of storage. A StorageClass resource hasn’t been defined in the file, so this PersistentVolumeClaims (PVC) uses the default StorageClass resource to provision a PersistentVolume (PV) backed by Persistent Disk.
1. In Cloud Shell, deploy the manifest file:
kubectl apply -f $WORKING_DIR/wordpress-volumeclaim.yaml
2. It can take up to ten seconds to provision the PersistentVolume (PV) backed by Persistent Disk and bind it to the PersistentVolumeClaims (PVC). Users can check the status with the following command:
kubectl get persistentvolumeclaim
3. When the process is completed, users can view an output similar to the one shown below:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE wordpress-volumeclaim Bound pvc-89d49350-3c44-11e8-80a6-42010a800002 200G RWO standard 5s
Creating a CloudSQL for MySQL Instance
1. In Cloud Shell, create an instance (mysql-wordpress-instance) by executing the following command:
INSTANCE_NAME=mysql-wordpress-instance gcloud sql instances create $INSTANCE_NAME
2. Next, add the instance connection name as an environment variable by executing the following command:
export INSTANCE_CONNECTION_NAME=$(gcloud sql instances describe $INSTANCE_NAME \ --format='value(connectionName)')
3. Execute the below command to create a database for WordPress to store its data:
gcloud sql databases create wordpress --instance $INSTANCE_NAME
Finally, create a database user named wordpress and a password for that WordPress user to authenticate the instance:
CLOUD_SQL_PASSWORD=$(openssl rand -base64 18) gcloud sql users create wordpress --host=% --instance $INSTANCE_NAME \ --password $CLOUD_SQL_PASSWORD
Configure a service account and create secrets
1. To let the WordPress app access the MySQL instance through a Cloud SQL proxy, create a service account:
SA_NAME=cloudsql-proxy gcloud iam service-accounts create $SA_NAME --display-name $SA_NAME
2. Next, add the service account email address as an environment variable by executing the following command:
SA_EMAIL=$(gcloud iam service-accounts list \ --filter=displayName:$SA_NAME \ --format='value(email)')
3. Execute the following command to add the cloudsql.client role to the service account:
gcloud projects add-iam-policy-binding $PROJECT_ID \ --role roles/cloudsql.client \ --member serviceAccount:$SA_EMAIL
4. Create a key for the service account by executing the following command:
gcloud iam service-accounts keys create $WORKING_DIR/key.json \ --iam-account $SA_EMAIL
5. The above command will download a copy of the key.json file.
6. Then, create a Kubernetes secret for the MySQL credentials by executing the following command:
kubectl create secret generic cloudsql-db-credentials \ --from-literal username=wordpress \ --from-literal password=$CLOUD_SQL_PASSWORD
7. Finally, create a Kubernetes secret for the service account credentials:
kubectl create secret generic cloudsql-instance-credentials \ --from-file $WORKING_DIR/key.json
The next step is to deploy the WordPress container in the Google Kubernetes Engine (GKE) cluster. The wordpress_cloudsql.yaml manifest file defines a Deployment that creates a single Pod that helps to run a container with a WordPress instance. This created container reads the WORDPRESS_DB_PASSWORD environment variable that contains the cloudsql-db-credentials secret that the user created. The wordpress_cloudsql.yaml manifest file also configures the WordPress container to communicate with the MySQL database through the Cloud SQL proxy running in the sidecar container. Users should set the host address value on the WORDPRESS_DB_HOST environment variable.
1. First, prepare the file by replacing the INSTANCE_CONNECTION_NAME environment variable, as shown below:
cat $WORKING_DIR/wordpress_cloudsql.yaml.template | envsubst > \ $WORKING_DIR/wordpress_cloudsql.yaml
2. Deploy the wordpress_cloudsql.yaml manifest file by executing the following. It will take a few minutes to deploy this manifest file while a Persistent Disk is attached to the compute node.
kubectl create -f $WORKING_DIR/wordpress_cloudsql.yaml
3. Execute the following command to check if the status has changed to running:
kubectl get pod -l app=wordpress --watch
4. When the output shows the following status, users can move on to the next step.
NAME READY STATUS RESTARTS AGE wordpress-387015-02xxb 2/2 Running 0 9h
Expose the WordPress Service
1. First, create a Service of type:LoadBalancer by executing the following command. It will take a few minutes to create a load balancer.
kubectl create -f $WORKING_DIR/wordpress-service.yaml
2. Next, watch the deployment and wait for the service to have an external IP address assigned:
kubectl get svc -l app=wordpress --watch
3. When the output shows an external IP address, users can proceed to the next step. Note that the user’s external IP address will be different from the following example. Make sure to note the EXTERNAL_IP address field to use later.
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE wordpress 10.51.243.233 203.0.113.3 80:32418/TCP 1m
Setting Up the WordPress Blog
To set up the WordPress blog, follow the below steps:
1. In a browser, go to the following URL. Replace the external-ip-address parameter with the EXTERNAL_IP address of the service that exposes the user’s WordPress instance:
2. On the WordPress installation page, choose a language and then click Continue.
3. Follow the on-screen instruction and then click Install WordPress.
4. Then, click the login button.
5. Enter the username and password that the user previously created.
6. Users can now have a blog site. To visit the blog, go to the following URL in a browser:
This tutorial presents the steps to deploy and set up a single-replica WordPress deployment on Google Kubernetes Engine (GKE) using a MySQL database. Hope this tutorial was helpful, and do reach out to us if you have any query or suggestions.