주:

Pacemaker가 관리하는 Oracle Cloud Infrastructure상에서 Linux 가상 IP 페일오버 설정

소개

대부분의 환경에서는 유동 IP를 사용해야 하는 능동 또는 수동 Linux 클러스터와 함께 인프라를 사용하는 것이 여전히 중요합니다. 클라우드 인프라에서는 보조 IP 주소를 운영 체제뿐만 아니라 클라우드 인프라에서도 관리해야 합니다.

이 자습서에서는 Pacemaker가 Linux 클러스터의 유동 IP를 통합 리소스로 관리하는 방법을 사용자 정의 코드 없이 간단한 방식으로 확인할 수 있습니다. 자세한 내용은 작업 3: Samba 클러스터 설정Oracle Cloud Infrastructure에서 자동 가상 IP 페일오버를 참조하십시오.

아키텍처 설계

이미지

목표

필요 조건

작업 1: 환경 설정

  1. 두 개의 컴퓨팅 인스턴스를 실행하고 각 인스턴스의 운영 체제로 Ubuntu 22를 선택합니다.

  2. 보조 개인 IP 주소를 VNIC(가상 네트워크 인터페이스 카드)에 node1에 지정합니다. 자세한 내용은 Assigning a New Secondary Private IP to a VNIC을 참조하십시오. 이것은 유동 IP가 될 것입니다. 예: 10.10.1.115.

  3. 동적 그룹 생성.

    1. OCI 콘솔에 로그인하여 ID 및 보안, 동적 그룹으로 이동하고 동적 그룹 생성을 누릅니다.

    2. 다음 정보를 입력하십시오.

      • 이름: OCIVIP를 입력합니다.
      • 지정된 컴파트먼트에 인스턴스를 포함하려면 다음 규칙을 추가합니다.

        All {instance.compartment.id = 'Your compartment OCI ID'}
        
  4. 동적 그룹에 정책을 추가합니다.

    1. ID 및 보안, 정책으로 이동하고 정책 생성을 누릅니다.

    2. 다음 정보를 입력하십시오.

      • 이름: OCIVIP_policy를 입력합니다.

      • 다음 명령문을 추가하여 동적 그룹이 가상 네트워크 제품군을 사용할 수 있도록 합니다.

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

작업 2: 클러스터 및 부동 IP 구성

환경이 설정된 후 Pacemaker 구성 및 OCIVIP 리소스 에이전트 통합을 계속 진행할 수 있습니다. SSH를 사용하여 인스턴스에 연결하고 10단계까지 두 노드에서 클러스터 설치 작업을 수행합니다.

  1. 운영체제를 업데이트하십시오.

    sudo apt update
    sudo apt upgrade
    
  2. OCI CLI를 설치하고 해당 기능을 확인합니다.

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

    OCI CLI를 설정합니다.

    oci setup config
    

    OCI CLI 설치를 확인합니다.

    oci os ns get
    
  3. 테스트 환경의 경우 iptables의 INPUT 섹션에 있는 6행에서 reject 규칙을 제거한 다음 인스턴스 통신을 허용하도록 지속되도록 설정할 수 있습니다. 운용 환경에서 iptables를 안전하고 적절하게 구성해야 합니다.

    sudo iptables -D INPUT 6
    sudo su
    sudo iptables-save > /etc/iptables/rules.v4
    sudo ip6tables-save > /etc/iptables/rules.v6
    
  4. /etc/hosts 파일을 두 인스턴스 node1node2에 지정된 전용 IP 주소로 업데이트합니다.

    다음 명령을 실행하여 파일을 편집합니다.

    sudo nano /etc/hosts
    

    노드 이름과 IP 주소를 추가합니다.

    10.10.1.111 node1
    10.10.1.118 node2
    
  5. jq를 포함하여 클러스터와 관련된 패키지를 설치합니다.

    sudo apt install -y pacemaker corosync pcs jq
    
  6. corosync.conf 파일을 백업합니다.

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

    corosync.conf 파일을 편집합니다.

    sudo nano /etc/corosync/corosync.conf
    

    다음 내용을 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. Pacemaker가 OCI 부동 IP를 기본적으로 관리하는 데 사용할 리소스를 /usr/lib/ocf/resource.d/heartbeat/ 디렉토리에 추가합니다. ocivip.txt에서 파일 내용을 다운로드합니다.

    : 이 리소스는 Oracle이 개발하지 않고 타사 개발자가 개발합니다.

    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. ocivip 파일을 편집하고 OCI CLI 경로를 사용하여 OCF_RESKEY_ocicli_default 변수의 OCI CLI 실행 파일 경로를 변경합니다.

    Ubuntu에서 OCI CLI를 설치하는 동안 기본 경로를 유지한 경우 변수는 /home/ubuntu/bin/oci가 됩니다.

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

    파일을 생성하고 단계 7에서 다운로드한 코드를 갱신된 변수로 복사합니다.

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

    권한 및 파일 소유자를 변경합니다.

    sudo chown root /usr/lib/ocf/resource.d/heartbeat/ocivip
    sudo chmod 755 /usr/lib/ocf/resource.d/heartbeat/ocivip
    
  9. 부트 시 사용으로 설정하고 서비스를 다시 시작하고 서비스가 올바르게 작동하는지 확인합니다.

    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. ocicluster 사용자에 대한 비밀번호를 설정합니다.

    sudo passwd ocicluster
    
  11. 다음 명령을 실행하여 노드를 인증합니다.

    sudo pcs cluster auth node1 node2 -u ocicluster -p YOUR_PASSWORD
    
  12. 클러스터를 생성합니다.

    sudo pcs cluster setup ha_cluster node1 node2
    
  13. 모든 노드에서 부트 시 클러스터를 시작하고 사용으로 설정합니다.

    sudo pcs cluster start --all
    sudo pcs cluster enable --all
    
  14. 클러스터가 활성 상태이고 작동 중인지 확인합니다.

    sudo pcs status
    
  15. 유동 IP 관리를 위한 OCIVIP 리소스를 추가합니다.

    주: 이 자습서의 2단계에서 가상 IP 주소를 VNIC에 보조로 지정된 주소로 변경합니다.

    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. 리소스가 제대로 추가되고 제대로 작동하는지 확인합니다.

    sudo pcs status
    
  17. 예를 들어, node1를 재시작하여 보조 IP 주소가 인스턴스 간에 이전될 수 있는지 확인하고, OCI 콘솔이 다른 인스턴스에 지정되었는지(그 반대도 가능) 확인합니다.

    node1를 다시 시작하기 전에 세번째 가상 머신에서 유동 주소를 핑하고 node1가 종료된 후에도 계속 응답하는지 확인할 수도 있습니다. 몇 가지 홉의 짧은 중단은 정상입니다.

능동 및 수동 클러스터가 작동되어 실행 중입니다. 이제 무중단 업무 운영이 필요한 서비스를 추가할 수 있습니다 .

확인

추가 학습 자원

docs.oracle.com/learn에서 다른 실습을 탐색하거나 Oracle Learning YouTube 채널에서 더 많은 무료 학습 콘텐츠에 액세스하세요. 또한 Oracle Learning Explorer가 되려면 education.oracle.com/learning-explorer을 방문하십시오.

제품 설명서는 Oracle Help Center를 참조하십시오.