...
Let's start with the simplest case, namely the static one. For convenience we create a folder in which we will insert only 3 .yaml files: one for the PV, one for the PVC and, finally, one for the application, which will exploit the persistence of the data. After sharing the folder /home/share between the cluster nodes, we copy the following .yaml file
| Code Block | ||||||
|---|---|---|---|---|---|---|
| ||||||
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv
spec:
persistentVolumeReclaimPolicy: Retain
volumeMode: Filesystem
capacity:
storage: 100Mi
accessModes:
- ReadWriteMany
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /home/share
server: <Node_IP> # Enter the IP of the node that shares the folder (usually the Master) |
Next we will use an Nginx image to carry out our tests. We could then create a file in the shared folder, called index.html, containing a simple string like "Hello from Kubernetes Storage!". At this point, let's deploy the PV. Note that the component's status is available for now.
...
| Code Block | ||||||
|---|---|---|---|---|---|---|
| ||||||
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mystate
spec:
serviceName: mysvc
selector:
matchLabels:
app: myapp
replicas: 3
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: mycontainer
image: nginx
imagePullPolicy: "IfNotPresent"
ports:
- containerPort: 80
volumeMounts:
- name: mydata
mountPath: /usr/share/nginx/html
volumes:
- name: mydata
persistentVolumeClaim:
claimName: mypvc # Note the reference to the Claim
---
apiVersion: v1
kind: Service
metadata:
name: mysvc
labels:
app: myapp
spec:
selector:
app: myapp
ports:
- protocol: TCP
name: http
port: 80
targetPort: 80 |
Deploy the application and verify that everything works correctly. To check it, you can run the curl command, followed by the IP of the service or Pod, or go directly to the folder specified in the container's mountPath (in this case /usr/share/nginx/html). So
| Code Block | ||||
|---|---|---|---|---|
| ||||
$ k get all -n myns -o wide
NAME READY STATUS RESTARTS AGE IP NODE
pod/mystate-0 1/1 Running 0 13m 172.16.231.239 mycentos-1.novalocal
pod/mystate-1 1/1 Running 0 13m 172.16.94.103 mycentos-2.novalocal
pod/mystate-2 1/1 Running 0 13m 172.16.141.62 mycentos-ing.novalocal
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/mysvc ClusterIP 10.98.99.55 <none> 80/TCP 13m app=myapp
NAME READY AGE CONTAINERS IMAGES
statefulset.apps/mystate 3/3 13m mycontainer nginx
# We use, for example, the IP of the service and of the pod/mystate-2
$ curl 10.98.99.55
Hello from Kubernetes Storage!
$ curl 172.16.141.62
Hello from Kubernetes Storage!
# Let's enter the pod/mystate-1 and go to the path indicated in the StatefulSet manifest, or run the "curl localhost" command
$ kubectl exec -it pod/mystate-1 -n myns -- bash
root@mystate-1:/usr/share/nginx/html# curl localhost
Hello from Kubernetes Storage!
root@mystate-1:/usr/share/nginx/html# cd /usr/share/nginx/html/; cat index.html
Hello from Kubernetes Storage! |
Finally, try to modify the index.html file from inside the Pod and verify that the changes are acquired from the file on the node (and vice versa).