For this example we recommend to use a Minikube installation described here.
In order to play a bit with memory limits, we assume that you use 2GB memory for your Minikube VM (which is also the default).
You can adapt the memory of the Minikube VM with --memory
.
To access the PersistentVolume used in this demo, let’s mount a local directory into the Minikube VM that we later then use a PersistentVolume mounted into the Pod:
minikube start --mount --mount-string="$(pwd)/logs:/example"
This makes this directory available within the Minikube VM at the path /example
.
For this (and many other demos) we are using a simple random number service, which is a simple REST service exposing a random number and can be found also in the image k8spatterns/random-generator:1.0
on Docker Hub
We will set up this image that it will write a log file in a PV and get some configuration data from a ConfigMap.
Now lets try to create the Pod
kubectl create -f https://k8spatterns.io/PredictableDemands/pod.yml
When we verify this with we immediately see, that pod doesn’t start:
kubectl get pods
NAME READY STATUS RESTARTS AGE
random-generator 0/1 Pending 0 3s
The first reason is, that the PVC is missing as you can easily see when describing the pod:
kubectl describe pod random-generator
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 44s (x2 over 44s) default-scheduler persistentvolumeclaim "random-generator-log" not found
Let’s now create the PersistentVolume and PVC:
kubectl create -f https://k8spatterns.io/PredictableDemands/pv-and-pvc.yml
When we create the PV and PVC we are already one step further:
kubectl describe pod random-generator
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 32s (x5 over 7m44s) default-scheduler persistentvolumeclaim "random-generator-log" not found
Warning FailedScheduling 15s (x6 over 15s) default-scheduler pod has unbound immediate PersistentVolumeClaims
Normal Scheduled 15s default-scheduler Successfully assigned default/random-generator to minikube
Normal Pulled 3s (x3 over 14s) kubelet, minikube Container image "k8spatterns/random-generator:1.0" already present on machine
Warning Failed 3s (x3 over 14s) kubelet, minikube Error: configmap "random-generator-config" not found
The PVC could be bound, but not the ConfigMap is missing.
Let’s add this last missing piece:
kubectl create -f https://k8spatterns.io/PredictableDemands/configmap.yml
and the pod will be finally up:
kubectl get pods
NAME READY STATUS RESTARTS AGE
random-generator 1/1 Running 0 3s
We can easily check this by sending an HTTP request. As we haven’t installed a Service, lets poke a hole with a port-forward into the cluster and use curl to check the output:
# Port forward to Pod
kubectl port-forward pod/random-generator 8080:8080 &
# Send a request to our service
curl -s http://localhost:8080 | jq .
{
"random": 79003229,
"pattern": "Predictable Demands",
"id": "d88cc0e5-c7f2-4e98-8073-ed76151b5218",
"version": "1.0"
}
# Check whether the log has been written locally
cat ./logs/random.log
16:52:44.734,fe870020-fcab-42bf-b745-db65ec1cc51f,2137264413
Now that our hard requirements (ConfigMap, PVC) are fulfilled our the application runs smoothly.
If you are done, it’s a good idea to cleanup:
# Killt the 'kubectl port-forward' first
kill %1
# Delete the plain pod
kubectl delete pod/random-generator
# Delete PV & PVC
kubectl delete -f https://k8spatterns.io/PredictableDemands/pv-and-pvc.yml
Let’s create now a real Deployment with resource limits
kubectl create -f https://k8spatterns.io/PredictableDemands/deployment.yml
This will use 200M as upper limit for our application. Since we are using Java 11 as JVM for our Java application, the JVM respects this boundary and allocates only a fraction of this as heap. You can easily check this with
# The 'pod' alias is explained in INSTALL.adoc
kubectl logs $(pod random-generator) | grep "=== "
i.k.examples.RandomGeneratorApplication : === Max Heap Memory: 96 MB
i.k.examples.RandomGeneratorApplication : === Used Heap Memory: 37 MB
i.k.examples.RandomGeneratorApplication : === Free Memory: 13 MB
i.k.examples.RandomGeneratorApplication : === Processors: 1
Let’s now try to change our limits and requests with smaller and larger values.
patch=$(cat <<EOT
[
{
"op": "replace",
"path": "/spec/template/spec/containers/0/resources/requests/memory",
"value": "30Mi"
},
{
"op": "replace",
"path": "/spec/template/spec/containers/0/resources/limits/memory",
"value": "30Mi"
}
]
EOT
)
kubectl patch deploy random-generator --type=json -p $patch
If you check your Pods now with kubectl get pods
and kubectl describe
, do you see what you expect ?
Also don’t forget the check the logs, too !