2月技术周 | Rocky Octavia 实现与分析 (三): 核心资源创建流程

前言

这是《OpenStack Rocky Octavia 实现与分析》系列的第三篇,主要关注 Octavia 核心资源对象的(Listener、Pool、Member、L7Policy、L7Rule、HeathMonitor)创建流程,在分析其创建流程的过程中我们可以感受到不同资源对象在 LBaaS 中所起到的作用。


listener 创建流程分析

create listener flow 的 UML 图

2月技术周 | Rocky Octavia 实现与分析 (三): 核心资源创建流程

从上图可知,执行指令 openstack loadbalancer listener create--protocol HTTP--protocol-port8080lb-1 创建 Listener 时会执行到 Task:ListenersUpdate,在该任务中,AmphoraAPIClient 会调用:

  • PUT listeners/{amphora_id}/{listener_id}/haproxy:更新 haproxy 配置文件

  • PUT listeners/{listener_id}/reload 重启 haproxy 服务进程

所以,只有当为 loadbalancer 创建 listener 时才会启动 haproxy 服务进程。还有一点补充的是创建 Listener 时也会执行 Task:UpdateVIP,这是因为 Lisenter 含有的协议及端口信息都需要被更新到 VIP 的安全组规则中。

启动 haproxy 服务进程

登录 amphora 查看 haproxy 的配置文件:

  1. # file: /var/lib/octavia/1385d3c4-615e-4a92-aea1-c4fa51a75557/haproxy.cfg, Listener UUID: 1385d3c4-615e-4a92-aea1-c4fa51a75557


  2. # Configuration for loadbalancer 01197be7-98d5-440d-a846-cd70f52dc503

  3. global

  4.    daemon

  5.    user nobody

  6.    log /dev/log local0

  7.    log /dev/log local1 notice

  8.    stats socket /var/lib/octavia/1385d3c4-615e-4a92-aea1-c4fa51a75557.sock mode 0666 level user

  9.    maxconn 1000000


  10. defaults

  11.    log global

  12.    retries 3

  13.    option redispatch


  14. peers 1385d3c4615e4a92aea1c4fa51a75557_peers

  15.    peer l_Ustq0qE-h-_Q1dlXLXBAiWR8U 172.16.1.7:1025

  16.    peer O08zAgUhIv9TEXhyYZf2iHdxOkA 172.16.1.3:1025



  17. frontend 1385d3c4-615e-4a92-aea1-c4fa51a75557

  18.    option httplog

  19.    maxconn 1000000

  20.    bind 172.16.1.10:8080

  21.    mode http

  22.    timeout client 50000

因为 Listener 指定了监听 HTTP 协议和端口 8080,所以 frontend section 也被渲染了的 bind172.16.1.10:8080mode http 配置项。

在 Amphora 操作系统启动的 haproxy 进程是 haproxy-1385d3c4-615e-4a92-aea1-c4fa51a75557.service(ListenerUUID:1385d3c4-615e-4a92-aea1-c4fa51a75557),查看该进程的 service 配置:

  1. # file: /usr/lib/systemd/system/haproxy-1385d3c4-615e-4a92-aea1-c4fa51a75557.service


  2. [Unit]

  3. Description=HAProxy Load Balancer

  4. After=network.target syslog.service amphora-netns.service

  5. Before=octavia-keepalived.service

  6. Wants=syslog.service

  7. Requires=amphora-netns.service


  8. [Service]

  9. # Force context as we start haproxy under "ip netns exec"

  10. SELinuxContext=system_u:system_r:haproxy_t:s0


  11. Environment="CONFIG=/var/lib/octavia/1385d3c4-615e-4a92-aea1-c4fa51a75557/haproxy.cfg" "USERCONFIG=/var/lib/octavia/haproxy-default-user-group.conf" "PIDFILE=/var/lib/octavia/1385d3c4-615e-4a92-aea1-c4fa51a75557/1385d3c4-615e-4a92-aea1-c4fa51a75557.pid"


  12. ExecStartPre=/usr/sbin/haproxy -f $CONFIG -f $USERCONFIG -c -q -L O08zAgUhIv9TEXhyYZf2iHdxOkA


  13. ExecReload=/usr/sbin/haproxy -c -f $CONFIG -f $USERCONFIG -L O08zAgUhIv9TEXhyYZf2iHdxOkA

  14. ExecReload=/bin/kill -USR2 $MAINPID


  15. ExecStart=/sbin/ip netns exec amphora-haproxy /usr/sbin/haproxy-systemd-wrapper -f $CONFIG -f $USERCONFIG -p $PIDFILE -L O08zAgUhIv9TEXhyYZf2iHdxOkA


  16. KillMode=mixed

  17. Restart=always

  18. LimitNOFILE=2097152


  19. [Install]

  20. WantedBy=multi-user.target

