Kubernetes Service's "Stateful Service Running Single Instance"

Posted by stringman on Sat, 15 Jun 2019 05:50:34 +0200

target

Create a PV in your environment
Create a Deployment for MySQl
Exposing MySQL to other pod s in the cluster by DNS name

Before the beginning

You need a Kubernetes cluster, a kubectl command-line tool that can connect to the cluster. If you don't have a cluster, you can use Minikube To create.
We will create a PV (Persistent Volume) for data storage. click here To see the types supported by PV, the guide will use GCEPersistentDisk to demonstrate, but in fact any PV type can work properly. GCE PersistentDisk works only on Google Compute Engine (GCE).

Create disks in your environment

In Google Compute Engine, run:

gcloud compute disks create --size=20GB mysql-disk

Then create a PV pointing to the mysql-disk you just created. Here is a configuration file for creating PV, pointing to the GCE disk mentioned above:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
spec:
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  gcePersistentDisk:
    pdName: mysql-disk
    fsType: ext4

Note that the line pdName: mysql-disk matches the name of the disk created by the GCE environment above. If you want to create PV s in other environments, you can view them Persistent Volumes To get detailed information.
Create PV:

kubectl create -f https://k8s.io/docs/tasks/run-application/gce-volume.yaml

Deployment of MySQL

You can create a stateful service through Kubernetes Deployment, and then use PVC (Persistent Volume Claim) to connect existing PVs. For example, the following YAML file describes a Deployment that runs MySQL and uses PVC. The file defines a mount to / var/lib/mysql volume and creates a 20G volume size PVC.
Note: The password is defined in the YAML configuration file, which is insecure. See Kubernetes Secrets Get a safer solution.

apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  ports:
    - port: 3306
  selector:
    app: mysql
  clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: mysql
spec:
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        env:
          # Use secret in real usage
        - name: MYSQL_ROOT_PASSWORD
          value: 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

1. Deploy the contents of the YAML file.

kubectl create -f https://k8s.io/docs/tasks/run-application/mysql-deployment.yaml

2. Display Deployment information.

kubectl describe deployment mysql

 Name:                 mysql
 Namespace:            default
 CreationTimestamp:    Tue, 01 Nov 2016 11:18:45 -0700
 Labels:               app=mysql
 Selector:             app=mysql
 Replicas:             1 updated | 1 total | 0 available | 1 unavailable
 StrategyType:         Recreate
 MinReadySeconds:      0
 OldReplicaSets:       <none>
 NewReplicaSet:        mysql-63082529 (1/1 replicas created)
 Events:
   FirstSeen    LastSeen    Count    From                SubobjectPath    Type        Reason            Message
   ---------    --------    -----    ----                -------------    --------    ------            -------
   33s          33s         1        {deployment-controller }             Normal      ScalingReplicaSet Scaled up replica set mysql-63082529 to 1

3. Display the pod created by Deployment.

kubectl get pods -l app=mysql

 NAME                   READY     STATUS    RESTARTS   AGE
 mysql-63082529-2z3ki   1/1       Running   0          3m

4. Check PV.

 kubectl describe pv mysql-pv

 Name:            mysql-pv
 Labels:          <none>
 Status:          Bound
 Claim:           default/mysql-pv-claim
 Reclaim Policy:  Retain
 Access Modes:    RWO
 Capacity:        20Gi
 Message:    
 Source:
     Type:        GCEPersistentDisk (a Persistent Disk resource in Google Compute Engine)
     PDName:      mysql-disk
     FSType:      ext4
     Partition:   0
     ReadOnly:    false
 No events.

5. Check PVC.

 kubectl describe pvc mysql-pv-claim

 Name:         mysql-pv-claim
 Namespace:    default
 Status:       Bound
 Volume:       mysql-pv
 Labels:       <none>
 Capacity:     20Gi
 Access Modes: RWO
 No events.

Visit MySQL instances

The previous YAML file creates a service that allows other Pods in the cluster to access the database. The service option cluster IP: None causes the DNS name of the service to be resolved directly to the IP address of Pod. When your service has only one Pod and you don't want to increase the number of Pods, this is the best way to use it.
Run a Mysql client to connect to the Mysql service:

kubectl run -it --rm --image=mysql:5.6 mysql-client -- mysql -h <pod-ip> -ppassword

The above command creates a new Pod in the cluster, which runs a MySQL client and connects to the Mysql Server of the above service. If it connects successfully, it means that the stateful MySQL database has been successfully started and run.

Waiting for pod default/mysql-client-274442439-zyp6i to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.

mysql> 

To update

Updating Deployment's image or other parts can also be done using the kubectl application command as usual. Here are some things to note when using stateful applications:

  • Do not expand the application. This application is only for single application. The following PV can only be mapped to one Pod. For stateful applications in clusters, see StatefulSet document.
  • Use strategy: type: Recreate in Deployment's YAML configuration document. It tells Kubernetes not to use rolling update. Because Rolling update doesn't work, there won't be multiple Pods running at the same time. The policy Recreate deletes the previous pod when a new Pod is created using the update configuration.

    Delete Deployment

    Delete Deployment objects by name:

    kubectl delete deployment,svc mysql
    kubectl delete pvc mysql-pv-claim
    kubectl delete pv mysql-pv

    In addition, if you are using GCE disk, you need to delete the corresponding disk:

    gcloud compute disks delete mysql-disk

Topics: MySQL Kubernetes Google DNS