github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/website/content/plugins/drivers/podman.mdx (about) 1 --- 2 layout: docs 3 page_title: 'Drivers: podman' 4 description: >- 5 The Podman task driver uses podman (https://podman.io/) for containerizing 6 tasks. 7 --- 8 9 # Podman Task Driver 10 11 Name: `podman` 12 13 Homepage: https://github.com/hashicorp/nomad-driver-podman 14 15 The Podman task driver plugin for Nomad uses the [Pod Manager (podman)][podman] 16 daemonless container runtime for executing Nomad tasks. Podman supports OCI 17 containers and its command line tool is meant to be [a drop-in replacement for 18 Docker's][podman-cli]. 19 20 Due to Podman's similarity to Docker, the example job created by 21 [`nomad init -short`][nomad-init] is easily adapted to use Podman instead: 22 23 ```hcl 24 job "redis" { 25 datacenters = ["dc1"] 26 type = "service" 27 28 group "cache" { 29 network { 30 port "redis" { to = 6379 } 31 } 32 33 task "redis" { 34 driver = "podman" 35 36 config { 37 image = "docker://redis" 38 ports = ["redis"] 39 } 40 } 41 } 42 } 43 ``` 44 45 Refer to the project's [homepage][homepage] for details. 46 47 ## Client Requirements 48 49 The Podman task driver is not builtin to Nomad. It must be 50 [downloaded][downloaded] onto the client host in the configured plugin 51 directory. 52 53 - [Nomad][nomad_download] 0.12.9+ 54 - Linux host with [`podman`][podman] installed 55 - For rootless containers you need a system supporting cgroup V2 and a few 56 other things, follow [this tutorial][rootless_tutorial]. 57 58 You need a 3.0.x podman binary and a system socket activation unit, refer to 59 [https://www.redhat.com/sysadmin/podmans-new-rest-api](https://www.redhat.com/sysadmin/podmans-new-rest-api). 60 61 Nomad agent, `nomad-driver-podman` and `podman` will reside on the same client, 62 so you do not have to worry about the `ssh` aspects of the Podman api. 63 64 Ensure that Nomad can find the plugin, refer to [`plugin_dir`][plugin_dir]. 65 66 ## Capabilities 67 68 The `podman` driver implements the following [capabilities](/docs/concepts/plugins/task-drivers#capabilities-capabilities-error). 69 70 | Feature | Implementation | 71 | -------------------- | ----------------------- | 72 | `nomad alloc signal` | true | 73 | `nomad alloc exec` | false | 74 | filesystem isolation | image | 75 | network isolation | host, group, task, none | 76 | volume mounting | none | 77 78 ## Task Configuration 79 80 - `args` - (Optional) A list of arguments to the optional command. If no 81 [`command`] is specified, the arguments are passed directly to the container. 82 83 ```hcl 84 config { 85 args = [ 86 "arg1", 87 "arg2", 88 ] 89 } 90 ``` 91 92 - `auth` - (Optional) Authenticate to the image registry using a static 93 credential. 94 95 ```hcl 96 config { 97 image = "your.registry.tld/some/image" 98 auth { 99 username = "someuser" 100 password = "sup3rs3creT" 101 } 102 } 103 ``` 104 105 - `cap_add` - (Optional) A list of Linux capabilities as strings to pass to 106 `--cap-add`. 107 108 ```hcl 109 config { 110 cap_add = [ 111 "SYS_TIME" 112 ] 113 } 114 ``` 115 116 - `cap_drop` - (Optional) A list of Linux capabilities as strings to pass to 117 `--cap-drop`. 118 119 ```hcl 120 config { 121 cap_drop = [ 122 "MKNOD" 123 ] 124 } 125 ``` 126 127 - `command` - (Optional) The command to run when starting the container. 128 129 ```hcl 130 config { 131 command = "some-command" 132 } 133 ``` 134 135 - `devices` - (Optional) A list of `host-device[:container-device][:permissions]` 136 definitions. Each entry adds a host device to the container. Optional 137 permissions can be used to specify device permissions, it is a combination of 138 `r` for read, `w` for write, and `m` for `mknod(2)`. Refer to Podman's 139 documentation for more details. 140 141 ```hcl 142 config { 143 devices = [ 144 "/dev/net/tun" 145 ] 146 } 147 ``` 148 149 - `entrypoint` - (Optional) The entrypoint for the container. Defaults to the 150 `entrypoint` set in the image. 151 152 ```hcl 153 config { 154 entrypoint = "/entrypoint.sh" 155 } 156 ``` 157 158 - `force_pull` - (Optional) `true` or `false` (default). Always pull the latest 159 image on container start. 160 161 ```hcl 162 config { 163 force_pull = true 164 } 165 ``` 166 167 - `hostname` - (Optional) The hostname to assign to the container. When 168 launching more than one of a task (using [`count`]) with this option set, 169 every container the task starts will have the same hostname. 170 171 - `image` - The image to run. Accepted transports are `docker` (default if 172 missing), `oci-archive` and `docker-archive`. Images referenced as 173 [short-names] will be treated according to user-configured preferences. 174 175 ```hcl 176 config { 177 image = "docker://redis" 178 } 179 ``` 180 181 - `image_pull_timeout` - (Optional) Time duration for your pull timeout 182 (default to `"5m"`). Cannot be longer than the [`client_http_timeout`]. 183 184 ```hcl 185 config { 186 image_pull_timeout = "5m" 187 } 188 ``` 189 190 - `init` - (Optional) Run an `init` inside the container that forwards signals 191 and reaps processes. 192 193 ```hcl 194 config { 195 init = true 196 } 197 ``` 198 199 - `init_path` - (Optional) Path to the `container-init` binary. 200 201 ```hcl 202 config { 203 init = true 204 init_path = "/usr/libexec/podman/catatonit" 205 } 206 ``` 207 208 - `labels` - (Optional) Set labels on the container. 209 210 ```hcl 211 config { 212 labels = { 213 "nomad" = "job" 214 } 215 } 216 ``` 217 218 - `logging` - (Optional) Configure logging. Also refer to the plugin option 219 [`disable_log_collection`]. 220 221 - `driver = "nomad"` - (Default) Podman redirects its combined 222 `stdout/stderr` logstream directly to a Nomad `fifo`. Benefits of this 223 mode are: zero overhead, don't have to worry about log rotation at system 224 or Podman level. Downside: you cannot easily ship the logstream to a log 225 aggregator plus `stdout/stderr` is multiplexed into a single stream. 226 227 ```hcl 228 config { 229 logging = { 230 driver = "nomad" 231 } 232 } 233 ``` 234 235 - `driver = "journald"` - The container log is forwarded from Podman to the 236 `journald` on your host. Next, it's pulled by the Podman API back from the 237 journal into the Nomad `fifo` (controllable by [`disable_log_collection`]). 238 Benefits: all containers can log into the host journal, you can ship a 239 structured stream including metadata to your log aggregator. No log 240 rotation at Podman level. You can add additional tags to the journal. 241 Drawbacks: a bit more overhead, depends on Journal (will not work on WSL2). 242 You should configure some rotation policy for your Journal. Ensure you're 243 running Podman 3.1.0 or higher because of bugs in older versions. 244 245 ```hcl 246 config { 247 logging = { 248 driver = "journald" 249 options = [ 250 { 251 "tag" = "redis" 252 } 253 ] 254 } 255 } 256 ``` 257 258 - `memory_reservation` - (Optional) Memory soft limit (units = `b` (bytes), `k` 259 (kilobytes), `m` (megabytes), or `g` (gigabytes)). 260 261 After setting memory reservation, when the system detects memory contention 262 or low memory, containers are forced to restrict their consumption to their 263 reservation. So you should always set the value below `--memory`, otherwise 264 the hard limit will take precedence. By default, memory reservation will be 265 the same as memory limit. 266 267 ```hcl 268 config { 269 memory_reservation = "100m" 270 } 271 ``` 272 273 - `memory_swap` - (Optional) A limit value equal to memory plus swap. The swap 274 limit should always be larger than the [memory value][memory-value]. Unit can 275 be `b` (bytes), `k` (kilobytes), `m` (megabytes), or `g` (gigabytes). If you 276 don't specify a unit, `b` is used. Set `LIMIT` to `-1` to enable unlimited 277 swap. 278 279 ```hcl 280 config { 281 memory_swap = "180m" 282 } 283 ``` 284 285 - `memory_swappiness` - Tune a container's memory swappiness behavior. Accepts 286 an integer between `0` and `100`. 287 288 ```hcl 289 config { 290 memory_swappiness = 60 291 } 292 ``` 293 294 - `network_mode` - (Optional) Set the [network mode][network-mode] for the 295 container. By default the task uses the network stack defined in the task 296 group [`network`][nomad_group_network] stanza. If the groups network behavior 297 is also undefined, it will fallback to `bridge` in rootful mode or 298 `slirp4netns` for rootless containers. 299 300 - `bridge` - (Default for rootful) Create a network stack on the default 301 Podman bridge. 302 - `container:id` - Reuse another container's network stack. 303 - `host` - Use the Podman host network stack. Note: the host mode gives the 304 container full access to local system services such as D-bus and is therefore 305 considered insecure. 306 - `none` - No networking. 307 - `slirp4netns` - (Default for rootless) Use `slirp4netns` to create a user 308 network stack. Podman currently does not support this option for rootful 309 containers ([issue][slirp-issue]). 310 - `task:name-of-other-task`: Join the network of another task in the same 311 allocation. 312 313 ```hcl 314 config { 315 network_mode = "bridge" 316 } 317 ``` 318 319 - `ports` - (Optional) Forward and expose ports. Refer to 320 [Docker driver configuration][nomad_driver_ports] for details. 321 322 - `privileged` - (Optional) `true` or `false` (default). A privileged container 323 turns off the security features that isolate the container from the host. 324 Dropped Capabilities, limited devices, read-only mount points, 325 Apparmor/SELinux separation, and Seccomp filters are all disabled. 326 327 - `readonly_rootfs` - (Optional) `true` or `false` (default). Mount the rootfs 328 as read-only. 329 330 ```hcl 331 config { 332 readonly_rootfs = true 333 } 334 ``` 335 336 - `sysctl` - (Optional) A key-value map of `sysctl` configurations to set to 337 the containers on start. 338 339 ```hcl 340 config { 341 sysctl = { 342 "net.core.somaxconn" = "16384" 343 } 344 } 345 ``` 346 347 - `tmpfs` - (Optional) A list of `/container_path` strings for `tmpfs` mount 348 points. Refer to `podman run --tmpfs` options for details. 349 350 ```hcl 351 config { 352 tmpfs = [ 353 "/var" 354 ] 355 } 356 ``` 357 358 - `tty` - (Optional) `true` or `false` (default). Allocate a pseudo-TTY for the 359 container. 360 361 - `user` - (Optional) Run the command as a specific user/uid within the 362 container. Refer to [task configuration][task]. 363 364 ```hcl 365 config { 366 user = "nobody" 367 } 368 ``` 369 370 - `volumes` - (Optional) A list of `host_path:container_path:options` strings 371 to bind host paths to container paths. Named volumes are not supported. 372 373 ```hcl 374 config { 375 volumes = [ 376 "/some/host/data:/container/data:ro,noexec" 377 ] 378 } 379 ``` 380 381 - `working_dir` - (Optional) The working directory for the container. Defaults 382 to the default set in the image. 383 384 ```hcl 385 config { 386 working_dir = "/data" 387 } 388 ``` 389 390 - `ulimit` - (Optional) A key-value map of ulimit configurations to set to the 391 containers to start. 392 393 ```hcl 394 config { 395 ulimit { 396 nproc = "4242" 397 nofile = "2048:4096" 398 } 399 } 400 ``` 401 402 ## Network Configuration 403 404 Nomad [lifecycle hooks][nomad_lifecycle_hooks] combined with the drivers 405 [`network_mode`] allows very flexible network namespace definitions. This 406 feature does not build upon the native Podman pod structure but simply reuses 407 the networking namespace of one container for other tasks in the same group. 408 409 A typical example is a network server and a metric exporter or log shipping 410 sidecar. The metric exporter needs access to a private monitoring port which 411 should not be exposed to the network and thus is usually bound to `localhost`. 412 413 The [`nomad-driver-podman` repository][homepage] includes three different 414 examples jobs for such a setup. All of them will start a 415 [nats](https://nats.io/) server and a 416 [prometheus-nats-exporter](https://github.com/nats-io/prometheus-nats-exporter) 417 using different approaches. 418 419 You can use `curl` to prove that the job is working correctly and that you can 420 get Prometheus metrics: 421 422 ```shell-session 423 $ curl http://your-machine:7777/metrics 424 ``` 425 426 ### 2 Task setup, server defines the network 427 428 Reference [`examples/jobs/nats_simple_pod.nomad`]. 429 430 Here, the `server` task is started as main workload and the `exporter` runs as 431 a `poststart` sidecar. Because of that, Nomad guarantees that the server is 432 started first and thus the exporter can easily join the servers network 433 namespace via `network_mode = "task:server"`. 434 435 Note, that the `server` configuration file binds the `http_port` to 436 `localhost`. 437 438 Be aware that ports must be defined in the parent network namespace, here 439 `server`. 440 441 ### 3 Task setup, a pause container defines the network 442 443 Reference [`examples/jobs/nats_pod.nomad`]. 444 445 A slightly different setup is demonstrated in this job. It reassembles more 446 closesly the idea of a `pod` by starting a `pause` task, named `pod` via a 447 [`prestart`] sidecar hook. 448 449 Next, the main workload, `server` is started and joins the network namespace by 450 using the `network_mode = "task:pod"` stanza. Finally, Nomad starts the 451 `poststart` sidecar `exporter` which also joins the network. 452 453 Note that all ports must be defined on the `pod` level. 454 455 ### 2 Task setup, shared Nomad network namespace 456 457 Reference [`examples/jobs/nats_group.nomad`]. 458 459 This example is very different. Both `server` and `exporter` join a network 460 namespace which is created and managed by Nomad itself. Refer to Nomad's 461 [`network`] stanza to get started with this generic approach. 462 463 ## Plugin Options 464 465 The Podman plugin has options which may be customized in the agent's 466 configuration file. 467 468 - `disable_log_collection` `(bool: false)` - Setting this to `true` will 469 disable Nomad logs collection of Podman tasks. If you don't rely on Nomad log 470 capabilities and exclusively use host based log aggregation, you may consider 471 this option to disable Nomad log collection overhead. Beware that you also 472 lose automatic log rotation. 473 474 ```hcl 475 plugin "nomad-driver-podman" { 476 config { 477 disable_log_collection = false 478 } 479 } 480 ``` 481 482 - `gc` stanza: 483 484 - `container` - Defaults to `true`. This option can be used to disable Nomad 485 from removing a container when the task exits. 486 487 ```hcl 488 plugin "nomad-driver-podman" { 489 config { 490 gc { 491 container = false 492 } 493 } 494 } 495 ``` 496 497 - `recover_stopped` - Defaults to `true`. Allows the driver to start and reuse 498 a previously stopped container after a Nomad client restart. Consider a 499 simple single node system and a complete reboot. All previously managed 500 containers will be reused instead of disposed and recreated. 501 502 ```hcl 503 plugin "nomad-driver-podman" { 504 config { 505 recover_stopped = false 506 } 507 } 508 ``` 509 510 - `socket_path` `(string)` - Defaults to `unix://run/podman/io.podman` when 511 running as `root` or a cgroup V1 system, and 512 `unix://run/user/<USER_ID>/podman/io.podman` for rootless cgroup V2 systems. 513 514 - `disable_log_collection` `(bool: false)` - Setting this to `true` will 515 disable Nomad logs collection of Podman tasks. If you don't rely on Nomad log 516 capabilities and exclusively use host based log aggregation, you may consider 517 this option to disable Nomad log collection overhead. Beware to you also lose 518 automatic log rotation. 519 520 ```hcl 521 plugin "nomad-driver-podman" { 522 config { 523 disable_log_collection = false 524 } 525 } 526 ``` 527 528 - `client_http_timeout` `(string: "60s")` - Default timeout used by 529 `http.Client` requests. 530 531 ```hcl 532 plugin "nomad-driver-podman" { 533 config { 534 client_http_timeout = "60s" 535 } 536 } 537 ``` 538 539 - `volumes` stanza: 540 541 - `enabled` - Defaults to `true`. Allows tasks to bind host paths (volumes) 542 inside their container. 543 - `selinuxlabel` - Allows the operator to set a SELinux label to the 544 allocation and task local bind-mounts to containers. If used with 545 `volumes.enabled` set to false, the labels will still be applied to the 546 standard binds in the container. 547 548 ```hcl 549 plugin "nomad-driver-podman" { 550 config { 551 volumes { 552 enabled = true 553 selinuxlabel = "z" 554 } 555 } 556 } 557 ``` 558 559 [`count`]: /docs/job-specification/group#count 560 [`disable_log_collection`]: #disable_log_collection 561 [docker-ports]: /docs/drivers/docker#forwarding-and-exposing-ports 562 [`examples/jobs/nats_group.nomad`]: https://github.com/hashicorp/nomad-driver-podman/blob/main/examples/jobs/nats_group.nomad 563 [`examples/jobs/nats_simple_pod.nomad`]: https://github.com/hashicorp/nomad-driver-podman/blob/main/examples/jobs/nats_simple_pod.nomad 564 [`examples/jobs/nats_pod.nomad`]: https://github.com/hashicorp/nomad-driver-podman/blob/main/examples/jobs/nats_pod.nomad 565 [homepage]: https://github.com/hashicorp/nomad-driver-podman 566 [memory-value]: /docs/job-specification/resources#memory 567 [`network`]: /docs/job-specification/network 568 [nomad-init]: /docs/commands/job/init 569 [nomad_download]: /downloads 570 [nomad_driver_ports]: /docs/drivers/docker#forwarding-and-exposing-ports 571 [nomad_group_network]: /docs/job-specification/group#network 572 [nomad_lifecycle_hooks]: /docs/job-specification/lifecycle 573 [plugin_dir]: /docs/configuration#plugin_dir 574 [podman]: https://podman.io/ 575 [podman-cli]: https://podman.io/whatis.html 576 [`prestart`]: /docs/job-specification/lifecycle#prestart 577 [releases]: https://releases.hashicorp.com/nomad-driver-podman 578 [rootless_tutorial]: https://github.com/containers/libpod/blob/master/docs/tutorials/rootless_tutorial.md 579 [task]: /docs/job-specification/task#user 580 [`network_mode`]: #network_mode 581 [network-mode]: http://docs.podman.io/en/latest/markdown/podman-run.1.html#options 582 [slirp-issue]: https://github.com/containers/libpod/issues/6097 583 [downloaded]: https://releases.hashicorp.com/nomad-driver-podman 584 [short-names]: https://github.com/containers/image/blob/master/docs/containers-registries.conf.5.md#short-name-aliasing 585 [`command`]: #command 586 [`client_http_timeout`]: #client_http_timeout