从配置内容可以看出实际启动的服务为 /usr/sbin/haproxy-systemd-wrapper,同样运行在 namespace amphora-haproxy 中,从日志可以了解到它所做的事情就是调用了 /usr/sbin/haproxy 指令而已:

  1. Nov 15 10:12:01 amphora-cd444019-ce8f-4f89-be6b-0edf76f41b77 ip[13206]: haproxy-systemd-wrapper: executing /usr/sbin/haproxy -f /var/lib/octavia/1385d3c4-615e-4a92-aea1-c4fa51a75557/haproxy.cfg -f /var/lib/octavia/haproxy-default-user-group.conf -p /var/lib/octavia/1385d3c4-615e-4a92-aea1-c4fa51a75557/1385d3c4-615e-4a92-aea1-c4fa51a75557.pid -L O08zAgUhIv9TEXhyYZf2iHdxOkA -Ds

除了 Listener 之外,Pool、Member、L7policy、L7rule 以及 Health Monitor 等对象的创建也会影响 haproxy 配置的变更。

pool 创建流程分析

create pool flow 的 UML 图

2月技术周 | Rocky Octavia 实现与分析 (三): 核心资源创建流程

create pool flow 最关键的任务依然是 Task:ListenersUpdate,更新 haproxy 的配置文件。当执行指令 openstack loadbalancer pool create--protocol HTTP--lb-algorithm ROUND_ROBIN--listener1385d3c4-615e-4a92-aea1-c4fa51a75557 为 listener 创建一个 default pool,haproxy.cfg 就会添加一个 backend section,并且根据指令传入的参数渲染 backend mode httpbalance roundrobin 配置项。

  1. # Configuration for loadbalancer 01197be7-98d5-440d-a846-cd70f52dc503

  2. global

  3.    daemon

  4.    user nobody

  5.    log /dev/log local0

  6.    log /dev/log local1 notice

  7.    stats socket /var/lib/octavia/1385d3c4-615e-4a92-aea1-c4fa51a75557.sock mode 0666 level user

  8.    maxconn 1000000


  9. defaults

  10.    log global

  11.    retries 3

  12.    option redispatch


  13. peers 1385d3c4615e4a92aea1c4fa51a75557_peers

  14.    peer l_Ustq0qE-h-_Q1dlXLXBAiWR8U 172.16.1.7:1025

  15.    peer O08zAgUhIv9TEXhyYZf2iHdxOkA 172.16.1.3:1025



  16. frontend 1385d3c4-615e-4a92-aea1-c4fa51a75557

  17.    option httplog

  18.    maxconn 1000000

  19.    bind 172.16.1.10:8080

  20.    mode http

  21.    default_backend 8196f752-a367-4fb4-9194-37c7eab95714       # UUID of pool

  22.    timeout client 50000


  23. backend 8196f752-a367-4fb4-9194-37c7eab95714

  24.    mode http

  25.    balance roundrobin

  26.    fullconn 1000000

  27.    option allbackups

  28.    timeout connect 5000

  29.    timeout server 50000

