From 5da5af3d42d9b96da055c16bf25236aca88f45d8 Mon Sep 17 00:00:00 2001 From: mek Date: Wed, 19 Apr 2023 15:52:01 +0000 Subject: [PATCH] Adding podman build container image FossilOrigin-Name: d2aa4c1b7aad2069d05a56e51e1f19086262743f78fc987433efa702d1bd1a9f --- .fossil-settings/ignore-glob | 3 + Makefile | 2 +- README.md | 3 + files/podman/storage.conf | 222 +++++++++++++++++++++++++++++++++++ podman.md | 159 +++++++++++++++++++++++++ 5 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 files/podman/storage.conf create mode 100644 podman.md diff --git a/.fossil-settings/ignore-glob b/.fossil-settings/ignore-glob index b434afa..a12cd28 100644 --- a/.fossil-settings/ignore-glob +++ b/.fossil-settings/ignore-glob @@ -1 +1,4 @@ *.dockerfile +*~ +Dockerfile* +Dockerfile.* diff --git a/Makefile b/Makefile index 4df0361..bb7bcbc 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ TANGLE=tclsh scripts/tangle.tcl -ALL=ubi9epel ubuntu fossil opensuse alpine +ALL=ubi9epel ubuntu fossil opensuse alpine podman .SUFFIXES: .md .dockerfile .test diff --git a/README.md b/README.md index 104d4c4..1e8c0a0 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,9 @@ I like to insure that my containers follow a few simple rules. * OpenSuse is my favorite development Linux distrobution. * [alpine](alpine.md) * Need a good base alpine image to use for deployments. + * [podman](podman.md) + * A UBI9 based podman container to build docker images. + * include [storage.conf](files/podman/storage.conf) ## As always, go Guardians! diff --git a/files/podman/storage.conf b/files/podman/storage.conf new file mode 100644 index 0000000..6fe5bde --- /dev/null +++ b/files/podman/storage.conf @@ -0,0 +1,222 @@ +# This file is the configuration file for all tools +# that use the containers/storage library. The storage.conf file +# overrides all other storage.conf files. Container engines using the +# container/storage library do not inherit fields from other storage.conf +# files. +# +# Note: The storage.conf file overrides other storage.conf files based on this precedence: +# /usr/containers/storage.conf +# /etc/containers/storage.conf +# $HOME/.config/containers/storage.conf +# $XDG_CONFIG_HOME/containers/storage.conf (If XDG_CONFIG_HOME is set) +# See man 5 containers-storage.conf for more information +# The "container storage" table contains all of the server options. +[storage] + +# Default Storage Driver, Must be set for proper operation. +driver = "overlay" + +# Temporary storage location +runroot = "/run/containers/storage" + +# Primary Read/Write location of container storage +# When changing the graphroot location on an SELINUX system, you must +# ensure the labeling matches the defaul + + +# Storage path for rootless users +# +# rootless_storage_path = "$HOME/.local/share/containers/storage" + +# Transient store mode makes all container metadata be saved in temporary storage +# (i.e. runroot above). This is faster, but doesn't persist across reboots. +# Additional garbage collection must also be performed at boot-time, so this +# option should remain disabled in most configurations. +# transient_store = true + +[storage.options] +# Storage options to be passed to underlying storage drivers + +# AdditionalImageStores is used to pass paths to additional Read/Only image stores +# Must be comma separated list. +additionalimagestores = [ +] + +# Allows specification of how storage is populated when pulling images. This +# option can speed the pulling process of images compressed with format +# zstd:chunked. Containers/storage looks for files within images that are being +# pulled from a container registry that were previously pulled to the host. It +# can copy or create a hard link to the existing file when it finds them, +# eliminating the need to pull them from the container registry. These options +# can deduplicate pulling of content, disk storage of content and can allow the +# kernel to use less memory when running containers. + +# containers/storage supports four keys +# * enable_partial_images="true" | "false" +# Tells containers/storage to look for files previously pulled in storage +# rather then always pulling them from the container registry. +# * use_hard_links = "false" | "true" +# Tells containers/storage to use hard links rather then create new files in +# the image, if an identical file already existed in storage. +# * ostree_repos = "" +# Tells containers/storage where an ostree repository exists that might have +# previously pulled content which can be used when attempting to avoid +# pulling content from the container registry +pull_options = {enable_partial_images = "false", use_hard_links = "false", ostree_repos=""} + +# Remap-UIDs/GIDs is the mapping from UIDs/GIDs as they should appear inside of +# a container, to the UIDs/GIDs as they should appear outside of the container, +# and the length of the range of UIDs/GIDs. Additional mapped sets can be +# listed and will be heeded by libraries, but there are limits to the number of +# mappings which the kernel will allow when you later attempt to run a +# container. +# +# remap-uids = 0:1668442479:65536 +# remap-gids = 0:1668442479:65536 + +# Remap-User/Group is a user name which can be used to look up one or more UID/GID +# ranges in the /etc/subuid or /etc/subgid file. Mappings are set up starting +# with an in-container ID of 0 and then a host-level ID taken from the lowest +# range that matches the specified name, and using the length of that range. +# Additional ranges are then assigned, using +# +# remap-user = "containers" +# remap-group = "containers" + +# Root-auto-userns-user is a user name which can be used to look up one or more UID/GID +# ranges in the /etc/subuid and /etc/subgid file. These ranges will be partitioned +# to containers configured to create automatically a user namespace. Containers +# configured to automatically create a user namespace can still overlap with containers +# having an explicit mapping set. +# This setting is ignored when running as rootless. +# root-auto-userns-user = "storage" +# +# Auto-userns-min-size is the minimum size for a user namespace created automatically. +# auto-userns-min-size=1024 +# +# Auto-userns-max-size is the minimum size for a user namespace created automatically. +# auto-userns-max-size=65536 + +[storage.options.overlay] +# ignore_chown_errors can be set to allow a non privileged +# separation between the users in the container. Only supported for the overlay +# and vfs drivers. +#ignore_chown_errors = "false" + +# Inodes is used to set a maximum inodes of the container image. +# inodes = "" + +# Path to an helper program to use for mounting the file system instead of mounting it +# directly. +#mount_program = "/usr/bin/fuse-overlayfs" + +# mountopt specifies comma separated list of extra mount options +mountopt = "nodev,metacopy=on" + +# Set to skip a PRIVATE bind mount on the storage home directory. +# skip_mount_home = "false" + +# Size is used to set a maximum size of the container image. +# size = "" + +# ForceMask specifies the permissions mask that is used for new files and +# directories. +# +# The values "shared" and "private" are accepted. +# Octal permission masks are also accepted. +# +# "": No value specified. +# All files/directories, get set with the permissions identified within the +# image. +# "private": it is equivalent to 0700. +# All files/directories get set with 0700 permissions. The owner has rwx +# access to the files. No other users on the system can access the files. +# This setting could be used with networked based homedirs. +# "shared": it is equivalent to 0755. +# The owner has rwx access to the files and everyone else can read, access +# and execute them. This setting is useful for sharing containers storage +# with other users. For instance have a storage owned by root but shared +# to rootless users as an additional store. +# NOTE: All files within the image are made readable and executable by any +# user on the system. Even /etc/shadow within your image is now readable by +# any user. +# +# OCTAL: Users can experiment with other OCTAL Permissions. +# +# Note: The force_mask Flag is an experimental feature, it could change in the +# future. When "force_mask" is set the original permission mask is stored in +# the "user.containers.override_stat" xattr and the "mount_program" option must +# be specified. Mount programs like "/usr/bin/fuse-overlayfs" present the +# extended attribute permissions to processes within containers rather than the +# "force_mask" permissions. +# +# force_mask = "" + +[storage.options.thinpool] +# Storage Options for thinpool + +# autoextend_percent determines the amount by which pool needs to be +# grown. This is specified in terms of % of pool size. So a value of 20 means +# that when threshold is hit, pool will be grown by 20% of existing +# pool size. +# autoextend_percent = "20" + +# autoextend_threshold determines the pool extension threshold in terms +# of percentage of pool size. For example, if threshold is 60, that means when +# pool is 60% full, threshold has been hit. +# autoextend_threshold = "80" + +# base +# thin pool. Required if you setup devicemapper. +# directlvm_device = "" + +# directlvm_device_force wipes device even if device already has a filesystem. +# directlvm_device_force = "True" + +# fs specifies the filesystem type to use for the base device. +# fs="xfs" + +# log_level sets the log level of devicemapper. +# 0: LogLevelSuppress 0 (Default) +# 2: LogLevelFatal +# 3: LogLevelErr +# 4: LogLevelWarn +# 5: LogLevelNotice +# 6: LogLevelInfo +# 7: LogLevelDebug +# log_level = "7" + +# min_free_space specifies the min free space percent in a thin pool require for +# new device creation to succeed. Valid values are from 0% - 99%. +# Value 0% disables +# min_free_space = "10%" + +# mkfsarg specifies extra mkfs arguments to be used when creating the base +# device. +# mkfsarg = "" + +# metadata_size is used to set the `pvcreate --metadatasize` options when +# creating thin devices. Default is 128k +# metadata_size = "" + +# Size is used to set a maximum size of the container image. +# size = "" + +# use_deferred_removal marks devicemapper block device for deferred removal. +# If the thinpool is in use when the driver attempts to remove it, the driver +# tells the kernel to remove it as soon as possible. Note this does not free +# up the disk space, use deferred deletion to fully remove the thinpool. +# use_deferred_removal = "True" + +# use_deferred_deletion marks thinpool device for deferred deletion. +# If the device is busy when the driver attempts to delete it, the driver +# will attempt to delete device every 30 seconds until successful. +# If the program using the driver exits, the driver will continue attempting +# to cleanup the next time the driver is used. Deferred deletion permanently +# deletes the device and all data stored in device will be lost. +# use_deferred_deletion = "True" + +# xfs_nospace_max_retries specifies the maximum number of retries XFS should +# attempt to complete IO when ENOSPC (no space) error is returned by +# underlying storage device. +# xfs_nospace_max_retries = "0" diff --git a/podman.md b/podman.md new file mode 100644 index 0000000..00b4b31 --- /dev/null +++ b/podman.md @@ -0,0 +1,159 @@ +# Podman Container Image + +This is my version of [Podman +Image](https://github.com/containers/podman/blob/main/contrib/podmanimage/stable/Containerfile). + +I will be building with a RH UBI Image (version 9). + +## UBI9 Podman Image + +### FROM + +An `ARG` for the version, `VER` is there. This can be overridden with `--build-arg 'VER='`. + +``` +<>= +ARG VER=latest +FROM docker.io/redhat/ubi9:${VER} +@ % def VER +``` + +### Setup user specific arguments. + +Setup a base username, uid, gid, and work directory with some defaults. All of these can be overridden with `-build-arg "ARG=VALUE"`. + +``` +<>= +ARG baseUSER="podman" +ARG baseUID=5000 +ARG baseGID=5000 +ARG baseDIR="/work" +@ +``` + +### Setup and install packages + +The container-commons package on UBI9 does not install the storage.conf +thatr we need, so we copy the file here. + +``` +<>= +RUN dnf -y update && \ + rpm --setcaps shadow-utils 2>/dev/null && \ + dnf -y install podman podman-docker \ + fuse-overlayfs openssh-clients \ + ed joe tcl tcllib \ + --exclude container-selinux && \ + rm -rf /var/cache /var/log/dnf* \ + /var/log/yum.* +ADD files/podman/storage.conf /usr/share/containers/storage.conf +@ +``` + +### Add podman user + +You'll need to be careful here to not change a current directory. For example, do not set baseDIR="/bin". + +Add the group, user, (with the home directory of the user ad the work directory) and insure the proper ownership on the work directory. + +``` +<>= +RUN useradd ${baseUSER}; \ +echo -e "${baseUSER}:1:999\n${baseUSER}:1001:64535" > /etc/subuid; \ +echo -e "${baseUSER}:1:999\n${baseUSER}:1001:64535" > /etc/subgid; +@ +``` + +### Additional Podman Changes + +Additonal changes are needed to the base image for podman to work as +expected. + +``` +<>= +ARG _REPO_URL="https://raw.githubusercontent.com/containers/podman/main/contrib/podmanimage/stable" +ADD $_REPO_URL/containers.conf /etc/containers/containers.conf +ADD $_REPO_URL/podman-containers.conf /home/podman/.config/containers/containers.conf + +RUN mkdir -p /home/podman/.local/share/containers && \ + chown podman:podman -R /home/podman && \ + chmod 644 /etc/containers/containers.conf + +# Copy & modify the defaults to provide reference if runtime changes needed. +# Changes here are required for running with fuse-overlay storage inside container. +RUN sed -e 's|^#mount_program|mount_program|g' \ + -e '/additionalimage.*/a "/var/lib/shared",' \ + -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' \ + /usr/share/containers/storage.conf \ + > /etc/containers/storage.conf + +# Note VOLUME options must always happen after the chown call above +# RUN commands can not modify existing volumes +VOLUME /var/lib/containers +VOLUME /home/podman/.local/share/containers + +RUN mkdir -p /var/lib/shared/overlay-images \ + /var/lib/shared/overlay-layers \ + /var/lib/shared/vfs-images \ + /var/lib/shared/vfs-layers && \ + touch /var/lib/shared/overlay-images/images.lock && \ + touch /var/lib/shared/overlay-layers/layers.lock && \ + touch /var/lib/shared/vfs-images/images.lock && \ + touch /var/lib/shared/vfs-layers/layers.lock + +ENV _CONTAINERS_USERNS_CONFIGURED="" +@ +``` + +### Add repos and update software. + +First, we'll add the EPEL repo. If you have additional repos you want to +enable, add them here. + +``` +<>= +RUN dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm && \ + /usr/bin/crb enable +@ +``` + +### Addtional root changes + +We are still root at this point, this is where we add software, make +additional changes, etc. + +The different sections are setup based on how often they may be changed. +The more likely some will change, the further down they should be to help +minimize the layers that need to be rebuilt. + +### Make sure we the user, volume, and workdir setup + +``` +<>= +# you can add entry point, etc. here. +@ +``` + +### Pulling it all together + +``` +<>= +<> +<> +<> +<> +<> +<> +<> +@ +``` + +## build and test + +`docker build -t mek:podman -f podman.dockerfile .` + +`docker run --rm -it mek:podman /bin/bash` + +``` +$ docker run --rm -it mek:podman /bin/bash +```