高可用虚拟IP(HaVip)

使用高可用虚拟IP(High-Availability Virtual IP Address,HaVip)功能,在云上可以实现同可用区服务器主备切换过程中服务IP不变。

Keepalived本身就可以支持实现虚拟IP高可用,为什么要配合HaVip来实现?

在传统数据中心中,Keepalived 软件在进行主备切换时,基于 VRRP 协议确定新的主服务器。新的主服务器可以直接将虚拟IP绑定到自身网卡,并主动发送Gratuitous ARP广播,宣告自己接管了虚拟IP。局域网中的各设备收到该 ARP 广播后,会更新本地 ARP 缓存,将虚拟IP指向新的主服务器的MAC地址。

然而,大部分云厂商采用SDN架构和虚拟化技术构建网络环境,虚拟服务器IP地址由云平台底层的虚拟化平台分配和管理。应用无法像传统方式一样修改主机IP地址。且整个虚拟网络是基于三层的隧道技术,ARP在发送端被终结,主机无法声明IP地址。为此,阿里云推出HaVip功能,解决此问题。

HaVip 是一种可以独立创建和释放的私网 IP 资源。在 Keepalived 的配置文件中将虚拟 IP 设置为 HaVip 地址,并将 HaVip 与多个服务器绑定。当 Keepalived 选举出新的主服务器后,系统会更新 HaVip 与主服务器的映射关系,实现类似 Gratuitous ARP 的效果,从而确保主备切换过程中服务 IP 不变。

工作原理

通过1HaVip2ECS实例实现高可用主备集群的架构如下图所示。工作原理如下:

  1. Keepalived配置:HaVip 绑定 ECS1 和 ECS2,二者均安装 Keepalived软件。在 Keepalived 的配置文件中,virtual_ipaddress(虚拟 IP)均设置为 HaVip 地址。同时,需要在配置文件中设置优先级priority,值越大,该服务器作为主服务器的优先级越高。

  2. 主服务器选举:Keepalived 软件基于 VRRP 协议,通过比较 ECS1 和 ECS2 的priority值大小,自动选举优先级更高的 ECS1 为主服务器,系统会自动更新 HaVip 与主服务器的映射关系,所有访问 HaVip 的流量将被转发至 ECS1。

  3. 主备切换:主服务器 ECS1 会周期性发送心跳消息到备服务器 ECS2(心跳间隔由配置文件中的advert_int决定)。如果 ECS2 在指定时间内未收到心跳消息,Keepalived 软件会自动将主服务器切换为 ECS2。系统检测到主服务器变更后,会自动更新 HaVip 与新主服务器的映射关系,所有访问 HaVip 的流量将被转发至 ECS2,从而实现主备切换过程中服务IP不变。

如果需要公网访问,可为HaVip绑定EIP,绑定后该HaVip可以通过EIP面向公网提供高可用服务。

image

使用 HaVip 实现主备切换

HaVip 支持绑定同一交换机内的ECS实例或弹性网卡,结合Keepalived等软件实现主备切换时的服务 IP 不变。

  • 配额:使用前,需登录配额中心控制台申请创建 HaVip 的权限。配额为1,代表可创建 HaVip,而单账号支持创建 HaVip 的数量为 50 个。

  • IP 版本:HaVip 仅支持 IPv4。

  • 绑定资源:

    • HaVip 只能同时绑定同一类型资源。如需绑定其他类型资源,需先解绑已经绑定的资源。

    • HaVip 绑定弹性网卡时,需确保弹性网卡绑定在ECS实例上。

    • 如果已绑定的 ECS 实例或弹性网卡被删除,系统会自动解除 HaVip 和对应 ECS 实例或弹性网卡的绑定关系。

    • 如果从 ECS 实例上解绑已绑定 HaVip 的辅助弹性网卡,不会影响 HaVip 和该辅助弹性网卡的绑定关系。

控制台