值得注意的是,创建 pool 时可以指定一个 listener uuid 或 loadbalancer uuid。当指定了前者时,意味着为 listener 指定了一个 default pool,listener 只能有一个 default pool,后续重复指定 default pool 则会触发异常;当指定了 loadbalancer uuid 时,则创建了一个 shared pool。shared pool 能被同属一个 loadbalancer 下的所有 listener 共享,常被用于辅助实现 l7policy 的功能。当 listener 的 l7policy 动作被设定为为「转发至另一个 pool」时,此时就可以选定一个 shared pool。shared pool 可以接受同属 loadbalancer 下所有 listener 的转发请求。执行指令创建一个 shared pool:

  1. $ openstack loadbalancer pool create --protocol HTTP --lb-algorithm ROUND_ROBIN --loadbalancer 01197be7-98d5-440d-a846-cd70f52dc503

  2. +---------------------+--------------------------------------+

  3. | Field               | Value                                |

  4. +---------------------+--------------------------------------+

  5. | admin_state_up      | True                                 |

  6. | created_at          | 2018-11-20T03:35:08                  |

  7. | description         |                                      |

  8. | healthmonitor_id    |                                      |

  9. | id                  | 822f78c3-ea2c-4770-bef0-e97f1ac2eba8 |

  10. | lb_algorithm        | ROUND_ROBIN                          |

  11. | listeners           |                                      |

  12. | loadbalancers       | 01197be7-98d5-440d-a846-cd70f52dc503 |

  13. | members             |                                      |

  14. | name                |                                      |

  15. | operating_status    | OFFLINE                              |

  16. | project_id          | 9e4fe13a6d7645269dc69579c027fde4     |

  17. | protocol            | HTTP                                 |

  18. | provisioning_status | PENDING_CREATE                       |

  19. | session_persistence | None                                 |

  20. | updated_at          | None                                 |

  21. +---------------------+--------------------------------------+

注意,单纯的创建 shared pool 不将其绑定到 listener 的话,haproxy.cfg 配置文件是不会立即更改的。

member 创建流程分析

使用下述指令创建一个 member 到 default pool,选项指定云主机所在的 subnet、ipaddress 以及接收数据转发的 protocol-port。

  1. [root@control01 ~]# openstack loadbalancer member create --subnet-id 2137f3fb-00ee-41a9-b66e-06705c724a36 --address 192.168.1.14 --protocol-port 80 8196f752-a367-4fb4-9194-37c7eab95714

  2. +---------------------+--------------------------------------+

  3. | Field               | Value                                |

  4. +---------------------+--------------------------------------+

  5. | address             | 192.168.1.14                         |

  6. | admin_state_up      | True                                 |

  7. | created_at          | 2018-11-20T06:09:58                  |

  8. | id                  | b6e464fd-dd1e-4775-90f2-4231444a0bbe |

  9. | name                |                                      |

  10. | operating_status    | NO_MONITOR                           |

  11. | project_id          | 9e4fe13a6d7645269dc69579c027fde4     |

  12. | protocol_port       | 80                                   |

  13. | provisioning_status | PENDING_CREATE                       |

  14. | subnet_id           | 2137f3fb-00ee-41a9-b66e-06705c724a36 |

  15. | updated_at          | None                                 |

  16. | weight              | 1                                    |

  17. | monitor_port        | None                                 |

  18. | monitor_address     | None                                 |

  19. | backup              | False                                |

  20. +---------------------+--------------------------------------+

在 octavia-api 层先会通过配置 CONF.networking.reserved_ips 验证该 member 的 ipaddress 是否可用,验证 member 所在的 subnet 是否存在,然后再进入 octavia-worker 的流程。

2月技术周 | Rocky Octavia 实现与分析 (三): 核心资源创建流程

下面展开几个关键的 TASKs。

CalculateDelta

TASK:CalculateDelta 轮询 loadbalancer 下属的 Amphorae 执行 Task:CalculateAmphoraDelta,计算 Amphora 现有的 NICs 集合与预期需要的 NICs 集合之间的 “差值”。

  1. # file: /opt/rocky/octavia/octavia/controller/worker/tasks/network_tasks.py



  2. class CalculateAmphoraDelta(BaseNetworkTask):


  3.    default_provides = constants.DELTA


  4.    def execute(self, loadbalancer, amphora):

  5.        LOG.debug("Calculating network delta for amphora id: %s", amphora.id)


  6.        # Figure out what networks we want

  7.        # seed with lb network(s)

  8.        vrrp_port = self.network_driver.get_port(amphora.vrrp_port_id)

  9.        desired_network_ids = {vrrp_port.network_id}.union(

  10.            CONF.controller_worker.amp_boot_network_list)


  11.        for pool in loadbalancer.pools:

  12.            member_networks = [

  13.                self.network_driver.get_subnet(member.subnet_id).network_id

  14.                for member in pool.members

  15.                if member.subnet_id

  16.            ]

  17.            desired_network_ids.update(member_networks)


  18.        nics = self.network_driver.get_plugged_networks(amphora.compute_id)

  19.        # assume we don't have two nics in the same network

  20.        actual_network_nics = dict((nic.network_id, nic) for nic in nics)


  21.        del_ids = set(actual_network_nics) - desired_network_ids

  22.        delete_nics = list(

  23.            actual_network_nics[net_id] for net_id in del_ids)


  24.        add_ids = desired_network_ids - set(actual_network_nics)

  25.        add_nics = list(n_data_models.Interface(

  26.            network_id=net_id) for net_id in add_ids)

  27.        delta = n_data_models.Delta(

  28.            amphora_id=amphora.id, compute_id=amphora.compute_id,

  29.            add_nics=add_nics, delete_nics=delete_nics)

  30.        return delta

