WordPress & MySQL Setup With Kubernetes

Github Source Code : https://github.com/NadunOvitigala/wordpress-mysql-kubernetes-ingress-yaml/tree/main

How to run

Clone the repo to your local

git clone https://github.com/NadunOvitigala/wordpress-mysql-kubernetes-ingress-yaml.git

Apply and Verify

kubectl apply -k ./
kubectl get pods

Edit /etc/hosts like bellow

Get node Internal IP

kubectl get nodes -o wide

Edit /etc/hosts like bellow

ADD NodeIP : 192.168.49.2   SITE-URL : wordpress-local.com

Type wordpress-local.com URl on you browser.

Source Code Explain

wordpress-deployment.yaml

apiVersion: v1
kind: Service
metadata:
  name: wordpress-service
  labels:
    app: wordpress-service
spec:
  ports:
    - port: 80
  selector:
    app: wordpress
    tier: frontend
  type: LoadBalancer

This section defines a Kubernetes Service named “wordpress-service.” A Service is used to expose a set of pods as a network service. It listens on port 80 and forwards traffic to pods that have the labels “app: wordpress” and “tier: frontend.” This Service is of type “LoadBalancer,” which means it will create an external load balancer to distribute incoming traffic to the WordPress pods.

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wp-pv-claim
  labels:
    app: wordpress
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi

This section defines a PersistentVolumeClaim (PVC) named “wp-pv-claim.” A PVC is used to request storage resources from a storage class. In this case, it requests 20GB of storage with the access mode “ReadWriteOnce,” which means it can be mounted by a single pod for both reading and writing.

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: frontend
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: frontend
    spec:
      containers:
      - image: wordpress:6.2.1-apache
        name: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: wordpress-mysql
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password
        - name: WORDPRESS_DB_USER
          value: wordpress
        ports:
        - containerPort: 80
          name: wordpress
        volumeMounts:
        - name: wordpress-persistent-storage
          mountPath: /var/www/html
      volumes:
      - name: wordpress-persistent-storage
        persistentVolumeClaim:
          claimName: wp-pv-claim

This section defines a Kubernetes Deployment for the WordPress application. A Deployment manages a set of replicated pods. Here are the key details:

  • The Deployment is named “wordpress” and labeled as “app: wordpress.”
  • The Deployment specifies that it should manage pods with labels “app: wordpress” and “tier: frontend.”
  • The strategy for managing pods is set to “Recreate,” which means existing pods will be terminated and new ones will be created when updates are made.
  • The template section describes the pod template. It specifies the container image, environment variables (for connecting to a MySQL database), ports, and volume mounts.
  • A volume named “wordpress-persistent-storage” is mounted at “/var/www/html” in the WordPress container, and it is associated with the PersistentVolumeClaim “wp-pv-claim” defined earlier. This allows WordPress to store its data persistently.

mysql-deployment.yaml

apiVersion: v1
kind: Service
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  ports:
    - port: 3306
  selector:
    app: wordpress
    tier: mysql
  clusterIP: None

In this section, you are defining a Kubernetes service named “wordpress-mysql” that exposes the MySQL database. The service has no cluster IP, indicating that it’s not accessible outside the cluster. It uses labels to select pods with the “app: wordpress” and “tier: mysql” labels. Port 3306 is exposed for MySQL traffic.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
  labels:
    app: wordpress
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi

This section defines a Persistent Volume Claim (PVC) named “mysql-pv-claim.” It requests 20Gi of storage with the “ReadWriteOnce” access mode. This claim is used to ensure that the MySQL data is stored persistently.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: mysql
    spec:
      containers:
      - image: mysql:8.0
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password
        - name: MYSQL_DATABASE
          value: wordpress
        - name: MYSQL_USER
          value: wordpress
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
    volumes:
    - name: mysql-persistent-storage
      persistentVolumeClaim:
        claimName: mysql-pv-claim

This is the most complex section, defining a Kubernetes Deployment for the MySQL database. Here’s a breakdown:

  • The deployment is named “wordpress-mysql” and has labels “app: wordpress.”
  • It selects pods based on the labels “app: wordpress” and “tier: mysql.”
  • It uses a “Recreate” strategy, which means old pods are deleted before new ones are created.
  • The pod template specifies the container to run, which is MySQL 8.0.
  • It sets environment variables for MySQL configuration, such as the root password, database name, user, and password. Some secrets are used here (e.g., “mysql-pass”).
  • Port 3306 is exposed for MySQL connections.
  • It defines a volume mount for persistent storage, ensuring that the MySQL data is stored on the volume claimed earlier.

kustomization.yaml

secretGenerator:
- name: mysql-pass
  literals:
  - password=YOUR_PASSWORD

In this section, you are defining a Kubernetes Secret Generator, which is used to create a secret. A secret is a Kubernetes resource used to store sensitive data, such as passwords, tokens, or other confidential information. In this case, it’s creating a secret named “mysql-pass” with a single key-value pair: “password” with the value “YOUR_PASSWORD.” You should replace “YOUR_PASSWORD” with your actual password when using this YAML file.

resources:
  - mysql-deployment.yaml
  - wordpress-deployment.yaml

This section specifies the resources that will be applied as part of the Kubernetes deployment. It references two separate YAML files: “mysql-deployment.yaml” and “wordpress-deployment.yaml.” These files likely contain the definitions for Kubernetes Deployments, which are used to manage the lifecycle of applications running on the cluster. These deployment files would typically include specifications for pods, services, and other resources needed for your MySQL and WordPress applications.

ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: wordpress-ingress
spec:
  rules:
    - host: wordpress-local.com
      http: 
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: wordpress-service
                port:
                  number: 80

The Kubernetes YAML file defines an Ingress resource, which plays a crucial role in managing external access to services within a Kubernetes cluster. This resource is named “wordpress-ingress” and is configured to handle incoming HTTP traffic with the hostname “wordpress-local.com.” The routing is specified using the rules section, where any requests to the root path (“/”) or its subpaths will be directed to the Kubernetes service named “wordpress-service” on port 80. The “pathType” is set to “Prefix,” which allows for flexible routing of various subpaths to the same backend service. This configuration is commonly used when hosting web applications, ensuring that traffic to a specific hostname is efficiently directed to the appropriate service within the cluster.

Thank You!!

Leave a Comment

Your email address will not be published. Required fields are marked *