# Using Podman with SELinux - SEL confines container processes to system_u:system_r:container_t:s0 domain - File perms for volumes must be system_u:object_r:container_file_t:s0 - This can be done easily by appending `:z` to volume mappings during container creation - Example: `-v /opt/docker/vw-data:/vw-data/:z` # Sources https://blog.christophersmart.com/2021/01/31/podman-volumes-and-selinux/ --- # Book Notes: Podman In Action ## Definitions - container orchestrator - orchestrate conatiners onto multiple machines or nodes; primary CO is Kubernetes; often interacts with a separate container engine - examples: Kubernetes, Docker Swarm, Apache Mesos - container engine - contfigures containerized apps to run on a single node - examples: Podman, Docker, containerd, CRI-O, buildah - Open Container Initiative container runtimes - configure parts of the linux kernel and launch the containerized app - examples: runc, crun, Kata, gVisor - pod - multiple containers sharing the same namespaces and cgroups - cgroups - control groups; linux kernel feature; allows processes to be put in hierarchical groups to limit and monitor resource usage - namespaces - virtualized environments where different processes see different sets of resources - examples: network namespace, mount namespace, PID namespace - skopeo - tool to inspect containers? - container image - a committed container ## Podman - supports images in OCI, docker v2, and docker v1 formats - supports all OCI runtimes - supports rootless containers ## Containers - groups of processes running on a linux system; isolated from one another - prevents processes from interfering with other processes - prevents processes from dominating system resources - allows installations to use specific shared libraries - isolated using resource constraints, security constraints, namespaces - security constraints include SELinux, RO-access to filesystems, user namespaces, seccomp - simplifies software distribution; correct dependencies are already there ## Container Image Format 1. Directory tree containing all software required to run the application 2. JSON file to describe the rootfs - laid out like it was the root of a linux filesystem 3. JSON file to link multiple images together to support different architectures ## Rootless Containers - docker requires root; podman does not - command to gain root privileges if the user is in the docker group: `docker run -ti --name hacker --privileged -v /:/host ubi8 chroot /host` - command to erase evidence of activities: `docker rm hacker` - this includes logging if docker's default logging config is used - docker *can* be run rootless, but it's rare to do so due to the additional configuration required - podman containers are owned by the user and have no addition privileges compared to that user - even on container escape, there are no additional privileges ## Fork/Exec Model - docker is client/server model with multiple daemons - server runs setup steps, then acts as a communication layer back to client - docker daemon, containerd daemon, etc; if any fail, all containers stop ## Systemd Integration - podman aims for integration with systemd - support systemd within containers - socket activation - systemd notifications - systemd management of cgroups ## Pods - shared storage/network resources - supports kubernetes YAML via `podman generate kube` and `podman play kube` - allows multiple microservice containers to be combined into a larger service pod ## Podman Container Customizability - allows container defaults to be overridden - multiple configuration files (distibution-level, system-level, user-level) - allows more or less security depending on need ## User-namespace Support - allows multiple UIDs to be assigned to a user - allows isolation between processes from the same user # Podman Commands (all commands should be prefixed with `podman`) - `run ` - pull image and execute in the foreground until exit - `run -ti ` - run the command in the specified image in interactive mode - `run --rm` - delete container upon exit - `run -d` - detach from the container and run it in the background - `run -p :` - publish the container's internal port to the external host - in rootless mode, only host ports below 1024 are usable - `run --name ` provides a name for the container - if a name is not specified, a unique name is generated - `run --user ` - run as a specific user in the image - `create ` - pull the image and build it, but don't execute - has near-identical flags to `run` - `start` - start a built image - `inspect` - get information about a container/image/network/etc - most items have a specific `inspect` command for their type - `podman image inspect` - `podman container inspect` - etc - `commit` - create new image from current container state - **should only be run while a container is stopped** - not the most common method compared to podman build - `push` - push image to registry - `login ` - log in to a registry to do push/pull actions - by default, credentials are stored in /run/user/\/containers/auth.json as a base64-encoded string - credentials are cleared on reboot - other options for storing passwords are available - `image prune` - remove images without a tag - `image prune -a` - remove all images not in use by a container - `image mount` - mount an images root filesystem as read-only - cannot be done in rootless mode - `unshare` - enter user amd mount namespaces - `build` - build a container using Dockerfile or Containerfile ## Container Images - containers are not the same as images - images are committed containers - "images" usually refers to content stored in container storage or in a container registry - stored as a series of layers ### Image Tagging - allows adding additional names ot images ### Image Mounting ``` podman unshare mnt=$(podman image mount ) ls $mnt podman image unmount exit ``` ## Image Building; Containerfiles - docker has Dockerfile; podman has Containerfile (and Dockerfile) - Containerfiles contain two types of directives - adding content to the container image - describing and documenting image use ### Containerfile directives ``` # FROM specifies the container to base the image off of # FROM scratch # start with no content at all FROM registry.access.redhat.com/ubi8 # start from the ubi8 image # COPY copies files, directories, or tarballs into the new rootfs # ADD provides the same function, but supports remote URLs as well # VOLUME will create a folder that is marked as holding externally-mounted volumes # RUN runs a command on the image during building # commonly used for package management tools RUN yum -y update RUN yum -y install procps-ng RUN yum -y clean all # install "ps" command and clean up cruft from yum # CMD runs a command if a different command is not specified # ENTRYPOINT allows container to run as an executable # ENV defines environment variables # EXPOSE announces ports that will be opened # **but** it does not actually map or open any ports # LABEL adds metadata # MAINTAINER sets author of image # STOPSIGNAL defines the signal to send to the container for exit # USER defined the user name (and group name) for subsequent RUN/CMD/ENTRYPOINT directives # WORKDIR sets the working directory for subsequent RUN/CMD/ENTRYPOINT/COPY directives # ONBUILD adds a trigger to use if the image is being used as a base for another build ``` ## Volumes - `volume rm ` - remove volume - `volume list` - list all volumes - `volume export` - export contents of volume to TAR archive - `volume import` - import TAR as volume ### Why volumes? - separate applications from data - have the same image in multiple environments - reduce overhead of read/write performance - share content via network storage ### Flags - flags are placed after the volume mapping - `-v ./html:/var/www/html:ro` - flags can be combined with commas - `-v ./html:/var/www/html:ro,z` - `:ro` - mount as read-only - `:z` - recursively relabel content for use by SELinux, allows multi-container access - `:Z` - recursively relabel content for use by SELinux, disallows multi-container access - `--security-opt label=disable` can be used to run containers with an "unconfined" label, if needed (but not recommended) - `:U` - change ownership of volume to match UID in container - `:O` - mount as temporary storage, destroyed when finished executing ### Named Volumes - `podman volume crate ` - defaults to locally named volumes - creates a directory for named volumes - can be used by multiple containers at once ## Pods - comes from the Kubernetes project - allows one or more containers to share namespaces and cgroups - ensured shared SELinux labels - all pods ahve a container called the *infra* or *pause* container to hold open namespaces/cgroups - pods can optionally have *init* containers that run before the primary containers are executed - can run either once on pod creation, or every time the pod is started - "sidecar containers" are just other containers in the pod ### conmon - container monitoring process - added to every container that is in a pod - lightweight C executable that monitors pod until exit - executes OCI runtime - responsible for reporting error code back to Podman - provides socket for STDOUT and STDERR fdsafdsa