简单的说,首先得到预期需要的 desirednetworkids 和已经存在的 actualnetworknics。然后计算出待删除的 deletenics 和待添加的 addnics,并最终 returns 一个 Delta data models 到 Task:HandleNetworkDeltas 执行实际的 Amphora NICs 挂载和卸载。

HandleNetworkDeltas

Task:HandleNetworkDelta 负载基于 Amphora Delta 挂载和卸载 networks。

  1. # file: /opt/rocky/octavia/octavia/controller/worker/tasks/network_tasks.py



  2. class HandleNetworkDelta(BaseNetworkTask):

  3.    """Task to plug and unplug networks


  4.    Plug or unplug networks based on delta

  5.    """


  6.    def execute(self, amphora, delta):

  7.        """Handle network plugging based off deltas."""

  8.        added_ports = {}

  9.        added_ports[amphora.id] = []

  10.        for nic in delta.add_nics:

  11.            interface = self.network_driver.plug_network(delta.compute_id,

  12.                                                         nic.network_id)

  13.            port = self.network_driver.get_port(interface.port_id)

  14.            port.network = self.network_driver.get_network(port.network_id)

  15.            for fixed_ip in port.fixed_ips:

  16.                fixed_ip.subnet = self.network_driver.get_subnet(

  17.                    fixed_ip.subnet_id)

  18.            added_ports[amphora.id].append(port)

  19.        for nic in delta.delete_nics:

  20.            try:

  21.                self.network_driver.unplug_network(delta.compute_id,

  22.                                                   nic.network_id)

  23.            except base.NetworkNotFound:

  24.                LOG.debug("Network %d not found ", nic.network_id)

  25.            except Exception:

  26.                LOG.exception("Unable to unplug network")

  27.        return added_ports

最后返回 added_port return 给后续的 TASK:AmphoraePostNetworkPlug 使用。

AmphoraePostNetworkPlug

Task:AmphoraePostNetworkPlug 负责将 member 所处网络的 port 的信息注入到 network namespace 中。需要注意区分 AmphoraePostNetworkPlug 与 AmphoraePostVIPPlug,前者在 create menber flow 中生效,用于添加连通 member tenant-net 的 interface;后者在 create lb flow 中生效,用于添加连通 vip-net 的 interface。当然了,如果说 member 与 VIP 来自同一个网络,则不再需要为 amphora 添加新的 inferface 了。

2月技术周 | Rocky Octavia 实现与分析 (三): 核心资源创建流程

添加 member 之后再次查看 Amphora 的网络情况:

  1. root@amphora-cd444019-ce8f-4f89-be6b-0edf76f41b77:~# ip netns exec amphora-haproxy ifconfig

  2. eth1      Link encap:Ethernet  HWaddr fa:16:3e:f4:69:4b

  3.          inet addr:172.16.1.3  Bcast:172.16.1.255  Mask:255.255.255.0

  4.          inet6 addr: fe80::f816:3eff:fef4:694b/64 Scope:Link

  5.          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1

  6.          RX packets:12705 errors:0 dropped:0 overruns:0 frame:0

  7.          TX packets:613211 errors:0 dropped:0 overruns:0 carrier:0

  8.          collisions:0 txqueuelen:1000

  9.          RX bytes:762300 (762.3 KB)  TX bytes:36792968 (36.7 MB)


  10. eth1:0    Link encap:Ethernet  HWaddr fa:16:3e:f4:69:4b

  11.          inet addr:172.16.1.10  Bcast:172.16.1.255  Mask:255.255.255.0

  12.          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1


  13. eth2      Link encap:Ethernet  HWaddr fa:16:3e:18:23:7a

  14.          inet addr:192.168.1.3  Bcast:192.168.1.255  Mask:255.255.255.0

  15.          inet6 addr: fe80::f816:3eff:fe18:237a/64 Scope:Link

  16.          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1

  17.          RX packets:8 errors:2 dropped:0 overruns:0 frame:2

  18.          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0

  19.          collisions:0 txqueuelen:1000

  20.          RX bytes:2156 (2.1 KB)  TX bytes:808 (808.0 B)

