Skip to main content
In this lesson we’ll persist application logs from a Pod so they survive Pod restarts and deletions. The application writes logs to /log/app.log inside the container. We’ll:
  • Confirm the webapp Pod is running and inspect its logs.
  • Demonstrate two persistence approaches:
    • A direct hostPath volume mounted into the Pod (quick proof-of-concept).
    • A PersistentVolume (PV) backed by a hostPath and a PersistentVolumeClaim (PVC) that the Pod consumes (recommended for controlled lifecycle).

1) Confirm the Pod and view logs

Verify the webapp Pod is Running and read the application log:
Example output (truncated):
Describe the Pod to confirm there are no volumes currently configured for application logs:
Relevant excerpt (showing only the default kube-api-access volume mounted — no log volume yet):
Because the log file lives inside the container filesystem (/log/app.log) and no persistent volume is configured, deleting the Pod will delete the logs.

2) Quick proof-of-concept: mount a hostPath on the Pod

To validate that mounting a host directory preserves logs on the node, edit the Pod to add a hostPath volume and mount it to /log inside the container. Using kubectl edit pod webapp (or export → modify → replace), add a volumeMount and a hostPath volume: Container volumeMounts:
Under spec.volumes add the hostPath:
Save/apply the edit. If kubectl edit is inconvenient, export, modify, and replace the Pod manifest, or delete and recreate the Pod with the new spec. After the Pod is recreated, check the host node to verify logs are being written to the hostPath:
You should see the same application log lines in /var/log/webapp/app.log. This confirms the hostPath mount works, but note:
  • hostPath mounts are node-local and tied to the node’s filesystem.
  • They are not managed with Kubernetes reclaim semantics and are not ideal for multi-Pod sharing or for declarative lifecycle management.
Using hostPath bypasses Kubernetes storage abstractions. It can introduce security and portability issues (node-specific paths, permission mismatches, and potential data coupling to a single node). Use for short-lived demos or troubleshooting; prefer PV/PVC for production.

3) Create a PersistentVolume (PV) backed by a hostPath

To manage the storage lifecycle declaratively, create a PersistentVolume that references a host directory (we’ll use /pv/log for the PV’s hostPath). Example pv.yaml:
Create the PV and verify:
Expected output (example):
Notes:
  • This PV advertises 100Mi and access mode ReadWriteMany (RWX) with reclaim policy Retain.
  • A hostPath-based PV is node-local; although it advertises RWX, the underlying directory is only accessible on the node where it exists. It does not provide true multi-node RWX sharing.

4) Create a PersistentVolumeClaim (PVC) and bind it

Create a PVC that requests storage compatible with the PV: pvc.yaml:
Create and check the PVC and PV binding:
Expected binding output:
If the PVC is Pending, check for:
  • access mode mismatches (PVC requests modes not supported by PV)
  • storage class mismatches
  • insufficient capacity
Make sure accessModes in the PVC are compatible with the PV. A PVC’s requested accessModes must be supported by the PV (the PV must include every mode the PVC requests). For example, a PVC requesting ReadWriteOnce (RWO) will not bind to a PV that only advertises ReadWriteMany (RWX); the PV must include the requested mode.

5) Update the Pod to consume the PVC

Now update the Pod to consume the PVC instead of directly using a hostPath. The container volumeMounts remain the same (still mount to /log): Container volumeMounts:
Replace the volumes entry with the persistentVolumeClaim reference:
Apply the Pod changes (edit, replace or recreate). Example from the demo:
After the Pod is running and using claim-log-1, the application writes logs to /log/app.log inside the Pod and those writes appear on the node at the PV hostPath /pv/log/app.log:
Example log excerpt in /pv/log/app.log:
This confirms the Pod uses the PV via the PVC and logs are persisted on the node at /pv/log.

6) Reclaim policy and deletion behavior

Check the PV reclaim policy and current status:
Example:
With persistentVolumeReclaimPolicy: Retain:
  • Deleting the PVC does not automatically delete underlying data.
  • When the PVC is removed, the PV transitions to Released (binding removed but data preserved).
  • The administrator must manually clean up the data or make the PV available again.
If you try deleting the PVC while it is still referenced by a Pod, PVC deletion can get stuck in Terminating due to the PVC protection finalizer. Example:
Resolve this by first deleting the Pod that references the PVC:
After the Pod is removed, PVC deletion will complete (if previously requested). The PV then moves to Released and must be handled manually if you want to reuse or remove the data.

Quick comparison: hostPath vs PV/PVC


Useful commands reference


Summary

  • The application originally wrote logs to the container filesystem at /log/app.log. Without a volume, logs are lost when the Pod is removed.
  • Mounting a hostPath directly into a Pod demonstrates node-local persistence but lacks Kubernetes-managed lifecycle control and portability.
  • Creating a PersistentVolume (even backed by hostPath) and a matching PersistentVolumeClaim, then mounting that PVC into the Pod, provides persistent storage that survives Pod recreation and offers declarative lifecycle semantics.
  • Ensure PVC accessModes are compatible with the PV. HostPath PVs are node-local even when they advertise RWX.
  • persistentVolumeReclaimPolicy: Retain preserves data after PVC deletion; manual cleanup or reclamation is required.

Watch Video