Deploying Wordpress in Kubernetes with AzureFiles as a PV

Deploying Wordpress in Kubernetes with AzureFiles as a PV

Background

I was working on a project, migrating some applications to Azure. The information below pertains directly to creating a service endpoint and deployment for Wordpress in Kubernetes, whose non-ephemeral data storage is in AzureFiles (AzureDisk only allows at best an accessModes of ReadWriteOne). AzureFile lets you do ReadWriteMany, allowing multiple frontend wordpress pods (for HA) to read and write to a shared Persistent Volume (PV), per-environment.

While I can’t guarantee this to be absolutely true for lack of memory (on my part), the main difference in attaching the PV between the two versions mentioned below was that with v1.8.x, if the Storage Account was created under the regularly named Resource Group, Kubernetes couldn’t find it. After the creation of the storage class inside of the resource group that gets created to house the resources for Kubernetes in AKS, named something like MC_resource_group_and_region, then Kubernetes would locate the storage class and allocate the PV. I didn’t notice the same thing when testing on 1.9.6, unless I’m misremembering. Anyways, here’s how to get it done.

The example below is for strictly getting this setup up and running in a Dev environment. It is in no way secure. Do not use this approach in Production!

Pre-requisites

Kubernetes

  • Create AKS Cluster. This was tested on v1.8.7 and v1.9.6.

Storage

  • Create Storage Class in same Resource group as the cluster. The one beginning with MC_* for v1.8. If v1.9.6, it seems to work with the storage group in the non-MC_* resource group.

Database

  • Create a Azure MySQL Database with a strong password. Disable SSL.
  • Create a Firewall rule, either whitelisting possible IPs from where the Wordpress pods makes requests to the database, or 0.0.0.0.0 -> 255.255.255.255 .

Deployment

First Deployment

  1. Create a secret in k8s for storing the Database password: kubectl create secret generic wordpress-db --from-literal=password=PASSWORD_GOES_HERE

  2. Create a Storage Class and PVC by running kubectl create -f ./wp-data.yml where ./wp-data.yml’s contents are:

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: azurefile
  labels:
    kubernetes.io/cluster-service: 'true'
provisioner: kubernetes.io/azure-file
mountOptions:
  - dir_mode=0755
  - file_mode=0755
  - uid=1000
  - gid=1000
parameters:
  skuName: Standard_LRS
  location: centralus
  storageAccount: name_of_storage_account  # storage account needs to be in MC_* resource group (for 1.8.x?), not the resource group that contains the AKS cluster.
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: azurefile
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: azurefile
  resources:
    requests:
      storage: 5Gi

Note: mountOptions defaults will vary for AzureFiles and k8s version.

Subsequent Deployments

  1. Run kubectl create -f ./wp-frontend.yml to deploy the Wordpress frontent:
---
apiVersion: v1
kind: Service
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  ports:
    - port: 80
  selector:
    app: wordpress
    tier: frontend
  type: LoadBalancer
---
apiVersion: apps/v1beta2 # for versions before 1.9.0 use apps/v1beta2. After 1.9.0 use apps/v1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress
      tier: frontend
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: frontend
    spec:
      containers:
      - image: wordpress:4.8-apache
        name: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: databasename.mysql.database.azure.com
        - name: WORDPRESS_DB_USER
          value: username@databasename
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: wordpress-db
              key: password
        ports:
        - containerPort: 80
          name: wordpress
        volumeMounts:
        - name: azurefile
          mountPath: "/var/www/html"
      volumes:
      - name: azurefile
        persistentVolumeClaim:
          claimName: azurefile

References