feat: add section on volumes
This commit is contained in:
parent
925bc4a4a7
commit
0902fd0bb0
|
@ -0,0 +1,11 @@
|
|||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: mysql-pv-volume
|
||||
spec:
|
||||
capacity:
|
||||
storage: 1Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
hostPath:
|
||||
path: "/mnt/data"
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: mysql-pv-claim
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
|
@ -0,0 +1,31 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mysql
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mysql
|
||||
spec:
|
||||
containers:
|
||||
- image: mysql:5.6
|
||||
name: mysql
|
||||
env:
|
||||
- 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
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
ports:
|
||||
- port: 3306
|
||||
selector:
|
||||
app: mysql
|
||||
clusterIP: None
|
|
@ -0,0 +1,144 @@
|
|||
# Running a stateful application: `volumes`
|
||||
|
||||
## Introduction
|
||||
|
||||
In this section you will learn how to deploy a stateful application, mysql in this example.
|
||||
|
||||
As you know a `pod` is mortal, meaning it can be destroyed by k8s anytime, and with it it's local data, memory, etc. So it's perfect for stateless applications. Of course, in the real world we need a way to store our data, and we need this data to be persistent in time.
|
||||
|
||||
So how can we deploy a stateful application with a persistent storage in k8s? Let's deploy a mysql.
|
||||
|
||||
## Volumes
|
||||
|
||||
We need to review what a volume is before continuing with the deployment of our mysql. As stated above, the disk of a pod is destroyed with it, so it's lost. For a database it'll nice if we could keep the data between restarts of the pods. Here comes the `volume`.
|
||||
|
||||
We can see a `pod` as something that requests CPU & RAM. We can see a `volume` as something that requests a storage on disk. K8s handles a lot of different kind of volumes - 26 has this file hands on is written - from local disk storage to s3.
|
||||
|
||||
Here we will use `persistentVolumeClaim`, it's an abstraction over the hard drives of the k8s nodes - a fancy name for local hard drive.
|
||||
|
||||
Let's create the volume where our mysql data will be stored.
|
||||
|
||||
First we create the `PersistentVolume`. Ir is a piece of storage in the cluster that has been provisioned by a cluster administrator. It is a resource in the cluster just like a node is a cluster resource.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: mysql-pv-volume
|
||||
spec:
|
||||
capacity:
|
||||
storage: 1Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
hostPath:
|
||||
path: "/mnt/data"
|
||||
```
|
||||
|
||||
Let's review some parameters:
|
||||
|
||||
* `capacity`: the capacity of the volume
|
||||
* `storage`: the volume size - here `1Gb`
|
||||
* `accessModes`: how this volume will be accessed, here `ReadWriteOnce`
|
||||
* `ReadWriteOnce`: the volume can be mounted as read-write by a single node
|
||||
* `ReadOnlyMany`: the volume can be mounted read-only by many nodes
|
||||
* `ReadWriteMany`: the volume can be mounted as read-write by many nodes
|
||||
* `hostPath`: where the storage will be stored on the host, here `/mnt/data/`
|
||||
|
||||
Apply it:
|
||||
|
||||
```bash
|
||||
kubectl apply -f 10-volumes/01-simple-mysql-pv.yml
|
||||
```
|
||||
|
||||
Now that we have a storage, we need to claim it, make it available for our pods. So we need a `PersistentVolumeClaim`. It is a request for storage by a user. It is similar to a pod. Pods consume node resources and `PersistentVolumeClaim` consume `PersistentVolume` resources.
|
||||
|
||||
```yml
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: mysql-pv-claim
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
```
|
||||
|
||||
The manifest is pretty similar to the `PersistentVolume`:
|
||||
|
||||
```bash
|
||||
kubectl apply -f 10-volumes/02-simple-mysql-pvc.yml
|
||||
```
|
||||
|
||||
## Stateful application
|
||||
|
||||
Now let's create the `deployment` of mysql:
|
||||
|
||||
```bash
|
||||
kubectl apply -f 10-volumes/03-simple-mysql-deployment.yml
|
||||
```
|
||||
|
||||
There is a bunch of parameters we haven't seen yet:
|
||||
|
||||
* `strategy`: the strategy of updates of the pods
|
||||
* `type`: `Recreate`. This instructs Kubernetes to not use rolling updates. Rolling updates will not work, as you cannot have more than one Pod running at a time.
|
||||
* `env`: the list of environment variables to pass to the container
|
||||
* `name`: the name of the env variable
|
||||
* `value`: the value of the env variable
|
||||
* `volumeMounts`: the volumes, think directories, to give access to the container
|
||||
* `name`: the name of the volume to mount
|
||||
* `mountPath`: where in the container to mount the volume
|
||||
* `volumes`: the volumes to request access to
|
||||
* `name`: the name of the volume, same as `volumeMounts.name`
|
||||
* `persistentVolumeClaim`: the `PersistentVolumeClaim` we want
|
||||
* `claimName`: the name of the claim
|
||||
|
||||
Let's finish by creating a `service` to have stable DNS entry inside our cluster.
|
||||
|
||||
```bash
|
||||
kubectl apply -f 10-volumes/04-simple-mysql-service.yml
|
||||
```
|
||||
|
||||
Finally let's access the mysql
|
||||
|
||||
```bash
|
||||
kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -ppassword
|
||||
|
||||
If you don't see a command prompt, try pressing enter.
|
||||
|
||||
mysql> show databases;
|
||||
+--------------------+
|
||||
| Database |
|
||||
+--------------------+
|
||||
| information_schema |
|
||||
| mysql |
|
||||
| performance_schema |
|
||||
+--------------------+
|
||||
3 rows in set (0.02 sec)
|
||||
```
|
||||
|
||||
Create a new database in mysql:
|
||||
|
||||
```bash
|
||||
mysql> CREATE DATABASE testing;
|
||||
Query OK, 1 row affected (0.01 sec)
|
||||
```
|
||||
|
||||
Now delete the service and the deployment:
|
||||
|
||||
```bash
|
||||
kubectl delete service,deployment --all
|
||||
```
|
||||
|
||||
Recreate them, reconnect to mysql and see if you still have the database `testing` you created.
|
||||
|
||||
## Exercices
|
||||
|
||||
Nothing to see here.
|
||||
|
||||
## Clean up
|
||||
|
||||
```bash
|
||||
kubectl delete service,deployment,pvc,pv,pod --all
|
||||
```
|
Loading…
Reference in New Issue