目录

从 Octavia API 看起

通过 CLI 创建一个 loadbalancer

(octavia_env) [root@control01 ~]# openstack loadbalancer create --vip-subnet-id 122056f4-0fad-4ab2-bdf9-9b0942d0b213 --name lb1 --debug

Create LB 的 Octavia API UML 图

其中 2. _validate_vip_request_object 的细节如下 UML 图

通过 上述 UML 图可以看出当 octavia-api service 接收到 create loadbalancer 请求后主要处理了下列几件事情:

  1. 验证请求用户的身份。
  2. 验证请求 VIP 及其相关对象(e.g. port, subnet, network, )是否可用,可以通过 config secition [networking] 来配置 Allow/disallow 的网络对象。
  3. 检查请求 Project 的 LB 相关 Quota,可以通过 config section [quotas] 来配置默认 Quota。
  4. 准备创建 loadbalancer 数据库记录的数据结构。
  5. 创建 loadbalancer 和 vip 的数据库记录。
  6. 调用 Amphora driver(default lb provider)创建 VIP 对应的 port,并将 Port、VIP、LB 三者的数据库记录关联起来。
  7. 以图的方式创建 loadbalancer 下属的 Listeners 和 Pools。
  8. 准备传递给 Amphora driver 实际用于 create_loadbalancer_flow 的数据结构。
  9. 异步调用 octavia-cw service 执行 create_loadbalancer_flow。

其中有几点值得我们额外的注意:

  • 通过 networking 和 quota 用户可以限制 LBaaS 的资源范围,e.g. loadbalancer 的个数、listener 的个数 etc… 甚至可以规定使用的 VIP 列表和 VIP 只能在规定的 network/subnet 中创建。

  • 虽然 CLI 并没有给出类似 --listeners or --pools 的选项让用户传递 loadbalancer 下属 Listeners 和 Pools 的 body 属性,但实际上 POST /v2.0/lbaas/loadbalancers 的视图函数时可以处理这两个参数的。所以在 UI 设定的时候可以完成 CLI 不支持的一次性创建 loadbalancer、listener 及 pool 的操作。

  • 创建 loadbalancer 时,如果 VIP 的 port 不存在,那么 octavia-api 会调用 neutronclient 创建,命名规则为 lb-<load_balancer.id>,所以你会在 VIP 的 network/subnet 中看见类似的 Port。

Octavia Controller Worker

这是一个典型的 taskflow 外层封装,从 get flow、prepare flow store、get flow engine 到最后的 run flow。其中最核心的步骤是 3. self._lb_flows.get_create_load_balancer_flow,想要知道创建 loadbalancer 都做了些什么事情,就要看看这个 Flow 里面都有哪些 Task。

这里我们主要关注为 loadbalancer 准备 Amphora 和 Amphora 的 Networking Setup。

为 loadbalancer 准备 Amphora 的 UML 如下:

为 loadbalancer 准备 Amphora 的过程中有几点值得我们注意:

  • 如果配置 [controller_worker] loadbalancer_topology = ACTIVE_STANDBY 时,可以结合 [nova] enable_anti_affinity = True 反亲和性进一步提高 loadbalancer 的高可用性。
  • 为 loadbalancer 准备 Amphora 并非每次都是通过 create amphora 来实现的,flow 会先检查是否存在可以映射到 loadbalancer 的 Amphora instance,如果存在就直接映射给 loadbalancer 使用。如果不存在才会启动创建 Amphora instance 的任务流,这里需要配合 housekeeping 机制来完成。housekeeping 会根据配置 [house_keeping] spare_amphora_pool_size=2 来准备 spare Amphora instance pool,加速 loadbalancer 的创建流程。
  • 创建 Amphora 使用的是 graph flow(图流),图流的特性就是开发者可以自定义条件来控制任务的流向,amp_for_lb_flow.link 就是设定判断条件的语句,这里的判断条件设定为了:如果为 loadbalancer mapping Amphora instance 成功就直接修改数据库中相关对象的隐射关系,如果 mapping 失败则先创建 Amphora instance 之后再修改数据库中相关对象的隐射关系。

为 loadbalancer 的 Amphora 准备 networking 的 UML 如下:

从 UML 可以见 Amphora 的 Networking 主要的工作是为 Amphora 的 Keepalived 设定 VIP,过程中会涉及到大量的 octavia-cw service 与 amphora agent 的通信。后面我们再继续深入看看关键的 Task 中都做什么什么事情。

