Description
What happened?
When the SIGHUP signal was sent to a currently running CRI-O process, it reloaded its configuration.
However, the CRI-O process was started with several command-line arguments, which were used to override default configuration options such as the log level or the pause image reference.
Following the request to CRI-O to reload its runtime configuration, the options specific via the command-line arguments were overridden with either a default or an item from the /etc/crio/crio.conf (or a drop-in from /etc/crio/crio.conf.d) file.
From this point onwards, the log level was changed, and the reference for the pause container image was updated to a hardcoded default.
What did you expect to happen?
The configuration to be reloaded with the options set through the applied command-line arguments to be preserved.
The precedence of configuration parsing should remain unchanged, and everything should also be merged accordingly, whether it was a fresh start of a runtime configuration reload request via the associated Linux signal delivered to the running process.
Additionally, the message that notifies the user about configuration reload should always be printed - this is not the case currently, as the log line itself is subjected to the presently set log level.
Preferably, it would also be nice if CRI-O had printed its runtime configuration on startup or even following a configuration reload, mainly to capture this type of detail in the log file for later reference (which can be helpful during troubleshooting). However, if the amount of logs this would produce is substantial, then perhaps the entire configuration will only be printed at the debug log level, and otherwise, only (so at the "info" level) difference to the default options would be printed - not sure if this would be desirable, though.
How can we reproduce it (as minimally and precisely as possible)?
Only a few steps are needed to reproduce this behaviour reliably:
- Prepare a configuration file drop-in to override the default log level (which is "info") to the level of warning (or "warn")
# cat > /etc/crio/crio.conf.d/99-log-level.conf
[crio.runtime]
log_level = "warn"
^D
- Start a new CRI-O process manually overriding the log level and setting it to the "debug" level
# crio --log-level debug
INFO[2023-12-12 22:13:11.794601654Z] Starting CRI-O, version: 1.29.0, git: 7380d8ff553b9b2ead8bf3173e8c1db0bc9004db(clean)
(... log lines that follow omitted for brevity ...)
At this point, you can observe CRI-O process log level being set to "debug", and a rather substantial number of log lines being produced. Aside from the logs themselves, you can use the crio
binary itself (assuming a modern version of CRI-O; otherwise, the crio-status
can be used) to verify the current runtime configuration log level and what it's being set to, per:
# crio status config print | grep log_level
INFO[2023-12-12 22:08:57.099952659Z] Starting CRI-O, version: 1.28.1, git: unknown(clean)
log_level = "debug"
- Send the SIGHUP signal to the running CRI-O process in a different terminal session
$ kill -HUP $(pgrep crio) # Or using pkill -HUP crio, whichever is more convenient.
Please return your attention to the terminal session running the CRI-O process in the foreground. At this point, you can observe the following lines appearing amongst other messages:
(... a great many other log lines omitted for brevity ...)
DEBU[2023-12-12 22:13:13.762844491Z] received signal file="crio/main.go:57" signal=hangup
INFO[2023-12-12 22:13:13.763082980Z] Reloading configuration file="config/reload.go:18"
DEBU[2023-12-12 22:13:13.763491295Z] Using /sbin/apparmor_parser binary file="supported/supported.go:61"
DEBU[2023-12-12 22:13:13.763702316Z] Using /sbin/apparmor_parser binary file="supported/supported.go:61"
INFO[2023-12-12 22:13:13.764018888Z] Updating config from file /etc/crio/crio.conf file="config/reload.go:27"
INFO[2023-12-12 22:13:13.764863975Z] Updating config from path /etc/crio/crio.conf.d file="config/reload.go:36"
INFO[2023-12-12 22:13:13.765185045Z] Set config log_level to "warn" file="config/reload.go:83"
Note the confirmation of signal reception and configuration reload. There is also a log line corresponding to a change in the log level, which is crucial to note.
Similarly to before, you can use the crio
binary itself to obtain the current runtime configuration, per:
# crio status config print | grep log_level
INFO[2023-12-12 22:15:27.997584925Z] Starting CRI-O, version: 1.28.1, git: unknown(clean)
log_level = "warn"
This observed behaviour following a runtime configuration reload is not necessarily desirable.
Anything else we need to know?
Personally, I believe we should aim to preserve the order of precedence when reloading the runtime configuration. One could argue that "but, what when the user makes a change to the configuration file, and would like or override option set prior via a command-line arguments?" - well, it's a fair point. Nonetheless, what was set via the configuration arguments should remain unchanged and be the default behaviour. Otherwise, we risk violating the principle of least surprise for the user, which we should avoid if it can be helped.
The suggested order of preference when merging configuration would be (higher to lower):
- Any command-line arguments that were passed
- Environment variables set
- Configuration files (including any files from the so-called "conf.d" directory where the drop-ins are to be stored)
- Default configuration
Now, the "conf.d" directory also has its own rules of how files from there are to be read and in what order - a lot of users respect files to be sorted and read in some order, most likely lexicographic (sort with the "C" locale to remove ambiguity), such that file called "01-foo.conf" would be loaded before files such as "zzz_bar.conf" or "99-baz.conf", I suppose.
Much of this is already working as intended, of course.
The following code is relevant:
- Main and runtime configuration types
Lines 65 to 80 in 7380d8f
Lines 236 to 477 in 7380d8f
- Configuration reload handler
Lines 583 to 600 in 7380d8f
- The Config type concrete Reload() function
Lines 17 to 77 in 7380d8f
- The function that handles log level reload and set-up
Lines 88 to 102 in 7380d8f
CRI-O and Kubernetes version
$ crio --version
crio version 1.29.0
Version: 1.29.0
GitCommit: 7380d8ff553b9b2ead8bf3173e8c1db0bc9004db
GitCommitDate: 2023-12-12T19:22:16Z
GitTreeState: clean
BuildDate: 2023-12-12T21:54:46Z
GoVersion: go1.21.5
Compiler: gc
Platform: linux/amd64
Linkmode: static
BuildTags:
containers_image_ostree_stub
libdm_no_deferred_remove
containers_image_openpgp
seccomp
selinux
apparmor
static
netgo
exclude_graphdriver_btrfs
LDFlags: unknown
SeccompEnabled: true
AppArmorEnabled: true
OS version
$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
$ uname -a
Linux worker-node01 5.15.0-83-generic #92-Ubuntu SMP Mon Aug 14 09:30:42 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
Additional environment details (AWS, VirtualBox, physical, etc.)
Metadata
Metadata
Assignees
Labels
Type
Projects
Status