Pod with Volume

Containers might need access to persistent data (for example configuration files, state files, and log files) at their start or after their termination. This can be accomplished by mounting a volume to the container. Volumes can be of many types, including

Configuration Files

This files are read only. SecretVolumeSource must be used for sensitive information, for example passwords, and are detailed in Pod with Sensitive Information. ConfigMapVolumeSource is the preferable option for non-sensitive information. HostPathVolumeSource is also an option for non-sensitive information but can cause problems due file permissions differences with host.

Tip

HostPathVolumeSource is a great option during development.

Example with HostPathVolumeSource

Warning

Podman is not able to access files in a WSL machine, for example \\wsl.localhost\Ubuntu\home\user\file. This feature was requested in Podman’s GitHub project issue 17986 and 21813.

Attention

This example does NOT work out of the box because the host machines must have the directory to be bind to the container.

Given the following Kubernetes manifest file

play.yml
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-5.3.1

# NOTE: If you generated this yaml from an unprivileged and rootless podman container on an SELinux
# enabled system, check the podman generate kube man page for steps to follow to ensure that your pod/container
# has the right permissions to access the volumes added.
---
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx2
  name: nginx2
spec:
  containers:
  - args:
    - nginx
    - -g
    - daemon off;
    image: docker.io/library/nginx:alpine
    name: nginx2
    ports:
    - containerPort: 80
      hostPort: 8080
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: nginx-html
  volumes:
  - hostPath:
      # This is the path in the host machine running Kubernetes or Podman.
      # When using WSL2, the Windows C disk is mounted into /mnt/c.
      path: /mnt/c/Users/costadre/Downloads/html
      type: Directory
    name: nginx-html

running

podman kube play play.yml

creates a pod named nginx2 with a container named nginx running the image docker.io/library/nginx:alpine and the port 8080 in the host is mapped to the port 80 in the container.

The NGINX server can be tested with

curl http://localhost:8080

that is expected to return

<!DOCTYPE html>
<html>
    <body>
        <h1>Hello!</h1>
    </body>
</html>

Example with ConfigMapVolumeSource

Important

The ConfigMap manifest file is bundle with the Pod manifest file.

Given the following Kubernetes manifest file

play.yml
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-5.3.1

# NOTE: If you generated this yaml from an unprivileged and rootless podman container on an SELinux
# enabled system, check the podman generate kube man page for steps to follow to ensure that your pod/container
# has the right permissions to access the volumes added.
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: html
data:
  index.html: |
    <!DOCTYPE html>
    <html>
        <body>
            <h1>Hello!</h1>
        </body>
    </html>  
---
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx3
  name: nginx3
spec:
  containers:
  - args:
    - nginx
    - -g
    - daemon off;
    image: docker.io/library/nginx:alpine
    name: nginx3
    ports:
    - containerPort: 80
      hostPort: 8080
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: nginx-html
  volumes:
  - configMap:
      # Provide the name of the ConfigMap you want to mount.
      name: html
      # An array of keys from the ConfigMap to create as files
      items:
      - key: "index.html"
        path: "index.html"
    name: nginx-html

running

podman kube play play.yml

creates a pod named nginx3 with a container named nginx running the image docker.io/library/nginx:alpine and the port 8080 in the host is mapped to the port 80 in the container.

The NGINX server can be tested with

curl http://localhost:8080

that is expected to return

<!DOCTYPE html>
<html>
    <body>
        <h1>Hello!</h1>
    </body>
</html>

State Files

This files are, generaly, write by the container. PersistentVolumeClaimVolumeSource is the preferable option here. HostPathVolumeSource is also an option but can cause problems due file permissions differences with host.

Example with HostPathVolumeSource

Warning

Podman is not able to access files in a WSL machine, for example \\wsl.localhost\Ubuntu\home\user\file. This feature was requested in Podman’s GitHub project issue 17986 and 21813.

Attention

This example does NOT work out of the box because the host machines must have the directory to be bind to the container.

Given the following Kubernetes manifest file

play.yml
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-5.3.1
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: postgresql
  name: postgresql
spec:
  containers:
  - args:
    - postgres
    env:
    - name: POSTGRES_DB
      value: gesis
    - name: POSTGRES_PASSWORD
      value: "123"
    - name: POSTGRES_USER
      value: gesis
    image: docker.io/library/postgres:17.4-alpine3.21
    name: db
    volumeMounts:
    - mountPath: /var/lib/postgresql/data
      name: db-data-pvc
  volumes:
  - hostPath:
      # This is the path in the host machine running Kubernetes or Podman.
      # When using WSL2, the Windows C disk is mounted into /mnt/c.
      path: /mnt/c/Users/costadre/Downloads/postgresql
      type: Directory
    name: db-data-pvc

running

podman kube play play.yml

creates a pod named postgresql with a container named db running the image docker.io/library/postgres:17.4-alpine3.21 with a volume mounted.

Example with PersistentVolumeClaimVolumeSource

Given the following Kubernetes manifest file

play.yml
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-5.3.1
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: postgresql
  name: postgresql
spec:
  containers:
  - args:
    - postgres
    env:
    - name: POSTGRES_DB
      value: gesis
    - name: POSTGRES_PASSWORD
      value: "123"
    - name: POSTGRES_USER
      value: gesis
    image: docker.io/library/postgres:17.4-alpine3.21
    name: db
    volumeMounts:
    - mountPath: /var/lib/postgresql/data
      name: db-data-pvc
  volumes:
  - name: db-data-pvc
    persistentVolumeClaim:
      claimName: db-data

running

podman kube play play.yml

creates a pod named postgresql with a container named db running the image docker.io/library/postgres:17.4-alpine3.21 with a volume mounted.