配置文件如下:

  1. # Generated by Octavia agent

  2. auto eth2

  3. iface eth2 inet static

  4. address 192.168.1.3

  5. broadcast 192.168.1.255

  6. netmask 255.255.255.0

  7. mtu 1450

  8. post-up /sbin/iptables -t nat -A POSTROUTING -p udp -o eth2 -j MASQUERADE

  9. post-down /sbin/iptables -t nat -D POSTROUTING -p udp -o eth2 -j MASQUERADE

ListenersUpdate

最后 haproxy 配置的变更依旧是由 Task:ListenersUpdate 完成。

  1. # Configuration for loadbalancer 01197be7-98d5-440d-a846-cd70f52dc503

  2. global

  3.    daemon

  4.    user nobody

  5.    log /dev/log local0

  6.    log /dev/log local1 notice

  7.    stats socket /var/lib/octavia/1385d3c4-615e-4a92-aea1-c4fa51a75557.sock mode 0666 level user

  8.    maxconn 1000000


  9. defaults

  10.    log global

  11.    retries 3

  12.    option redispatch


  13. peers 1385d3c4615e4a92aea1c4fa51a75557_peers

  14.    peer l_Ustq0qE-h-_Q1dlXLXBAiWR8U 172.16.1.7:1025

  15.    peer O08zAgUhIv9TEXhyYZf2iHdxOkA 172.16.1.3:1025



  16. frontend 1385d3c4-615e-4a92-aea1-c4fa51a75557

  17.    option httplog

  18.    maxconn 1000000

  19.    bind 172.16.1.10:8080

  20.    mode http

  21.    default_backend 8196f752-a367-4fb4-9194-37c7eab95714

  22.    timeout client 50000


  23. backend 8196f752-a367-4fb4-9194-37c7eab95714

  24.    mode http

  25.    balance roundrobin

  26.    fullconn 1000000

  27.    option allbackups

  28.    timeout connect 5000

  29.    timeout server 50000

  30.    server b6e464fd-dd1e-4775-90f2-4231444a0bbe 192.168.1.14:80 weight 1

实际上,添加 member 就是在 backend(default pool)中加入了 server<member_id>192.168.1.14:80weight1 项目,表示该云主机作为了 default pool 的一部分。

L7policy & L7rule & Health Monitor 的创建流程分析

L7policy 对象的语义是用于描述转发的动作类型(e.g. 转发至 pool、转发至 URL 或拒绝转发)以及 L7rule 的容器,下属于 Listener。

2月技术周 | Rocky Octavia 实现与分析 (三): 核心资源创建流程

L7Rule 对象的语义是数据转发的匹配域,描述了转发的路由关系,下属于 L7policy。

2月技术周 | Rocky Octavia 实现与分析 (三): 核心资源创建流程

Health Monitor 对象用于对 Pool 中 Member 的健康状态进行监控,本质就是一条数据库记录,描述了健康检查的的规则,下属于 Pool。

2月技术周 | Rocky Octavia 实现与分析 (三): 核心资源创建流程

为什么将三者一同分析?从上述三个 UML 图可以感受到 Create L7policy、L7rule、Health-Monitor 和 Pool 实际上是非常类似,关键都是在于 TASK:ListenersUpdate 对 haproxy 配置文件内容的更新。所以,我们主要通过一些例子来观察 haproxy 配置文件的更改规律即可。

