OpenStack Heat模板学习二 之LBaaS(负载均衡即服务)


理解好了hello world HOT 模板,然后接下来就可以看【9】HOT的spec文档了,包括Structure,PGS,PS,RS,OS以及Intrinsic Functions
现在Heat支持的Resource类型可以在http://docs.openstack.org/developer/heat/template_guide/openstack.html上找到,下面主要探索advancedservices(LB,FW,VPN)的相关模板,需要在阅读[7]OpenStack Resource Types 以及[9]的前提下,才能了解下面模板的具体含义。

Loadbalancer 模板

接下来首先根据[13]下手做一个Loadbalancer模板,网络拓扑图如下:


“””如上图所示,我们的服务器网络的网址范围为10.0.0.0/24,负载均衡器网络的网址范围是192.168.40.0/24,public网络链接办公网络,网址范围是192.168.10.224/28。路由器链接了所有三个网络。public网络和路由器是通过路由器的网关臂(NeutronAPIroutergateway相连的。路由器把服务器网络和负载均衡器网络的IP地址SNAT成路由器的网关臂public网络的地址。这样他们就可以访问办公网络的IP啦。但是如果要想从办公网络访问服务器网络和负载均衡器网络,我们还需要动态地址(FloatingIP).”””引自[13]

Network 设备及拓扑

public_net: 192.168.10.224/28

lb_net:  192.168.40.0/24

server_net: 10.0.0.0/24

router: {

gateway: <from public_net>,

interface1: lb_net,

interface2: server_net

}

Router resource 要depends on public_net, lb_net以及server_net

根据以上信息:设置LB网络拓扑图模板network_topology.template如下,注意在这之前你可能需要清理网络拓扑环境,然后设置合适的br-ex配置(sudo ifconfig br-ex 192.168.10.225netmask 255.255.224.0 up),式能够访问public_net:

heat_template_version: 2013-05-23

 

description: >

    network topology deployment HOT template reference to

    http://www.ustack.com/blog/neutron_loadbalance/

 

parameters:

    public_net_name:

        type: string

        label: Public Network Name

        default: public_net

    lb_net_name:

        type: string

        label: Loadbalancer Network Name

        default: lb_net

    server_net_name:

        type: string

        label: Web Servers Network Name

        default: server_net

    public_subnet_name:

        type: string

        label: Public Subnet Name

        default: public_subnet

    public_subnet_cidr:

        type: string

        label: Public Subnet CIDR

        default: 192.168.10.224/28

    lb_subnet_name:

        type: string

        label: Loadbalancer Subnet Name

        default: lb_subnet

    lb_subnet_cidr:

        type: string

        label: Loadbalancer Subnet CIDR

        default: 192.168.40.0/24

    server_subnet_name:

        type: string

        label: Web Servers Subnet Name

        default: server_subnet

    server_subnet_cidr:

        type: string

        label: Web Servers Subnet CIDR

        default: 10.0.0.0/24

    router_name:

        type: string

        label: The Router Name

        default: router

 

outputs:

    lb_subnet_gateway:

        description: Loadbalancer Subnet Gateway

        value: {get_attr: [lb_subnet, gateway_ip]}

    lb_subnet_cidr:

        description: Loadbalancer Subnet CIDR

        value: {get_attr: [lb_subnet, cidr]}

    server_subnet_gateway:

        description: Web Servers Subnet Gateway

        value: {get_attr: [server_subnet, gateway_ip]}

    server_subnet_cidr:

        description: Web Servers Subnet CIDR

        value: {get_attr: [server_subnet, cidr]}

    

 

resources:

    public_net:

        type: OS::Neutron::Net

        properties:

            name: {get_param: public_net_name}

            shared: True

            value_specs: {"router:external": True}

    lb_net:

        type: OS::Neutron::Net

        properties:

            name: {get_param: lb_net_name}

    server_net:

        type: OS::Neutron::Net

        properties:

            name: {get_param: server_net_name}

    public_subnet:

        type: OS::Neutron::Subnet

        depends_on: public_net

        properties:

            name: {get_param: public_subnet_name}

            cidr: {get_param: public_subnet_cidr}

            network_id: {get_resource: public_net}

            enable_dhcp: False

    lb_subnet:

        type: OS::Neutron::Subnet

        depends_on: lb_net

        properties:

            name: {get_param: lb_subnet_name}

            cidr: {get_param: lb_subnet_cidr}

            network_id: {get_resource: lb_net}

    server_subnet:

        type: OS::Neutron::Subnet

        depends_on: server_net

        properties:

            name: {get_param: server_subnet_name}

            cidr: {get_param: server_subnet_cidr}

            network_id: {get_resource: server_net}

    router:

        type: OS::Neutron::Router

        depends_on: [public_net, public_subnet]

        properties:

            name: {get_param: router_name}

            external_gateway_info: {"network": {get_resource: public_net}}

    lb_interface:

        type: OS::Neutron::RouterInterface

        depends_on: [lb_subnet, router]

        properties:

            router_id: {get_resource: router}

            subnet_id: {get_resource: lb_subnet}

    server_interface:

        type: OS::Neutron::RouterInterface

        depends_on: [server_subnet, router]

        properties:

            router_id: {get_resource: router}

            subnet_id: {get_resource: server_subnet}

然后运行如下CLI命令,则自动生成相应的网络拓扑,省去不少命令行敲字,而且实验结束,直接heatstack-delete 掉即可。

#heat template-validate--template-file ./network_topology.template

#heat stack-create -f./network_topology.template lb-net-topology

网络拓扑用到的Resource资源如下:

OS::Neutron::Net: http://docs.openstack.org/developer/heat/template_guide/openstack.html#OS::Neutron::Net

OS::Neutron::Subnet:

http://docs.openstack.org/developer/heat/template_guide/openstack.html#OS::Neutron::Subnet

OS::Neutron::Router:

http://docs.openstack.org/developer/heat/template_guide/openstack.html#OS::Neutron::Router

接下来开始部署LB了, 主要有下面个资源:

Pool:

VIP:

Floating IP for VIP

HealthMonitor:

2 Pool Member instances (内部运行简单的web server):

根据以上信息设计LB模板如下:

heat_template_version: 2013-05-23

 

description: >

    LB service deployment HOT template reference to

    http://www.ustack.com/blog/neutron_loadbalance/

 

parameters:

    image_name:

        type: string   

        label: Image Name

        description: Image to be used for compute instance

        default: cirros-0.3.0-i386-uec

    instance_type:

        type: string

        label: Instance Type

        description: Type of instance (flavor) to be used

        default: m1.tiny

    health_monitor_type:

        type: string

        label: Type of HealthMonitor

        constraints:

            - allowed_values: [PING, TCP, HTTP, HTTPS]

        default: HTTP

    pool_name:

        type: string

        label: The Name of Pool

        default: pool

    lb_method:

        type: string

        label: The Algorithm used to distribute load between the memebers of pool

        constraints:

            - allowed_values: [ROUND_ROBIN, LEAST_CONNECTIONS, SOURCE_IP]

        default: ROUND_ROBIN

    pool_protocol:

        type: string

        label: Protocol for Pool Balancing

        constraints:

            - allowed_values: [HTTP, HTTPS, TCP]

        default: HTTP

    lb_subnet_id:

        type: string

        label: Loadbalancer Subnet uuid

    vip_name:

        type: string

        label: Name of VIP

        default: vip

    vip_address:

        type: string

        label: Address of VIP which must be within lb_subnet

    session_persistence_type:

        type: string

        label: Session Persistence Type

        constraints:

            - allowed_values: [SOURCE_IP, HTTP_COOKIE, APP_COOKIE]

        default: HTTP_COOKIE

    vip_protocol_port:

        type: number

        label: VIP protocol port

        default: 8080

    member_protocol_port:

        type: number

        label: Member protocol port

        default: 8080

    public_net_id:

        type: string

        label: Public Network uuid

    server_net_id:

        type: string

        label: Web Servers Network uuid

 

 

outputs:

    vip_floating_ip:

        description: FloatingIP of VIP

        value: {get_attr: [floatingip, floating_ip_address]}

    member1_ip_address:

        description: IP address of member1

        value: {get_attr: [member1, first_address]}

    member2_ip_address:

        description: IP address of member2

        value: {get_attr: [member2, first_address]}

    vip:

        description: VIP info

        value: {get_attr: [pool, vip]}

    lb_keypair_private_key:

        description: private key of KeyPair for 'ssh-add use'

        value: {get_attr: [lb_keypair, private_key]}

    

 

resources:

    lb_keypair:

        type: OS::Nova::KeyPair

        properties:

            name: lb_keypair

            save_private_key: True

    health_monitor:

        type: OS::Neutron::HealthMonitor

        properties:

            delay: 10

            expected_codes: "200"

            http_method: GET

            max_retries: 3

            timeout: 20

            type: {get_param: health_monitor_type}

            url_path: /

    pool:

        type: OS::Neutron::Pool

        depends_on: health_monitor

        properties:

            admin_state_up: False

            name: {get_param: pool_name}

            lb_method: {get_param: lb_method}

            protocol: {get_param: pool_protocol}

            monitors: [{get_resource: health_monitor}]

            subnet_id: {get_param: lb_subnet_id}

            vip:

                session_persistence:

                    type: {get_param: session_persistence_type}

                name: {get_param: vip_name}

                address: {get_param: vip_address}

                protocol_port: {get_param: vip_protocol_port}

    member1:

        type: OS::Nova::Server

        properties:

            name: server1

            key_name: {get_resource: lb_keypair}

            image: {get_param: image_name}

            flavor: {get_param: instance_type}

            networks:

                - {network: {get_param: server_net_id}}

    member2:

        type: OS::Nova::Server

        properties:

            name: server2

            key_name: {get_resource: lb_keypair}

            image: {get_param: image_name}

            flavor: {get_param: instance_type}

            networks:

                - {network: {get_param: server_net_id}}

    pool_member1:

        type: OS::Neutron::PoolMember

        depends_on: [pool, member1]

        properties:

            address: {get_attr: [member1, first_address]}

            pool_id: {get_resource: pool}

            protocol_port: {get_param: member_protocol_port}

            weight: 100

    pool_member2:

        type: OS::Neutron::PoolMember

        depends_on: [pool, member2]

        properties:

            address: {get_attr: [member2, first_address]}

            pool_id: {get_resource: pool}

            protocol_port: {get_param: member_protocol_port}

            weight: 100

    floatingip:

        type: OS::Neutron::FloatingIP

        depends_on: pool

        properties:

            fixed_ip_address: {get_param: vip_address}

            floating_network_id: {get_param: public_net_id}

            port_id: {get_attr: [pool, vip, port_id]}

然后运行如下命令部署lb模板:

stack@vm:~/hot-files$  heat stack-create lbaas -f ./lbaas.template -P"public_net_id=842a7996-b8ca-4f75-8bfa-72d930780694;lb_subnet_id=f33b03a9-0f39-4c25-a9fa-94d63042f206;server_net_id=33c2e2db-121f-489e-bdc0-06d091472727;vip_address=192.168.40.3"

Note: 可能注意到了现在Poo的admin_state_up是False状态,这是由于LBaaS Haproxy的一个bug,如果不设置,会导致vip直接返回Error,导致Heat模板运行中断,所以暂时设置为False,等部署好后,再打开admin_state_up,打开后发现Member是INACTIVE状态的,因为现在member还没有开启web server,我用很多方法试图用String,template,以及get_file将user_data注入到VM中,但不知道为什么都失败了,所以你只能自己进到VM中启动一个简单的web服务器了,我的如下所示:

$ while true

> do

> echo -e 'HTTP/1.0 200 OK\r\n\r\n<serverX>' | nc -l -p 8080

> done

启动后就看到Member变为ACTIVE状态了。

拿到VIP的floatingIP,然后就可以测试LB的运行状态了,结果如下:


LB成功运行!

 

另外: Keypair的用法:你可以import a keypair,将你的操作console的public key引入,也可以像上面lb模板创建一个keypair,然后将lb_private_key保存到一个文件(lb_private_key.pem)中,然后给VM加一个floatingIP

#eval `ssh-agent`

#ssh-add lb_private_key.pem

然后你就可以通过ssh访问VM了,其他可以进noVNC界面对VM进行相关操作。

LB模板用到的resources有: OS::Nova::Server, OS::Nova::KeyPair, OS::Neutron::Pool, OS::Neutron::PoolMember, OS::Neutron::HealthMonitor, OS::Neutron::FloatingIP

VPNaaS模板

未完待续。。。

FWaaS模板

未完待续。。。

用到的不方便的地方

1.      Template查错功能有待提高,阐释不清楚或者错误张冠李戴

2.      没有类似于action-continue –force的功能,比如LBaaS创建的VIP状态返回error是由于haproxy内部的一个bug,这类人类可控的错误希望能够just 忽略掉然后继续运行。

3.      不知道为什么,用heat一直不能把user_data注入VM中

Link

[1] Heat Wiki:https://wiki.openstack.org/wiki/Heat

[2] OpenStack G 版孵化项目heat介绍:http://blog.csdn.net/wangyish201201/article/details/8933581

[3] OpenStack Heat进阶:http://blog.csdn.net/lynn_kong/article/details/17195047

[4] OpenStack heat getting started guides: http://docs.openstack.org/developer/heat/getting_started/index.html

介绍安装heat的几种方法以及如何构建JEOS镜像(os with heat-cfntools package)

[5] *Heat 开发者文档:http://docs.openstack.org/developer/heat/

[6] Heat 术语表:http://docs.openstack.org/developer/heat/glossary.html

[7] *template Guide: http://docs.openstack.org/developer/heat/template_guide/index.html

[8] HOT template Guide: http://docs.openstack.org/developer/heat/template_guide/hot_guide.html

[9] *HOT template spec in detail: http://docs.openstack.org/developer/heat/template_guide/hot_spec.html

[10] Yaml: http://www.ibm.com/developerworks/cn/xml/x-1103linrr/

[11] My first OpenStack heat template: http://openstack.prov12n.com/my-first-openstack-heat-template/

[12] 龚永生:Neutron防火墙:http://www.ustack.com/blog/neutron-firewall/

[13] 龚永生: Neutron负载均衡:http://www.ustack.com/blog/neutron_loadbalance/

[14] CirrOS: https://www.eucalyptus.com/blog/2014/02/02/cirros-perfect-machine


相关内容

    暂无相关文章