Skip to content

Latest commit

 

History

History

mysql-wordpress-pd

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

Persistent Installation of MySQL and WordPress on Kubernetes

This example describes how to run a persistent installation of Wordpress using the volumes feature of Kubernetes, and Google Compute Engine persistent disks.

We'll use the mysql and wordpress official Docker images for this installation. (The wordpress image includes an Apache server).

We'll create two Kubernetes pods to run mysql and wordpress, both with associated persistent disks, then set up a Kubernetes service to front each pod.

This example demonstrates several useful things, including: how to set up and use persistent disks with Kubernetes pods; how to define Kubernetes services to leverage docker-links-compatible service environment variables; and use of an external load balancer to expose the wordpress service externally and make it transparent to the user if the wordpress pod moves to a different cluster node.

Get started on Google Compute Engine (GCE)

Because we're using the GCEPersistentDisk type of volume for persistent storage, this example is only applicable to Google Compute Engine. Take a look at the volumes documentation for other options.

First, if you have not already done so:

  1. Create a Google Cloud Platform project.
  2. Enable billing.
  3. Install the gcloud SDK.

Authenticate with gcloud and set the gcloud default project name to point to the project you want to use for your Kubernetes cluster:

gcloud auth login
gcloud config set project <project-name>

Next, start up a Kubernetes cluster:

wget -q -O - https://get.k8s.io | bash

Please see the GCE getting started guide for full details and other options for starting a cluster.

Create two persistent disks

For this WordPress installation, we're going to configure our Kubernetes pods to use persistent disks. This means that we can preserve installation state across pod shutdown and re-startup.

You will need to create the disks in the same GCE zone as the Kubernetes cluster. The default setup script will create the cluster in the us-central1-b zone, as seen in the config-default.sh file. Replace $ZONE below with the appropriate zone.

We will create two disks: one for the mysql pod, and one for the wordpress pod. In this example, we create 20GB disks, which will be sufficient for this demo. Feel free to change the size to align with your needs, as wordpress requirements can vary. Also, keep in mind that disk performance scales with size.

First create the mysql disk.

gcloud compute disks create --size=20GB --zone=$ZONE mysql-disk

Then create the wordpress disk.

gcloud compute disks create --size=20GB --zone=$ZONE wordpress-disk

Start the Mysql Pod and Service

Now that the persistent disks are defined, the Kubernetes pods can be launched. We'll start with the mysql pod.

Start the Mysql pod

First, edit mysql.yaml, the mysql pod definition, to use a database password that you specify. mysql.yaml looks like this:

apiVersion: v1
kind: Pod
metadata:
  name: mysql
  labels: 
    name: mysql
spec: 
  containers: 
    - resources:
        limits :
          cpu: 0.5
      image: mysql:5.6
      name: mysql
      env:
        - name: MYSQL_ROOT_PASSWORD
          # change this
          value: yourpassword
      ports: 
        - containerPort: 3306
          name: mysql
      volumeMounts:
          # name must match the volume name below
        - name: mysql-persistent-storage
          # mount path within the container
          mountPath: /var/lib/mysql
  volumes:
    - name: mysql-persistent-storage
      gcePersistentDisk:
        # This GCE PD must already exist.
        pdName: mysql-disk
        fsType: ext4

Download example

Note that we've defined a volume mount for /var/lib/mysql, and specified a volume that uses the persistent disk (mysql-disk) that you created. Once you've edited the file to set your database password, create the pod as follows, where <kubernetes> is the path to your Kubernetes installation:

$ kubectl create -f examples/mysql-wordpress-pd/mysql.yaml

It may take a short period before the new pod reaches the Running state. List all pods to see the status of this new pod and the cluster node that it is running on:

$ kubectl get pods

Check the running pod on the Compute instance

You can take a look at the logs for a pod by using kubectl.sh log. For example:

$ kubectl logs mysql

If you want to do deeper troubleshooting, e.g. if it seems a container is not staying up, you can also ssh in to the node that a pod is running on. There, you can run sudo -s, then docker ps -a to see all the containers. You can then inspect the logs of containers that have exited, via docker logs <container_id>. (You can also find some relevant logs under /var/log, e.g. docker.log and kubelet.log).

Start the Mysql service

