La mise en conteneur d’environnement est classique de nos jours et est indiscutablement nécessaire.
Certains, se sont maintes fois heurtés à un mur sous formes d’insultes systèmes en installant le service de temps sous Linux; et notamment sous CentOS/RedHat.
La maudite erreur Normale ”adj_systime: Operation not permitted“
Cette dernière ne permet pas d’installer le service de temps, si nécessaire.
Comme par exemple pour installer un client IPA. La base de temps est obligatoire.
Certes, en mode conteneur non privilégié, c’est une situation tout à fait normale. Et finalement … heureusement !
L’objectif des conteneurs n’est pas d’intervenir sur la partie matérielle de l’hyperviseur !
CAP_SYS_TIME est la responsable.
Plus exactement, il s’agit d’un privilège qui doit-être est accordé. Sur plusieurs conteneurs qui pourraient se battre sur le temps du système, cela poserait un sérieux soucis. Hors le noyau Linux ne fournissent pas (encore) cette gestion de temps en mode conteneur.
LA solution
Sous Ubuntu, une petite potion magique a été créée pour cela. Bien évidemment, par la fondation Ubuntu, qui à sa propre solution de de Cloud et a travaillée sur un contournement de cette problématique.
La solution de contournement est simple: Par défaut l’option -x est appliquée au lancement du démon chronyd sera choisi afin de ne pas régler l’horloge système dans des conteneurs. Cette solution est d’ailleurs définitivement utilisée par la fondation.
Mais alors pour les non Ubuntu, comment faire ?
Le contournement technique repose sur un bash intégré dans toute distribution Ubuntu récente sous le nom de chronyd-starter.sh.
Ce script utilise un fichier de configuration implicite qui peut être renseigné, ou non. Par exemple si l’on veut forcer la synchronisation de l’heure dans un conteneur. Le script met à disposition la variable SYNC_IN_CONTAINER=”NO” dans /etc/default/chrony qui faut possitionner à “YES”.
L’installation
Première chose : on récupère une version du script chronyd-starter.sh sur une distribution Ubuntu dans le chemin /usr/lib/systemd/scripts/
Puis il faut créer le fichier de paramétrage avec ce contenu sous le chemin : /etc/default/chrony
# This is a configuration file for /etc/init.d/chrony and
# /lib/systemd/system/chrony.service; it allows you to pass various options to
# the chrony daemon without editing the init script or service file.
# Options to pass to chrony.
DAEMON_OPTS="-F -1"
# Sync system clock in containers or without CAP_SYS_TIME (likely to fail)
# See /usr/share/doc/chrony/README.container for details.
SYNC_IN_CONTAINER="NO"
Le script chronyd-starter.sh est a déposer dans le chemin /usr/lib/systemd/scripts/ du serveur à traiter. N’oubliez pas les droits d’exécution ! (chmod +x par exemple).
Puis modifions le service chronyd.service, pour exécuter ce script:
[Unit]
Description=NTP client/server
Documentation=man:chronyd(8) man:chrony.conf(5)
After=ntpdate.service sntp.service ntpd.service
Conflicts=ntpd.service systemd-timesyncd.service
ConditionCapability=CAP_SYS_TIME
[Service]
Type=forking
PIDFile=/run/chrony/chronyd.pid
EnvironmentFile=-/etc/sysconfig/chronyd
# Starter takes care of special cases mostly for containers
--> ExecStart=/usr/lib/systemd/scripts/chronyd-starter.sh $DAEMON_OPTS
ExecStartPost=/usr/libexec/chrony-helper update-daemon
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=full
[Install]
WantedBy=multi-user.target
Une fois sauvegardé, effectuez un rechargement de la configuration des services par un systemctl daemon-reload
Et enfin démarrez le service chrony par systemctl start chronyd.service.
Si vous n’avez pas de retour de démarrage, c’est gagné !