[LINUX] So erstellen Sie einen OCF-kompatiblen Ressourcenagenten

Ich möchte meine eigene Anwendung in einem Cluster mit Pacemaker verwalten

Sie können es einfach erstellen, indem Sie das OCF Resource Agent-Entwicklerhandbuch lesen. Da die Textmenge jedoch groß ist, "funktioniert dies vorerst". Für Leute, die es schaffen wollen.

OCF-Grundlagen

OCF ist eine Abkürzung für OpenCluster Framework, die die Schnittstelle für Clustering-Anwendungen definiert. Cluster-Manager wie Pacemaker, der Cluster verwaltet, verwaltete Anwendungen und virtuelle IP-Adressen als "Ressourcen" verwalten. Pacemaker befiehlt Ressourcen zum Starten, Stoppen, Migrieren, Heraufstufen zum Master, Herabstufen zum Slave usw. Sie können Ihre eigenen Apps mit Pacemaker gruppieren, indem Sie ein OCF-kompatibles Programm mit Cluster-Verwaltungssoftware wie Pacemaker und der Schnittstelle zwischen Ressourcen erstellen. Das Ziel dieser Zeit ist es, diesen Ressourcenagenten selbst zu erstellen.

Insbesondere wird der Ressourcenagent durch eine OCF-kompatible Clusterverwaltungssoftware aktiviert, indem eine Aktion in die Umgebungsvariable "$ __ OCF_ACTION" eingefügt wird. Zu den Aktionen gehören Start / Stopp / Migration / Beförderung zum Master / Herabstufung zum Slave. Einige Aktionen müssen definiert werden, andere nicht (optional). Ausführungsdateien werden beim Steuern von Ressourcen gekickt. Diese ausführbare Datei wird als Ressourcenagent bezeichnet und verwaltet den Betrieb von Ressourcen. Der Ressourcenagent betrachtet die Umgebungsvariable "$ __ OCF_ACTION" und führt diese Aktion tatsächlich aus. Wenn für jede Aktion Parameter erforderlich sind, werden diese in einer Umgebungsvariablen mit dem Präfix "$ OCF_RESKEY" übergeben. Solange das Ausführungsdateiformat die API-Anforderungen von OCF erfüllt, gibt es keine Einschränkungen für die Sprache, aber es scheint, dass es im Allgemeinen von Shell-Skripten implementiert wird.

Der einfachste Ressourcenagent

Der einfachste OCF-kompatible Code

sample-resource


#!/bin/sh

#Initialize
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs

RUNNING_FILE=/tmp/.running

sample_meta_data() {
    cat << EOF
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="sample-resource" version="0.1">
    <version>0.1</version>
    <longdesc lang="en">sample resource</longdesc>
    <shortdesc lang="en">sample resource</shortdesc>
    <parameters>
    </parameters>
    <actions>
        <action name="meta-data" timeout="5" />
        <action name="start" timeout="5" />
        <action name="stop" timeout="5" />
        <action name="monitor" timeout="5" />
        <action name="validate-all" timeout="5" />
    </actions>
</resource-agent>
EOF
    return $OCF_SUCCESS
}

sample_validate(){
    return $OCF_SUCCESS
}

sample_start(){
    touch ${RUNNING_FILE}
    return $OCF_SUCCESS
}

sample_stop(){
    rm -f ${RUNNING_FILE}
    return $OCF_SUCCESS
}

sample_monitor(){
    if [ -f ${RUNNING_FILE} ];
    then
        return $OCF_SUCCESS
    fi
    return $OCF_NOT_RUNNING
}

sample_usage(){
    echo "Test Resource."
    return $OCF_SUCCESS
}

# Translate each action into the appropriate function call
case $__OCF_ACTION in
meta-data)      sample_meta_data
                exit $OCF_SUCCESS
                ;;
start)          sample_start;;
stop)           sample_stop;;
monitor)        sample_monitor;;
validate-all)   sample_validate;;
*)              sample_usage
                exit $OCF_ERR_UNIMPLEMENTED
                ;;
esac

Initialisieren

Diese Magie wird auch im OCF Resource Agent-Entwicklerhandbuch beschrieben.

#Initialize
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs

