podman-kube-play - Create containers, pods and volumes based on Kubernetes YAML
podman kube play [options] file.yml|-|https://website.io/file.yml
podman kube play reads in a structured file of
Kubernetes YAML. It recreates the containers, pods, or volumes described
in the YAML. Containers within a pod are then started, and the ID of the
new Pod or the name of the new Volume is output. If the YAML file is
specified as "-", then podman kube play
reads the YAML file
from stdin. The input can also be a URL that points to a YAML file such
as https://podman.io/demo.yml. podman kube play
reads the
YAML from the URL and create pods and containers from it.
Using the --down
command line option, it is also capable
of tearing down the pods created by a previous run of
podman kube play
.
Using the --replace
command line option, it tears down
the pods(if any) created by a previous run of
podman kube play
and recreate the pods with the Kubernetes
YAML file.
Ideally the input file is created by the Podman command (see podman-kube-generate(1)). This guarantees a smooth import and expected results.
Currently, the supported Kubernetes kinds are:
Kubernetes Pods or Deployments
Only four volume types are supported by kube play, the hostPath, emptyDir, persistentVolumeClaim, and image volume types.
Note: The default restart policy for containers is
always
. You can change the default by setting the
restartPolicy
field in the spec.
Note: When playing a kube YAML with init containers, the init
container is created with init type value once
. To change
the default type, use the
io.podman.annotations.init.container.type
annotation to set
the type to always
.
Note: hostPath volume types created by kube play is given an
SELinux shared label (z), bind mounts are not relabeled (use
chcon -t container_file_t -R <directory>
).
Note: To set userns of a pod, use the
io.podman.annotations.userns annotation in the
pod/deployment definition. For example,
io.podman.annotations.userns=keep-id annotation tells
Podman to create a user namespace where the current rootless user's
UID:GID are mapped to the same values in the container. This can be
overridden with the --userns
flag.
Note: Use the io.podman.annotations.volumes-from
annotation 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 is
io.podman.annotations.volumes-from/targetContainer: "sourceContainer1:mountOpts1;sourceContainer2:mountOpts2"
.
Note: If the :latest
tag is used, Podman attempts to
pull the image from a registry. If the image was built locally with
Podman or Buildah, it has localhost
as the domain, in that
case, Podman uses the image from the local store even if it has the
:latest
tag.
Note: The command podman play kube
is an alias of
podman kube play
, and performs the same function.
Note: The command podman kube down
can be used to stop
and remove pods or containers based on the same Kubernetes YAML used by
podman kube play
to create them.
Note: To customize the name of the infra container created during
podman kube play
, use the
io.podman.annotations.infra.name annotation in the pod
definition. This annotation is automatically set when generating a kube
yaml from a pod that was created with the --infra-name
flag
set.
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.
Use volume.podman.io/import-source
to import the
contents of the tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz)
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 is a directory named foobar
in the current
working directory with a file named Containerfile
or
Dockerfile
, Podman kube play builds that image and name 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 is 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.
Kubernetes ConfigMap
Kubernetes ConfigMap can be referred 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 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 environment variable FOO
is set to
bar
for container container-1
.
Kubernetes Secret
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 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.
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:
/test/test_dir
will have /test/test_dir
in the
image mounted to /test/test_dir
in the container.Add an annotation to the container or pod. This option can be set multiple times.
Path of the authentication file. Default is
${XDG_RUNTIME_DIR}/containers/auth.json
on Linux, and
$HOME/.config/containers/auth.json
on Windows/macOS. The
file is created by podman
login. If the authorization state is not found there,
$HOME/.docker/config.json
is checked, which is set using
docker login.
Note: There is also the option to override the default path of the
authentication file by setting the REGISTRY_AUTH_FILE
environment variable. This can be done with export
REGISTRY_AUTH_FILE=path.
Build images even if they are found in the local storage. Use
--build=false
to completely disable builds. (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. export BUILDAH_ISOLATION=oci. See podman-build.1.md for more information.
Use certificates at path (*.crt, *.cert, *.key) to connect to the registry. (Default: /etc/containers/certs.d) For details, see containers-certs.d(5). (This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines)
Use Kubernetes configmap YAML at path to provide a source for environment variable values within the containers of the pod. (This option is 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 container only configmaps
Use path as the build context directory for each image. Requires --build option be true. (This option is not available with the remote Podman client)
The [username[:password]] to use to authenticate with the registry, if required. If one or both values are not supplied, a command line prompt appears and the value can be entered. The password is entered without echo.
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.
Tear down the volumes linked to the PersistentVolumeClaims as part of --down
Print usage statement
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.
Set logging driver for all created containers.
Logging driver specific options.
Set custom logging configuration. The following names 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 as podman inspect --format. This option is currently supported only by the journald log driver.
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.
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:
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 by
podman network
create. It is possible to specify the same options
described under the bridge mode above. Use the
--network option multiple times to specify additional
networks.
For backwards compatibility it is also possible to specify
comma-separated networks on the first --network
argument, 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.
container:_id_: Reuse another container's network stack.
host: Do not create a network namespace, the container uses the host's network. Note: The host mode gives the container full access to local system services such as D-bus and is therefore considered insecure.
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 slirp4netns for rootless ones.
slirp4netns[:OPTIONS,...]: use
slirp4netns(1) to create a user network stack. It is
possible to specify these additional options, they can also be set with
network_cmd_options
in containers.conf:
65520
).10.0.2.0/24
).outbound_addr6
).10.0.2.100
. If the application requires the real source IP
address, e.g. web server logs, use the slirp4netns port handler. The
rootlesskit port handler is also used for rootless containers when
connected to user-defined networks.pasta[:OPTIONS,...]: use
pasta(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. If port forwarding isn't
configured, ports are forwarded dynamically as services are bound on
either side (init namespace or container namespace). Port forwarding
preserves the original source IP address. Options described in pasta(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).
Also, -t none and -u none are passed
if, respectively, no TCP or UDP port forwarding from host to container
is configured, 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.
Some examples:
10.0.2.0/24
to the tap0
interface in the
container, with gateway 10.0.2.3
, enable DNS forwarder
reachable at 10.0.2.3
, set MTU to 1500 bytes, disable NDP,
DHCPv6 and DHCP support.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.
Do not create /etc/hosts for the pod. By default, Podman manages /etc/hosts, adding the container's own IP address and any hosts from --add-host. --no-hosts disables this, and the image's /etc/hosts is preserved unmodified.
This option conflicts with host added in the Kubernetes YAML.
Define or override a port definition in the YAML file.
The lists of ports in the YAML file and the command line are merged. Matching is done by using the containerPort field. If containerPort exists in both the YAML file and the option, the latter takes precedence.
Setting this option to true
will expose all ports to the
host, even if only specified via containerPort in the
K8 YAML. In terms of which port will be exposed,
--publish has higher priority than
hostPort, has higher priority than
containerPort.
If set to false
(which is the default), only ports
defined via hostPort or --publish are
published on the host.
Suppress output information when pulling images
Tears down the pods created by a previous run of
kube play
and recreates the pods. This option is used to
keep the existing pods up to date based upon the Kubernetes YAML.
Directory path for seccomp profiles (default: "/var/lib/kubelet/seccomp"). (This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines)
Start the pod after creating it, set to false to only create it.
Require HTTPS and verify certificates when contacting registries (default: true). If explicitly set to true, TLS verification is used. If set to false, TLS verification is not used. If not specified, TLS verification is used unless the target registry is listed as an insecure registry in containers-registries.conf(5)
Set the user namespace mode for the container.
If --userns
is not set, the default value is determined
as follows. - If --pod
is set, --userns
is
ignored and the user namespace of the pod is used. - If the environment
variable PODMAN_USERNS is set its value is used. - If
userns
is specified in containers.conf
this
value is used. - Otherwise, --userns=host
is assumed.
--userns=""
(i.e., an empty string) is an alias for
--userns=host
.
This option is incompatible with --gidmap, --uidmap, --subuidname and --subgidname.
Rootless user --userns=Key mappings:
Key | Host User | Container User |
---|---|---|
auto | $UID | nil (Host User UID is not mapped into container.) |
host | $UID | 0 (Default User account mapped to root user in container.) |
keep-id | $UID | $UID (Map user account to same UID within container.) |
keep-id:uid=200,gid=210 | $UID | 200:210 (Map user account to specified UID, GID value within container.) |
nomap | $UID | nil (Host User UID is not mapped into container.) |
Valid mode values are:
auto[:OPTIONS,...]: automatically create a unique user namespace.
rootful mode
: The --userns=auto
flag
requires that the user name containers be specified in
the /etc/subuid and /etc/subgid files, 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/subuid
and /etc/subgid files will be used. Note running a single container
without using --userns=auto will use the entire range of UIDs and not
allow further subdividing. See subuid(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=keep-id
or --userns=nomap
.
Valid auto
options:
--userns=auto:size=8192
. If
size
is not specified, auto
estimates a size
for the user namespace.The host UID and GID in gidmapping and uidmapping
can optionally be prefixed with the @
symbol. In this 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.
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.
Valid keep-id
options:
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.
Run pods and containers in the foreground. Default is false.
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 receiving any other interrupt signals.
All pods, containers, and volumes created with
podman kube play
is removed upon exit.
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).
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.
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.
Field | Support |
---|---|
containers | ✅ |
initContainers | ✅ |
imagePullSecrets | no |
enableServiceLinks | no |
os.name | no |
volumes | ✅ |
nodeSelector | N/A |
nodeName | N/A |
affinity.nodeAffinity | N/A |
affinity.podAffinity | N/A |
affinity.podAntiAffinity | N/A |
tolerations.key | N/A |
tolerations.operator | N/A |
tolerations.effect | N/A |
tolerations.tolerationSeconds | N/A |
schedulerName | N/A |
runtimeClassName | no |
priorityClassName | no |
priority | no |
topologySpreadConstraints.maxSkew | N/A |
topologySpreadConstraints.topologyKey | N/A |
topologySpreadConstraints.whenUnsatisfiable | N/A |
topologySpreadConstraints.labelSelector | N/A |
topologySpreadConstraints.minDomains | N/A |
restartPolicy | ✅ |
terminationGracePeriodSeconds | ✅ |
activeDeadlineSeconds | no |
readinessGates.conditionType | no |
hostname | ✅ |
setHostnameAsFQDN | no |
subdomain | no |
hostAliases.hostnames | ✅ |
hostAliases.ip | ✅ |
dnsConfig.nameservers | ✅ |
dnsConfig.options.name | ✅ |
dnsConfig.options.value | ✅ |
dnsConfig.searches | ✅ |
dnsPolicy | no |
hostNetwork | ✅ |
hostPID | ✅ |
hostIPC | ✅ |
shareProcessNamespace | ✅ |
serviceAccountName | no |
automountServiceAccountToken | no |
securityContext.runAsUser | ✅ |
securityContext.runAsNonRoot | no |
securityContext.runAsGroup | ✅ |
securityContext.supplementalGroups | ✅ |
securityContext.fsGroup | no |
securityContext.fsGroupChangePolicy | no |
securityContext.seccompProfile.type | no |
securityContext.seccompProfile.localhostProfile | no |
securityContext.seLinuxOptions.level | ✅ |
securityContext.seLinuxOptions.role | ✅ |
securityContext.seLinuxOptions.type | ✅ |
securityContext.seLinuxOptions.user | ✅ |
securityContext.sysctls.name | ✅ |
securityContext.sysctls.value | ✅ |
securityContext.windowsOptions.gmsaCredentialSpec | no |
securityContext.windowsOptions.hostProcess | no |
securityContext.windowsOptions.runAsUserName | no |
Field | Support |
---|---|
name | ✅ |
image | ✅ |
imagePullPolicy | ✅ |
command | ✅ |
args | ✅ |
workingDir | ✅ |
ports.containerPort | ✅ |
ports.hostIP | ✅ |
ports.hostPort | ✅ |
ports.name | ✅ |
ports.protocol | ✅ |
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 | ✅ |
envFrom.configMapRef.name | ✅ |
envFrom.configMapRef.optional | ✅ |
envFrom.prefix | no |
envFrom.secretRef.name | ✅ |
envFrom.secretRef.optional | ✅ |
volumeMounts.mountPath | ✅ |
volumeMounts.name | ✅ |
volumeMounts.mountPropagation | no |
volumeMounts.readOnly | ✅ |
volumeMounts.subPath | ✅ |
volumeMounts.subPathExpr | no |
volumeDevices.devicePath | no |
volumeDevices.name | no |
resources.limits | ✅ |
resources.requests | ✅ |
lifecycle.postStart | no |
lifecycle.preStop | no |
terminationMessagePath | no |
terminationMessagePolicy | no |
livenessProbe | ✅ |
readinessProbe | no |
startupProbe | no |
securityContext.runAsUser | ✅ |
securityContext.runAsNonRoot | no |
securityContext.runAsGroup | ✅ |
securityContext.readOnlyRootFilesystem | ✅ |
securityContext.procMount | ✅ |
securityContext.privileged | ✅ |
securityContext.allowPrivilegeEscalation | ✅ |
securityContext.capabilities.add | ✅ |
securityContext.capabilities.drop | ✅ |
securityContext.seccompProfile.type | no |
securityContext.seccompProfile.localhostProfile | no |
securityContext.seLinuxOptions.level | ✅ |
securityContext.seLinuxOptions.role | ✅ |
securityContext.seLinuxOptions.type | ✅ |
securityContext.seLinuxOptions.user | ✅ |
securityContext.windowsOptions.gmsaCredentialSpec | no |
securityContext.windowsOptions.hostProcess | no |
securityContext.windowsOptions.runAsUserName | no |
stdin | no |
stdinOnce | no |
tty | no |
Field | Support |
---|---|
volumeName | no |
storageClassName | ✅ |
volumeMode | no |
accessModes | ✅ |
selector | no |
resources.limits | no |
resources.requests | ✅ |
Field | Support |
---|---|
binaryData | ✅ |
data | ✅ |
immutable | no |
Field | Support |
---|---|
replicas | ✅ (the actual replica count is ignored and set to 1) |
selector | ✅ |
template | ✅ |
minReadySeconds | no |
strategy.type | no |
strategy.rollingUpdate.maxSurge | no |
strategy.rollingUpdate.maxUnavailable | no |
revisionHistoryLimit | no |
progressDeadlineSeconds | no |
paused | no |
Field | Support |
---|---|
selector | ✅ |
template | ✅ |
minReadySeconds | no |
strategy.type | no |
strategy.rollingUpdate.maxSurge | no |
strategy.rollingUpdate.maxUnavailable | no |
revisionHistoryLimit | no |
Field | Support |
---|---|
activeDeadlineSeconds | no |
selector | no (automatically set by k8s) |
template | ✅ |
backoffLimit | no |
completionMode | no |
completions | no (set to 1 with kube generate) |
manualSelector | no |
parallelism | no (set to 1 with kube generate) |
podFailurePolicy | no |
suspend | no |
ttlSecondsAfterFinished | no |
podman(1), podman-kube(1), podman-kube-down(1), podman-network-create(1), podman-kube-generate(1), podman-build(1), containers-certs.d(5)