创建 HaVip 并绑定主备实例

  1. 前往专有网络控制台-HaVip,在页面上方选择 ECS 实例所在的地域后,单击创建高可用虚拟IP

  2. 选择需绑定的 ECS 实例所属的 VPC 和交换机,可从选定的交换机网段自动分配私网 IP 地址,也可以自行指定未被分配的 IP。

  3. 在主备 ECS 实例上安装 Keepalived,并执行systemctl start keepalived启动 Keepalived。

    Keepalived 安装示例

    本示例以双机主备为例,介绍操作系统为CentOSECS实例如何安装Keepalived。推荐使用V1.2.15及以上版本的Keepalived。

    如有多台备用 ECS 实例,需在各 ECS 实例的unicast_peer中声明所有对端实例的 IP。
    可前往Keepalived GitHub了解更多信息。

    主服务器配置

    1. 登录主 ECS 实例。

    2. 执行yum install keepalived安装Keepalived。

    3. 执行vim /etc/keepalived/keepalived.conf编辑keepalived.conf文件。

      本示例仅展示需修改部分,请结合具体实例修改keepalived.conf文件配置。请勿直接复制本示例覆盖已有keepalived.conf文件。
      ! Configuration File for keepalived
      vrrp_instance VI_1 {
          state MASTER            # 设置为主实例
          interface eth0          # 绑定VIP的网卡,本示例配置为eth0  
          virtual_router_id 51    # 主备集群的virtual_router_id;同一VPC下的不同主备集群需要配置不同的virtual_router_id
          nopreempt               # 设置非抢占模式
          priority 100            # 设置优先级,数字越大,优先级越高;本示例配置优先级为100,将本实例设置为主实例
          advert_int 1            # 心跳报文发送间隔,单位为秒。设置过小,易受网络抖动影响,可能发生频繁倒换和暂时双主(即脑裂)。设置过大,可能导致主实例故障后,主备切换时间长。
          authentication {
              auth_type PASS
              auth_pass 1111
          }
          unicast_src_ip 192.168.0.25     # 本实例的私网IP地址,本示例配置为192.168.0.25
          unicast_peer {
              192.168.0.26          # 对端实例的私网IP地址,本示例配置为192.168.0.26;如有多台备用ECS实例,需声明所有对端实例的IP,每个地址单独占一行,无需逗号或其他分隔符。
          }
          virtual_ipaddress {
              192.168.0.24          # 虚拟IP地址,配置为HaVipIP地址,本示例为192.168.0.24
          }   
          garp_master_delay 1       # 当切为主实例后多久更新ARP缓存,单位为秒
          garp_master_refresh 5     # 发送ARP报文的时间间隔,单位为秒
      
          track_interface {
              eth0                  # 绑定VIP的网卡,本示例配置为eth0
          }
      }
    4. 执行systemctl start keepalived启动 Keepalived。

    备服务器配置

    1. 登录备 ECS 实例。

    2. 执行yum install keepalived安装Keepalived。

    3. 执行vim /etc/keepalived/keepalived.conf编辑keepalived.conf文件。

      本示例仅展示需修改部分,请结合具体实例修改keepalived.conf文件配置。请勿直接复制本示例覆盖已有keepalived.conf文件。
      ! Configuration File for keepalived
      vrrp_instance VI_1 {
          state BACKUP            # 设置为备实例
          interface eth0          # 绑定VIP的网卡,本示例配置为eth0  
          virtual_router_id 51    # 主备集群的virtual_router_id;同一VPC下的不同主备集群需要配置不同的virtual_router_id
          nopreempt               # 设置非抢占模式
          priority 10             # 设置优先级,数字越大,优先级越高;本示例配置优先级为10,将本实例设置为备实例
          advert_int 1            # 心跳报文发送间隔,单位为秒。设置过小,易受网络抖动影响,可能发生频繁倒换和暂时双主(即脑裂)。设置过大,可能导致主实例故障后,主备切换时间长。
          authentication {
              auth_type PASS
              auth_pass 1111
          }
          unicast_src_ip 192.168.0.26   # 本实例的私网IP地址,本示例配置为192.168.0.26
          unicast_peer {
              192.168.0.25          # 对端实例的私网IP地址,本示例配置为192.168.0.25。需声明所有对端实例的IP,每个地址单独占一行,无需逗号或其他分隔符。
          }
          virtual_ipaddress {
              192.168.0.24          # 虚拟IP地址,配置为HaVipIP地址,本示例为192.168.0.24
          }    
          garp_master_delay 1       # 当切为主实例后多久更新ARP缓存,单位为秒
          garp_master_refresh 5     # 发送ARP报文的时间间隔,单位为秒
      
          track_interface {
              eth0                  # 绑定VIP的网卡,本示例配置为eth0
          }
      }
    4. 执行systemctl start keepalived启动 Keepalived。

  4. 单击目标 HaVip ID,在绑定资源区域,单击 ECS实例右侧的立即绑定,选择要绑定的 ECS 实例或弹性网卡。

    绑定完成后,可以在目标 HaVip 的绑定实例列或详情页的绑定资源区域,查看当前的主备关系。
  5. 效果验证:

    1. 在主备实例分别执行以下命令,创建Web测试服务,返回不同结果。

      通过netstat -an | grep 8000查看端口占用情况,如果8000端口被占用,需要选择其他端口。

      主实例:

      echo "ECS 1" > index.html  # 主实例返回"ECS 1"
      python3 -m http.server 8000

      备实例:

      echo "ECS 2" > index.html  # 备实例返回"ECS 2"
      python3 -m http.server 8000
    2. 在同 VPC 内的其他 ECS 实例中,执行curl <havip_private_ip>:8000,将返回ECS 1;当主服务器停机后,将返回ECS 2

      请确保主备实例的安全组已允许同 VPC 内的 HTTP 流量访问 8000 端口。