Implementieren Sie die erforderlichen Aktionen

Die folgenden Aktionen müssen implementiert werden. Abgesehen davon wird es als Option behandelt. Definieren wir daher vorerst die folgenden Aktionen.

Bei jeder Aktion müssen geeignete Rückgabewerte zurückgegeben werden. Der Rückgabewert ist definiert in OCF.

Umgebungsvariablen, die im Ressourcenagenten verwendet werden

Beschreibt die zu verwendenden Umgebungsvariablen, bevor auf die konkrete Definition jeder erforderlichen Aktion eingegangen wird.

Variable $ __ OCF_ACTION

Enthält die vom Ressourcenagenten angeforderte Verarbeitung und wird festgelegt, wenn der Ressourcenagent aufgerufen wird. Der Ressourcenagent liest zuerst diese Umgebungsvariable und löst jede Aktion aus.

Implementierungsbeispiel Entwicklerhandbuch für OCF Resource Agent

case $__OCF_ACTION in
meta-data)      sample_meta_data
                exit $OCF_SUCCESS
                ;;
start)          sample_start;;
stop)           sample_stop;;
monitor)        sample_monitor;;
validate-all)   sample_validate;;
*)              sample_usage
                exit $OCF_ERR_UNIMPLEMENTED
                ;;
esac
$ OCF_RESKEY_ Parametername

Eine Variable, die die Parameter enthält, die beim Erstellen der Ressource festgelegt werden. Es wird in diesem Beispiel nicht verwendet, wird jedoch beim Clustering des später beschriebenen TCP-Server-Daemons verwendet.

meta-data Die Metadaten enthalten grundlegende Informationen zum Ressourcenagenten, z. B. den Namen des Ressourcenagenten, die von ihm bereitgestellten Aktionen und die Parameter, die er empfangen kann. Der in XML geschriebene Resource Agent gibt auf Anfrage Metadaten in der Standardausgabe zurück.

start Implementieren Sie den Ressourcenstartprozess. Schreiben Sie insbesondere das Startskript des Dämons. Dieses Mal wird der eigentliche Dämon nicht gestartet und nur eine bestimmte Datei erstellt. Wenn der Start erfolgreich ist, wird "$ OCF_SUCCESS" zurückgegeben.

stop Implementieren Sie die Beendigung von Ressourcen. Beschreibt den Stopp des Dämons. Dieses Mal löschen wir die beim Start erstellte Datei.

Wenn es kein Problem mit der Stoppverarbeitung gibt, wird "$ OCF_SUCCESS" zurückgegeben. (Beachten Sie, dass es sich nicht um $ OCF_NOT_RUNNING handelt.)

Beachten Sie, dass die Stoppaktion "erzwungenes Stoppen" der Ressource bedeutet. Auch wenn die Ressource nicht sicher gestoppt werden kann, ist es eine Aktion, sie trotzdem zu stoppen. Wenn die Stoppaktion fehlschlägt, kann dies schwerwiegende Probleme verursachen und der Cluster-Manager führt möglicherweise ein Knoten-Fencing durch (Isolation, z. B. erzwungenes Herunterfahren). Die Stoppaktion sollte alle möglichen Mittel verwenden, um eine Ressource zu stoppen und nur dann einen Fehlercode zurückzugeben, wenn der Stopp immer noch fehlschlägt.

monitor Implementieren Sie den Prozess, um den Ressourcenstatus abzurufen. Wenn es ausgeführt wird, gibt es "$ OCF_SUCCESS" zurück, und wenn es nicht ausgeführt wird, gibt es "$ OCF_NOT_RUNNING" zurück. Wenn ein Fehler vorliegt, wird abhängig vom Fehlerinhalt die entsprechende Fehlerkonstante zurückgegeben, die mit "$ OCF_ERR_" beginnt.

validate-all Überprüfen Sie die Ressourceneinstellungen. Überprüfen Sie, ob die Parameter korrekt eingestellt sind, ob die Berechtigungen der von der Ressource verwendeten Dateien angemessen sind usw. Der Rückgabewert muss einer der folgenden sein:

Rückgabewert Bedeutung
$OCF_SUCCESS kein Problem
$OCF_ERR_CONFIGURED Es liegt ein Problem mit den Einstellungen vor
$OCF_ERR_INSTALLED Erforderliche Komponenten sind nicht vorhanden (z. B. ist der zu startende Dämon nicht installiert).
$OCF_ERR_PERM Es liegt ein Problem mit den Zugriffsberechtigungen der für die Ressourcenverwaltung erforderlichen Dateien vor

(Diesmal ist es einfach, daher wird immer "$ OCF_SUCCESS" zurückgegeben.)

Versuche zu testen

Sie können mit ocf-tester testen.

#ocf-tester -n [Ressourcenname] [Pfad der Ressourcenagentur]

salacia@ha1:~/ocf-scr$ sudo ocf-tester -n sample-resource ./sample-resource
Beginning tests for ./sample-resource...
* Your agent does not support the notify action (optional)
* Your agent does not support the demote action (optional)
* Your agent does not support the promote action (optional)
* Your agent does not support master/slave (optional)
* Your agent does not support the reload action (optional)
./sample-resource passed all tests

Beginnen Sie eigentlich mit Pacemaker

Stellen Sie einen Ressourcenagenten bereit

Der Speicherort des Ressourcenagenten von Pacemaker befindet sich unter "/ usr / lib / ocf / resource.d /". Erstellen Sie hier ein Verzeichnis mit dem Anbieternamen und platzieren Sie den erstellten Ressourcenagenten darin.

Da mein Handle-Name Kamaboko ist, ist der Anbietername Kamaboko und die obige Beispielressource wird platziert. (Ressourcenagenten müssen auf allen Knoten des Clusters platziert werden.)

salacia@ha1:~/ocf-scr$ ls -al /usr/lib/ocf/resource.d/kamaboko/
total 16
drwxrwxr-x 2 root root 4096 Aug 11 14:07 .
drwxr-xr-x 6 root root 4096 Jun 21 03:36 ..
-rwxr-xr-x 1 root root 1547 Aug 11 14:07 sample-resource
-rwxrwxr-x 1 root root 2103 Jun 21 03:36 sample-tcp-server

Nachdem der Ressourcenagent bei Pacemaker verfügbar ist, erstellen wir eine Ressource mit dem Befehl pcs.

salacia@ha1:~/ocf-scr$ sudo pcs resource create SAMPLE ocf:kamaboko:sample-resource

salacia@ha1:~$ sudo pcs status
Cluster name: c1
Stack: corosync
Current DC: ha2 (version 1.1.18-2b07d5c5a9) - partition with quorum
Last updated: Tue Aug 11 14:15:47 2020
Last change: Tue Aug 11 14:15:45 2020 by root via cibadmin on ha1

2 nodes configured
1 resource configured

Online: [ ha1 ha2 ]

Full list of resources:

 SAMPLE (ocf::kamaboko:sample-resource):        Started ha1

Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled

Ich konnte meinen eigenen Ressourcenagenten auf Pacemaker ausführen.

Ein etwas praktischeres Beispiel

Hier ist der Beispielcode. OCF Resource Agent Samle

Derzeit wird nur das .deb-Paket unterstützt, daher denke ich, dass es unter Debian, Ubuntu usw. funktionieren kann. (Entwicklungsumgebung ist Ubuntu 18.04) Herzschrittmacher ist Voraussetzung für die Installation.

Apps zum Clustering

Ich habe gerade einen geeigneten Daemon erstellt, also habe ich eine App erstellt, die mich nur begrüßt, wenn ich mich mit TCP verbinde. (Erwähnen Sie nicht den Code selbst, da es sich nur um ein Beispiel handelt ...) Wenn Sie die Anwendung starten und eine Verbindung mit Telnet usw. herstellen, werden der in der Umgebungsvariablen festgelegte Begrüßungstext und Ihr eigener Knotenname zurückgegeben.

daemon/tcp-server.py.py


#!/usr/bin/python3
import os
import socket
import threading
import time
import signal
import sys

PORT = 5678
PID_FILE_DIR = "/var/run/sample-tcp-server"
PID_FILE_NAME = "tcp-server.pid"
PID_FILE = "%s/%s" % (PID_FILE_DIR, PID_FILE_NAME)
EXIT = False
GREET = os.environ.get("GREET", "Hello!")