We'll define and start a service that lets other pods access the mysql database on a known port and host. We will specifically name the service mysql. This will let us leverage the support for Docker-links-compatible service environment variables when we set up the wordpress pod. The wordpress Docker image expects to be linked to a mysql container named mysql, as you can see in the "How to use this image" section on the wordpress docker hub page.

So if we label our Kubernetes mysql service mysql, the wordpress pod will be able to use the Docker-links-compatible environment variables, defined by Kubernetes, to connect to the database.

The mysql-service.yaml file looks like this:

apiVersion: v1
kind: Service
metadata: 
  labels: 
    name: mysql
  name: mysql
spec: 
  ports:
    # the port that this service should serve on
    - port: 3306
  # label keys and values that must match in order to receive traffic for this service
  selector: 
    name: mysql

Download example

Start the service like this:

$ kubectl create -f examples/mysql-wordpress-pd/mysql-service.yaml

You can see what services are running via:

$ kubectl get services

Start the WordPress Pod and Service

Once the mysql service is up, start the wordpress pod, specified in wordpress.yaml. Before you start it, edit wordpress.yaml and set the database password to be the same as you used in mysql.yaml. Note that this config file also defines a volume, this one using the wordpress-disk persistent disk that you created.

apiVersion: v1
kind: Pod
metadata:
  name: wordpress
  labels: 
    name: wordpress
spec: 
  containers: 
    - image: wordpress
      name: wordpress
      env:
        - name: WORDPRESS_DB_PASSWORD
          # change this - must match mysql.yaml password
          value: yourpassword
      ports: 
        - containerPort: 80
          name: wordpress
      volumeMounts:
          # name must match the volume name below
        - name: wordpress-persistent-storage
          # mount path within the container
          mountPath: /var/www/html
  volumes:
    - name: wordpress-persistent-storage
      gcePersistentDisk:
        # This GCE PD must already exist.
        pdName: wordpress-disk
        fsType: ext4

Download example

Create the pod:

$ kubectl create -f examples/mysql-wordpress-pd/wordpress.yaml

And list the pods to check that the status of the new pod changes to Running. As above, this might take a minute.

$ kubectl get pods

Start the WordPress service

Once the wordpress pod is running, start its service, specified by wordpress-service.yaml.

The service config file looks like this:

apiVersion: v1
kind: Service
metadata: 
  labels: 
    name: wpfrontend
  name: wpfrontend
spec: 
  ports:
    # the port that this service should serve on
    - port: 80
  # label keys and values that must match in order to receive traffic for this service
  selector: 
    name: wordpress
  type: LoadBalancer

Download example

Note the type: LoadBalancer setting. This will set up the wordpress service behind an external IP. Note also that we've set the service port to 80. We'll return to that shortly.

Start the service:

$ kubectl create -f examples/mysql-wordpress-pd/wordpress-service.yaml

and see it in the list of services:

$ kubectl get services

Then, find the external IP for your WordPress service by running:

$ kubectl get services/wpfrontend
NAME                  CLUSTER_IP       EXTERNAL_IP       PORT(S)       SELECTOR               AGE
wpfrontend            10.0.0.2         1.2.3.4           80/TCP        ...                    ...

or by listing the forwarding rules for your project:

$ gcloud compute forwarding-rules list

Look for the rule called wpfrontend, which is what we named the wordpress service, and note its IP address.

Visit your new WordPress blog

To access your new installation, you first may need to open up port 80 (the port specified in the wordpress service config) in the firewall for your cluster. You can do this, e.g. via:

$ gcloud compute firewall-rules create sample-http --allow tcp:80

This will define a firewall rule called sample-http that opens port 80 in the default network for your project.

Now, we can visit the running WordPress app. Use the external IP that you obtained above, and visit it on port 80:

http://<external-ip>

You should see the familiar WordPress init page.

Take down and restart your blog

Set up your WordPress blog and play around with it a bit. Then, take down its pods and bring them back up again. Because you used persistent disks, your blog state will be preserved.

If you are just experimenting, you can take down and bring up only the pods:

$ kubectl delete -f examples/mysql-wordpress-pd/wordpress.yaml
$ kubectl delete -f examples/mysql-wordpress-pd/mysql.yaml

When you restart the pods again (using the create operation as described above), their services will pick up the new pods based on their labels.

If you want to shut down the entire app installation, you can delete the services as well.

If you are ready to turn down your Kubernetes cluster altogether, run:

$ cluster/kube-down.sh

Analytics