解绑资源

单击目标 HaVip ID,在绑定资源区域的已绑定ECS实例已绑定弹性网卡处找到目标 ECS 实例或弹性网卡,单击解除关联

删除 HaVip

需先确保 HaVip 未绑定 ECS实例、弹性网卡或 EIP,在目标 HaVip 的操作列或详情页单击删除

API

Terraform

Resource:alicloud_havipalicloud_havip_attachmentalicloud_instancealicloud_security_groupalicloud_security_group_rule
# 指定创建HaVip的地域
provider "alicloud" {
  region = "cn-hangzhou"
}

# 指定VPC的ID
variable "vpc_id" {
  default = "vpc-bp1k******" # 修改为VPC的实际ID
}

# 指定交换机ID
variable "vswitch_id" {
  default = "vsw-bp1y******" # 修改为交换机的实际ID
}

# 指定实例规格
variable "instance_type" {
  default = "ecs.e-c1m1.large"
}

# 指定镜像ID
variable "image_id" {
  default = "aliyun_3_x64_20G_alibase_20221102.vhd"
}

# 创建HaVip
resource "alicloud_havip" "test_havip" {
  ha_vip_name = "test_havip_name"
  vswitch_id  = var.vswitch_id
  ip_address  = "192.168.0.24" # 从交换机网段内,指定HaVip的IP地址;若不指定,将由系统分配
}

# 创建安全组
resource "alicloud_security_group" "test_security_group" {
  security_group_name = "test_security_group_name"
  vpc_id              = var.vpc_id
}

# 创建安全组规则,需根据实际流量调整协议、访问来源与端口。
resource "alicloud_security_group_rule" "allow_vpc_tcp" {
  type              = "ingress"
  ip_protocol       = "tcp"
  nic_type          = "intranet"
  policy            = "accept"
  port_range        = "8000/8000"
  priority          = 1
  security_group_id = alicloud_security_group.test_security_group.id
  cidr_ip           = "192.168.0.0/24"
}