def signal_handler(signum, stack):
    EXIT = True

def server():
    os.makedirs(PID_FILE_DIR, exist_ok=True)
    if os.path.isfile(PID_FILE):
        raise Exception("Already running")
    
    with open(PID_FILE, "w") as f:
        f.write(str(os.getpid()))
    
    print("Create Socket")
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(('', PORT))
    s.listen(5)

    try:
        while True:
            if EXIT:
                raise Exception("Stop daemon due to receive signal")
            
            (con, addr) = s.accept()
            t = threading.Thread(
                target=handler,
                args=(con, addr),
                daemon=False
            )
            t.start()
    except Exception as e:
        sys.stderr.write("%s\n" % e)
    finally:
        print("Close Socket")
        s.close()
        os.remove(PID_FILE)
        return

def handler(con, addr):
    con.send(("%s This is %s!\n" % (GREET, socket.gethostname())).encode())
    con.close()

if __name__ == '__main__':
    signal.signal(signal.SIGINT, handler)
    signal.signal(signal.SIGTERM, handler)
    server()
    

Da es nur mit Standardmodulen erstellt wurde, müssen keine Bibliotheken installiert werden. Ich versuche, eine PID-Datei zu generieren, um den Start des Prozesses zu bestätigen. Da die PID-Datei beim Schließen der Anwendung gelöscht wird, können Sie den Start der Anwendung anhand des Vorhandenseins der PID-Datei überprüfen. Wenn sie jedoch von SIGKILL usw. gelöscht wird, wird sie nicht gelöscht. Ich denke, sie ist nicht sehr gut. (Diesmal ist es nur ein Test, also mache ich das der Einfachheit halber)

Anlaufen

GREET=Hii! python3 tcp-server.py

Versuchen Sie, eine Verbindung mit Telnet herzustellen

salacia@ha1:~$ telnet localhost 5678
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hi!, This is ha1!
Connection closed by foreign host.

Der Beispielcode enthält eine Servicedatei, mit der systemd diese App starten und stoppen kann. Lassen Sie uns diese App dieses Mal in einem Hochverfügbarkeitscluster ausführen, um sie redundant zu machen.

Installation

Sie können ein Paket mit make herunterladen und erstellen. Sie müssen es also nur von dpkg installieren. (Muss auf allen Knoten des Clusters installiert sein)

git clone https://github.com/kamaboko123/OCF_resource_agent_sample.git
cd OCF_resource_agent_sample
make
sudo dpkg -i dist/sampletcpserver_1.0_amd64.deb

Funktionsprüfung

Stellen Sie vorerst VIP (VRRP) zwischen den beiden Knoten ein und verursachen Sie im Fehlerfall ein Failover.

#Registrieren Sie VIP als Service
sudo pcs resource create VIP ocf:heartbeat:IPaddr2 ip=172.16.0.50 cidr_netmask=24 op monitor interval=10s on-fail="standby"

#Registrieren Sie die Beispiel-App als Service
sudo pcs resource create TCP-SERVER ocf:kamaboko:sample-tcp-server greet=Hi!

#Legen Sie die Einschränkungen so fest, dass die VIP- und ACTIVE-Knoten der Beispiel-App identisch sind
sudo pcs constraint colocation add TCP-SERVER with VIP INFINITY

Stellen Sie über Telnet von einem externen Knoten aus eine Verbindung zur virtuellen IP-Adresse her.

salacia@Vega:~$ telnet 172.16.0.50 5678
Trying 172.16.0.50...
Connected to 172.16.0.50.
Escape character is '^]'.
Hi!, This is ha1!
Connection closed by foreign host.

Fahren Sie den verbundenen Knoten herunter, um einen Fehler zu verursachen, und überprüfen Sie, ob der Dienst noch verfügbar ist.

#Derzeit VIP und TCP-Knoten, auf dem die SERVER-Ressource ausgeführt wird(ha1)Fallen
salacia@ha1:~$ sudo pcs status
[sudo] password for salacia:
Cluster name: c1
Stack: corosync
Current DC: ha2 (version 1.1.18-2b07d5c5a9) - partition with quorum
Last updated: Tue Aug 11 14:31:30 2020
Last change: Tue Aug 11 14:17:26 2020 by root via cibadmin on ha1

