% podman-kube.unit 5 # NAME podman\-kube.unit - systemd unit files for managing Podman Kubernetes YAML deployments using Quadlet # SYNOPSIS *name*.kube # DESCRIPTION Kube units are named with a `.kube` extension and contain a `[Kube]` section describing how `podman kube play` runs as a service. The resulting service file contains a line like `ExecStart=podman kube play … file.yml`, and most of the keys in this section control the command-line options passed to Podman. However, some options also affect the details of how systemd is set up to run and interact with the container. There is only one required key, `Yaml`, which defines the path to the Kubernetes YAML file. # USAGE SUMMARY The `.kube` file is parsed by the `podman-system-generator` at boot or reload, generating a systemd `.service` that runs `podman kube play`. That service can be managed like any other unit: ```bash systemctl --user start name.service ``` # OPTIONS Valid options for `[Kube]` are listed below: | **[Kube] options** | **podman kube play equivalent** | | ------------------------------------| -----------------------------------------------------------------| | AutoUpdate=registry | --annotation "io.containers.autoupdate=registry" | | ConfigMap=/tmp/config.map | --configmap /tmp/config.map | | ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf | | ExitCodePropagation=how | How to propagate container error status | | GlobalArgs=--log-level=debug | --log-level=debug | | KubeDownForce=true | --force (for `podman kube down`) | | LogDriver=journald | --log-driver journald | | Network=host | --network host | | PodmanArgs=\-\-annotation=key=value | --annotation=key=value | | PublishPort=8080:80 | --publish 8080:80 | | SetWorkingDirectory=yaml | Set `WorkingDirectory` of unit file to location of the YAML file | | UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 | | Yaml=/tmp/kube.yaml | podman kube play /tmp/kube.yaml | Supported keys in the `[Kube]` section are: ### `AutoUpdate=` Indicates whether pods and containers from this Kubernetes workload are auto-updated ([podman-auto-update(1)](podman-auto-update.1.md)). `AutoUpdate` can be specified multiple times. The following values are supported: * `registry`: Requires a fully-qualified image reference (e.g., quay.io/podman/stable:latest) to be used to create the container. This enforcement is necessary to know which images to actually check and pull. If an image ID was used, Podman does not know which image to check/pull anymore. * `local`: Tells Podman to compare the image a container is using to the image with its raw name in local storage. If an image is updated locally, Podman simply restarts the systemd unit executing the Kubernetes Quadlet. * `name/(local|registry)`: Tells Podman to perform the `local` or `registry` auto-update on the specified container name. [//]: # (BEGIN included file options/configmap.md) ### `ConfigMap=path` Use the Kubernetes ConfigMap YAML as the *path* to provide environment variable values within the containers of the pod. (This option is not available with the remote Podman client) The value may contain only one path but it may be absolute or relative to the location of the unit file. [//]: # (END included file options/configmap.md) [//]: # (BEGIN included file options/module.md) ### `ContainersConfModule=module` Load the specified containers.conf(5) module. This option can be listed multiple times. [//]: # (END included file options/module.md) ### `ExitCodePropagation=how` Control how the main PID of the systemd service should exit. The following values are supported: - `all`: exit non-zero if all containers have failed (i.e., exited non-zero) - `any`: exit non-zero if any container has failed - `none`: exit zero and ignore failed containers The current default value is `none`. [//]: # (BEGIN included file options/global-args.md) ### `GlobalArgs=` This key contains a list of arguments passed directly after the `podman` command in the generated file. It can be used to access Podman features otherwise unsupported by the generator. Since the generator is unaware of what unexpected interactions can be caused by these arguments, it is not recommended to use this option. The format of this is a space separated list of arguments, which can optionally be individually escaped to allow inclusion of whitespace and other control characters. This key can be listed multiple times. [//]: # (END included file options/global-args.md) ### `KubeDownForce=true` Remove all resources, including volumes, when calling `podman kube down`. Equivalent to the Podman `--force` option. [//]: # (BEGIN included file options/log-driver.md) ### `LogDriver=driver` Logging driver for the container. Currently available options are **k8s-file**, **journald**, **none**, **passthrough** and **passthrough-tty**, with **json-file** aliased to **k8s-file** for scripting compatibility. (Default **journald**). The podman info command below displays the default log-driver for the system. ``` $ podman info --format '{{ .Host.LogDriver }}' journald ``` The **passthrough** driver passes down the standard streams (stdin, stdout, stderr) to the container. It is not allowed with the remote Podman client, including Mac and Windows (excluding WSL2) machines, and on a tty, since it is vulnerable to attacks via TIOCSTI. The **passthrough-tty** driver is the same as **passthrough** except that it also allows it to be used on a TTY if the user really wants it. [//]: # (END included file options/log-driver.md) [//]: # (BEGIN included file options/network.md) ### `Network=mode` Set the network mode for the container. Special cases: * If the `name` of the network ends with `.network`, a Podman network called `systemd-$name` is used, and the generated systemd service contains a dependency on the `$name-network.service`. Such a network can be automatically created by using a `$name.network` Quadlet file. Note: the corresponding `.network` file must exist. * If the `name` ends with `.container`, the container will reuse the network stack of another container created by `$name.container`. The generated systemd service contains a dependency on `$name.service`. Note: the corresponding `.container` file must exist. 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)](https://github.com/containers/container-libs/blob/main/common/docs/containers.conf.5.md)** 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`. - _\_**[:OPTIONS,...]**: Connect to a user-defined network; this is the network name or ID from a network created by **[podman network create](podman-network-create.1.md)**. 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**: 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. - **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,...]**: 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. 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). \ 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)](https://github.com/containers/container-libs/blob/main/common/docs/containers.conf.5.md)**; 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, assign `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. - **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 [//]: # (END included file options/network.md) [//]: # (BEGIN included file options/podman-args.md) ### `PodmanArgs=` This key contains a list of arguments passed directly to the end of the `podman` command in the generated file. It can be used to access Podman features otherwise unsupported by the generator. Since the generator is unaware of what unexpected interactions can be caused by these arguments, it is not recommended to use this option. The format of this is a space separated list of arguments, which can optionally be individually escaped to allow inclusion of whitespace and other control characters. This key can be listed multiple times. [//]: # (END included file options/podman-args.md) [//]: # (BEGIN included file options/publish.md) ### `PublishPort=[[ip:][hostPort]:]containerPort[/protocol]` Publish a container's port, or range of ports, to the host. Both *hostPort* and *containerPort* can be specified as a range of ports. When specifying ranges for both, the number of container ports in the range must match the number of host ports in the range. If host IP is set to 0.0.0.0 or not set at all, the port is bound on all IPs on the host. By default, Podman publishes TCP ports. To publish a UDP port instead, give `udp` as protocol. To publish both TCP and UDP ports, set `--publish` twice, with `tcp`, and `udp` as protocols respectively. Rootful containers can also publish ports using the `sctp` protocol. Host port does not have to be specified (e.g. `podman run -p 127.0.0.1::80`). If it is not, the container port is randomly assigned a port on the host. Use **podman port** to see the actual mapping: `podman port $CONTAINER $CONTAINERPORT`. Port publishing is only supported for containers utilizing their own network namespace through `bridge` networks, or the `pasta` network mode. For rootless bridge networks, port forwarding uses `rootlessport` by default, which is a userspace proxy that does not preserve client source IPs. Setting `rootless_port_forwarder="pasta"` in the `[network]` section of **[containers.conf(5)](https://github.com/containers/container-libs/blob/main/common/docs/containers.conf.5.md)** switches to pasta's kernel-level forwarding via `pesto`, preserving the original client IP address inside the container. This option is experimental and its behavior is subject to change. [//]: # (END included file options/publish.md) ### `SetWorkingDirectory=yaml` Set the `WorkingDirectory` directive in the `[Service]` section of the systemd service unit file. Used to allow `podman kube play` to correctly resolve relative paths. Supported values are `yaml` and `unit` to set the working directory to that of the YAML file or Quadlet unit file, respectively. Alternatively, users can explicitly set the `WorkingDirectory` directive in the `[Service]` section of the `.kube` file. Please note that if the `WorkingDirectory` directive in the `[Service]` section is set, Quadlet will not set it even if `SetWorkingDirectory` is set. [//]: # (BEGIN included file options/userns.container.md) ### `UserNS=mode` 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=**, **SubUIDMap=** and **SubGIDMap=**. 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=nomap` or `--userns=keep-id` without limiting the user namespace size. 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`. If `size` is not specified, `auto` estimates 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 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. 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 is 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 container in the given existing user namespace. [//]: # (END included file options/userns.container.md) ### `Yaml=path` The path, absolute or relative to the location of the unit file, to the Kubernetes YAML file to use. # EXAMPLES Deploy from local YAML: ``` [Unit] Description=A kubernetes yaml based service Before=local-fs.target [Kube] Yaml=/opt/k8s/deployment.yml [Install] # Start by default on boot WantedBy=multi-user.target default.target ``` # SEE ALSO [podman-kube-generate(1)](podman-kube-generate.1.md), [podman-kube-play(1)](podman-kube-play.1.md), [podman-systemd.unit(5)](podman-systemd.unit.5.md), [systemd.unit(5)](https://www.freedesktop.org/software/systemd/man/systemd.unit.html)