An admission controller is a key component in Red Hat OpenShift and Kubernetes. Admission controllers are used to enforce policies and rules that control the admission of pods (containers) and other resources into a Kubernetes cluster. They allow administrators to define and implement custom checks and validations that determine whether a new resource is allowed to be created or modified within the cluster. But what about podman?
Let’s imagine a scenario where developers are given a Red Hat Enterprise Linux (RHEL) system and are allowed to run containerized workloads directly via podman
. Let’s also imagine users have sudo privileges on the podman
command. Without extensive investigation, how could a sysadmin see at a glance which user started one of the many containers currently running on the host as root?
Of course, this is quite easy by walking up the process tree and seeing which user started the sudo (or reading audit logs or other classic methods), but what if you want to embed this information into the container itself? Open Container Initiative (OCI) hooks can help with modifying the container configuration file in various stages of the container lifecycle.
What are OCI hooks?
Container hooks are a feature of the OCI specification that allow users to define and execute actions at various points in the lifecycle of a container. These hooks are scripts or commands that are executed at specific events, such as before or after the container is created, started, stopped or deleted. Container hooks provide a way to extend the behavior of containers and can be used for various purposes, including setup, configuration and cleanup tasks.
OCI container hooks include the following types:
precreate
: This hook is executed after the container configuration is generated, but before the actual start of the container.prestart
: This hook is executed before the container's primary process is started. It can be used to perform tasks like setting up environment variables, configuring network settings or preparing the container's filesystem.poststart
: This hook is executed after the container's primary process is started. It can be used for tasks that need to be performed after the container has started running, such as registering the container with a service discovery system or monitoring tools.poststop
: This hook is executed after the container's primary process has exited or the container has been stopped. It can be used for cleanup tasks, logging or any actions that should be taken after the container has stopped running.
Container hooks can be defined in the OCI configuration for a container, which is typically stored in a JSON file. The configuration specifies the path to the hook script or command, as well as any required arguments or environment variables.
Adding an annotation automatically when a container is created
We will be using the precreate
hook in order to change the container configuration before it is created and started.
The first step required is actually configuring the hooks definition location by editing the /etc/containers/containers.conf
file:
$ cat /etc/containers/containers.conf
[engine]
hooks_dir = ["/etc/containers/oci/hooks.d"]
Then we add our hook definition in JSON format:
$ cat /etc/containers/oci/hooks.d/names.json
{
"version": "1.0.0",
"hook": {
"path": "/usr/local/bin/annotate-sudo-user"
},
"when": {
"always": true
},
"stages": ["precreate"]
}
There are a couple of observations to make on the above.
First, you should create the hooks directory:
$ mkdir -p /etc/containers/oci/hooks.d
Second, the script referenced in hook.path needs to be executable:
$ chmod +x /usr/local/bin/check-container-name
The when
section can be further customized to only apply the hook when certain conditions are met. For this simple case, always: true
means for every container created, this hook will run. More complex options are detailed in the documentation.
For the precreate
stage, the script defined in hook.path
will take input on stdin in the form of the container configuration JSON and the container runtime expects a (potentially modified) valid configuration JSON on stdout.
The final configuration is the script itself:
$ cat /usr/local/bin/annotate-sudo-user
#!/bin/bash
input="-"
CONTAINER_CONFIG=$(cat "$input")
PSTREE=$(pstree -AacTlSucp -s "$$")
LAST_PODMAN_PPID=$(echo "${PSTREE}" | grep -C 1 podman | head -n 1 | awk -F, '{print $2}' | awk '{print $1}')
if [ -z "$LAST_PODMAN_PPID" ]
then
LAST_USER="?"
else
LAST_USER=$(ps -o user= -p "${LAST_PODMAN_PPID}")
fi
echo "$CONTAINER_CONFIG" | jq ".annotations += {\"ran_by\": \"${LAST_USER}\"}"
In the above script, note:
- Read the standard input and save it to the
$CONTAINER_CONFIG
variable. As previously stated, theprecreate
hook runs your script with stdin as the generated container configuration and expects a valid JSON container configuration as the standard out of the script - At run time, the script still runs in the host namespace, as root and with access to the whole process tree.
- The long series of pipes in the building of
$LAST_PODMAN_PPID
is simply getting the parent PID of the firstpodman
process encountered in the process tree above the running script. As the focus of this article is not on the discovery of the parent user, this step might include bugs, but the key takeaway is$LAST_PODMAN_PPID
should contain the immediate parent of thesudo podman (...)
command. - The
$LAST_USER
variable is set to the user that initially startedpodman
. - Finally, add the
ran_by
annotation to the container configuration by usingjq
.
Results
Let’s see how it behaves in real life. After adding the three files described above, notice that any newly started container should have the actual username as an annotation even if run with sudo:
$ whoami
kwozyman
$ sudo podman run --name foobar --detach --rm -ti fedora
1fd5f86ab5065158d135c8a4b8e28059b0e8b61fb0ef4e46f39eb88c43c5ef47
$ sudo podman inspect foobar | jq '.[].Config.Annotations'
{
"io.container.manager": "libpod",
"io.podman.annotations.autoremove": "TRUE",
"org.opencontainers.image.stopSignal": "15",
"ran_by": "kwozyman"
}
In conclusion, the use of OCI container hooks offers a powerful and flexible mechanism for enhancing the capabilities of containerized applications. By enabling developers and administrators to inject custom logic at various stages of a container's lifecycle, OCI hooks provide a valuable tool for automating tasks, enforcing security policies and optimizing performance.
Please note, however, that it's essential to exercise caution when implementing scripted hooks, as they can introduce complexity and potential security risks. Proper documentation, thorough testing and adherence to best practices are crucial to using hooks effectively without increasing your security risks.
Sull'autore
An old school Linux enthusiast, I joined Red Hat in 2021 and I've been helping our customers and partners integrate with Red Hat software ever since. Besides Linux and open source, I'm passionate about science and I've been occasionally known to cycle and hike around Switzerland.
Ricerca per canale
Automazione
Novità sull'automazione IT di tecnologie, team e ambienti
Intelligenza artificiale
Aggiornamenti sulle piattaforme che consentono alle aziende di eseguire carichi di lavoro IA ovunque
Hybrid cloud open source
Scopri come affrontare il futuro in modo più agile grazie al cloud ibrido
Sicurezza
Le ultime novità sulle nostre soluzioni per ridurre i rischi nelle tecnologie e negli ambienti
Edge computing
Aggiornamenti sulle piattaforme che semplificano l'operatività edge
Infrastruttura
Le ultime novità sulla piattaforma Linux aziendale leader a livello mondiale
Applicazioni
Approfondimenti sulle nostre soluzioni alle sfide applicative più difficili
Serie originali
Raccontiamo le interessanti storie di leader e creatori di tecnologie pensate per le aziende
Prodotti
- Red Hat Enterprise Linux
- Red Hat OpenShift
- Red Hat Ansible Automation Platform
- Servizi cloud
- Scopri tutti i prodotti
Strumenti
- Formazione e certificazioni
- Il mio account
- Supporto clienti
- Risorse per sviluppatori
- Trova un partner
- Red Hat Ecosystem Catalog
- Calcola il valore delle soluzioni Red Hat
- Documentazione
Prova, acquista, vendi
Comunica
- Contatta l'ufficio vendite
- Contatta l'assistenza clienti
- Contatta un esperto della formazione
- Social media
Informazioni su Red Hat
Red Hat è leader mondiale nella fornitura di soluzioni open source per le aziende, tra cui Linux, Kubernetes, container e soluzioni cloud. Le nostre soluzioni open source, rese sicure per un uso aziendale, consentono di operare su più piattaforme e ambienti, dal datacenter centrale all'edge della rete.
Seleziona la tua lingua
Red Hat legal and privacy links
- Informazioni su Red Hat
- Opportunità di lavoro
- Eventi
- Sedi
- Contattaci
- Blog di Red Hat
- Diversità, equità e inclusione
- Cool Stuff Store
- Red Hat Summit