2 nodes configured
2 resources configured

Online: [ ha1 ha2 ]

Full list of resources:

 VIP    (ocf::heartbeat:IPaddr2):       Started ha1
 TCP-SERVER     (ocf::kamaboko:sample-tcp-server):      Started ha1

Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled

salacia@ha1:~$ sudo shutdown -h now
Connection to 172.16.0.51 closed by remote host.
Connection to 172.16.0.51 closed.



#Überprüfen Sie, ob der Dienst weiterhin vom externen Knoten für den VIP bereitgestellt wird
salacia@Vega:~$ telnet 172.16.0.50 5678
Trying 172.16.0.50...
Connected to 172.16.0.50.
Escape character is '^]'.
Hi!, This is ha2!
Connection closed by foreign host.

#Failover-Zielknoten(ha2)Überprüfen Sie den Status mit
salacia@ha2:~$ sudo pcs status
[sudo] password for salacia:
Cluster name: c1
Stack: corosync
Current DC: ha2 (version 1.1.18-2b07d5c5a9) - partition with quorum
Last updated: Tue Aug 11 14:35:51 2020
Last change: Tue Aug 11 14:17:26 2020 by root via cibadmin on ha1

2 nodes configured
2 resources configured

Online: [ ha2 ]
OFFLINE: [ ha1 ]

Full list of resources:

 VIP    (ocf::heartbeat:IPaddr2):       Started ha2
 TCP-SERVER     (ocf::kamaboko:sample-tcp-server):      Started ha2

Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled

Übrigens ist es beim Testen von ocf-tester in Ordnung, wenn Sie den vollständigen Pfad angeben.

sudo ocf-tester -n sample-tcp-server /usr/lib/ocf/resource.d/kamaboko/sample-tcp-server

Kommentar

Wie bereits erläutert, ist der Ressourcenagent in einem Shell-Skript geschrieben.

/usr/lib/ocf/resource.d/kamaboko/sample-tcp-server


#!/bin/sh

#Initialize
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs

#default value
OCF_RESKEY_greet_default="Hello!"
: ${OCF_RESKEY_greet=${OCF_RESKEY_greet_default}}

#environment variables for systemd
DAEMON_PID_FILE=/var/run/sample-tcp-server/tcp-server.pid

sample_meta_data() {
    cat << EOF
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="sample-tcp-server" version="0.1">
    <version>0.1</version>
    <longdesc lang="en">sample tcp server</longdesc>
    <shortdesc lang="en">sample tcp server</shortdesc>
    <parameters>
        <parameter name="greet" unique="0" required="0">
            <longdesc lang="en">greet message</longdesc>
            <shortdesc lang="en">greet message</shortdesc>
            <content type="string"/>
        </parameter>
    </parameters>
    <actions>
        <action name="meta-data" timeout="5" />
        <action name="start" timeout="5" />
        <action name="stop" timeout="5" />
        <action name="monitor" timeout="5" />
        <action name="validate-all" timeout="5" />
    </actions>
</resource-agent>
EOF
    return $OCF_SUCCESS
}

sample_validate(){
    return $OCF_SUCCESS
}

sample_start(){
    mkdir -p /var/run/sample-tcp-server
    echo "GREET=${OCF_RESKEY_greet}" > /var/run/sample-tcp-server/env
    systemctl start sample-tcp-server
    sleep 1
    return $OCF_SUCCESS
}

sample_stop(){
    systemctl stop sample-tcp-server
    return $OCF_SUCCESS
}

sample_monitor(){
    if [ -f ${DAEMON_PID_FILE} ];
    then
        return $OCF_SUCCESS
    fi
    return $OCF_NOT_RUNNING
}

sample_usage(){
    echo "Test Resource."
    return $OCF_SUCCESS
}

# Translate each action into the appropriate function call
case $__OCF_ACTION in
meta-data)      sample_meta_data
                exit $OCF_SUCCESS
                ;;
start)          sample_start;;
stop)           sample_stop;;
monitor)        sample_monitor;;
validate-all)   sample_validate;;
*)              sample_usage
                exit $OCF_ERR_UNIMPLEMENTED
                ;;
