Artigo
· Fev. 8 8min de leitura

VIP no Azure

Se você estiver executando o IRIS em uma configuração espelhada para alta disponibilidade (HA) no Azure, a questão de fornecer um [VIP espelho] (https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...) (IP virtual) se torna relevante. O IP virtual oferece uma maneira de sistemas downstream interagirem com o IRIS usando um endereço IP. Mesmo quando ocorre uma tolerância a falhas, os sistemas downstream podem se reconectar ao mesmo endereço IP e continuar trabalhando.

O principal problema, ao implantar no Azure, é que um VIP IRIS requer que o IRIS seja basicamente um administrador de rede, de acordo com a documentação.

Para obter HA, os membros espelho IRIS precisam ser implantados em diferentes zonas de disponibilidade de uma sub-rede (o que é possível no Azure, já que as sub-redes podem abranger várias zonas). Uma das soluções pode ser os balanceadores de carga, mas eles têm um custo extra e você precisa administrá-los.

Neste artigo, quero fornecer uma maneira de configurar um VIP espelho sem usar os balanceadores de carga sugeridos na maioria das outras arquiteturas de referência do Azure.

Arquitetura

Architecture

Temos uma sub-rede em execução em duas zonas de disponibilidade (simplifiquei aqui: claro, você provavelmente terá sub-redes públicas, árbitro em outra az, e assim por diante, mas esse é o mínimo absoluto necessário para demonstrar essa abordagem). O CIDR da sub-rede é "10.0.0.0/24", ou seja, alocou os IPs "10.0.0.1" a "10.0.0.255". Como o Azure reserva os primeiros quatro endereços e o último, podemos usar "10.0.0.4" a "10.0.0.254".

Vamos implementar VIPs públicos e privados ao mesmo tempo. Se quiser, você pode implementar apenas o VIP privado.

Ideia

As máquinas virtuais (VM) no Azure têm interfaces de rede. Essas interfaces de rede têm configurações de IP. A configuração de IP é uma combinação de IPs públicos e/ou privados e é roteada automaticamente para a máquina virtual associada à interface de rede. Portanto, não é preciso atualizar as rotas. Faremos o seguinte: durante um evento de tolerância a falhas de espelho, vamos excluir a configuração de IP VIP da primária antiga e criar uma nova primária. Todas as operações envolvidas nisso levam de 5 a 20 segundos apenas para o VIP privado, de 5 segundos a um minuto para uma combinação de IP VIP público/privado.

Como implementar o VIP

  1. Aloque o IP externo para usar como VIP público. Pule essa etapa se você quiser apenas o VIP privado. Se você alocar o VIP, ele precisa residir no mesmo grupo de recursos e na mesma região e estar em todas as zonas com primária e backup. Você precisará de um nome de IP externo.
  2. Decida o valor do VIP privado. Usarei o último IP disponível: "10.0.0.254".
  3. Em cada VM, aloque o endereço IP VIP em cada interface de rede "eth0:1".
cat << EOFVIP >> /etc/sysconfig/network-scripts/ifcfg-eth0:1
          DEVICE=eth0:1
          ONPARENT=on
          IPADDR=10.0.0.254
          PREFIX=32
          EOFVIP
sudo chmod -x /etc/sysconfig/network-scripts/ifcfg-eth0:1
sudo ifconfig eth0:1 up

Se você só quiser testar, execute (mas ele não sobreviverá à reinicialização do sistema):

sudo ifconfig eth0:1 10.0.0.254

Dependendo do SO, talvez seja preciso executar o seguinte:

ifconfig eth0:1
systemctl restart network
  1. Para cada VM, ative a identidade atribuída pelo sistema ou usuário.
  2. Para cada identidade, atribua as permissões para modificar as interfaces de rede. Para isso, crie uma função personalizada, a permissão mínima definida nesse caso seria:
{
  "roleName": "custom_nic_write",
  "description": "IRIS Role to assign VIP",
  "assignableScopes": [
    "/subscriptions/{subscriptionid}/resourceGroups/{resourcegroupid}/providers/Microsoft.Network/networkInterfaces/{nicid_primary}",
    "/subscriptions/{subscriptionid}/resourceGroups/{resourcegroupid}/providers/Microsoft.Network/networkInterfaces/{nicid_backup}"
  ],
  "permissions": [
    {
      "actions": [
        "Microsoft.Network/networkInterfaces/write",
        "Microsoft.Network/networkInterfaces/read"
      ],
      "notActions": [],
      "dataActions": [],
      "notDataActions": []
    }
  ]
}

Para ambientes que não sejam de produção, você pode usar uma função de sistema contribuidor de rede no grupo de recursos, mas essa abordagem não é recomendada, já que contribuidor de rede é uma função muito ampla.

  1. Cada interface de rede no Azure pode ter um conjunto de configurações de IP. Quando um membro espelho atual se torna primário, vamos usar um retorno de chamadas ZMIRROR para excluir uma configuração de IP VIP na interface de rede de outro membro espelho e criar uma configuração de IP VIP que aponte para ela mesma:

Aqui estão os comandos de CLI do Azure para ambos os nós, considerando o grupo de recursos "rg", a configuração de IP "vip" e o IP externo "my_vip_ip":

az login --identity
az network nic ip-config delete --resource-group rg --name vip --nic-name mirrorb280_z2
az network nic ip-config create --resource-group rg --name vip --nic-name mirrora290_z1 --private-ip-address 10.0.0.254 --public-ip-address my_vip_ip

e:

az login --identity
az network nic ip-config delete --resource-group rg --name vip --nic-name mirrora290_z1
az network nic ip-config create --resource-group rg --name vip --nic-name mirrorb280_z2 --private-ip-address 10.0.0.254 --public-ip-address my_vip_ip

E o mesmo código como uma rotina "ZMIRROR":

ROUTINE ZMIRROR

NotifyBecomePrimary() PUBLIC {
    #include %occMessages
    set rg = "rg"
    set config = "vip"
    set privateVIP = "10.0.0.254"
    set publicVIP = "my_vip_ip"

    set nic = "mirrora290_z1"
    set otherNIC = "mirrorb280_z2"
    if ##class(SYS.Mirror).DefaultSystemName() [ "MIRRORB" {
        // estamos no nó mirrorb, troque
        set $lb(nic, otherNIC)=$lb(otherNIC, nic)
    }

    set rc1 = $zf(-100, "/SHELL", "export", "AZURE_CONFIG_DIR=/tmp", "&&", "az", "login", "--identity")
    set rc2 = $zf(-100, "/SHELL", "export", "AZURE_CONFIG_DIR=/tmp", "&&", "az", "network", "nic", "ip-config", "delete", "--resource-group", rg, "--name", config, "--nic-name", otherNIC)
    set rc3 = $zf(-100, "/SHELL", "export", "AZURE_CONFIG_DIR=/tmp", "&&", "az", "network", "nic", "ip-config", "create", "--resource-group", rg, "--name", config, "--nic-name",      nic,  "--private-ip-address", privateVIP, "--public-ip-address", publicVIP)
    quit 1
}

A rotina é a mesma para ambos os membros espelho, só trocamos os nomes NIC com base no nome do membro espelho atual. Você talvez não precise de "export AZURE_CONFIG_DIR=/tmp", mas, às vezes, "az" tenta gravar as credenciais no dir home raiz, o que pode falhar. Em vez de "/tmp", é melhor usar o subdiretório home do usuário IRIS (ou talvez você nem precise dessa variável de ambiente, dependendo da sua configuração).

Se você quiser usar o Embedded Python, aqui está o código do SDK Azure para Python:

from azure.identity import DefaultAzureCredential
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.network.models import NetworkInterface, NetworkInterfaceIPConfiguration, PublicIPAddress

sub_id = "AZURE_SUBSCRIPTION_ID"
client = NetworkManagementClient(credential=DefaultAzureCredential(), subscription_id=sub_id)

resource_group_name = "rg"
nic_name = "mirrora290_z1"
other_nic_name = "mirrorb280_z2"
public_ip_address_name = "my_vip_ip"
private_ip_address = "10.0.0.254"
vip_configuration_name = "vip"


# remova a configuração VIP antiga
nic: NetworkInterface = client.network_interfaces.get(resource_group_name, other_nic_name)
ip_configurations_old_length = len(nic.ip_configurations)
nic.ip_configurations[:] = [ip_configuration for ip_configuration in nic.ip_configurations if
                            ip_configuration.name != vip_configuration_name]

if ip_configurations_old_length != len(nic.ip_configurations):
    poller = client.network_interfaces.begin_create_or_update(
        resource_group_name,
        other_nic_name,
        nic
    )
    nic_info = poller.result()

# adicione a nova configuração VIP
nic: NetworkInterface = client.network_interfaces.get(resource_group_name, nic_name)
ip: PublicIPAddress = client.public_ip_addresses.get(resource_group_name, public_ip_address_name)
vip = NetworkInterfaceIPConfiguration(name=vip_configuration_name,
                                      private_ip_address=private_ip_address,
                                      private_ip_allocation_method="Static",
                                      public_ip_address=ip,
                                      subnet=nic.ip_configurations[0].subnet)
nic.ip_configurations.append(vip)

poller = client.network_interfaces.begin_create_or_update(
    resource_group_name,
    nic_name,
    nic
)
nic_info = poller.result()

Inicialização

"NotifyBecomePrimary" também é chamado automaticamente na inicialização do sistema (após a reconexão do espelho), mas, se você quiser que seus ambientes não espelhados adquiram o VIP da mesma maneira, use a rotina ZSTART:

SYSTEM() PUBLIC {
  if '$SYSTEM.Mirror.IsMember() {
    do NotifyBecomePrimary^ZMIRROR()
  }
  quit 1
}

Conclusão

E é isso! Mudamos a configuração de IP que aponta para um espelho primário atual quando ocorre o evento "NotifyBecomePrimary".

Discussão (0)1
Entre ou crie uma conta para continuar