# 创建主服务器 
resource "alicloud_instance" "test_master_instance" {
  instance_name        = "test_master_instance_name"
  vswitch_id           = var.vswitch_id
  instance_type        = var.instance_type
  image_id             = var.image_id
  system_disk_category = "cloud_essd"
  security_groups      = [alicloud_security_group.test_security_group.id]
  user_data = base64encode(<<-EOT
    #!/bin/sh
    yum install keepalived -y

    printf '! Configuration File for keepalived
    vrrp_instance VI_1 {
        state MASTER            # 设置为主实例
        interface eth0          # 绑定VIP的网卡,本示例配置为eth0  
        virtual_router_id 51    # 主备集群的virtual_router_id;同一VPC下的不同主备集群需要配置不同的virtual_router_id
        nopreempt               # 设置非抢占模式
        priority 100            # 设置优先级,数字越大,优先级越高;本示例配置优先级为100,将本实例设置为主实例
        advert_int 1            # 心跳报文发送间隔,单位为秒。设置过小,易受网络抖动影响,可能发生频繁倒换和暂时双主(即脑裂)。设置过大,可能导致主实例故障后,主备切换时间长。
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        unicast_src_ip 192.168.0.25     # 本实例的私网IP地址,本示例配置为192.168.0.25
        unicast_peer {
            192.168.0.26                # 对端实例的私网IP地址,本示例配置为192.168.0.26;如有多台备用ECS实例,需声明所有对端实例的IP。每个地址单独占一行,无需逗号或其他分隔符。
        }
        virtual_ipaddress {
            192.168.0.24                # 虚拟IP地址,配置为HaVip的IP地址,本示例为192.168.0.24
        }   
        garp_master_delay 1             # 当切为主实例后多久更新ARP缓存,单位为秒 
        garp_master_refresh 5           # 发送ARP报文的时间间隔,单位为秒 

        track_interface {
            eth0                        # 绑定VIP的网卡,本示例配置为eth0
        }
    }' > /etc/keepalived/keepalived.conf
    systemctl start keepalived
  EOT
  )                                           # 指定主服务器的初始化脚本,为主服务器安装keepalived
  private_ip           = "192.168.0.25"       # 指定主服务器的私网IP
  instance_charge_type = "PostPaid"           # 指定付费类型为按量付费
  spot_strategy        = "SpotWithPriceLimit" # 设置上限价格的抢占式实例
}

# 创建备服务器 
resource "alicloud_instance" "test_backup_instance" {
  instance_name        = "test_backup_instance_name"
  vswitch_id           = var.vswitch_id
  instance_type        = var.instance_type
  image_id             = var.image_id
  system_disk_category = "cloud_essd"
  security_groups      = [alicloud_security_group.test_security_group.id]
  user_data = base64encode(<<-EOT
    #!/bin/sh
    yum install keepalived -y

    printf '! Configuration File for keepalived
    vrrp_instance VI_1 {
        state BACKUP            # 设置为备实例
        interface eth0          # 绑定VIP的网卡,本示例配置为eth0  
        virtual_router_id 51    # 主备集群的virtual_router_id;同一VPC下的不同主备集群需要配置不同的virtual_router_id
        nopreempt               # 设置非抢占模式
        priority 10             # 设置优先级,数字越大,优先级越高;本示例配置优先级为10,将本实例设置为备实例
        advert_int 1            # 心跳报文发送间隔,单位为秒。设置过小,易受网络抖动影响,可能发生频繁倒换和暂时双主(即脑裂)。设置过大,可能导致主实例故障后,主备切换时间长
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        unicast_src_ip 192.168.0.26   # 本实例的私网IP地址,本示例配置为192.168.0.26
        unicast_peer {
            192.168.0.25          # 对端实例的私网IP地址,本示例配置为192.168.0.25。需声明所有对端实例的IP。每个地址单独占一行,无需逗号或其他分隔符。
        }
        virtual_ipaddress {
            192.168.0.24          # 虚拟IP地址,配置为HaVip的IP地址,本示例为192.168.0.24 
        }    
        garp_master_delay 1       # 当切为主实例后多久更新ARP缓存,单位为秒 
        garp_master_refresh 5     # 发送ARP报文的时间间隔,单位为秒 

        track_interface {
            eth0                  # 绑定VIP的网卡,本示例配置为eth0
        }
    }' > /etc/keepalived/keepalived.conf
    systemctl start keepalived
  EOT
  )                                           # 指定备服务器的初始化脚本,为备服务器安装keepalived
  private_ip           = "192.168.0.26"       # 指定备服务器的私网IP 
  instance_charge_type = "PostPaid"           # 指定付费类型为按量付费
  spot_strategy        = "SpotWithPriceLimit" # 设置上限价格的抢占式实例
}

# 绑定主服务器
resource "alicloud_havip_attachment" "test_havip_attachment" {
  ha_vip_id   = alicloud_havip.test_havip.id
  instance_id = alicloud_instance.test_master_instance.id # 指定HaVip关联的实例ID
}

# 绑定备服务器
resource "alicloud_havip_attachment" "test_havip_attachment_new" {
  ha_vip_id   = alicloud_havip.test_havip.id
  instance_id = alicloud_instance.test_backup_instance.id # 指定HaVip关联的实例ID
}

