0

我正在尝试创建一个 HEAT 模板,该模板将使用“allowed_address_pairs”和中子端口来支持类似于 VRRP 的应用程序实例之间共享的虚拟 IP 地址的概念。

我遵循了http://superuser.openstack.org/articles/implementing-high-availability-instances-with-neutron-using-vrrphttps://github.com/nvpnathan/heat/blob/中的示例master/allowed-address-pairs.yaml提出我自己的模板来实现这一点,它适用于单个虚拟 IP 地址。

这是该模板的外观:

heat_template_version: 2013-05-23

description: Simple template using allowed_address_pairs for a virtual IP

parameters:
  image:
    type: string
    label: Image name or ID
    description: Image to be used for compute instance
    default: "cirros"
  flavor:
    type: string
    label: Flavor
    description: Type of instance (flavor) to be used
    default: "t1.small"
  key:
    type: string
    label: Key name
    description: Name of key-pair to be used for compute instance
    default: "mykey"
  ext_network:
    type: string
    label: External network name or ID
    description: External network that can assign a floating IP
    default: "provider"
  test_virtual_ip:
    type: string
    label: Virtual IP address 
    description: Virtual IP address that can be used on different instances
    default: "192.168.10.101"


resources:
  # Create the internal test network
  test_net:
    type: OS::Neutron::Net
    properties:
      admin_state_up: true
      name: test_net

  # Create a subnet on the test network
  test_subnet:
    type: OS::Neutron::Subnet
    properties:
      name: test_subnet
      cidr: 192.168.10.2/24
      enable_dhcp: true
      allocation_pools: [{end: 192.168.10.99, start: 192.168.10.10}]
      gateway_ip: 192.168.10.1
      network_id: { get_resource: test_net }

  # Create router for the test network
  test_router:
    type: OS::Neutron::Router
    properties:
      admin_state_up: true
      name: test_router
      external_gateway_info: { "network": { get_param: ext_network }}

  # Create router interface and attach to subnet
  test_router_itf:
    type: OS::Neutron::RouterInterface
    properties:
      router_id: { get_resource: test_router }
      subnet_id: { get_resource: test_subnet }


  # Create extra port for a virtual IP address
  test_vip_port:
    type: OS::Neutron::Port
    properties:
      network_id: { get_resource: test_net }
      fixed_ips:
        - ip_address: { get_param: test_virtual_ip }


  # Create instance ports that have an internal IP and the virtual IP
  instance1_test_vip_port:
    type: OS::Neutron::Port
    properties:
      admin_state_up: true
      network_id: { get_resource: test_net }
      allowed_address_pairs:
        - ip_address: { get_param: test_virtual_ip}
      security_groups:
        - default

  # Create instances
  test_instance_1:
    type: OS::Nova::Server
    properties:
      name: instance1
      image: { get_param: image }
      flavor: { get_param: flavor }
      key_name: { get_param: key }
      networks:
        - port: { get_resource: instance1_test_vip_port }
      user_data_format: RAW
      user_data: |
        #cloud-config
        password: mysecret
        chpasswd: { expire: False }
        ssh_pwauth: True
        final_message: "The system is up after $UPTIME sec"

outputs:
  instance1_ip:
    description: IP address of the first instance
    value: { get_attr: [test_instance_1, first_address] }

到目前为止,一切都很好。现在我需要将其提升到一个新的水平,并分配多个 IP 地址,这些地址可以用作实例中的虚拟 IP。问题是实例启动时事先不知道需要多少个,所以它需要是一个参数,不能简单地硬编码为

- ip_address: {get_param: ip1}
- ip_address: {get_param: ip2}
and so on

换句话说,参数test_virtual_ip需要是 IP 地址列表而不是单个 IP 地址,例如“191.168.10.101, 192.168.10.102, 192.168.10.103”

这会影响test_vip_portinstance1_test_vip_port的定义,但我无法弄清楚正确的语法。

我试过这个:

# Create extra port for a virtual IP address
  test_vip_port:
    type: OS::Neutron::Port
    properties:
      network_id: { get_resource: test_net }
      fixed_ips: [{ get_param: test_virtual_ip }]

  # Create instance ports that have an internal IP and the virtual IP
  instance1_test_vip_port:
    type: OS::Neutron::Port
    properties:
      admin_state_up: true
      network_id: { get_resource: test_net }
      allowed_address_pairs: [{ get_param: test_virtual_ip}]
      security_groups:
        - default

但是当我尝试启动堆栈时出现错误“unicode object has no attribute get”。

将 IP 地址列表作为参数提供给OS::Neutron::Port::fixed_ipsOS::Neutron::Port::allowed_address_pairs的正确语法是什么?

4

1 回答 1

1

我能够开始工作的唯一解决方案是使用 repeat/for_each 构造并将参数定义为 comma_delimited_list,如下所示:

  test_virtual_ip:
    type: comma_delimited_list
    label: Virtual IP address
    description: Virtual IP address that can be used on different instances
    default: "192.168.10.101,192.168.10.102"

  test_vip_port:
    type: OS::Neutron::Port
    properties:
      network_id: { get_resource: test_net }
      fixed_ips:
        repeat:
          for_each:
            <%ipaddr%>: {get_param: test_virtual_ip}
          template:
            ip_address: <%ipaddr%>

这个工作的几个细节:

  • 您的 heat 模板版本必须支持 repeat/for_each 构造,我使用 heat_template_version: 2016-04-08
  • 不要在 IP 地址列表中包含任何空格,否则您将收到验证错误。
于 2016-08-03T18:08:09.397 回答