esac

Metadaten und Standardwerte

In Metadaten werden zusätzlich zu den erforderlichen Elementen Parameter definiert. Der Parameter ist ein Wert, der beim Erstellen der Ressource festgelegt wird und mit der Variablen "OCF_RESKEY_parameter name" im Ressourcenagenten abgerufen werden kann. Diesmal wird der Text der Begrüßung durch den Parameternamen greet definiert. Im Fall eines erforderlichen Parameters wird das Attribut "erforderlich" auf 1 gesetzt, diesmal jedoch auf 0, sodass es als Option behandelt wird. Daher enthält es auch eine Definition des Standardwerts, falls nicht angegeben. (Wenn nicht angegeben, befindet sich dieser Standardwert "Hallo!" In "$ OCF_RESKEY_greet".)

#default value
OCF_RESKEY_greet_default="Hello!"
: ${OCF_RESKEY_greet=${OCF_RESKEY_greet_default}}

sample_meta_data() {
    cat << EOF
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="sample-tcp-server" version="0.1">
    <version>0.1</version>
    <longdesc lang="en">sample tcp server</longdesc>
    <shortdesc lang="en">sample tcp server</shortdesc>
    <parameters>
        <parameter name="greet" unique="0" required="0">
            <longdesc lang="en">greet message</longdesc>
            <shortdesc lang="en">greet message</shortdesc>
            <content type="string"/>
        </parameter>
    </parameters>
    <actions>
        <action name="meta-data" timeout="5" />
        <action name="start" timeout="5" />
        <action name="stop" timeout="5" />
        <action name="monitor" timeout="5" />
        <action name="validate-all" timeout="5" />
    </actions>
</resource-agent>
EOF
    return $OCF_SUCCESS
}

start Ich starte gerade einen Dienst mit systemd. Die Servicedatei wird später erklärt. Da die Parameter von OCF beim Starten des Dienstes als Umgebungsvariablen übergeben werden, wird "$ {OCF_RESKEY_greet}" in die Datei geschrieben.

sample_start(){
    mkdir -p /var/run/sample-tcp-server
    echo "GREET=${OCF_RESKEY_greet}" > /var/run/sample-tcp-server/env
    systemctl start sample-tcp-server
    sleep 1
    return $OCF_SUCCESS
}

stop Es gibt keine besondere Erklärung und der Dienst wird gestoppt.

sample_stop(){
    systemctl stop sample-tcp-server
    return $OCF_SUCCESS
}

monitor Diesmal schaue ich mir die PID-Datei an.

sample_monitor(){
    if [ -f ${DAEMON_PID_FILE} ];
    then
        return $OCF_SUCCESS
    fi
    return $OCF_NOT_RUNNING
}

Ich habe dies der Einfachheit halber getan, aber ich denke nicht, dass es wirklich eine gute Implementierung ist. Es wird implementiert, um die PID-Datei am Ende des Prozesses zu löschen. Wenn sie jedoch von SIGKILL beendet wird, wird die PID-Datei nicht gelöscht. Abhängig von der Erstellung der Servicedatei wird davon ausgegangen, dass die Stoppaktion die Ressource auf jeden Fall stoppt, sodass am Ende möglicherweise SIGKILL ausgegeben wird. In diesem Fall bleibt die PID-Datei auch dann bestehen, wenn sie gestoppt wird, und es besteht die Möglichkeit, dass der tatsächliche Status von dem durch die Überwachungsaktion bestätigten Status abweicht. (Da ich systemd für das Service Management verwende, hätte ich es über systemd tun sollen.)

validate-all Ich mache nichts Besonderes.

sample_validate(){
    return $OCF_SUCCESS
}

Servicedatei

Es wird nichts Besonderes getan. Starten Sie einfach den Dämon, während Sie die Umgebungsvariablen aus der Umgebungsvariablendatei lesen, die beim Festlegen der Ressource erstellt wurde.

/lib/systemd/system/sample-tcp-server.service


[Unit]
Description=Sample TCP Server

[Service]
Type=simple
ExecStartPre=/bin/touch /var/run/sample-tcp-server/env
EnvironmentFile=/var/run/sample-tcp-server/env
ExecStart=/usr/bin/tcp-server.py
ExecStop=/usr/bin/pkill -F /var/run/sample-tcp-server/tcp-server.pid