绑定 EIP 实现公网访问

HaVip 是交换机内的私网 IP 资源,如需公网访问,可以将 HaVip 与弹性公网IP(EIP)绑定。EIP 的使用会产生费用

1、绑定的 EIP 地域需和 HaVip 的地域相同,且处于可用状态。
2、ECS 实例借助 HaVip 绑定的 EIP 访问公网时,数据包的源 IP 为 HaVip 的私网IP,而非 ECS 实例的私网 IP。

控制台

绑定/解绑 EIP

绑定 EIP 前,确保已创建 EIP。可通过EIP 控制台创建 EIP,也可在绑定页面,单击创建弹性公网IP

在目标 HaVip 的操作列,单击绑定EIP解绑EIP,完成相应操作。

API

绑定 EIP 前,确保已调用AllocateEipAddress创建 EIP。

Terraform

Resource:alicloud_eip_addressalicloud_eip_association
# 指定HaVip所在地域 
provider "alicloud" {
  region = "cn-hangzhou"
}

# 指定HaVip的ID
variable "havip_id" {
  default = "havip-8vb0******"  # 修改为HaVip的实际ID
}

# 创建EIP
resource "alicloud_eip_address" "test_eip" {
  address_name = "test_eip_name"
  isp          = "BGP"
  netmode      = "public"
  bandwidth    = "1"
  payment_type = "PayAsYouGo"
}

# 绑定EIP
resource "alicloud_eip_association" "test_eip_havip_association" {
  allocation_id = alicloud_eip_address.test_eip.id
  instance_type = "HAVIP"
  instance_id   = var.havip_id # 指定HaVip的ID
}

更多信息

计费说明

HaVip 功能正在公测,可免费使用,但不承诺任何服务等级协议(SLA)相关的保障条款。

HaVip 绑定的云资源,如 ECS 实例EIP,将按其各自的计费规则独立计费。

支持的地域

公有云支持的地域

区域

支持高可用虚拟IP的地域

亚太-中国

华东1(杭州)华东2(上海)华东5 (南京-本地地域-关停中)华北1(青岛)华北2(北京)华北3(张家口)华北5(呼和浩特)华北6(乌兰察布)华南1(深圳)华南2(河源)华南3(广州)西南1(成都)中国香港华中1(武汉-本地地域)华东6(福州-本地地域-关停中)

亚太-其他

日本(东京)韩国(首尔)新加坡马来西亚(吉隆坡)印度尼西亚(雅加达)菲律宾(马尼拉)泰国(曼谷)

欧洲与美洲

德国(法兰克福)英国(伦敦)美国(硅谷)美国(弗吉尼亚)墨西哥

中东

阿联酋(迪拜)沙特(利雅得)- 合作伙伴运营

金融云支持的地域

区域

支持高可用虚拟IP的地域

亚太

华南1 金融云华东2 金融云华北2 金融云(邀测)

政务云支持的地域

区域

支持高可用虚拟IP的地域

亚太

华北2 阿里政务云1

配额

HaVip 功能正在公测,需登录阿里云配额中心控制台进行自助申请。

配额名称

描述

默认限制

提升配额

支持创建高可用虚拟IP(HaVip)的网络类型

VPC类型

无法提升

单个ECS实例支持同时绑定的HaVip数量

5

单个HaVip支持同时绑定的EIP数量

1

单个HaVip支持同时绑定的ECS实例或弹性网卡的数量

10

1、1HaVip支持同时绑定10ECS实例或同时绑定10个弹性网卡,但1HaVip不能同时绑定ECS实例和弹性网卡。
2、HaVip具有子网属性,仅支持绑定到同一交换机下的ECS实例或弹性网卡上。

HaVip是否支持广播和组播通信

不支持

HaVip只支持单播,如果您使用Keepalived等第三方软件实现高可用,需要修改配置文件中的通信方式为单播通信。

单个账号支持创建的HaVip的数量

50

单个VPC支持创建的HaVip的数量

50

vpc_quota_havip_custom_route_entry

单个路由表内,目的地址指向HaVip的路由条目的数量

5

前往配额管理页面配额中心申请提升配额。