K8S DIY SERIES - 2.3 - PV & PVC

Preface

In experiment 2.2 - Deployment, we successfully transformed wordpress+mysql based on Pod deployment into Deployment-based deployment. Deployment-based deployment has many advantages, such as supporting Rolling Update and horizontal expansion.

However, there is a problem that when our Deployment is modified or Pod is deleted and reconstructed, the data will also be lost. This is what we don't want to see. In this article, we will try stateful application based on PV & PVC to save data state.

scene

For single instance stateful applications, we can define Deployment and replicas can only be 1, associate it with a PV by specifying PVC, and use the state storage function provided by PV. If you want to start multiple instances, then Deployment is not competent for this task. You must use the StatefulSet+PVC Template approach, which we will talk about later, to create a multi-instance-to-multi-PVC model.

All the source codes of this experiment are saved in:
https://github.com/zrbcool/blog-public/tree/master/k8s-hands-on/lab06

actual combat

Definition of PVC

  lab06 git:(master)  cat 03-wordpress-pvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wordpress-pv-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

View status after deployment

  lab06 git:(master)  kubectl apply -f 03-wordpress-pvc.yaml
persistentvolumeclaim/wordpress-pv-claim created
  lab06 git:(master)  kubectl get pvc
NAME                       STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
wordpress-mysql-pv-claim   Pending                                                     4s

Find out that PVC is in Pending state, trace down the reasons

  lab06 git:(master)  kubectl describe pvc/wordpress-mysql-pv-claim
Name:          wordpress-mysql-pv-claim
Namespace:     default
StorageClass:  
Status:        Pending
Volume:        
Labels:        <none>
Annotations:   kubectl.kubernetes.io/last-applied-configuration:
                 {"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"name":"wordpress-mysql-pv-claim","namespace":"default"},"s...
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      
Access Modes:  
VolumeMode:    Filesystem
Events:
  Type       Reason         Age               From                         Message
  ----       ------         ----              ----                         -------
  Normal     FailedBinding  6s (x4 over 36s)  persistentvolume-controller  no persistent volumes available for this claim and no storage class is set
Mounted By:  <none>

Next we create PV

PV Definition

View Definitions

  lab06 git:(master)  cat 04-wordpress-pv.yaml 
kind: PersistentVolume
apiVersion: v1
metadata:
  name: wordpress-mysql-pv-volume
  labels:
    type: local
spec:
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/data/pv/wordpress/mysql"

The pv definition is based on hostPath, so we need to create a directory on the node in advance, as follows:

  lab06 git:(master)  mkdir -p /data/pv/wordpress/mysql

  lab06 git:(master)  kubectl create -f 04-wordpress-pv.yaml 
persistentvolume/wordpress-mysql-pv-volume created
  lab06 git:(master)  kubectl get pv
NAME                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                              STORAGECLASS   REASON   AGE
wordpress-mysql-pv-volume   2Gi        RWO            Retain           Bound    default/wordpress-mysql-pv-claim                           31s
  lab06 git:(master)  kubectl get pvc
NAME                       STATUS   VOLUME                      CAPACITY   ACCESS MODES   STORAGECLASS   AGE
wordpress-mysql-pv-claim   Bound    wordpress-mysql-pv-volume   2Gi        RWO                           118s

At this point, the pvc we defined earlier has been successfully bound

Make Deployment use the PVC

View Definitions

  lab06 git:(master)  cat 01-wordpress-mysql-deployment.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: wordpress
  name: wordpress
spec:
  replicas: 1 
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress 
    spec:
      containers:
      - image: wordpress:latest
        imagePullPolicy: IfNotPresent
        name: wordpress
        env:
          - name: WORDPRESS_DB_HOST
            value: "127.0.0.1"
          - name: WORDPRESS_DB_USER
            value: "root"
          - name: WORDPRESS_DB_PASSWORD
            value: "passw0rd"
      - image: mysql:5.7.26
        imagePullPolicy: IfNotPresent
        name: mysql
        env:
          - name: MYSQL_ROOT_PASSWORD 
            value: "passw0rd"
          - name: MYSQL_DATABASE
            value: "wordpress"
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: wordpress-mysql-pv-claim 

Perform updates and view effects

  lab06 git:(master)  kubectl apply -f 01-wordpress-mysql-deployment.yaml 
deployment.extensions/wordpress configured
  lab06 git:(master)  kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
wordpress-6cfd879fcd-9mlhb   2/2     Running   0          29s

  lab06 git:(master)  ls -l /data/pv/wordpress/mysql/
total 188480
-rw-r----- 1 999 999       56 Jun 10 23:42 auto.cnf
-rw------- 1 999 999     1675 Jun 10 23:42 ca-key.pem
-rw-r--r-- 1 999 999     1107 Jun 10 23:42 ca.pem
...
drwxr-x--- 2 999 999    12288 Jun 10 23:42 sys
drwxr-x--- 2 999 999     4096 Jun 10 23:42 wordpress

It is obvious that Pod has already generated data under / data/pv/wordpress/mysql/. Next, let's try to delete Pod after configuration data, so that Deployment controls Pod reconstruction and whether configuration data can be saved.
Remove Pod and rebuild it by following commands

  lab06 git:(master)  kubectl get pod  
NAME                         READY   STATUS    RESTARTS   AGE
wordpress-6cfd879fcd-9mlhb   2/2     Running   0          7m34s
  lab06 git:(master)  kubectl delete pod/wordpress-6cfd879fcd-9mlhb
pod "wordpress-6cfd879fcd-9mlhb" deleted
  lab06 git:(master)  kubectl get pod                              
NAME                         READY   STATUS    RESTARTS   AGE
wordpress-6cfd879fcd-29qg9   2/2     Running   1          11s

Refresh the web page, the test file is still published, the test is successful

New issues

Check the official website notes:

This means that the stateful Deployment of this single instance should not be expanded, and that rolling updates should not be used when the Deployment definition is updated. Instead, it should be deleted and recreated, namely strategy: type: Recreate.
The revised documents are as follows:

  lab06 git:(master)  cat 01-wordpress-mysql-deployment.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: wordpress
  name: wordpress
spec:
  strategy:
    type: Recreate
  replicas: 1 
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress 
    spec:
      containers:
      - image: wordpress:latest
        imagePullPolicy: IfNotPresent
        name: wordpress
        env:
          - name: WORDPRESS_DB_HOST
            value: "127.0.0.1"
          - name: WORDPRESS_DB_USER
            value: "root"
          - name: WORDPRESS_DB_PASSWORD
            value: "passw0rd"
      - image: mysql:5.7.26
        imagePullPolicy: IfNotPresent
        name: mysql
        env:
          - name: MYSQL_ROOT_PASSWORD 
            value: "passw0rd"
          - name: MYSQL_DATABASE
            value: "wordpress"
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: wordpress-mysql-pv-claim

Clear data

  lab06 git:(master)  kubectl delete -f .
deployment.extensions "wordpress" deleted
service "wordpress-svc" deleted
persistentvolumeclaim "wordpress-mysql-pv-claim" deleted
persistentvolume "wordpress-mysql-pv-volume" deleted

Keywords: Java MySQL git Kubernetes github

Added by joviyach on Thu, 20 Jun 2019 23:57:25 +0300