Hinweis:

Richten Sie ein virtuelles Linux-IP-Failover auf Oracle Cloud Infrastructure ein, das von Pacemaker verwaltet wird

Einführung

In vielen Umgebungen ist es immer noch wichtig, Infrastrukturen mit einem aktiven oder passiven Linux-Cluster zu verwenden, die den Einsatz von Floating-IPs erfordern. In der Cloud-Infrastruktur muss die sekundäre IP-Adresse nicht nur vom Betriebssystem, sondern auch von der Cloud-Infrastruktur verwaltet werden.

In diesem Tutorial sehen wir, wie die schwimmende IP eines Linux-Clusters von Pacemaker einfach und ohne benutzerdefinierten Code als integrierte Ressource verwaltet werden kann. Weitere Informationen finden Sie unter Aufgabe 3: Samba-Cluster einrichten und Automatisches virtuelles IP-Failover auf Oracle Cloud Infrastructure.

Architekturdesign

image

Ziele

Voraussetzungen

Aufgabe 1: Umgebung einrichten

  1. Starten Sie zwei Compute-Instanzen, und wählen Sie Ubuntu 22 als Betriebssystem für jede Instanz aus.

  2. Weisen Sie der Virtual Network Interface Card (VNIC) der Datei node1 eine sekundäre private IP-Adresse zu. Weitere Informationen finden Sie unter Eine neue sekundäre private IP einer VNIC zuweisen. Dies ist die Floating IP. Beispiel: 10.10.1.115.

  3. Dynamische Gruppe erstellen.

    1. Melden Sie sich bei der OCI-Konsole an, navigieren Sie zu Identität und Sicherheit, Dynamische Gruppen, und klicken Sie auf Dynamische Gruppe erstellen.

    2. Geben Sie folgende Informationen ein.

      • Name: Geben Sie OCIVIP ein.
      • Fügen Sie die folgende Regel hinzu, um Instanzen in das angegebene Compartment einzuschließen.

        All {instance.compartment.id = 'Your compartment OCI ID'}
        
  4. Fügen Sie der dynamischen Gruppe eine Policy hinzu.

    1. Navigieren Sie zu Identität und Sicherheit, Policys, und klicken Sie auf Policy erstellen.

    2. Geben Sie folgende Informationen ein.

      • Name: Geben Sie OCIVIP_policy ein.

      • Fügen Sie die folgende Anweisung hinzu, damit die dynamische Gruppe die virtuelle Netzwerkfamilie verwenden kann:

        allow dynamic-group OracleIdentityCloudService/OCIVIP to use virtual-network-family in compartment id 'Your compartment OCI ID'
        

Aufgabe 2: Cluster und Floating-IP konfigurieren

