Résumé : Y a-t-il un moyen de s’assurer que le serveur NFS n’est pas démarré par Systemd jusqu’à ce qu’il puisse résoudre correctement les noms de machine client spécifiés dans /etc/exports
?
Description du problème : J'ai constaté que les partages NFS ne sont pas correctement rendus disponibles après le redémarrage du serveur (sous 16.10). Les clients reçoivent des erreurs "Accès refusé par le serveur" jusqu'à ce que exportfs -ra
ou service nfs-server restart
soit exécuté manuellement sur le serveur. Après cela, tout fonctionne comme prévu.
Le /etc/exports
du serveur ne contient que:
/mnt/raidarray clientmachine(rw)
où clientmachine
est le nom d'hôte de la machine cliente NFS sur le réseau local.
Identification du problème : Le résultat de systemctl status nfs-server
(ci-dessous) rend le problème clair: le nom du client ne peut pas être résolu à ce moment-là. que le serveur NFS a été démarré.
● nfs-server.service - NFS server and services
Loaded: loaded (/lib/systemd/system/nfs-server.service; enabled
Active: active (exited) since Tue 2017-01-17 16:47:38 CST; 26min ago
Main PID: 1520 (code=exited, status=0/SUCCESS)
Tasks: 0 (limit: 4915)
CGroup: /system.slice/nfs-server.service
Jan 17 16:47:38 servermachine exportfs[1511]: exportfs: Failed to resolve clientmachine
Jan 17 16:47:38 servermachine systemd[1]: Started NFS server and services.
NetworkManager-wait-online.service
est activé et I l'avais compris sert à s'assurer que network.target
(sur lequel nfs-server
dépend) n'est pas satisfait jusqu'à ce que network-online.target
soit satisfait .
Ce qui n'a pas aidé :
Au cas où j'aurais mal compris ce que NetworkManager-wait-online.service
fait, j'ai essayé d'ajouter un After=network-online.target
et Wants=network-online.target
explicites à nfs-server.service
. Cela ne répare rien. Je vois la nouvelle dépendance apparaître dans systemctl list-dependencies
, mais la résolution de nom échoue toujours au démarrage. Il semble donc que network-online.target
ne garantisse pas la résolution du nom d'hôte.
Certaines personnes ont suggéré que requérir nss-lookup.target
pour s'assurer que la résolution du réseau est disponible, mais l'ajouter en tant que dépendance Wants
et/ou After
à nfs-server.service
ne corrige pas le problème!
Ajouter une dépendance Wants
et/ou After
sur systemd-resolved.service
au lieu de nss-lookup.target
ne résout rien.
Après avoir ajouté toutes ces dépendances, nfs-server
démarre très tard dans le processus de démarrage (juste avant la connexion au bureau), mais il ne peut toujours pas résoudre les hôtes. D'après systemd-analyze plot
, il apparaît que nmbd
est calé à peu près à ce moment-là, mais je ne sais pas si c'est lié.
Informations de configuration : Il s’agit d’une version de bureau de kubuntu 16.10 qui est en fait une nouvelle installation.
NetworkManager.service
est activé et systemd-networkd.service
est désactivé - je ne l'ai pas modifié par défaut.
Voici la définition du service NetworkManager-wait-online
:
[Unit]
Description=Network Manager Wait Online
Documentation=man:nm-online(1)
Requisite=NetworkManager.service
After=NetworkManager.service
Before=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/bin/nm-online -s -q --timeout=30
RemainAfterExit=yes
[Install]
WantedBy=network-online.target
Comme solution de contournement, je pourrais coder en dur les adresses IP au lieu des noms d’hôte dans /etc/exports
ou /etc/hosts
, mais cela semble quelque peu fragile. Y a-t-il une meilleure réponse?
EDIT - Update : Suivant les conseils de @ muru ci-dessous, j'ai essayé de créer un script qui attend pour résoudre les noms d'hôte, histoire de voir combien de temps cela prend. Mon script doit attendre des dizaines de secondes après le démarrage de systemd-resolved
avant de pouvoir réellement résoudre un hôte. C'est très bizarre. Je me demande si c'est vraiment un problème de réseau local? Cela ressemble peut-être à un fichier codé en dur (et à une mise à jour automatique, comme suggéré par @ mark-stosberg) /etc/exports
ou /etc/hosts
est justifié.
Sur la base du commentaire de @ muru, j'ai créé un script python pour attendre la résolution DNS:
import socket
import time
import itertools
TIMEOUT = 30
HOSTS = ['stanford.edu', 'google.com', 'example.com']
def main():
hosts = itertools.cycle(HOSTS)
t0 = time.time()
for Host in hosts:
t = time.time()
elapsed = t - t0
if elapsed > TIMEOUT:
break
try:
socket.getaddrinfo(Host, None, proto=socket.IPPROTO_TCP)
print('Resolved {} at t = {}'.format(Host, elapsed))
break
except socket.gaierror:
print('Could not resolve {} at t = {}'.format(Host, elapsed))
time.sleep(0.25)
t = time.time()
if __== '__main__':
main()
J'ai enregistré ce script sous le nom /etc/systemd/system/nfs-server.service.d/wait_for_dns.py
(il faut d'abord créer le répertoire parent), puis j'ai exécuté Sudo systemctl edit --full nfs-server
, en ajoutant les éléments suivants avant les autres lignes ExecStartPre:
ExecStartPre=/usr/bin/python3 /etc/systemd/system/nfs-server.service.d/wait_for_dns.py
Cela a bien fonctionné, même si cela semble un peu féroce et pourrait être amélioré à bien des égards. (J'ai fini par abandonner NFS dans ce contexte; c'était plus pénible que cela ne valait la peine.)
J'ai eu le même problème sur une installation Ubuntu 16.04.03 LTS.
Le fichier exportfs ne s’est pas exécuté correctement après un redémarrage et le serveur nfs-kernel-server n’a donc pas démarré correctement.
J'ai essayé d’ajouter un sommeil au début de la procédure dans /etc/init.d/nfs-kernel-server mais cela n’a pas aidé.
J'ai également essayé quelques astuces trouvées https://discourse.osmc.tv/t/nfs-kernel-server-wont-stont-start-boot/5936/7
J'ai finalement résolu le problème en ajoutant la ligne suivante à /etc/rc.local
systemctl restart nfs-kernel-server
En ce qui concerne ce que vous essayez de faire avec systemd
, vous avez déjà essayé de faire ce qu'il y a de mieux, qui consiste à configurer votre service pour qu'il démarre après network-online
. J'ai lu beaucoup de questions systemd
, et d'autres ont signalé des problèmes liés au fait que le réseau n'était pas entièrement en ligne.
Je recommande l’idée de mettre les adresses IP dans /etc/exports
ou /etc/hosts
comme vous le recommandez. Cela simplifie une tâche de montage de disque importante au démarrage.
Pour rendre le système plus robuste, vous pouvez utiliser un travail cron ou une minuterie systemd qui vérifie périodiquement si le DNS des hôtes intéressants a changé. Si c'est le cas, mettez à jour automatiquement /etc/hosts
avec les nouvelles valeurs.