podman-kube-play(1)
π podman-kube-play(1) π
okay so bestie, welcome to podman-kube-play(1) from the General Commands Manual section β this is the one that takes your Kubernetes YAML and makes real containers, pods and volumes out of it β¨
π NAME π
podman-kube-play β create containers, pods and volumes based on Kubernetes YAML π«Ά
π SYNOPSIS π
podman kube play [options] file.yml|-|https://website.io/file.yml
π¦ DESCRIPTION π¦
So podman kube play reads in a structured file of Kubernetes YAML and recreates the containers, pods, or volumes that are described in it. Containers inside a pod get started, and then you get back the ID of the new Pod or the name of the new Volume π
If the YAML file is passed as -, then podman kube play reads that YAML straight from stdin. And the input can also be a URL pointing at a YAML file β think something like https://podman.io/demo.yml β and Podman will read the YAML from that URL and create pods and containers from it. no cap πΈ
With the --down command line option, it's also able to tear down the pods created by a previous run of podman kube play. bye bestie π
With the --replace command line option, it tears down the pods (if any) created by a previous run of podman kube play and recreates the pods using the Kubernetes YAML file. glow-up era π
Ideally your input file is created by the Podman command itself (see podman-kube-generate(1)) β that guarantees a smooth import and the expected results. iykyk β¨
Currently, the supported Kubernetes kinds are:
PodDeploymentPersistentVolumeClaimConfigMapSecretDaemonSetJob
π Kubernetes Pods or Deployments π
Only five volume types are supported by kube play: the hostPath, emptyDir, configMap, persistentVolumeClaim, and image volume types.
- When you use the
hostPathvolume type, only the default (empty),DirectoryOrCreate,Directory,FileOrCreate,File,Socket,CharDeviceandBlockDevicesubtypes are supported. Podman interprets the value ofhostPathpathas a file path when it contains at least one forward slash β otherwise Podman treats that value as the name of a named volume ποΈ - When you use a
persistentVolumeClaim, the value forclaimNameis the name for the Podman named volume. - When you use an
emptyDirvolume, Podman creates an anonymous volume that is attached to the containers running inside the pod, and it's deleted once the pod is removed. - When you use a
configMapvolume, Podman creates an anonymous volume that is attached to the containers running inside the pod, and it's deleted once the pod is removed. - When you use an
imagevolume, Podman creates a read-only image volume with an empty subpath (the whole image is mounted). The image must already exist locally. It's supported in rootful mode only π
Note: the default restart policy for containers isalways. You can change that default by setting therestartPolicyfield in the spec.
Note: when playing a kube YAML with init containers, the init container is created with init type valueonce. To change that default type, use theio.podman.annotations.init.container.typeannotation to set the type toalways.
Note:hostPathvolume types created by kube play get an SELinux shared label (z), and bind mounts are not relabeled (usechcon -t container_file_t -R <directory>). π
Note: to set the userns of a pod, use theio.podman.annotations.usernsannotation in the pod/deployment definition. For example,io.podman.annotations.userns=keep-idtells Podman to create a user namespace where the current rootless user'sUID:GIDare mapped to the same values in the container. This can be overridden with the--usernsflag.
Note: use theio.podman.annotations.volumes-fromannotation to bind mount volumes of one container to another. You can mount volumes from multiple source containers to a target container. The source containers that belong to the same pod must be defined before the source container in the kube YAML. The annotation format isio.podman.annotations.volumes-from/targetContainer: "sourceContainer1:mountOpts1;sourceContainer2:mountOpts2".
Note: if the:latesttag is used, Podman attempts to pull the image from a registry. If the image was built locally with Podman or Buildah, it haslocalhostas the domain β in that case, Podman uses the image from the local store even if it has the:latesttag π―
Note: the commandpodman play kubeis an alias ofpodman kube play, and performs the same function.
Note: the commandpodman kube downcan be used to stop and remove pods or containers based on the same Kubernetes YAML thatpodman kube playused to create them.
Note: to customize the name of the infra container created duringpodman kube play, use theio.podman.annotations.infra.nameannotation in the pod definition. This annotation is automatically set when generating a kube yaml from a pod that was created with the--infra-nameflag set.
Note: use the io.podman.annotations.pids-limit/$ctrname annotation to configure the pod's pids limit.
Note: use theio.podman.annotations.cpuset/$ctrnameannotation to restrict a container's execution to a specific set of CPU cores. This is equivalent to the--cpuset-cpus=numberoption inpodman-run(1).
Note: use theio.podman.annotations.memory-nodes/$ctrnameannotation to restrict a container's memory allocations to a specific set of memory nodes on NUMA systems. This is equivalent to the--cpuset-mems=nodesoption inpodman-run(1).
π Kubernetes PersistentVolumeClaims π
A Kubernetes PersistentVolumeClaim represents a Podman named volume. Only the PersistentVolumeClaim name is required by Podman to create a volume. Kubernetes annotations can be used to make use of the available options for Podman volumes π
volume.podman.io/drivervolume.podman.io/devicevolume.podman.io/typevolume.podman.io/uidvolume.podman.io/gidvolume.podman.io/mount-optionsvolume.podman.io/import-sourcevolume.podman.io/image
Use volume.podman.io/import-source to import the contents of the tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz, .tar.zst) specified in the annotation's value into the created Podman volume π¦
Kube play is capable of building images on the fly given the correct directory layout and Containerfiles. This option is not available for remote clients, including Mac and Windows (excluding WSL2) machines, yet. Consider the following excerpt from a YAML file:
apiVersion: v1
kind: Pod
metadata:
...
spec:
containers:
- name: container
image: foobar
...
If there's a directory named foobar in the current working directory with a file named Containerfile or Dockerfile inside it, Podman kube play builds that image and names it foobar. An example directory structure for this example looks like:
|- mykubefiles
|- myplayfile.yaml
|- foobar
|- Containerfile
The build considers foobar to be the context directory for the build. If there's an image in local storage called foobar, the image is not built unless the --build flag is used. Use --build=false to completely disable builds π
ββοΈ
Kube play supports CDI (Container Device Interface) device selectors to share host devices (e.g. GPUs) with containers. The configuration format follows Kubernetes extended resource management:
apiVersion: v1
kind: Pod
spec:
containers:
- name: container
resources:
limits:
nvidia.com/gpu=all: 1
To enable sharing host devices β analogous to using the --device flag β Podman kube supports a custom CDI selector: podman.io/device=<host device path> π₯
π§ Kubernetes ConfigMap π§
A Kubernetes ConfigMap can be referred to as a source of environment variables or volumes in Pods or Deployments. ConfigMaps aren't a standalone object in Podman; instead, when a container uses a ConfigMap, Podman creates the environment variables or volumes as needed β¨
For example, the following YAML document defines a ConfigMap and then uses it in a Pod:
apiVersion: v1
kind: ConfigMap
metadata:
name: foo
data:
FOO: bar
---
apiVersion: v1
kind: Pod
metadata:
name: foobar
spec:
containers:
- name: container-1
image: foobar
envFrom:
- configMapRef:
name: foo
optional: false
and as a result the environment variable FOO is set to bar for container container-1 π
πΈ Kubernetes Secret πΈ
A Kubernetes Secret represents a Podman named secret. The Kubernetes Secret is saved as a whole and may be referred to as a source of environment variables or volumes in Pods or Deployments π
For example, the following YAML document defines a Secret and then uses it in a Pod:
kind: Secret
apiVersion: v1
metadata:
name: foo
data:
foo: YmFy # base64 for bar
---
apiVersion: v1
kind: Pod
metadata:
name: foobar
spec:
containers:
- name: container-1
image: foobar
env:
- name: FOO
valueFrom:
secretKeyRef:
name: foo
key: foo
and as a result the environment variable FOO is set to bar for container container-1 π
π Automounting Volumes (deprecated) π
Note: the automounting annotation is deprecated. Kubernetes has native support for image volumes, and that should be used rather than this podman-specific annotation. periodt.
An image can be automatically mounted into a container if the annotation io.podman.annotations.kube.image.automount/$ctrname is given. The following rules apply:
- The image must already exist locally.
- The image must have at least
1volume directive. - The path given by the volume directive is mounted from the image into the container. For example, an image with a volume at
/test/test_dirhas/test/test_dirin the image mounted to/test/test_dirin the container. - Multiple images can be specified. If multiple images have a volume at a specific path, the last image specified trumps π
- The images are always mounted read-only.
- Images to mount are defined in the annotation
"io.podman.annotations.kube.image.automount/$ctrname"as a semicolon-separated list. They're mounted into a single container in the pod, not the whole pod. The annotation can be specified for additional containers if additional mounts are required.
β¨ OPTIONS β¨
π --annotation=key=value π
--annotation=key=valueβ add an annotation to the container or pod. This option can be set multiple times π
Note: forpodman kube play, the--annotationflag adds Podman-specific annotations to the containers and pods created by Podman β not to the Kubernetes YAML itself. These annotations can be used to configure Podman-specific features like user namespaces (io.podman.annotations.userns), volumes-from (io.podman.annotations.volumes-from), and other container behaviors π
--authfile=pathβ where your auth file lives, bestie π. Default is${XDG_RUNTIME_DIR}/containers/auth.jsonon Linux, and$HOME/.config/containers/auth.jsonon Windows/macOS. That file? Made bypodman login. And if the authorization state isn't chillin' there, it checks$HOME/.docker/config.json, which is set usingdocker login.
Note: you can also override the default path of the authentication file by setting the REGISTRY_AUTH_FILE environment variable β just do export REGISTRY_AUTH_FILE=path.
--buildβ builds images even if they're already found in local storage, no cap β¨. Use--build=falseto completely disable builds. (heads up: this option is not available with the remote Podman client)
Note: you can also override the default isolation type by setting the BUILDAH_ISOLATION environment variable, like export BUILDAH_ISOLATION=oci. See podman-build.1.md for more info. π
--cert-dir=pathβ use certificates at path (*.crt,*.cert,*.key) to connect to the registry. (Default:/etc/containers/certs.d) For details, seecontainers-certs.d(5). (this one's not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines π)--configmap=pathβ use the Kubernetes ConfigMap YAML at path to provide environment variable values within the containers of the pod π¦. (not available with the remote Podman client)
Note: the --configmap option can be used multiple times, or a comma-separated list of paths can be used to pass multiple Kubernetes ConfigMap YAMLs. The YAML file may be in a multi-doc YAML format β but it must contain only ConfigMaps, okay? π
--context-dir=pathβ use path as the build context directory for each image. Requires the--buildoption to be true. (not available with the remote Podman client)--creds=[username[:password]]β the[username[:password]]to use to authenticate with the registry, if it's required π₯. If one or both values aren't supplied, a command line prompt shows up and you can type the value in. The password is entered without echo (very discreet, we love that π ).
Note that the specified credentials are only used to authenticate against target registries. They are not used for mirrors or when the registry gets rewritten (see containers-registries.conf(5)); to authenticate against those, consider using a containers-auth.json(5) file. iykyk πΈ
--forceβ tear down the volumes linked to the PersistentVolumeClaims as part of--down. Fr fr, it's the cleanup crew π§Ή--help,-hβ print usage statement. Classic, iconic, always there for you π«Ά--ip=IP addressβ assign a static ip address to the pod. This option can be specified several times when kube play creates more than one pod. Note: when joining multiple networks, use the--network name:ip=<ip>syntax π--log-driver=driverβ set logging driver for all created containers. Simple as that β¨--log-opt=name=valueβ logging driver specific options. Set custom logging configuration π. The following *name*s are supported:path: specify a path to the log file (e.g.--log-opt path=/var/log/container/mycontainer.json);max-size: specify a max size of the log file (e.g.--log-opt max-size=10mb);tag: specify a custom log tag for the container (e.g.--log-opt tag="{{.ImageName}}"). It supports the same keys aspodman inspect --format. This option is currently supported only by thejournaldlog driver.label: specify a custom log label for the container (e.g.--log-opt label="CONTAINER_IMAGE={{.ImageName}}"). It supports the same keys aspodman inspect --format. This option can be repeated multiple times. This option is currently supported only by thejournaldlog driver.
--mac-address=MAC addressβ assign a static mac address to the pod. This option can be specified several times when kube play creates more than one pod. Note: when joining multiple networks, use the--network name:mac=<mac>syntax π--network=mode,--netβ set the network mode for the pod π. Valid mode values are:bridge[:OPTIONS,...]: create a network stack on the default bridge. This is the default for rootful containers. It is possible to specify these additional options:alias=name: add network-scoped alias for the container.ip=IPv4: specify a static IPv4 address for this container.ip6=IPv6: specify a static IPv6 address for this container.mac=MAC: specify a static MAC address for this container.interface_name=name: specify a name for the created network interface inside the container.host_interface_name=name: specify a name for the created network interface outside the container.
Any other options will be passed through to netavark without validation. This can be useful to pass arguments to netavark plugins.
For rootless bridge networks, port forwarding uses rootlessport by default. Setting rootless_port_forwarder="pasta" in the [network] section of containers.conf(5) switches to pasta's kernel-level forwarding (via pesto), which preserves the original client source IP address inside the container. This option is experimental and its behavior is subject to change π.
For example, to set a static IPv4 address and a static mac address, use --network bridge:ip=10.88.0.10,mac=44:33:22:11:00:99.
<network name or ID>[:OPTIONS,...]: connect to a user-defined network β this is the network name or ID from a network created bypodman network create. It is possible to specify the same options described under the bridge mode above. Use the--networkoption multiple times to specify additional networks. For backwards compatibility it is also possible to specify comma-separated networks on the first--networkargument, however this prevents you from using the options described under the bridge section above π¦.none: create a network namespace for the container but do not configure network interfaces for it, thus the container has no network connectivity. Ghost mode, literally π»container:id: reuse another container's network stack.host: use the host's network namespace for the container instead of creating an isolated namespace.
Warning: this gives the container full access to abstract Unix domain sockets and to TCP/UDP sockets bound to localhost. Since these mechanisms are often used to prevent access to sensitive system services, isolating them from access by external entities, use of this option may be considered a security vulnerability. π Not the vibe, be careful!
ns:path: path to a network namespace to join.private: create a new namespace for the container. This uses the bridge mode for rootful containers and pasta for rootless ones.pasta[:OPTIONS,...]: usepasta(1)to create a user-mode networking stack. This is the default for rootless containers and only supported in rootless mode. By default, IPv4 and IPv6 addresses and routes, as well as the pod interface name, are copied from the host. Port forwarding preserves the original source IP address. Options described inpasta(1)can be specified as comma-separated arguments.
In terms of pasta(1) options, --config-net is given by default, in order to configure networking when the container is started, and --no-map-gw is also assumed by default, to avoid direct access from container to host using the gateway address. The latter can be overridden by passing --map-gw in the pasta-specific options (despite not being an actual pasta(1) option) π
.
For better integration with DNS handling, --dns-forward 169.254.1.1 is passed by default, and this address is added to resolv.conf(5) as first resolver. It is possible to pass --dns-forward explicitly in case a different IP address should be used.
To make the host.containers.internal /etc/hosts entry work and allow connections to the host, --map-guest-addr 169.254.1.2 is passed by default. Again, it can be set explicitly to choose a different IP address β¨.
Also, -t none and -u none are passed if, respectively, no TCP or UDP port forwarding from host to container is configured (via Podman's --publish or by passing the pasta -t/-u options directly), to disable automatic port forwarding based on bound ports. Similarly, -T none and -U none are given to disable the same functionality from container to host.
All options can also be set in containers.conf(5); see the pasta_options key under the network section in that file.
Some examples π
pasta:--map-gw: allow the container to directly reach the host using the gateway address.pasta:--mtu,1500: specify a 1500 bytes MTU for the tap interface in the container.pasta:--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,--dns-forward,10.0.2.3,-m,1500,--no-ndp,--no-dhcpv6,--no-dhcp: disable IPv6, assign10.0.2.0/24to the tap0 interface in the container, with gateway10.0.2.3, enable DNS forwarder reachable at10.0.2.3, set MTU to 1500 bytes, disable NDP, DHCPv6 and DHCP support.pasta:-I,tap0,--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,--dns-forward,10.0.2.3,--no-ndp,--no-dhcpv6,--no-dhcp: same as above, but leave the MTU to 65520 bytes.pasta:-t,auto,-u,auto,-T,auto,-U,auto: enable automatic port forwarding based on observed bound ports from both host and container sides.pasta:-T,5201: enable forwarding of TCP port 5201 from container to host, using the loopback interface instead of the tap interface for improved performance.
When no network option is specified and host network mode is not configured in the YAML file, a new network stack is created and pods are attached to it making possible pod to pod communication π«Ά.
--no-hostnameβ do not create the/etc/hostnamefile in the containers.
By default, Podman manages the /etc/hostname file, adding the container's own hostname. When the --no-hostname option is set, the image's /etc/hostname will be preserved unmodified if it exists πΈ
--no-hostsβ do not modify the/etc/hostsfile in the pod.
Podman assumes control over the pod's /etc/hosts file by default and adds entries for the container's name (see --name option) and hostname (see --hostname option), the internal host.containers.internal and host.docker.internal hosts, as well as any hostname added using the --add-host option. Refer to the --add-host option for details. Passing --no-hosts disables this, so that the image's /etc/hosts file is kept unmodified. The same can be achieved globally by setting no_hosts=true in containers.conf.
This option conflicts with host added in the Kubernetes YAML. π
--no-pod-prefixβ do not prefix container name with pod name. Let them have their own identity, main character energy π--publish=[[ip:][hostPort]:]containerPort[/protocol]β define or override a port definition in the YAML file π₯
Okay so the port lists in your YAML file and on the command line literally get merged together π
. Matchmaking is done using the containerPort field β and if containerPort shows up in both the YAML file and the option, the option wins, periodt.
--publish-allβ set this totrueand every single port gets exposed to the host, even the ones that were only chillin' ascontainerPortin the K8 YAML. As for which port actually gets exposed? Priority order bestie:--publish>hostPort>containerPort. π If it'sfalse(and that's the default), only ports defined viahostPortor--publishget published on the host. No sneaky extras.--quiet,-qβ shhh π€« suppress the output info while pulling images. Silent mode, very demure.--replaceβ tears down the pods created by a previous run ofkube playand recreates them. Use this when you wanna keep your existing pods up to date based on the Kubernetes YAML. Glow-up for your pods β¨.- *
--seccomp-profile-root=path* β the directory path for seccomp profiles (default:"/var/lib/kubelet/seccomp"). π Heads up: this option is NOT available with the remote Podman client, including Mac and Windows (excluding WSL2) machines. --startβ start the pod after creating it. Set it tofalseif you just wanna create it and let it sit there looking cute. π--tls-verifyβ require HTTPS and verify certificates when contacting registries (default:true).- explicitly set to
trueβ TLS verification is used β - set to
falseβ TLS verification is not used π - not specified at all β TLS verification is used unless the target registry is listed as an insecure registry in
containers-registries.conf(5).
- explicitly set to
π --userns=mode
Sets the user namespace mode for the container. This one's a whole journey, bestie, stay with me π«Ά.
If --userns isn't set, the default value is determined like this:
- If
--podis set,--usernsis ignored and the user namespace of the pod is used. - If the environment variable
PODMAN_USERNSis set, its value is used. - If
usernsis specified incontainers.conf, that value is used. - Otherwise,
--userns=hostis assumed.
--userns="" (i.e., an empty string) is an alias for --userns=host, iykyk.
β οΈ This option is incompatible with--gidmap,--uidmap,--subuidnameand--subgidname. They can't sit with us π.
Rootless user --userns=Key mappings β the receipts:
autoβ host user$UID, container usernil(host user UID is not mapped into container.)hostβ host user$UID, container user0(default user account mapped to root user in container.)keep-idβ host user$UID, container user$UID(map the user account to the same UID within the container.)keep-id:uid=200,gid=210β host user$UID, container user200:210(map the user account to the specified UID, GID value within the container.)nomapβ host user$UID, container usernil(host user UID is not mapped into container.)
Valid mode values are:
auto[:OPTIONS,...] β automatically create a unique user namespace π.
- rootful mode: the
--userns=autoflag requires that the user namecontainersbe specified in the/etc/subuidand/etc/subgidfiles, with an unused range of subordinate user IDs that Podman containers are allowed to allocate. Example:containers:2147483647:2147483648. - rootless mode: the users range from the
/etc/subuidand/etc/subgidfiles will be used. Note that running a single container without using--userns=autowill use the entire range of UIDs and not allow further subdividing. Seesubuid(5).
Podman allocates unique ranges of UIDs and GIDs from the containers subordinate user IDs. The size of the ranges is based on the number of UIDs required in the image πΌοΈ. The number of UIDs and GIDs can be overridden with the size option.
The option --userns=keep-id uses all the subuids and subgids of the user. The option --userns=nomap uses all the subuids and subgids of the user except the user's own ID. Using --userns=auto when starting new containers does not work as long as any containers exist that were started with --userns=nomap or --userns=keep-id without limiting the user namespace size. π Yeah. That one's a vibe check that fails.
Valid auto options:
gidmapping=CONTAINER_GID:HOST_GID:SIZEβ to force a GID mapping to be present in the user namespace.size=SIZEβ to specify an explicit size for the automatic user namespace. e.g.--userns=auto:size=8192. Ifsizeis not specified,autoestimates a size for the user namespace.uidmapping=CONTAINER_UID:HOST_UID:SIZEβ to force a UID mapping to be present in the user namespace.
The host UID and GID in gidmapping and uidmapping can optionally be prefixed with the @ symbol. In that case, podman will look up the intermediate ID corresponding to host ID and it will map the found intermediate ID to the container id. For details see --uidmap π.
*container:id* β join the user namespace of the specified container. Slay, shared vibes only.
host or "" (empty string) β run in the user namespace of the caller. The processes running in the container have the same privileges on the host as any other process launched by the calling user. π
keep-id β creates a user namespace where the current user's UID:GID are mapped to the same values in the container. For containers created by root, the current mapping is created into a new user namespace.
In addition, the init process within the container will run under the current user's UID. This behavior overrides the image's USER instruction unless you explicitly set --user.
Valid keep-id options:
uid=UIDβ override the UID inside the container that is used to map the current user to.gid=GIDβ override the GID inside the container that is used to map the current user to.size=SIZEβ override the size of the configured user namespace. It's useful to not saturate all the available IDs. Not supported when running as root.
nomap β creates a user namespace where the current rootless user's UID:GID are not mapped into the container. π This option is not allowed for containers created by the root user.
ns:namespace β run the pod in the given existing user namespace.
--wait,-wβ run pods and containers in the foreground. Default isfalse.
At any time you can run podman pod ps in another shell to view a list of the running pods and containers. π
When attached in the tty mode, you can kill the pods and containers by pressing Ctrl+C or by receiving any other interrupt signals.
All pods, containers, and volumes created with podman kube play are removed upon exit. π Gone. Poof. So keep that in mind before you rage-quit.
πΈ EXAMPLES πΈ
Recreate the pod and containers described in the specified host YAML file:
$ podman kube play demo.yml
52182811df2b1e73f36476003a66ec872101ea59034ac0d4d3a7b40903b955a6
Recreate the pod and containers specified in a YAML file sent to stdin:
$ cat demo.yml | podman kube play -
52182811df2b1e73f36476003a66ec872101ea59034ac0d4d3a7b40903b955a6
Tear down the pod and containers as described in the specified YAML file:
$ podman kube play --down demo.yml
Pods stopped:
52182811df2b1e73f36476003a66ec872101ea59034ac0d4d3a7b40903b955a6
Pods removed:
52182811df2b1e73f36476003a66ec872101ea59034ac0d4d3a7b40903b955a6
Provide multiple configmap files as sources for environment variables within the specified pods and containers π:
$ podman kube play demo.yml --configmap configmap-foo.yml,configmap-bar.yml
52182811df2b1e73f36476003a66ec872101ea59034ac0d4d3a7b40903b955a6
$ podman kube play demo.yml --configmap configmap-foo.yml --configmap configmap-bar.yml
52182811df2b1e73f36476003a66ec872101ea59034ac0d4d3a7b40903b955a6
Create a pod connected to two networks with a static ip on each π₯:
$ podman kube play demo.yml --network net1:ip=10.89.1.5 --network net2:ip=10.89.10.10
52182811df2b1e73f36476003a66ec872101ea59034ac0d4d3a7b40903b955a6
Please take into account that networks must be created first using podman-network-create(1). No network, no vibes.
Create and teardown from a URL pointing to a YAML file:
$ podman kube play https://podman.io/demo.yml
52182811df2b1e73f36476003a66ec872101ea59034ac0d4d3a7b40903b955a6
$ podman kube play --down https://podman.io/demo.yml
Pods stopped:
52182811df2b1e73f36476003a66ec872101ea59034ac0d4d3a7b40903b955a6
Pods removed:
52182811df2b1e73f36476003a66ec872101ea59034ac0d4d3a7b40903b955a6
β οΈ podman kube play --down does not work with a URL if the YAML file the URL points to has been changed or altered. Iconic but rude. π
π Podman Kube Play Support π
This document outlines the kube yaml fields that are currently supported by the podman kube play command π«Ά.
π Note: N/A means that the option cannot be supported in a single-node Podman environment.
πΈ Pod Fields πΈ
okay bestie, this is the part where we do a vibe check on every single pod field you might drop into your YAML π β some of them Podman is obsessed with (that's the β
), some it just... doesn't do (that's no π), and some are straight-up N/A because they're scheduling things that genuinely do not apply here, no cap. Here's the whole list, nothing skipped, in the exact order the original gives it π
containersβ β slay, fully supportedinitContainersβ β yes bestieimagePullSecretsβ noenableServiceLinksβ noos.nameβ novolumesβ β supportednodeSelectorβ N/AnodeNameβ N/Aaffinity.nodeAffinityβ N/Aaffinity.podAffinityβ N/Aaffinity.podAntiAffinityβ N/Atolerations.keyβ N/Atolerations.operatorβ N/Atolerations.effectβ N/Atolerations.tolerationSecondsβ N/AschedulerNameβ N/AruntimeClassNameβ nopriorityClassNameβ nopriorityβ notopologySpreadConstraints.maxSkewβ N/AtopologySpreadConstraints.topologyKeyβ N/AtopologySpreadConstraints.whenUnsatisfiableβ N/AtopologySpreadConstraints.labelSelectorβ N/AtopologySpreadConstraints.minDomainsβ N/ArestartPolicyβ β yes queenterminationGracePeriodSecondsβ β supportedactiveDeadlineSecondsβ noreadinessGates.conditionTypeβ nohostnameβ β supportedsetHostnameAsFQDNβ nosubdomainβ nohostAliases.hostnamesβ β supportedhostAliases.ipβ β supporteddnsConfig.nameserversβ β supporteddnsConfig.options.nameβ β supporteddnsConfig.options.valueβ β supporteddnsConfig.searchesβ β supporteddnsPolicyβ nohostNetworkβ β supportedhostPIDβ β supportedhostIPCβ β supportedshareProcessNamespaceβ β supported
π«Ά quick legend so nobody's confused: β = Podman's got you,no= nope, not supported,N/A= doesn't apply here at all. That's literally it, fr fr π
β¦and we're right back into it, bestie π
here's the rest of the field list β β
means yes it's supported, plain no means nope, not supported:
serviceAccountNameβ no π not supportedautomountServiceAccountTokenβ no π not supportedsecurityContext.runAsUserβ β supported, slaysecurityContext.runAsNonRootβ no π not supportedsecurityContext.runAsGroupβ β supported, iconicsecurityContext.supplementalGroupsβ β supportedsecurityContext.fsGroupβ no π not supportedsecurityContext.fsGroupChangePolicyβ no π not supportedsecurityContext.seccompProfile.typeβ no π not supportedsecurityContext.seccompProfile.localhostProfileβ no π not supportedsecurityContext.seLinuxOptions.levelβ β supportedsecurityContext.seLinuxOptions.roleβ β supportedsecurityContext.seLinuxOptions.typeβ β supportedsecurityContext.seLinuxOptions.userβ β supportedsecurityContext.sysctls.nameβ β supportedsecurityContext.sysctls.valueβ β supportedsecurityContext.windowsOptions.gmsaCredentialSpecβ no π not supportedsecurityContext.windowsOptions.hostProcessβ no π not supportedsecurityContext.windowsOptions.runAsUserNameβ no π not supported
like, the pattern is pretty clear at this point, right? the SELinux + sysctl + basic runAs bits ate, and the Windows optionsβ¦ did not π
π§ Container Fields β aka "what can I actually put in a container spec, bestie?" π
okay so this is the part everyone DMs me about. every field you might want to cram into a container in your Pod YAML, and whether podman kube play is gonna vibe with it or leave you on read. β
means slay, it works. no means... not so much π.
Quick legend, iykyk: the β
is support, no is "nope, not implemented, don't come for me."
β¨ The basics β¨
nameβ β yes bestie, your container gets a nameimageβ β the whole point honestlyimagePullPolicyβ β respected, we love a pull strategycommandβ β override that entrypointargsβ β and the args tooworkingDirβ β where the container starts chillin'
π ports.* β let the internet in π
ports.containerPortβ βports.hostIPβ βports.hostPortβ βports.nameβ βports.protocolβ β
all five port fields, fully supported, no crumbs π
π env.* β environment variables, the whole buffet π
env.nameβ βenv.valueβ βenv.valueFrom.configMapKeyRef.keyβ βenv.valueFrom.configMapKeyRef.nameβ βenv.valueFrom.configMapKeyRef.optionalβ βenv.valueFrom.fieldRefβ βenv.valueFrom.resourceFieldRefβ βenv.valueFrom.secretKeyRef.keyβ βenv.valueFrom.secretKeyRef.nameβ βenv.valueFrom.secretKeyRef.optionalβ β
configmaps, secrets, field refs, resource field refs β all of it, iconic behavior π
π§ envFrom.* β bulk env, with one tiny catch π
envFrom.configMapRef.nameβ βenvFrom.configMapRef.optionalβ βenvFrom.prefixβ no πenvFrom.secretRef.nameβ βenvFrom.secretRef.optionalβ β
bestie, envFrom.prefix is not supported. so no cute little prefix on your bulk vars, adjust your plans accordingly π
π¦ volumeMounts.* β where the files live π
volumeMounts.mountPathβ βvolumeMounts.nameβ βvolumeMounts.mountPropagationβ novolumeMounts.readOnlyβ βvolumeMounts.subPathβ βvolumeMounts.subPathExprβ no
so mountPropagation and subPathExpr are both a no β literally not supported, don't fight it π
π volumeDevices.* β bestie... no πΈ
volumeDevices.devicePathβ novolumeDevices.nameβ no
raw block devices? not today, not supported, we move π
π₯ resources.* β limits and requests, both ate π₯
resources.limitsβ βresources.requestsβ β
π lifecycle.* β a mixed bag, ngl
lifecycle.postStartβ nolifecycle.preStopβ nolifecycle.stopSignalβ β
so the lifecycle hooks are a no-no, but stopSignal is supported and honestly that's the one that matters most of the time π«Ά
π terminationMessage* β nope, both of them
terminationMessagePathβ noterminationMessagePolicyβ no
β livenessProbe β yes queen π
livenessProbeβ β
she's alive, she's supported, she's checking on you π
β¦and finishing off the container fields, bestie π
readinessProbeβ no π not supportedstartupProbeβ no π not supportedsecurityContext.runAsUserβ β yup, supportedsecurityContext.runAsNonRootβ no π not supportedsecurityContext.runAsGroupβ β supportedsecurityContext.readOnlyRootFilesystemβ β supportedsecurityContext.procMountβ β supportedsecurityContext.privilegedβ β supportedsecurityContext.allowPrivilegeEscalationβ β supportedsecurityContext.capabilities.addβ β supportedsecurityContext.capabilities.dropβ β supportedsecurityContext.seccompProfile.typeβ no π not supportedsecurityContext.seccompProfile.localhostProfileβ no π not supportedsecurityContext.seLinuxOptions.levelβ β supportedsecurityContext.seLinuxOptions.roleβ β supportedsecurityContext.seLinuxOptions.typeβ β supportedsecurityContext.seLinuxOptions.userβ β supportedsecurityContext.windowsOptions.gmsaCredentialSpecβ no π not supportedsecurityContext.windowsOptions.hostProcessβ no π not supportedsecurityContext.windowsOptions.runAsUserNameβ no π not supportedstdinβ no π not supportedstdinOnceβ no π not supportedttyβ no π not supported
That's the whole container list, done and dusted β¨ (and yeah, tty being a no is a little tragic, we know π)
ποΈ PersistentVolumeClaim Fields
Now the storage girlies πΎ β here's what a PersistentVolumeClaim can and can't do:
volumeNameβ no π not supportedstorageClassNameβ β supportedvolumeModeβ no π not supportedaccessModesβ β supportedselectorβ no π not supportedresources.limitsβ no π not supportedresources.requestsβ β supported
So like β requests? iconic, supported. limits? not invited to the party π. Don't @ me, that's just what the table says.
π ConfigMap Fields
And the ConfigMap girlies, last but never least π:
binaryDataβ β supporteddataβ β supportedimmutableβ no π not supported
data and binaryData? both eating, no crumbs π. immutable? bestie that's a no from us.
π Deployment Fields
okay so a Deployment is like... a whole squad, right? here's what actually gets picked up when you hand it to podman kube play:
replicasβ β yes bestie, it's supported... BUT β¨plot twistβ¨ the actual replica count is ignored and set to1. so don't come for me when you asked for 12 and got 1, that's just the vibe π«Άselectorβ βtemplateβ βminReadySecondsβ no πstrategy.typeβ nostrategy.rollingUpdate.maxSurgeβ nostrategy.rollingUpdate.maxUnavailableβ norevisionHistoryLimitβ noprogressDeadlineSecondsβ nopausedβ no
like half the deployment spec is just... not invited to the party π but the important bits (selector, template) showed up and ate π₯
π DaemonSet Fields
DaemonSet sounds intense and honestly? iconic name. here's the support list:
selectorβ βtemplateβ βminReadySecondsβ nostrategy.typeβ nostrategy.rollingUpdate.maxSurgeβ nostrategy.rollingUpdate.maxUnavailableβ norevisionHistoryLimitβ no
same story as Deployment: the core two (selector + template) said yes, everything else left you on read π
π Job Fields
Job fields, aka the "one and done" energy of k8s. peep this:
activeDeadlineSecondsβ noselectorβ no (it's automatically set by k8s, so like... not your business, the cluster handles it π)templateβ βbackoffLimitβ nocompletionModeβ nocompletionsβ no (set to1withkube generate)manualSelectorβ noparallelismβ no (set to1withkube generate)podFailurePolicyβ nosuspendβ nottlSecondsAfterFinishedβ no
not me noticing that template is literally the only β
here π everything else is a hard no, with completions and parallelism both getting quietly set to 1 by kube generate. lowkey a solo mission fr fr.
π SEE ALSO π
go read these next, bestie, they're the whole friend group:
podman(1)podman-kube(1)podman-kube-down(1)podman-network-create(1)podman-kube-generate(1)podman-build(1)containers-certs.d(5)
and that's the whole page!! π you made it to the end, I'm so proud of you π₯Ήπ
that was podman-kube-play(1) from the Podman manual, version-and-date era as shipped with the docs β¨ go forth and play your kubes, you absolute main character πΈπ¦π
π¦ where this page comes from
- arch rolling: podman-docker 6.1.4-1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms