Remarques :

Configuration d'un basculement d'adresse IP virtuelle Linux sur Oracle Cloud Infrastructure géré par Pacemaker

Introduction

Dans de nombreux environnements, il est toujours essentiel d'utiliser des infrastructures avec un cluster Linux actif ou passif, qui nécessitent l'utilisation d'IP flottantes. Dans l'infrastructure cloud, l'adresse IP secondaire doit être gérée non seulement par le système d'exploitation, mais également par l'infrastructure cloud.

Dans ce tutoriel, nous verrons comment l'IP flottante d'un cluster Linux peut être gérée en tant que ressource intégrée par Pacemaker, de manière simple et sans code personnalisé. Pour plus d'informations, reportez-vous à Tâche 3 : configuration du cluster Samba et à Basculement d'adresse IP virtuelle automatique sur Oracle Cloud Infrastructure.

Conception d'architecture

image

Objectifs

Prérequis

Tâche 1 : configurer l'environnement

  1. Lancez deux instances de calcul, sélectionnez Ubuntu 22 comme système d'exploitation pour chaque instance.

  2. Affectez une adresse IP privée secondaire à la carte d'interface réseau virtuelle (VNIC) à node1. Pour plus d'informations, reportez-vous à Affectation d'une nouvelle adresse IP privée secondaire à une VNIC. Il s'agit de l'IP flottante. Par exemple, 10.10.1.115.

  3. Créer un groupe dynamique.

    1. Connectez-vous à la console OCI, accédez à Identité et sécurité, à Groupes dynamiques et cliquez sur Créer un groupe dynamique.

    2. Saisissez les informations suivantes .

      • Nom : entrez OCIVIP.
      • Ajoutez la règle suivante pour inclure les instances dans le compartiment indiqué.

        All {instance.compartment.id = 'Your compartment OCI ID'}
        
  4. Ajoutez une stratégie au groupe dynamique.

    1. Accédez à Identité et sécurité, à Stratégies et cliquez sur Créer une stratégie.

    2. Saisissez les informations suivantes .

      • Nom : entrez OCIVIP_policy.

      • Ajoutez l'instruction suivante pour permettre au groupe dynamique d'utiliser la famille de réseaux virtuels :

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

Tâche 2 : configuration du cluster et de l'adresse IP flottante

Une fois l'environnement configuré, nous pouvons procéder à la configuration de Pacemaker et à l'intégration de l'agent de ressource OCIVIP. Connectez-vous aux instances à l'aide de SSH et effectuez les opérations d'installation de cluster sur les deux noeuds jusqu'à l'étape 10 incluse.

  1. Mettez à jour le système d'exploitation.

    sudo apt update
    sudo apt upgrade
    
  2. Installez l'interface de ligne de commande OCI et vérifiez sa fonctionnalité.

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

    Configuration de l'interface de ligne de commande OCI.

    oci setup config
    

    Vérifiez l'installation de l'interface de ligne de commande OCI.

    oci os ns get
    
  3. Pour un environnement de test, vous pouvez supprimer la règle reject à la ligne 6 de la section INPUT d'iptables, puis la rendre persistante pour autoriser la communication d'instance. N'oubliez pas de configurer iptables de manière sécurisée et appropriée dans les environnements de production.

    sudo iptables -D INPUT 6
    sudo su
    sudo iptables-save > /etc/iptables/rules.v4
    sudo ip6tables-save > /etc/iptables/rules.v6
    
  4. Mettez à jour le fichier /etc/hosts avec les adresses IP privées affectées à vos deux instances : node1 et node2.

    Exécutez la commande suivante pour modifier le fichier.

    sudo nano /etc/hosts
    

    Ajoutez les noms de noeud et les adresses IP.

    10.10.1.111 node1
    10.10.1.118 node2
    
  5. Installez les packages liés au cluster, y compris jq.

    sudo apt install -y pacemaker corosync pcs jq
    
  6. Sauvegardez le fichier corosync.conf.

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

    Modifiez le fichier corosync.conf.

    sudo nano /etc/corosync/corosync.conf
    

    Copiez le contenu suivant dans le fichier 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. Ajoutez la ressource que Pacemaker utilisera pour gérer OCI flottant IP nativement dans le répertoire /usr/lib/ocf/resource.d/heartbeat/. Téléchargez le contenu du fichier à partir de cette page : ocivip.txt.

    Remarque : cette ressource n'est pas développée par Oracle, mais par des développeurs tiers.

    Il s'agit du contenu du fichier 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. Modifiez le fichier ocivip et le chemin de l'exécutable de l'interface de ligne de commande OCI dans la variable OCF_RESKEY_ocicli_default avec le chemin de l'interface de ligne de commande OCI.

    Si vous avez conservé le chemin par défaut lors de l'installation de l'interface de ligne de commande OCI sur Ubuntu, la variable sera /home/ubuntu/bin/oci.

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

    Créez le fichier et copiez le code téléchargé à partir de l'étape 7 avec la variable mise à jour.

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

    Modifiez le droit d'accès et le propriétaire du fichier.

    sudo chown root /usr/lib/ocf/resource.d/heartbeat/ocivip
    sudo chmod 755 /usr/lib/ocf/resource.d/heartbeat/ocivip
    
  9. Activez à l'initialisation et redémarrez les services, ainsi que vérifiez qu'ils fonctionnent correctement.

    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. Définissez le mot de passe de l'utilisateur ocicluster.

    sudo passwd ocicluster
    
  11. Exécutez la commande suivante pour authentifier les noeuds.

    sudo pcs cluster auth node1 node2 -u ocicluster -p YOUR_PASSWORD
    
  12. Créez le cluster.

    sudo pcs cluster setup ha_cluster node1 node2
    
  13. Démarrez et activez le cluster à l'initialisation sur tous les noeuds.

    sudo pcs cluster start --all
    sudo pcs cluster enable --all
    
  14. Vérifiez que le cluster est actif et fonctionnel.

    sudo pcs status
    
  15. Ajoutez la ressource OCIVIP pour gérer l'adresse IP flottante.

    Remarque : remplacez l'adresse IP virtuelle par celle affectée en tant qu'adresse secondaire à votre carte d'interface réseau virtuelle à l'étape 2 de ce tutoriel.

    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. Vérifiez que la ressource a été correctement ajoutée et fonctionne correctement.

    sudo pcs status
    
  17. Vérifiez que l'adresse IP secondaire peut migrer entre les instances, par exemple en redémarrant node1, et vérifiez dans la console OCI qu'elle est affectée à l'autre instance, et inversement.

    Avant de redémarrer node1, vous pouvez également envoyer une commande ping à l'adresse flottante à partir d'une troisième machine virtuelle et vérifier qu'elle continue de répondre après l'arrêt de node1. Une brève interruption de quelques houblons est normale.

Votre cluster actif et passif est en fonctionnement. Vous pouvez désormais ajouter les services qui nécessitent une continuité d'activité.

Accusés de réception

Ressources de formation supplémentaires

Explorez d'autres ateliers sur docs.oracle.com/learn ou accédez à d'autres contenus de formation gratuits sur le canal Oracle Learning YouTube. De plus, visitez le site education.oracle.com/learning-explorer pour devenir un explorateur Oracle Learning.

Pour obtenir la documentation produit, consultez le site Oracle Help Center.