[Install]
WantedBy=multi-user.target

Zusammenfassung

OCF-Ressourcenagenten sind überraschend einfach zu erstellen. Dieses Mal haben wir als Eingang zuerst einen Ressourcenagenten erstellt, der tatsächlich nur mit den erforderlichen Aktionen arbeitet. Es gibt jedoch einige detaillierte Hinweise, wenn Sie ihn tatsächlich erstellen. Das OCF Resource Agent-Entwicklerhandbuch enthält verschiedene Hinweise, daher denke ich, dass dies hilfreich sein wird.

Beiseite

LPIC304 Als ich studierte, verstand ich nicht wirklich, was Pacemaker tat, und als ich verschiedene Dinge recherchierte, wurde mir klar, dass ich meinen eigenen Ressourcenagenten herstellen konnte, und so wurde dieser Artikel geboren.

Recommended Posts

So erstellen Sie einen OCF-kompatiblen Ressourcenagenten
So erstellen Sie eine NVIDIA Docker-Umgebung
So erstellen Sie einen Artikel über die Befehlszeile
So erstellen Sie einen Bild-Uploader mit Bottle (Python)
[Python Kivy] So erstellen Sie mit pyinstaller eine exe-Datei
So erstellen Sie eine ISO-Datei (CD-Image) unter Linux
So erstellen Sie ein Conda-Paket
So erstellen Sie eine virtuelle Brücke
So erstellen / löschen Sie symbolische Links
Wie erstelle ich eine Docker-Datei?
So erstellen Sie eine Konfigurationsdatei
So erstellen Sie einen Git-Klonordner
python3 So installieren Sie ein externes Modul
So konvertieren Sie Python in eine exe-Datei
So erstellen Sie ein Repository aus Medien
Erstellen von CSV-Beispieldaten mit Hypothese
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (11)
So erstellen Sie große Dateien mit hoher Geschwindigkeit
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (8)
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (1)
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (4)
So erstellen Sie ein Funktionsobjekt aus einer Zeichenfolge
So erstellen Sie erklärende Variablen und Zielfunktionen
So erstellen Sie eine JSON-Datei in Python
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (7)
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (2)
So beschneiden Sie ein Bild mit Python + OpenCV
So erhalten Sie Hilfe in einer interaktiven Shell
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (3)
So lesen Sie ein Array mit Pythons ConfigParser
So erstellen Sie Daten für CNN (Chainer)
Erstellen Sie eine AWS-GPU-Instanz, um StyleNet zu trainieren
[Hinweis] So erstellen Sie eine Ruby-Entwicklungsumgebung
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (6)
So erstellen Sie ein 1-zeiliges Kivy-Eingabefeld
Verfahren zur Erstellung plattformübergreifender Apps mit kivy
Versuchen Sie, mit Node.js einen HTTP-Server zu erstellen
So erstellen Sie eine Rest-API in Django
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (5)
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (10)
So erstellen Sie einen eingebetteten Linux-Gerätetreiber (9)
[Hinweis] So erstellen Sie eine Mac-Entwicklungsumgebung
Wie man Zufallszahlen mit dem Zufallsmodul von NumPy macht
Verwendung der NUITKA-Utilities-Hinweis-Kompilierung zum einfachen Erstellen einer ausführbaren Datei aus einem Python-Skript
Lesen Sie die Python-Markdown-Quelle: So erstellen Sie einen Parser
So erstellen Sie ein Untermenü mit dem Plug-In [Blender]
[Go] So erstellen Sie einen benutzerdefinierten Fehler für Sentry
Backtrader So importieren Sie einen Indikator aus einer anderen Datei
Eine einfache Möglichkeit, ein Importmodul mit jupyter zu erstellen
So erstellen Sie ein interaktives CLI-Tool mit Golang
So verwandeln Sie eine .py-Datei in eine .exe-Datei
So erstellen Sie einen HTTPS-Server mit Go / Gin
So erstellen Sie ein lokales Repository für Linux
[Python] So erstellen Sie eine Korrelationsmatrix und eine Heatmap