Nachdem die Umgebung eingerichtet wurde, können wir Pacemaker konfigurieren und den Ressourcen-Agent OCIVIP integrieren. Stellen Sie mit SSH eine Verbindung zu den Instanzen her, und führen Sie die Clusterinstallationsvorgänge auf beiden Knoten bis einschließlich Schritt 10 aus.

  1. Aktualisieren Sie das Betriebssystem.

    sudo apt update
    sudo apt upgrade
    
  2. Installieren Sie die OCI-CLI, und prüfen Sie deren Funktionalität.

    bash -c "$(curl -L https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh)"
    

    Richten Sie die OCI-CLI ein.

    oci setup config
    

    Prüfen Sie die OCI-CLI-Installation.

    oci os ns get
    
  3. Bei einer Testumgebung können Sie die Regel reject in Zeile 6 im Abschnitt INPUT von iptables entfernen und dann persistent machen, um die Instanzkommunikation zu ermöglichen. Denken Sie daran, iptables sicher und angemessen in Produktionsumgebungen zu konfigurieren.

    sudo iptables -D INPUT 6
    sudo su
    sudo iptables-save > /etc/iptables/rules.v4
    sudo ip6tables-save > /etc/iptables/rules.v6
    
  4. Aktualisieren Sie die Datei /etc/hosts mit den privaten IP-Adressen, die Ihren beiden Instanzen zugewiesen sind: node1 und node2.

    Führen Sie den folgenden Befehl aus, um die Datei zu bearbeiten.

    sudo nano /etc/hosts
    

    Fügen Sie die Knotennamen und IP-Adressen hinzu.

    10.10.1.111 node1
    10.10.1.118 node2
    
  5. Installieren Sie die Packages für das Cluster, einschließlich jq.

    sudo apt install -y pacemaker corosync pcs jq
    
  6. Sichern Sie die Datei corosync.conf.

    sudo cp /etc/corosync/corosync.conf /etc/corosync/corosync.conf.bk
    

    Bearbeiten Sie die Datei corosync.conf.

    sudo nano /etc/corosync/corosync.conf
    

    Kopieren Sie den folgenden Inhalt in die Datei corosync.conf.

     # Please read the corosync.conf.5 manual page
     system {
             # This is required to use transport=knet in an unprivileged
             # environment, such as a container. See man page for details.
             allow_knet_handle_fallback: yes
     }
    
     totem {
             version: 2
    
             # Corosync itself works without a cluster name, but DLM needs one.
             # The cluster name is also written into the VG metadata of newly
             # created shared LVM volume groups, if lvmlockd uses DLM locking.
            cluster_name: ha_cluster
             transport: udpu
             secauth: off
             # crypto_cipher and crypto_hash: Used for mutual node authentication.
             # If you choose to enable this, then do remember to create a shared
             # secret with "corosync-keygen".
             # enabling crypto_cipher, requires also enabling of crypto_hash.
             # crypto works only with knet transport
             crypto_cipher: none
             crypto_hash: none
     }
    
     logging {
             # Log the source file and line where messages are being
             # generated. When in doubt, leave off. Potentially useful for
             # debugging.
             fileline: off
             # Log to standard error. When in doubt, set to yes. Useful when
             # running in the foreground (when invoking "corosync -f")
             to_stderr: yes
             # Log to a log file. When set to "no", the "logfile" option
             # must not be set.
             to_logfile: yes
             logfile: /var/log/corosync/corosync.log
             # Log to the system log daemon. When in doubt, set to yes.
             to_syslog: yes
             # Log debug messages (very verbose). When in doubt, leave off.
             debug: off
             # Log messages with time stamps. When in doubt, set to hires (or on)
             #timestamp: hires
             logger_subsys {
                     subsys: QUORUM
                     debug: off
             }
     }
    
     quorum {
             # Enable and configure quorum subsystem (default: off)
             # see also corosync.conf.5 and votequorum.5
             provider: corosync_votequorum
             two_node: 1
             wait_for_all: 1
             last_man_standing: 1
             auto_tie_breaker: 0
     }
    
     nodelist {
             # Change/uncomment/add node sections to match cluster configuration
    
             node {
                     # Hostname of the node.
                     # name: node1
                     # Cluster membership node identifier
                     nodeid: 101
                     # Address of first link
                     ring0_addr: node1
                     # When knet transport is used it's possible to define up to 8 links
                     #ring1_addr: 192.168.1.1
             }
             # ...
             node {
                     ring0_addr: node2
                     nodeid: 102
                 }
    }
    
  7. Fügen Sie die Ressource, mit der Pacemaker OCI-Floating-IP nativ verwaltet, in das Verzeichnis /usr/lib/ocf/resource.d/heartbeat/ ein. Laden Sie den Inhalt der Datei hier herunter: ocivip.txt.

    Hinweis: Diese Ressource wird nicht von Oracle, sondern von Entwicklern von Drittanbietern entwickelt.

    Dies ist der Inhalt der Datei ocivip.

    #!/bin/sh
    #
    #
    # Manage Secondary Private IP in Oracle Cloud Infrastructure with Pacemaker
    #
    #
    # Copyright 2016-2018 Lorenzo Garuti <garuti.lorenzo@gmail.com>
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    #
    #
    
    #
    #  Prerequisites:
    #
    #  - OCI CLI installed (https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/climanualinst.htm)
    #  - jq installed
    #  - dynamic group with a policy attached
    #  - the policy must have this statement:
    #    allow dynamic-group <GROUP_NAME> to use virtual-network-family in compartment id <COMPARTMENT_ID>
    #  - a reserved secondary private IP address for Compute Instances high availability
    #
    
    #######################################################################
    # Initialization:
    
    : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
    . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
    
    #######################################################################
    
    #
    # Defaults
    #
    OCF_RESKEY_ocicli_default="/usr/local/bin/oci"
    OCF_RESKEY_api_delay_default="3"
    OCF_RESKEY_cidr_netmask_default="24"
    OCF_RESKEY_interface_alias_default="0"
    export OCI_CLI_AUTH=instance_principal
    
    : ${OCF_RESKEY_ocicli=${OCF_RESKEY_ocicli_default}}
    : ${OCF_RESKEY_api_delay=${OCF_RESKEY_api_delay_default}}
    : ${OCF_RESKEY_cidr_netmask=${OCF_RESKEY_cidr_netmask_default}}
    : ${OCF_RESKEY_interface_alias=${OCF_RESKEY_interface_alias_default}}
    
    meta_data() {
        cat <<END
    <?xml version="1.0"?>
    <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
    <resource-agent name="ocivip">
    <version>1.0</version>
    
    <longdesc lang="en">
    Resource Agent for OCI Compute instance Secondary Private IP Addresses.
    
    It manages OCI Secondary Private IP Addresses for Compute instances with oci cli.
    
    See https://docs.oracle.com/en-us/iaas/Content/API/Concepts/cliconcepts.htm for more information about oci cli.
    
    Prerequisites:
    
    - OCI CLI installed (https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/climanualinst.htm)
    - jq installed
    - dynamic group with a policy attached
    - the policy must have this statement: allow dynamic-group GROUP_NAME to use virtual-network-family in compartment id COMPARTMENT_ID
    - a reserved secondary private IP address for Compute Instances high availability
    
    </longdesc>
    <shortdesc lang="en">OCI Secondary Private IP Address for Compute instances Resource Agent</shortdesc>
    
    <parameters>
    
    <parameter name="ocicli" unique="0">
    <longdesc lang="en">
    OCI Command line interface (CLI) tools
    </longdesc>
    <shortdesc lang="en">OCI cli tools</shortdesc>
    <content type="string" default="${OCF_RESKEY_ocicli_default}" />
    </parameter>
    
    <parameter name="secondary_private_ip" unique="1" required="1">
    <longdesc lang="en">
    reserved secondary private ip for compute instance
    </longdesc>
    <shortdesc lang="en">reserved secondary private ip for compute instance</shortdesc>
    <content type="string" default="" />
    </parameter>
    
    <parameter name="cidr_netmask" unique="0">
    <longdesc lang="en">
    netmask for the secondary_private_ip
    </longdesc>
    <shortdesc lang="en">netmask for the secondary_private_ip</shortdesc>
    <content type="integer" default="${OCF_RESKEY_cidr_netmask_default}" />
    </parameter>
    
    <parameter name="interface_alias" unique="0">
    <longdesc lang="en">
    numeric alias for the interface
    </longdesc>
    <shortdesc lang="en">numeric alias for the interface</shortdesc>
    <content type="integer" default="${OCF_RESKEY_interface_alias_default}" />
    </parameter>
    
    <parameter name="api_delay" unique="0">
    <longdesc lang="en">
    a short delay between API calls, to avoid sending API too quick
    </longdesc>
    <shortdesc lang="en">a short delay between API calls</shortdesc>
    <content type="integer" default="${OCF_RESKEY_api_delay_default}" />
    </parameter>
    
    </parameters>
    
    <actions>
    <action name="start"        timeout="30s" />
    <action name="stop"         timeout="30s" />
    <action name="monitor"      timeout="30s" interval="20s" depth="0" />
    <action name="migrate_to"   timeout="30s" />
    <action name="migrate_from" timeout="30s" />
    <action name="meta-data"    timeout="5s" />
    <action name="validate"     timeout="10s" />
    <action name="validate-all" timeout="10s" />
    </actions>
    </resource-agent>
    END
    }
    
    #######################################################################
    
    ocivip_usage() {
        cat <<END
    usage: $0 {start|stop|monitor|migrate_to|migrate_from|validate|validate-all|meta-data}
    
    Expects to have a fully populated OCF RA-compliant environment set.
    END
    }
    
    ocivip_start() {
        ocivip_monitor && return $OCF_SUCCESS
    
        $OCICLI network vnic assign-private-ip --vnic-id $VNIC_ID \
            --unassign-if-already-assigned \
            --ip-address ${SECONDARY_PRIVATE_IP}
        RETOCI=$?
        ip addr add ${SECONDARY_PRIVATE_IP}/${CIDR_NETMASK} dev ${PRIMARY_IFACE} label ${PRIMARY_IFACE}:${INTERFACE_ALIAS}
        RETIP=$?
    
        # delay to avoid sending request too fast
        sleep ${OCF_RESKEY_api_delay}
    
        if [ $RETOCI -ne 0 ] || [ $RETIP -ne 0 ]; then
            return $OCF_NOT_RUNNING
        fi
    
        ocf_log info "secondary_private_ip has been successfully brought up (${SECONDARY_PRIVATE_IP})"
        return $OCF_SUCCESS
    }
    
    ocivip_stop() {
        ocivip_monitor || return $OCF_SUCCESS
    
        $OCICLI network vnic unassign-private-ip --vnic-id $VNIC_ID \
            --ip-address ${SECONDARY_PRIVATE_IP}
        RETOCI=$?
        ip addr del ${SECONDARY_PRIVATE_IP}/${CIDR_NETMASK} dev ${PRIMARY_IFACE}:${INTERFACE_ALIAS}
        RETIP=$?
    
        # delay to avoid sending request too fast
        sleep ${OCF_RESKEY_api_delay}
    
        if [ $RETOCI -ne 0 ] || [ $RETIP -ne 0 ]; then
            return $OCF_NOT_RUNNING
        fi
    
        ocf_log info "secondary_private_ip has been successfully brought down (${SECONDARY_PRIVATE_IP})"
        return $OCF_SUCCESS
    }
    
    ocivip_monitor() {
        $OCICLI network private-ip list --vnic-id $VNIC_ID | grep -q "${SECONDARY_PRIVATE_IP}"
        RETOCI=$?
    
        if [ $RETOCI -ne 0 ]; then
            return $OCF_NOT_RUNNING
        fi
        return $OCF_SUCCESS
    }
    
    ocivip_validate() {
        check_binary ${OCICLI}
        check_binary jq
    
        if [ -z "${VNIC_ID}" ]; then
            ocf_exit_reason "vnic_id not found. Is this a Compute instance?"
            return $OCF_ERR_GENERIC
        fi
    
        return $OCF_SUCCESS
    }
    
    case $__OCF_ACTION in
        meta-data)
            meta_data
            exit $OCF_SUCCESS
            ;;
    esac
    
    OCICLI="${OCF_RESKEY_ocicli}"
    SECONDARY_PRIVATE_IP="${OCF_RESKEY_secondary_private_ip}"
    CIDR_NETMASK="${OCF_RESKEY_cidr_netmask}"
    INTERFACE_ALIAS="${OCF_RESKEY_interface_alias}"
    VNIC_ID="$(curl -s -H "Authorization: Bearer Oracle" -L http://169.254.169.254/opc/v2/vnics/ | jq -r '.[0].vnicId')"
    PRIMARY_IFACE=$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)' | head -n1)
    
    case $__OCF_ACTION in
        start)
            ocivip_validate || exit $?
            ocivip_start
            ;;
        stop)
            ocivip_stop
            ;;
        monitor)
            ocivip_monitor
            ;;
        migrate_to)
            ocf_log info "Migrating ${OCF_RESOURCE_INSTANCE} to ${OCF_RESKEY_CRM_meta_migrate_target}."
            ocivip_stop
            ;;
        migrate_from)
            ocf_log info "Migrating ${OCF_RESOURCE_INSTANCE} from ${OCF_RESKEY_CRM_meta_migrate_source}."
            ocivip_start
            ;;
        reload)
            ocf_log info "Reloading ${OCF_RESOURCE_INSTANCE} ..."
            ;;
        validate|validate-all)
            ocivip_validate
            ;;
        usage|help)
            ocivip_usage
            exit $OCF_SUCCESS
            ;;
        *)
            ocivip_usage
            exit $OCF_ERR_UNIMPLEMENTED
            ;;
    esac
    
    rc=$?
    ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc"
    exit $rc
    
  8. Bearbeiten Sie die Datei ocivip, und ändern Sie den Pfad der ausführbaren OCI-CLI-Datei in der Variablen OCF_RESKEY_ocicli_default mit dem OCI-CLI-Pfad.

    Wenn Sie den Standardpfad während der OCI-CLI-Installation auf Ubuntu beibehalten haben, lautet die Variable /home/ubuntu/bin/oci.

    OCF_RESKEY_ocicli_default="/home/ubuntu/bin/oci"
    

    Erstellen Sie die Datei, und kopieren Sie den heruntergeladenen Code aus Schritt 7 mit der aktualisierten Variablen.

    sudo nano /usr/lib/ocf/resource.d/heartbeat/ocivip
    

    Ändern Sie die Berechtigung und den Eigentümer der Datei.

    sudo chown root /usr/lib/ocf/resource.d/heartbeat/ocivip
    sudo chmod 755 /usr/lib/ocf/resource.d/heartbeat/ocivip
    
  9. Aktivieren Sie die Services beim Booten, und starten Sie sie neu. Prüfen Sie außerdem, ob sie ordnungsgemäß funktionieren.

    sudo systemctl enable corosync
    sudo systemctl enable pacemaker
    sudo systemctl enable pcsd
    sudo systemctl restart pcsd
    sudo systemctl restart corosync
    sudo systemctl restart pacemaker
    sudo systemctl status pcsd
    sudo systemctl status corosync
    sudo systemctl status pacemaker
    
  10. Legen Sie das Kennwort für den Benutzer ocicluster fest.

    sudo passwd ocicluster
    
  11. Führen Sie den folgenden Befehl aus, um die Knoten zu authentifizieren.

    sudo pcs cluster auth node1 node2 -u ocicluster -p YOUR_PASSWORD
    
  12. Erstellen Sie ein Cluster.

    sudo pcs cluster setup ha_cluster node1 node2
    
  13. Starten und aktivieren Sie das Cluster beim Booten auf allen Knoten.

    sudo pcs cluster start --all
    sudo pcs cluster enable --all
    
  14. Prüfen Sie, ob das Cluster aktiv und funktionsfähig ist.

    sudo pcs status
    
  15. Fügen Sie die Ressource OCIVIP zur Verwaltung der Floating-IP hinzu.

    Hinweis: Ändern Sie die virtuelle IP-Adresse in die Adresse, die Ihrer VNIC im 2. Schritt dieses Tutorials als sekundär zugewiesen ist.

    sudo pcs resource create OCIVIP ocf:heartbeat:ocivip secondary_private_ip="10.10.1.115" cidr_netmask="24" op monitor timeout="30s" interval="20s" OCF_CHECK_LEVEL="0"
    
  16. Prüfen Sie, ob die Ressource korrekt hinzugefügt wurde und ordnungsgemäß funktioniert.

    sudo pcs status
    
  17. Stellen Sie sicher, dass die sekundäre IP-Adresse zwischen Instanzen migriert werden kann, indem Sie beispielsweise node1 neu starten, und prüfen Sie die OCI-Konsole, dass sie der anderen Instanz zugewiesen ist, und umgekehrt.

    Vor dem Neustart von node1 können Sie auch die Floating-Adresse von einer dritten virtuellen Maschine pingen und prüfen, ob sie nach dem Herunterfahren von node1 weiterhin reagiert. Eine kurze Unterbrechung einiger Hopfen ist normal.

Ihr aktives und passives Cluster ist hochgefahren und gestartet. Sie können jetzt die Services hinzufügen, die eine Geschäftskontinuität erfordern.

Danksagungen

Weitere Lernressourcen

Sehen Sie sich andere Übungen zu docs.oracle.com/learn an, oder greifen Sie im Oracle Learning YouTube-Channel auf weitere kostenlose Lerninhalte zu. Besuchen Sie außerdem education.oracle.com/learning-explorer, um Oracle Learning Explorer zu werden.

Die Produktdokumentation finden Sie im Oracle Help Center.