EXAMPLE 1. 转发至 default pool

  1. $ openstack loadbalancer healthmonitor create --name healthmonitor1 --type PING --delay 5 --timeout 10 --max-retries 3 8196f752-a367-4fb4-9194-37c7eab95714


  2. $ openstack loadbalancer l7policy create --name l7p1 --action REDIRECT_TO_POOL --redirect-pool 8196f752-a367-4fb4-9194-37c7eab95714 1385d3c4-615e-4a92-aea1-c4fa51a75557


  3. $ openstack loadbalancer l7rule create --type HOST_NAME --compare-type STARTS_WITH --value "server" 87593985-e02f-4880-b80f-22a4095c05a7

haproxy.cfg:

  1. # Configuration for loadbalancer 01197be7-98d5-440d-a846-cd70f52dc503

  2. global

  3.    daemon

  4.    user nobody

  5.    log /dev/log local0

  6.    log /dev/log local1 notice

  7.    stats socket /var/lib/octavia/1385d3c4-615e-4a92-aea1-c4fa51a75557.sock mode 0666 level user

  8.    maxconn 1000000

  9.    external-check


  10. defaults

  11.    log global

  12.    retries 3

  13.    option redispatch


  14. peers 1385d3c4615e4a92aea1c4fa51a75557_peers

  15.    peer l_Ustq0qE-h-_Q1dlXLXBAiWR8U 172.16.1.7:1025

  16.    peer O08zAgUhIv9TEXhyYZf2iHdxOkA 172.16.1.3:1025



  17. frontend 1385d3c4-615e-4a92-aea1-c4fa51a75557

  18.    option httplog

  19.    maxconn 1000000

  20.    # 前端监听 http://172.16.1.10:8080

  21.    bind 172.16.1.10:8080

  22.    mode http

  23.        # ACL 转发规则

  24.        acl 8d9b8b1e-83d7-44ca-a5b4-0103d5f90cb9 req.hdr(host) -i -m beg server

  25.    # if ACL 8d9b8b1e-83d7-44ca-a5b4-0103d5f90cb9 满足,则转发至 backend 8196f752-a367-4fb4-9194-37c7eab95714

  26.    use_backend 8196f752-a367-4fb4-9194-37c7eab95714 if 8d9b8b1e-83d7-44ca-a5b4-0103d5f90cb9

  27.    # 如果没有匹配到任何 ACL 规则,则转发至默认 backend 8196f752-a367-4fb4-9194-37c7eab95714

  28.    default_backend 8196f752-a367-4fb4-9194-37c7eab95714

  29.    timeout client 50000


  30. backend 8196f752-a367-4fb4-9194-37c7eab95714

  31.    # 后端监听协议为 http

  32.    mode http

  33.    # 负载均衡算法为 RR 轮询

  34.    balance roundrobin

  35.    timeout check 10s

  36.    option external-check

  37.    # 使用脚本 ping-wrapper.sh 对 server 进行健康检查

  38.    external-check command /var/lib/octavia/ping-wrapper.sh

  39.    fullconn 1000000

  40.    option allbackups

  41.    timeout connect 5000

  42.    timeout server 50000

  43.    # 后端真实服务器(real server),服务端口为 80,监控检查规则为 inter 5s fall 3 rise 3

  44.    server b6e464fd-dd1e-4775-90f2-4231444a0bbe 192.168.1.14:80 weight 1 check inter 5s fall 3 rise 3

健康检查脚本,正如我们设定的 PING 方式:

  1. #!/bin/bash

  2. if [[ $HAPROXY_SERVER_ADDR =~ ":" ]]; then

  3.    /bin/ping6 -q -n -w 1 -c 1 $HAPROXY_SERVER_ADDR > /dev/null 2>&1

  4. else

  5.    /bin/ping -q -n -w 1 -c 1 $HAPROXY_SERVER_ADDR > /dev/null 2>&1

  6. fi

EXAMPLE 2. 转发至 shared pool

  1. $ openstack loadbalancer healthmonitor create --name healthmonitor1 --type PING --delay 5 --timeout 10 --max-retries 3 822f78c3-ea2c-4770-bef0-e97f1ac2eba8


  2. $ openstack loadbalancer l7policy create --name l7p1 --action REDIRECT_TO_POOL --redirect-pool 822f78c3-ea2c-4770-bef0-e97f1ac2eba8 1385d3c4-615e-4a92-aea1-c4fa51a75557


  3. $ openstack loadbalancer l7rule create --type HOST_NAME --compare-type STARTS_WITH --value "server" fb90a3b5-c97c-4d99-973e-118840a7a236

