Func

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
Fiche express
Type Exécution de commandes à distance (architecture maître/minion)
Statut Projet historique Red Hat, abandonné
Ports requis 51234, 51235 (TCP)
Voir aussi Cobbler · Puppet · Ansible · SaltStack

Func (Fedora Unified Network Controller) est un outil d'exécution de commandes à distance né dans l'écosystème Red Hat/Fedora, pensé comme complément à Cobbler et Puppet pour appliquer des actions ponctuelles non couvertes nativement par la gestion de configuration : redémarrage de service, commande shell arbitraire sur un parc de machines, etc.

Statut : projet arrêté depuis le début des années 2010 ; ses cas d'usage sont aujourd'hui couverts par Ansible ou SaltStack (exécution ad hoc sans agent lourd à administrer).

Architecture

  • certmaster : autorité de certification qui signe les certificats des minions (nœuds
 gérés).
  • funcd : agent (« minion ») installé sur chaque serveur géré, qui reçoit les commandes
 via XML-RPC sur SSL.
  • Flux réseau à ouvrir entre le contrôleur et les minions : ports 51234 et 51235
 en TCP.

Installation (CentOS/RHEL + EPEL)

# yum --enablerepo=epel -y install func certmaster

Sur le serveur certmaster :

# /etc/rc.d/init.d/certmaster start
# chkconfig certmaster on

Sur chaque minion, configurer /etc/func/minion.conf :

[main]
certmaster = certmaster.exemple.com   ; nom d'hôte ou IP du certmaster
certmaster_port = 51235
log_level = DEBUG
cert_dir = /etc/pki/certmaster
# /etc/rc.d/init.d/funcd start
# chkconfig funcd on

Signature des certificats

# certmaster-ca --list
# certmaster-ca --sign minion.exemple.com

Vérifier les machines acceptées :

# func "*" list_minions

Groupes de serveurs

Les groupes sont définis dans /etc/func/groups :

[groupe_exemple]
host = hote0.exemple.fr; hote1.exemple.fr; hote2.exemple.fr;
# func @groupe_exemple call command run "eject /dev/cdrom"

Utilisation

En ligne de commande, sur un ou plusieurs hôtes désignés par motif, liste explicite ou groupe :

# func "*.exemple.com" call service restart httpd
# func "*.lan" call command run "df -h"
# func @groupe_exemple call command run "yum -y install paquet"
# func "hote0.exemple.fr;hote1.exemple.fr" call command run "yum -y install paquet"

# func @groupe_exemple call service status gpm
# func @groupe_exemple call service start gpm
# func @groupe_exemple call service stop gpm

# sortie XML-RPC brute
# func exemple.fr call --xmlrpc service status puppet

En Python, via l'API overlord :

>>> from func.overlord import client
>>> c = client.Client("*.lan")
>>> c.service.restart("httpd")
>>> c.command.run("df -h")

(correction par rapport à la source : l'appel est command.run, la page d'origine comportait la faute de frappe command.rum.)

Script d'exploitation type

Exemple de script encapsulant un appel func pour produire un rapport plus lisible lors d'une mise à jour de parc, avec repérage des hôtes en échec (script d'origine généricisé et adapté à la syntaxe Python 3 ; à retester avant réutilisation) :

#!/usr/bin/python
# -*- coding: utf-8 -*-
import func.overlord.client as fc
from time import strftime

client = fc.Client("*.exemple.fr")

print("\n" + strftime("%d %b %Y %H:%M:%S") + "\n")

commande = "LANG=C yum -y update --skip-broken --exclude=paquet-a-exclure"
print("Commande en cours : " + commande + "\n")

result = client.command.run(commande)

postes_a_probleme = []
for (host, details) in result.items():
    print(host + "\n --------------")
    try:
        (retour, texte, autre) = details
        if retour != 0:
            print("/!\\ Le poste : " + host + " a un probleme ! /!\\")
            postes_a_probleme.append(host)
        print("Le retour de la commande est : " + str(retour))
        print(texte)
        print(autre)
    except ValueError:
        if details[0] == "REMOTE_ERROR" and details[2] == "(113, 'No route to host')":
            print("/!\\ Le poste : " + host + " n'est pas joignable ! /!\\")
            postes_a_probleme.append(host)
        else:
            print("/!\\ La connexion ne se fait pas avec le poste !\n")
            for info in details:
                print(info)
            postes_a_probleme.append(host)

if postes_a_probleme:
    print("\n /!\\ Les postes reticents sont : \n ------------------------ ")
    print(postes_a_probleme)

Voir aussi

  • Cobbler — provisioning bare-metal, complémentaire de Func dans l'écosystème Red Hat historique
  • Puppet — gestion de configuration déclarative
  • Ansible — successeur fonctionnel agentless
  • SaltStack — alternative avec architecture maître/minion comparable