Overview
In this tutorial, you will be guided on how to deploy WordPress on Kubernetes platforms. The instruction can be used for any Kubernetes cluster, whether it is on-premise, GKE (Google Kubernetes Engine), AKS (Azure Kubernetes Service), or EKS (Elastic Kubernetes Service).
The first section of this tutorial will show you how to launch your first WordPress instance in Kubernetes.
Kubernetes Pods
Kubernetes runs containers within a construct called a pod, which are the smallest atomic unit of a Kubernetes cluster. All containers run within a Kubernetes pod, but a container does not equal a pod.
Each pod provides a single, shared namespace for networking and storage. Multiple containers may run within a single pod, where each container will have access to the same networking namespace and storage. And while multiple containers may run within a single pod, it is best practice for each application being deployed to Kubernetes to have its own pod.
You may be asking yourself why allow running multiple containers within a single pod if it isn’t best practice. The answer to the question is this allows us to attach utility containers to our pods, such as log aggregators, for example.
For a pod to start successfully all containers within it must execute successfully. If your application container starts, but your logging or application monitoring container fails, the pod will not transition to a running state.
Creating a WordPress Pod
To create our first WordPress pod you will need to create a declarative configuration in YAML. The configuration if declarative because we are instructing Kubernetes to set the desired state for our pod.
Create a YAML file named wordpress-blog.yml
--- apiVersion: v1 kind: Pod metadata: name: wordpress-blog spec: containers: - name: wordpress-blog image: wordpress:5.2 env: - name: WORDPRESS_DB_HOST value: database.host.name:3306 - name: WORDPRESS_DB_NAME value: wordpress - name: WORDPRESS_DB_PREFIX value: myblog_
Create the configuration in Kubernetes
kubectl create -f wordpress-blog.yml
The output of the create command will display the status of your request, so will know right away if the pod was created successfully or not. To list your running pods you will use the kubectl get command.
kubectl get pods
The output will look similar to the following, depending on how many pods are running in your cluster and which Kubernetes namespace you are querying against.
NAME READY STATUS RESTARTS AGE wordpress-blog 1/1 Running 0 65s
Getting Pod Details
The kubectl get command will only show you basic information about your pods. For a detailed look at the configuration and state of your pod you will use the kubectl describe command.
kubectl describe pods wordpress-blog
Name: wordpress-blog Namespace: default Priority: 0 PriorityClassName: Node: worker/192.168.1.131 Start Time: Sat, 18 May 2019 06:38:16 -0400 Labels: Annotations: cni.projectcalico.org/podIP: 172.20.1.56/32 Status: Running IP: 172.20.1.56 Containers: wordpress-blog: Container ID: docker://f9b860f167fb990992cc4c0d57e51f7934bb58cd377848e0cbf90dfc4d0fc42b Image: wordpress:5.2 Image ID: docker-pullable://wordpress@sha256:8eb650ebbc8ea8bf743e046967c06a789c43c4baa46252013faf3c6f5ddd0d58 Port: Host Port: State: Running Started: Sat, 18 May 2019 06:38:18 -0400 Ready: True Restart Count: 0 Environment: WORDPRESS_DB_HOST: database.host.name:3306 WORDPRESS_DB_NAME: wordpress WORDPRESS_DB_PREFIX: myblog_ Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-x8jnp (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-x8jnp: Type: Secret (a volume populated by a Secret) SecretName: default-token-x8jnp Optional: false QoS Class: BestEffort Node-Selectors: Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 7m40s default-scheduler Successfully assigned default/wordpress-blog to worker Normal Pulling 7m40s kubelet, worker pulling image "wordpress:5.2" Normal Pulled 7m38s kubelet, worker Successfully pulled image "wordpress:5.2" Normal Created 7m38s kubelet, worker Created container Normal Started 7m38s kubelet, worker Started container
Using the describe command against your pods is useful for troubleshooting problems. The Events section, found at the bottom of the output, provides a window into the activities performed to run the containers within the pod, and if there are any errors during container execution they will be outputted here.
Updating a Pod
It is very unlikely that your pod’s state will be static during its entire lifespan. You will likely need to update it at some point, such as to update WordPress version.
To update a pod you will first update the wordpress-blog.yml file used to create the pod. Then you apply the new configuration using kubectl apply.
kubectl apply -f wordpress-blog.yml
Creating a WordPress Pod Deployment
Kubernetes deployments are used to set a desired deployment state for your pods. You can set the number of replicas you want of your pod to run, for example.
Creating a WordPress Service
Pods are ephemeral by design, so they would not be good candidates for exposing to other services or to the public Internet. Instead, when we want to expose our applications running within a pod we must create a service definition.
Service definitions set how a service will be exposed on the network. There are several options to choose from, and the one you select will be for the particular use case of your service.
LoadBalancer
The load balancer service type will assign a public, routable IP address to your service. The load balancer provisioned will be determined by your Kubernetes network settings. If your cluster is running in GKE or Digital Ocean, for example, a compute load balancer will be provisioned.
NodePort
Node level service types will expose your service using a port local a node. To access the service the IP address of the Kubernetes node the pods are running on will be used.
ClusterIP
A cluster service type will expose the service to entire Kubernetes cluster. This type is useful for exposing internal services to other services and pods. For instance, if you were running a database service within your cluster it would unlikely need to be exposed to the Internet. Instead we can limit the expose to only resources running within our cluster.
Creating a Service
Create new filed called wordpress-blog-service.yml, and add the following contents to the file.
--- apiVersion: v1 kind: Service metadata: name: wordpress-blog-service spec: type: LoadBalancer selector: application: wordpress-blog ports: - port: 80 targetPort: - port: 80
To attach the service definition to your application a selector is used. The value specified in the selector’s application key is the name key value from your pod or deployment yaml file.
Create the service using the kubectl apply command.
kubectl apply -f wordpress-blog-service.yml