haproxy.cfg:

  1. # Configuration for loadbalancer 01197be7-98d5-440d-a846-cd70f52dc503

  2. global

  3.    daemon

  4.    user nobody

  5.    log /dev/log local0

  6.    log /dev/log local1 notice

  7.    stats socket /var/lib/octavia/1385d3c4-615e-4a92-aea1-c4fa51a75557.sock mode 0666 level user

  8.    maxconn 1000000

  9.    external-check


  10. defaults

  11.    log global

  12.    retries 3

  13.    option redispatch


  14. peers 1385d3c4615e4a92aea1c4fa51a75557_peers

  15.    peer l_Ustq0qE-h-_Q1dlXLXBAiWR8U 172.16.1.7:1025

  16.    peer O08zAgUhIv9TEXhyYZf2iHdxOkA 172.16.1.3:1025



  17. frontend 1385d3c4-615e-4a92-aea1-c4fa51a75557

  18.    option httplog

  19.    maxconn 1000000

  20.    bind 172.16.1.10:8080

  21.    mode http

  22.        acl 8d9b8b1e-83d7-44ca-a5b4-0103d5f90cb9 req.hdr(host) -i -m beg server

  23.    use_backend 8196f752-a367-4fb4-9194-37c7eab95714 if 8d9b8b1e-83d7-44ca-a5b4-0103d5f90cb9

  24.        acl c76f36bc-92c0-4f48-8d57-a13e3b1f09e1 req.hdr(host) -i -m beg server

  25.    use_backend 822f78c3-ea2c-4770-bef0-e97f1ac2eba8 if c76f36bc-92c0-4f48-8d57-a13e3b1f09e1

  26.    default_backend 8196f752-a367-4fb4-9194-37c7eab95714

  27.    timeout client 50000


  28. backend 8196f752-a367-4fb4-9194-37c7eab95714

  29.    mode http

  30.    balance roundrobin

  31.    timeout check 10s

  32.    option external-check

  33.    external-check command /var/lib/octavia/ping-wrapper.sh

  34.    fullconn 1000000

  35.    option allbackups

  36.    timeout connect 5000

  37.    timeout server 50000

  38.    server b6e464fd-dd1e-4775-90f2-4231444a0bbe 192.168.1.14:80 weight 1 check inter 5s fall 3 rise 3


  39. backend 822f78c3-ea2c-4770-bef0-e97f1ac2eba8

  40.    mode http

  41.    balance roundrobin

  42.    timeout check 10s

  43.    option external-check

  44.    external-check command /var/lib/octavia/ping-wrapper.sh

  45.    fullconn 1000000

  46.    option allbackups

  47.    timeout connect 5000

  48.    timeout server 50000

  49.    server 7da6f176-36c6-479a-9d86-c892ecca6ae5 192.168.1.6:80 weight 1 check inter 5s fall 3 rise 3

可见,在为 listener 添加了 shared pool 之后,会在增加一个 backend section 对应 shared pool 822f78c3-ea2c-4770-bef0-e97f1ac2eba8。

最后

至此,系列三篇基本已经将 Octavia 的资源模型介绍完了,接下来主要会关注 Octavia 在高可用、通信安全、协议类型、性能上的实现细节,敬请关注!



关于九州云99Cloud

九州云成立于2012年,是中国早期从事开放基础架构服务的专业公司。公司成立六年,秉承“开源 · 赋能变革”的理念,不断夯实自身实力,先后为政府、金融、运营商、能源、制造业、商业、交通、物流、教育、医疗等各大行业的企业级客户提供高质量的开放基础架构服务。目前拥有国家电网、南方电网广东公司、中国人民银行、中国银联、中国移动、中国电信、中国联通、中国资源卫星、eBay、国际陆港集团、中国人寿、万达信息、东风汽车、诺基亚等众多重量级客户,被用户认可为最值得信赖的合作伙伴。

2月技术周 | Rocky Octavia 实现与分析 (三): 核心资源创建流程