再继续看看当 listeners 参数被传入时的 flow 是怎么样的:

创建 Listener 实际上就是更新了 Amphora 内 HAProxy 的配置信息,所以可见上述最重要的 Task 就是 amphora_driver_task.ListenersUpdate

自此整个 create loadbalancer 的 flow 就都看完了,接下来我们继续深入到一些关键的 Task 里,看看都做了什么事情。

database_tasks.MapLoadbalancerToAmphora

为 loadbalancer 创建 amphora 时首先会尝试 Maps and assigns a load balancer to an amphora in the database,如果 mapping SUCCESS 则会 return amphora uuid 否则为 None。graph flow 类型的 amp_for_lb_flow 就是通过这个 return 来作为任务流向控制判断条件的。

if None:
create_amp
else:
map_lb_to_amp

compute_tasks.CertComputeCreate & ComputeCreate

Task CertComputeCreate & ComputeCreate 都是创建一个 amphora instance,通过配置项 [controller_worker] amphora_driver 进行选择。当 amphora_driver = amphora_haproxy_rest_driver 时使用 CertComputeCreate,octavia-cw service 与 amphora-agent 之间通过 HTTPS 进行安全通信;当 amphora_driver = amphora_noop_driver 时使用后者,但 amphora_noop_driver 一般被用作测试,可以忽略不计。

            compute_id = self.compute.build(
name="amphora-" + amphora_id,
amphora_flavor=CONF.controller_worker.amp_flavor_id,
image_id=CONF.controller_worker.amp_image_id,
image_tag=CONF.controller_worker.amp_image_tag,
image_owner=CONF.controller_worker.amp_image_owner_id,
key_name=key_name,
sec_groups=CONF.controller_worker.amp_secgroup_list,
network_ids=network_ids,
port_ids=[port.id for port in ports],
config_drive_files=config_drive_files,
user_data=user_data,
server_group_id=server_group_id)

这里调用了 novaclient 的封装来创建 amphora instance,其中 image、flavor、sec_groups、keypair 均在配置 [controller_worker] 中定义了。需要注意的是 config_drive_files 和 user_data 两个形参就是为了 amphora instance 启动时为 amphora-agent 注入证书的参数项,应用了 Nova Store metadata on a configuration drive 机制。

config_drive_files = {
'/etc/octavia/certs/server.pem': server_pem,
'/etc/octavia/certs/client_ca.pem': ca}

network_tasks.AllocateVIP

Task AllocateVIP 实际调用了 octavia.network.drivers.neutron.allowed_address_pairs:AllowedAddressPairsDriver.allocate_vip method,return 的是一个建立了 Port、VIP 和 LB 三者关系的 data_models.Vip 对象。该 method 在 octavia-api 已经被调用过一次了,所以到此时 VIP 的 Port 一般都已经存在了,只需要返回一个 data object 即可。然后在通过 Task UpdateAmphoraVIPData 落库持久化。

network_tasks.PlugVIP

Task PlugVIP 是实际为 Amphora instance(s) 设定 VIP 的。

在 PlugVIP 的过程中需要注意几点:

  • 在创建 Listener 时都会 update VIP port 的 security_group_rules,因为 Listener 是依附于 VIP 的,所以 Listener 监听的协议端口都应该在 VIP 的安全组上打开,并且关闭不必要的端口。
  • PlugVIP 会轮询检查所有 loadbalancer.amphora 是否具有 VIP 对应的 Port,如果没有则会创建出来,设定 VIP 再挂载到 Amphora instance 上。

NOTE:VIP 是 Act/Stby topo Amphora 的虚拟 IP。

最后

至此 Octavia 创建 loadbalancer 的流程就分析分完了,总的来说一图顶千言,还是希望通过 UML 图来描述主要流程再辅以文字说明关键点的方式来进行介绍。

Octavia 创建 loadbalancer 的实现与分析的更多相关文章

  1. springboot创建,自动装配原理分析,run方法启动

    使用IDEA快速创建一个springboot项目 创建Spring Initializr,然后一直下一步下一步直至完成 选择web,表示创建web项目 运行原理分析 我们先来看看pom.xml文件 核 ...

  2. Octavia 创建 Listener、Pool、Member、L7policy、L7 rule 与 Health Manager 的实现与分析

    目录 文章目录 目录 创建 Listener 创建 Pool 创建 Member CalculateDelta HandleNetworkDeltas AmphoraePostNetworkPlug ...

  3. Nova创建虚拟机的底层代码分析

    作为个人学习笔记分享.有不论什么问题欢迎交流! 在openstack中创建虚拟机的底层实现是nova使用了libvirt,代码在nova/virt/libvirt/driver.py. #image_ ...

  4. JS对象创建常用方式及原理分析

    ====此文章是稍早前写的,本次属于文章迁移@2017.06.27==== 前言 俗话说"在js语言中,一切都对象",而且创建对象的方式也有很多种,所以今天我们做一下梳理 最简单的 ...

  5. 虚拟机创建流程中neutron代码分析(二)

    前言: 当nova服务发送了创建port的restful调用信息之后,在neutron服务中有相应的处理函数来处理调用.根据restful的工作原理,是按照 paste.ini文件中配置好的流程去处理 ...

  6. 虚拟机创建流程中neutron代码分析(三)

    前言: 当neutron-server创建了port信息,将port信息写入数据库中.流程返回到nova服务端,接着nova创建的流程继续走.在计算节点中neutron-agent同样要完成很多的工作 ...

  7. 虚拟机创建流程中neutron代码分析(一)

    前言: 在openstack的学习当中有一说法就是网络占学习时间的百分之七十.这个说法或许有夸大的成分,但不可否认的是openstack中的 网络是及其重要的部分,并且难度也是相当大.试图通过nova ...

  8. Hadoop-1.2.1学习之Job创建和提交源码分析

    在Hadoop中,MapReduce的Java作业通常由编写Mapper和Reducer開始.接着创建Job对象.然后使用该对象的set方法设置Mapper和Reducer以及诸如输入输出等參数,最后 ...

  9. 通过fork函数创建进程的跟踪,分析linux内核进程的创建

    作者:吴乐 山东师范大学 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.实验过程 1.打开gdb, ...

随机推荐

  1. 配置ShiroFilter需要注意的问题(Shiro_DelegatingFilterProxy)

    ShiroFilter的工作原理 ShiroFilter:DelegatingFilterProxy作用是自动到Spring 容器查找名字为shiroFilter(filter-name)的bean并 ...

  2. python常见问题解决方案

    平时工作中经常需要用到这些python小技巧,顺便做个记录 import requests import time def get_pr(domain): pr = 6 time.sleep(1) h ...

  3. Spring boot 拦截器和过滤器

    1. 过滤器 Filter介绍 Filter可以认为是Servlet的一种“加强版”,是对Servlet的扩展(既可以对请求进行预处理,又可以对处理结果进行后续处理.使用Filter完整的一般流程是: ...

  4. Laravel session的保存机制

    与$_SESSION不同Laraver中的session是在当次程序执行完毕时保存到文件或其他存储引擎中的,也就是说如果使用了die等强制结束程序的函数将不会自动保存session导致session失 ...

  5. Big Data(七)MapReduce计算框架

    二.计算向数据移动如何实现? Hadoop1.x(已经淘汰): hdfs暴露数据的位置 1)资源管理 2)任务调度 角色:JobTracker&TaskTracker JobTracker: ...

  6. hdu 3549 网络流最大流 Ford-Fulkerson

    Ford-Fulkerson方法依赖于三种重要思想,这三个思想就是:残留网络,增广路径和割. Ford-Fulkerson方法是一种迭代的方法.开始时,对所有的u,v∈V有f(u,v)=0,即初始状态 ...

  7. Codeforces Round #606 Div. 2 比赛总结

    比赛情况 bq. A题 Wrong Answer on test 2 , E题sb题没切.bqbqbq. 比赛总结 bq. 那就直接上题解吧!^-^ A 数位dp,分类讨论,注意细节. Talk is ...

  8. 【洛谷P2922】Secret Message

    题目大意:给定 N 个字符串组成的字典,有 M 个询问,每次给定一个字符串,求字典中有多少个单词为给定字符串的前缀或前缀是给定的字符串. 题解:在 trie 上维护一个 tag 表示有多少字符串以当前 ...

  9. Python修炼之路-文件操作

    Python编程之文件操作 文件操作流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 每次文件打开.读取信息时,Python自动记录所达到的位置,好比一个书签,之后每一次 ...

  10. CPC/CPM/CPA/CPS定义

    CPC 每点击次数计费   CPM 每千人次展现计费   CPA 每行动成果计费(比如推广成功一个用户)   CPS 淘宝客类型,按照商品佣金,推广成功计费