云计算之OpenStack核心

04-27 5860阅读 0评论

云计算之OpenStack核心

  • 一、OpenStack架构
    • 1.1 OpenStack概念架构
    • 1.2 OpenStack逻辑架构
    • 1.3 拓扑部署
    • 1.4 使用OpenStack CLI
      • 1.4.1 OpenStack 服务都有自己的 CLI
      • 二、OpenStack核心服务
        • 2.1 认证服务Keystone
          • 2.1.1 基本功能
          • 2.1.2 基本概念
          • 2.1.3 举例说明:admin用户查看Project中的image
          • 2.2 镜像服务Image
            • 2.2.1 基本概念
            • 2.2.2 Glance架构
              • 2.2.2.1 glance-api
              • 2.2.2.2 glance-registry
              • 2.2.2.3 Database
              • 2.2.2.4 Store backend
              • 2.2.3 Glance操作
                • 2.2.3.1 Web UI操作
                  • 2.2.3.1.1 Web UI 创建 image
                  • 2.2.3.1.2 Web UI 删除 image
                  • 2.2.3.2 CLI操作
                    • 2.2.3.2.1 CLI 创建 image
                    • 2.2.3.2.2 CLI 删除 image
                    • 2.2.4 如何 Troubleshooting
                    • 2.3 计算服务Nova
                      • 2.3.1 Nova架构
                        • 2.3.1.1 API
                        • 2.3.1.2 Compute Core
                        • 2.3.1.3 Console Interface
                        • 2.3.1.4 Database
                        • 2.3.1.5 Message Queue
                        • 2.3.2 Nova 物理部署方案
                        • 2.3.3 从虚机创建流程看 nova-* 子服务如何协同工作
                        • 2.3.4 OpenStack 通用设计思路
                          • 2.3.4.1 API 前端服务
                          • 2.3.4.2 Scheduler 调度服务
                          • 2.3.4.3 Worker工作服务
                          • 2.3.4.4 Driver 框架
                          • 2.3.4.5 Messaging 服务
                          • 2.3.4.6 Database
                          • 2.3.5 Nova 组件详解
                            • 2.3.5.1 nova-api
                            • 2.3.5.2 nova-conductor
                            • 2.3.5.3 nova-scheduler
                            • 2.3.5.4 nova-compute
                            • 2.3.6 看懂 OpenStack 日志
                              • 2.3.6.1 日志位置
                              • 2.3.6.2 日志类型
                              • 2.3.6.3 日志格式
                              • 2.3.6.4 日志说明
                              • 2.3.7 虚拟机生命周期管理
                                • 2.3.7.1 Launch-部署虚拟机
                                • 2.3.7.2 Shut Off-关闭虚拟机
                                • 2.3.7.3 Start-启动虚拟机
                                • 2.3.7.4 Soft/Hard Reboot-软/硬重启虚拟机
                                • 2.3.7.5 Lock/Unlock-加锁/解锁虚拟机
                                • 2.3.7.6 Terminate -删除虚拟机
                                • 2.3.7.7 Pause/Resume-暂停(短时间)/恢复(暂停后的恢复,非故障时恢复)虚拟机
                                • 2.3.7.8 Suspend/Resume-暂停(长时间)/恢复(暂停后的恢复,非故障时恢复)虚拟机
                                • 2.3.7.9 Rescue/Unrescue-恢复(发生故障时恢复)/重新引导虚拟机
                                • 2.3.7.10 Snapshot -创建虚拟机快照
                                • 2.3.7.11 Rebuild -通过快照恢复虚拟机
                                • 2.3.7.12 Shelve-搁置虚拟机
                                • 2.3.7.13 Unshelve-取消搁置虚拟机
                                • 2.3.7.14 Migrate -迁移虚拟机
                                • 2.3.7.15 Resize-调整虚拟机的vCPU、内存和磁盘资源
                                • 2.3.7.16 Live Migrate-在线迁移虚拟机
                                • 2.3.7.17 Evacuate-撤离虚拟机
                                • 2.3.7.18 Nova操作总结
                                • 2.4 块存储服务Cinder:为 instance 提供虚拟磁盘
                                  • 2.4.1 Cider架构
                                  • 2.4.2 物理部署方案
                                  • 2.4.3 Cinder设计思想
                                  • 2.4.4 Cinder 组件详解
                                    • 2.4.4.1 cinder-api
                                    • 2.4.4.2 cinder-scheduler
                                    • 2.4.4.3 cinder-volume
                                    • 2.4.5 通过场景学习Cinder
                                      • 2.4.5.1 准备LVM Volume Provider
                                      • 2.4.5.2 创建volume
                                      • 2.4.5.3 Attach附加磁盘
                                      • 2.4.5.4 Detach卸载磁盘
                                      • 2.4.5.5 Extend扩展磁盘
                                      • 2.4.5.6 Delete删除磁盘
                                      • 2.4.5.7 Snapshot磁盘快照
                                      • 2.4.5.8 Backup磁盘备份
                                      • 2.4.5.9 restore磁盘恢复
                                      • 2.4.5.10 Boot From Volume 将Volume作为虚拟机的启动盘
                                      • 2.4.5.11 NFS Volume Provider
                                      • 2.5 网络服务Neutron
                                        • 2.5.1 Neutron概述
                                          • 2.5.1.1 Neutron功能
                                          • 2.5.1.2 Neutron网络基本概念
                                          • 2.5.2 Neutron架构
                                            • 2.5.2.1 Neutron组件概括
                                            • 2.5.2.2 Neutron物理部署方案
                                            • 2.5.3 Neutron组件详细说明
                                              • 2.5.3.1 Neutron Server
                                              • 2.5.3.2 Neutron如何支持多种network provider
                                              • 2.5.3.3 ML2 Core Plugin
                                              • 2.5.3.4 Service Plugin/Agent
                                              • 2.5.3.5 小结
                                              • 2.5.4 为Neutron准备底层基础设施
                                              • 2.5.5 Linux Bridge实现Neutron网络
                                                • 2.5.5.1 配置 Linux-Bridge Mechanism Driver
                                                • 2.5.5.2 初始网络状态
                                                • 2.5.5.3 local network
                                                • 2.5.5.4 flat network
                                                • 2.5.5.5 DHCP服务
                                                • 2.5.5.6 vlan network
                                                • 2.5.5.7 Routing
                                                • 2.5.5.8 vxlan network
                                                • 2.5.5.9 Security Group
                                                • 2.5.5.10 Firewall as a Service
                                                • 2.5.5.11 Load Balancing as a Service
                                                • 2.5.6 Open vSwitch实现Neutron网络
                                                  • 2.5.6.1 local network
                                                  • 2.5.6.2 flat network
                                                  • 2.5.6.3 vlan network
                                                  • 2.5.6.4 Routing
                                                  • 2.5.6.5 vxlan network

                                                    一、OpenStack架构

                                                    1.1 OpenStack概念架构

                                                    云计算之OpenStack核心 第1张

                                                    • 中间菱形:是虚拟机,围绕 VM 的那些长方形代表 OpenStack 不同的模块或服务;
                                                    • Nova(计算服务,核心服务):管理 管理计算资源,是 OpenStack 中最核心的服务;
                                                    • Neutron(网络服务,核心服务):为 OpenStack 提供网络连接服务,负责创建和管理L2、L3 网络, 为 VM 提供虚拟网络和物理网络连接;
                                                    • Glance(镜像服务,核心服务):管理 VM 的启动镜像,Nova 创建 VM 时将使用 Glance 提供的镜像;
                                                    • Cinder(块存储,核心服务):为 VM 提供块存储服务。Cinder 提供的每一个 Volume 在 VM 看来是一块虚拟硬盘,一般用作数据盘;
                                                    • Swift(对象存储,可选服务):提供对象存储服务。VM 可以通过 RESTful API 存放对象数据;作为可选的方案,Glance 可以将镜像存放在 Swift 中;Cinder 也可以将 Volume 备份到 Swift 中;
                                                    • Keystone(认证服务,核心服务):为 OpenStack 的各种服务提供认证和权限管理服务。简单的说,OpenStack 上的每一个操作都必须通过 Keystone 的审核;
                                                    • Ceilometer(监控服务,可选服务):提供 OpenStack监控和计量服务,为报警、统计或计费提供数据;
                                                    • Horizon:为 OpenStack 用户提供一个 Web操作界面;

                                                      1.2 OpenStack逻辑架构

                                                      • 在逻辑架构中,可以看到每个服务又由若干组件组成:

                                                        云计算之OpenStack核心 第2张

                                                      • 上图逻辑架构中,以 Neutron 服务为例,描述了各个组成部分以及各组件之间的逻辑关系。 而在实际的部署方案上,各个组件可以部署到不同的物理节点上。
                                                      • OpenStack 本身是一个分布式系统,不但各个服务可以分布部署,服务中的组件也可以分布部署。 这种分布式特性让 OpenStack 具备极大的灵活性、伸缩性和高可用性。

                                                        1.3 拓扑部署

                                                        • OpenStack 是一个分布式系统,由若干不同功能的节点(Node)组成:

                                                          1)控制节点(Controller Node):管理 OpenStack,其上运行的服务有 Keystone、Glance、Horizon 以及 Nova 和 Neutron 中管理相关的组件。 控制节点也运行支持 OpenStack 的服务,例如 SQL 数据库(通常是 MySQL)、消息队列(通常是 RabbitMQ)和网络时间服务 NTP。

                                                          2)计算节点(Compute Node):其上运行 Hypervisor(默认使用 KVM)。 同时运行 Neutron 服务的 agent,为虚拟机提供网络支持。

                                                          3) 网络节点(Network Node):其上运行的服务为 Neutron。 为 OpenStack 提供 L2 和 L3 网络。 包括虚拟机网络、DHCP、路由、NAT 等。

                                                          4) 存储节点(Storage Node):提供块存储(Cinder)或对象存储(Swift)服务。

                                                        • 这几类节点是从功能上进行的逻辑划分,在实际部署时可以根据需求灵活配置,比如:在大规模OpenStack生产环境中,每类节点都分别部署在若干台物理服务器上,各司其职并互相协作。 这样的环境具备很好的性能、伸缩性和高可用性。在最小的实验环境中,可以将 4 类节点部署到一个物理的甚至是虚拟服务器上,通常也称为 All-in-One 部署。
                                                        • 在我们的实验环境中,为了使得拓扑简洁同时功能完备,我们用两个虚拟机:

                                                          devstack-controller: 控制节点 + 网络节点 + 块存储节点 + 计算节点

                                                          devstack-compute: 计算节点

                                                          云计算之OpenStack核心 第3张

                                                        • 物理资源需求,可根据实际需求动态调整:

                                                          云计算之OpenStack核心 第4张

                                                        • 网络规划:

                                                          云计算之OpenStack核心 第5张

                                                          网络上规划了三个网络

                                                          1)Management Network:用于 OpenStack 内部管理用,比如各服务之间通信。 这里使用 eth0;

                                                          2)VM(Tenant)Network:OpenStack 部署的虚拟机所使用的网络。OpenStack 支持多租户(Tenant),虚机是放在 Tenant 下的,所以叫 Tenant Network。 这里使用 eth1;

                                                          3)External Network:一般来说,Tenant Network 是内部私有网络,只用于 VM 之间通信,与其他非 VM 网络是隔离的。这里我们规划了一个外部网络(External Network),通过 devstak-controller 的 eth2 连接。 Neutron 通过 L3 服务让 VM 能够访问到 External Network。对于公有云,External Network 一般指的是 Internet。对于企业私有云,External Network 则可以是 Intranet 中的某个网络。

                                                        • 创建虚拟机:按照物理资源需求创建 devstack-controller 和 devstak-compute 虚拟机:

                                                          安装操作系统

                                                          安装 Ubuntu 14.04,并配置 eth0 的 IP,如下所示:

                                                          控制节点 devstack-controller  192.168.104.10
                                                          计算节点 devstak-compute      192.168.104.11
                                                          

                                                          参考:https://www.xjimmy.com/openstack-5min-17.html

                                                          1.4 使用OpenStack CLI

                                                          1.4.1 OpenStack 服务都有自己的 CLI

                                                          • 命令很好记,就是服务的名字,比如 Glance 就是 glance,Nova 就是 nova。但 Keystone 比较特殊,现在是用 openstack 来代替老版的 keystone 命令。比如查询用户列表,如果用 keystone user-list:

                                                            云计算之OpenStack核心 第6张会提示 keystone 已经 deprecated 了,用 openstack user list 命令代替:

                                                            云计算之OpenStack核心 第7张

                                                          • 执行命令之前,需要设置环境变量:

                                                            这些变量包含用户名、Project、密码等; 如果不设置,每次执行命令都必须设置相关的命令行参数

                                                          • 各个服务的命令都有增、删、改、查的操作,其格式是:
                                                            CMD -create [parm1] [parm2]…
                                                            CMD -delete [parm]
                                                            CMD -update [parm1] [parm2]…
                                                            CMD -list
                                                            CMD -show [parm]
                                                            
                                                            • 例如 glance 管理的是 image,那么:CMD 就是 glance;obj 就是 image,对应的命令就有:
                                                              glance image-create
                                                              glance image-delete
                                                              glance image-update
                                                              glance image-list
                                                              glance image-show
                                                              
                                                              • 再比如 neutron 管理的是网络和子网等,那么: CMD 就是 neutron;obj 就是 net 和 subnet :
                                                                # 网络相关操作
                                                                neutron net-create
                                                                neutron net -delete
                                                                neutron net -update
                                                                neutron net -list
                                                                neutron net –show
                                                                # 子网相关操作
                                                                neutron subnet-create
                                                                neutron subnet -delete
                                                                neutron subnet -update
                                                                neutron subnet -list
                                                                neutron subnet–show
                                                                
                                                                • 有的命令 可以省略,比如 nova,下面的操作都是针对 instance:
                                                                  nova boot
                                                                  nova delete
                                                                  nova list
                                                                  nova show
                                                                  
                                                                  • 没个对象都有ID:delete,show 等操作都以 ID 为参数,例如:

                                                                    云计算之OpenStack核心 第8张

                                                                  • 可用 help 查看命令的用法,除了 delete,show 等操作只需要 ID 一个参数,其他操作可能需要更多的参数,用 help 查看所需的参数,格式是:
                                                                    CMD help [SUB-CMD]
                                                                    

                                                                    例如查看 glance 都有哪些 SUB-CMD:

                                                                    云计算之OpenStack核心 第9张查看 glance image-update 的用法:

                                                                    云计算之OpenStack核心 第10张

                                                                    二、OpenStack核心服务

                                                                    云计算之OpenStack核心 第11张

                                                                    2.1 认证服务Keystone

                                                                    2.1.1 基本功能

                                                                    • 作为 OpenStack 的基础支持服务,Keystone 做下面这几件事情:

                                                                      1)管理用户及其权限;

                                                                      2)维护 OpenStack Services 的 Endpoint;

                                                                      3)Authentication(认证)和 Authorization(鉴权)。

                                                                      2.1.2 基本概念

                                                                      云计算之OpenStack核心 第12张

                                                                      • user:指代任何使用 OpenStack 的实体,可以是真正的用户,其他系统或者服务,当 User 请求访问 OpenStack 时,Keystone 会对其进行验证;

                                                                        Horizon 在 Identity->Users 管理 User:

                                                                        云计算之OpenStack核心 第13张

                                                                        除了 admin 和 demo,OpenStack 也为 nova、cinder、glance、neutron 服务创建了相应的 User。 admin 也可以管理这些 User。

                                                                        云计算之OpenStack核心 第14张

                                                                      • Credentials:Credentials 是 User 用来证明自己身份的信息,可以是: 1. 用户名/密码 2. Token 3. API Key 4. 其他高级方式。
                                                                      • Authentication: 是 Keystone 验证 User 身份的过程。User 访问 OpenStack 时向 Keystone 提交用户名和密码形式的 Credentials,Keystone 验证通过后会给 User 签发一个 Token 作为后续访问的 Credential。
                                                                      • Token:Token 是由数字和字母组成的字符串,User 成功 Authentication 后由 Keystone 分配给 User。Token 用做访问 Service 的 Credential;Service 会通过 Keystone 验证 Token 的有效性;Token 的有效期默认是 24 小时。
                                                                      • Project: 用于将 OpenStack 的资源(计算、存储和网络)进行分组和隔离。根据 OpenStack 服务的对象不同,Project 可以是一个客户(公有云,也叫租户)、部门或者项目组(私有云)。这里请注意:资源的所有权是属于 Project 的,而不是 User。在 OpenStack 的界面和文档中,Tenant / Project / Account 这几个术语是通用的,但长期看会倾向使用 Project。每个 User(包括 admin)必须挂在 Project 里才能访问该 Project 的资源。 一个User可以属于多个 Project。admin 相当于 root 用户,具有最高权限

                                                                        Horizon 在 Identity->Projects 中管理 Project:

                                                                        云计算之OpenStack核心 第15张

                                                                        通过 Manage Members 将 User 添加到 Project 中:

                                                                        云计算之OpenStack核心 第16张云计算之OpenStack核心 第17张

                                                                      • Service:OpenStack 的 Service 包括 Compute (Nova)、Block Storage (Cinder)、Object Storage (Swift)、Image Service (Glance) 、Networking Service (Neutron) 等。每个 Service 都会提供若干个 Endpoint,User 通过 Endpoint 访问资源和执行操作。
                                                                      • Endpoint:Endpoint 是一个网络上可访问的地址,通常是一个 URL。Service 通过 Endpoint 暴露自己的 API。Keystone 负责管理和维护每个 Service 的 Endpoint。

                                                                        可以使用下面的命令来查看 Endpoint:

                                                                        root@devstack-controller:~# source devstack/openrc admin admin //切换用户
                                                                        root@devstack-controller:~# openstack catalog list //查询服务的Endpoint
                                                                        

                                                                        云计算之OpenStack核心 第18张

                                                                        • Role:安全包含两部分:Authentication(认证)和 Authorization(鉴权)。Keystone 是借助 Role 来实现 Authorization 的。

                                                                          Keystone定义Role:

                                                                          云计算之OpenStack核心 第19张

                                                                          可以为 User 分配一个或多个 Role,Horizon 的菜单为 Identity->Project->Manage Members:

                                                                          云计算之OpenStack核心 第20张Service 决定每个 Role 能做什么事情 Service 通过各自的 policy.json 文件对 Role 进行访问控制。下面是 Nova 服务 /etc/nova/policy.json 中的示例:

                                                                          云计算之OpenStack核心 第21张

                                                                          上面配置的含义是:对于 create、attach_network 和 attach_volume 操作,任何Role的 User 都可以执行; 但只有 admin 这个 Role 的 User 才能执行 forced_host 操作。OpenStack 默认配置只区分 admin 和非 admin Role。 如果需要对特定的 Role 进行授权,可以修改 policy.json。

                                                                          2.1.3 举例说明:admin用户查看Project中的image

                                                                          • 登录:账号密码为admin/admin,点击“Connect”:

                                                                            云计算之OpenStack核心 第22张

                                                                            此时OpenStack 内部发生了哪些事情?请看下面:Token 中包含了 User 的 Role 信息。

                                                                            云计算之OpenStack核心 第23张

                                                                          • 显示操作界面:请注意,顶部显示 admin 可访问的 Project 为 “admin” 和 “demo”。

                                                                            云计算之OpenStack核心 第24张

                                                                            在此之前发生了什么事情:

                                                                            云计算之OpenStack核心 第25张

                                                                            同时,admin 可以访问 Intance, Volume, Image 等服务

                                                                            云计算之OpenStack核心 第26张

                                                                            因为 admin 已经从 Keystone 拿到了各 Service 的 Endpoints

                                                                            云计算之OpenStack核心 第27张

                                                                          • 显示image列表:点击 “Images”,会显示 image 列表;

                                                                            云计算之OpenStack核心 第28张

                                                                            背后发生了这些事:首先,admin 将请求发送到 Glance 的 Endpoint:

                                                                            云计算之OpenStack核心 第29张

                                                                            Glance 向 Keystone 询问 admin 身份的有效性:

                                                                            云计算之OpenStack核心 第30张

                                                                            接下来 Glance 会查看 /etc/glance/policy.json,判断 admin 是否有查看 image 的权限:

                                                                            云计算之OpenStack核心 第31张

                                                                            权限判定通过,Glance 将 image 列表发给 admin。

                                                                          • Troubleshoot :OpenStack 排查问题的方法主要是通过日志,每个 Service 都有自己的日志文件。Keystone 主要有两个日志:keystone.log 和 keystone_access.log,保存在 /var/log/apache2/ 目录里。

                                                                            devstack 的 screen 窗口已经帮我们打开了这两个日志。可以直接查看:

                                                                            云计算之OpenStack核心 第32张

                                                                            如果需要得到最详细的日志信息,可以在 /etc/keystone/keystone.conf 中打开 debug 选项:

                                                                            云计算之OpenStack核心 第33张

                                                                            在非 devstack 安装中,日志可能在 /var/log/keystone/ 目录里。

                                                                            2.2 镜像服务Image

                                                                            2.2.1 基本概念

                                                                            • 在传统 IT 环境下,安装一个系统是要么从安装 CD 从头安装,要么用 Ghost 等克隆工具恢复,这两种方式有如下几个问题:

                                                                              1)如果要安装的系统多了效率就很低;

                                                                              2)时间长,工作量大;

                                                                              3)安装完还要进行手工配置,比如安装其他的软件,设置 IP 等;

                                                                              4)备份和恢复系统不灵活。

                                                                            • 云环境下需要更高效的解决方案,这就是 Image:

                                                                              Image 是一个模板,里面包含了基本的操作系统和其他的软件。 举例来说,有家公司需要为每位员工配置一套办公用的系统,一般需要一个 Win7 系统再加 MS office 软件。

                                                                              OpenStack 是这么玩的,先手工安装好这么一个虚机;然后对虚机执行 snapshot,这样就得到了一个 image;当有新员工入职需要办公环境时,立马启动一个或多个该 image 的 instance(虚机)就可以了。

                                                                            • 在这个过程中,第 1 步跟传统方式类似,需要手工操作和一定时间。但第 2、3 步非常快,全自动化,一般都是秒级别。而且 2、3 步可以循环做。比如公司新上了一套 OA 系统,每个员工的 PC 上都得有客户端软件。 那么可以在某个员工的虚机中手工安装好 OA 客户端,然后执行snapshot ,得到新的 image,以后就直接使用新 image 创建虚机就可以了。
                                                                            • 另外,snapshot 还有备份的作用,能够非常方便的恢复系统。
                                                                            • Image Service 的功能是管理 Image,让用户能够发现、获取和保存 Image。在 OpenStack 中,提供 Image Service 的是 Glance,其具体功能如下:

                                                                              1)提供 REST API 让用户能够查询和获取 image 的元数据和 image 本身;

                                                                              2)支持多种方式存储 image,包括普通的文件系统、Swift、Amazon S3 等;

                                                                              3)对 Instance 执行 Snapshot 创建新的 image。

                                                                              2.2.2 Glance架构

                                                                              云计算之OpenStack核心 第34张

                                                                              2.2.2.1 glance-api
                                                                              • glance-api 是系统后台运行的服务进程。 对外提供 REST API,响应 image 查询、获取和存储的调用。
                                                                              • glance-api 不会真正处理请求。
                                                                              • 如果是与 image metadata(元数据)相关的操作,glance-api 会把请求转发给 glance-registry;
                                                                              • 如果是与 image 自身存取相关的操作,glance-api 会把请求转发给该 image 的 store backend。
                                                                              • 在控制节点上可以查看 glance-api 进程:

                                                                                云计算之OpenStack核心 第35张

                                                                                2.2.2.2 glance-registry
                                                                                • glance-registry 是系统后台运行的服务进程。负责处理和存取 image 的 metadata,例如 image 的大小和类型。在控制节点上可以查看 glance-registry 进程:

                                                                                  云计算之OpenStack核心 第36张

                                                                                • Glance 支持多种格式的 image,包括:

                                                                                  云计算之OpenStack核心 第37张

                                                                                  2.2.2.3 Database
                                                                                  • Image 的 metadata 会保存到 database 中,默认是 MySQL。在控制节点上可以查看 glance 的 database 信息:

                                                                                    云计算之OpenStack核心 第38张

                                                                                    2.2.2.4 Store backend
                                                                                    • Glance 自己并不存储 image。 真正的 image 是存放在 backend 中的。 Glance 支持多种 backend,包括:

                                                                                      1)A directory on a local file system(这是默认配置);

                                                                                      2)GridFS;

                                                                                      3)Ceph RBD;

                                                                                      4)Amazon S3;

                                                                                      5)Sheepdog;

                                                                                      6)OpenStack Block Storage (Cinder);

                                                                                      7)OpenStack Object Storage (Swift);

                                                                                      8)VMware ESX。

                                                                                      具体使用哪种 backend,是在 /etc/glance/glance-api.conf 中配置的,在我们的 devstack 环境中,image 存放在控制节点本地目录 /opt/stack/data/glance/images/ 中:

                                                                                      云计算之OpenStack核心 第39张

                                                                                      其他 backend 的配置可参考:https://docs.openstack.org/liberty/config-reference/content/configuring-image-service-backends.html

                                                                                    • 查看目前已经存在的 image使用glance image-list:

                                                                                      云计算之OpenStack核心 第40张

                                                                                    • 查看保存目录:每个 image 在目录下都对应有一个文件,文件以 image 的 ID 命名。

                                                                                      云计算之OpenStack核心 第41张

                                                                                      2.2.3 Glance操作

                                                                                      • OpenStack 为终端用户提供了 Web UI(Horizon)和命令行 CLI 两种方式创建Image。
                                                                                        2.2.3.1 Web UI操作
                                                                                        2.2.3.1.1 Web UI 创建 image
                                                                                        • admin 登录后,Project -> Compute -> Images:

                                                                                          云计算之OpenStack核心 第42张

                                                                                        • 点击右上角“Create Image”按钮,为新 image 命名:

                                                                                          云计算之OpenStack核心 第43张云计算之OpenStack核心 第44张这里我们上传一个 image。 点击“浏览”,选择镜像文件 cirros-0.3.4-x86_64-disk.img。cirros 是一个很小的 linux 镜像,非常适合测试用。 可以到http://download.cirros-cloud.net/下载。

                                                                                        • 格式选择 QCOW2:

                                                                                          云计算之OpenStack核心 第45张如果勾选“Public”,该 image 可以被其他 Project 使用;如果勾选“Protected”,该 image 不允许被删除。

                                                                                        • 点击“Create Image”,文件上传到 OpenStack 并创建新的 image:

                                                                                          云计算之OpenStack核心 第46张

                                                                                        • 点击 image 的“cirros链接”:

                                                                                          云计算之OpenStack核心 第47张显示详细信息

                                                                                          云计算之OpenStack核心 第48张

                                                                                          2.2.3.1.2 Web UI 删除 image
                                                                                          • admin 登录后,Project -> Compute -> Images:

                                                                                            云计算之OpenStack核心 第49张云计算之OpenStack核心 第50张点击“Delete Images”确认删除,操作成功:

                                                                                            云计算之OpenStack核心 第51张

                                                                                            2.2.3.2 CLI操作
                                                                                            2.2.3.2.1 CLI 创建 image
                                                                                            • cirros 这个 linux 镜像很小,通过 Web UI 上传很快,操作会很顺畅。 但如果我们要上传的镜像比较大(比如好几个 G ),那么操作会长时间停留在上传的 Web 界面,我们也不知道目前到底处于什么状态。对于这样的操作,CLI 是更好的选择。
                                                                                            • 将 image 上传到控制节点的文件系统中,例如 /tmp/cirros-0.3.4-x86_64-disk.img:
                                                                                            • 设置环境变量:

                                                                                              云计算之OpenStack核心 第52张Devstack 的安装目录下有个 openrc 文件。source 该文件就可以配置 CLI 的环境变量。这里我们传入了两个参数,第一个参数是 OpenStack 用户名 admin;第二个参数是 Project 名 admin。

                                                                                            • 执行 image 创建命令:
                                                                                              glance image-create --name cirros --file /tmp/cirros-0.3.4-x86_64-disk.img --disk-format qcow2 --container-format bare --progress
                                                                                              

                                                                                              云计算之OpenStack核心 第53张在创建 image 的 CLI 参数中我们用 –progress 让其显示文件上传的百分比 %。在 /opt/stack/data/glance/images/ 下查看新的 Image:

                                                                                              云计算之OpenStack核心 第54张

                                                                                              2.2.3.2.2 CLI 删除 image
                                                                                              • 设置环境变量:

                                                                                                云计算之OpenStack核心 第55张

                                                                                              • 查询现有image:

                                                                                                云计算之OpenStack核心 第56张云计算之OpenStack核心 第57张

                                                                                              • 删除image采用glance image-delete 镜像ID:

                                                                                                云计算之OpenStack核心 第58张

                                                                                                2.2.4 如何 Troubleshooting

                                                                                                • OpenStack 排查问题的方法主要是通过日志,Service 都有自己单独的日志。Glance 主要有两个日志,glance_api.log 和 glance_registry.log,保存在 /opt/stack/logs/ 目录里。devstack 的 screen 窗口已经帮我们打开了这两个日志,可以直接查看:

                                                                                                  云计算之OpenStack核心 第59张

                                                                                                • g-api 窗口显示 glance-api 日志,记录 REST API 调用情况;g-reg 窗口显示 glance-registry 日志,记录 Glance 服务处理请求的过程以及数据库操作。如果需要得到最详细的日志信息,可以在 /etc/glance/*.conf 中打开 debug 选项。devstack 默认已经打开了 debug。

                                                                                                  云计算之OpenStack核心 第60张

                                                                                                • 在非 devstack 安装中,日志在 /var/log/glance/ 目录里。

                                                                                                  2.3 计算服务Nova

                                                                                                  • Compute Service Nova 是 OpenStack 最核心的服务,负责维护和管理云环境的计算资源。OpenStack 作为 IaaS 的云操作系统,虚拟机生命周期管理也就是通过 Nova 来实现的。

                                                                                                    云计算之OpenStack核心 第61张

                                                                                                    在上图中可以看到,Nova 处于 Openstak 架构的中心,其他组件都为 Nova 提供支持。Glance 为 VM 提供 image;Cinder 和 Swift 分别为 VM 提供块存储和对象存储 ;Neutron 为 VM 提供网络连接。

                                                                                                    2.3.1 Nova架构

                                                                                                    云计算之OpenStack核心 第62张

                                                                                                    2.3.1.1 API
                                                                                                    • nova-api:接收和响应客户的 API 调用。

                                                                                                      除了提供 OpenStack 自己的API,nova-api 还支持 Amazon EC2 API。也就是说,如果客户以前使用 Amazon EC2,并且用 EC2 的 API 开发工具来管理虚机,那么如果现在要换成 OpenStack,这些工具可以无缝迁移到OpenStack,因为 nova-api 兼容 EC2 API,无需做任何修改。

                                                                                                      2.3.1.2 Compute Core
                                                                                                      • nova-scheduler:虚机调度服务,负责决定在哪个计算节点上运行虚机;
                                                                                                      • nova-compute:管理虚机的核心服务,通过调用 Hypervisor API 实现虚机生命周期管理;
                                                                                                      • Hypervisor:计算节点上跑的虚拟化管理程序,虚机管理最底层的程序。 不同虚拟化技术提供自己的 Hypervisor。 常用的 Hypervisor 有 KVM,Xen,VMWare 等;
                                                                                                      • nova-conductor:nova-compute 经常需要更新数据库,比如更新虚机的状态。出于安全性和伸缩性的考虑,nova-compute 并不会直接访问数据库,而是将这个任务委托给 nova-conductor。
                                                                                                        2.3.1.3 Console Interface
                                                                                                        • nova-console:用户可以通过多种方式访问虚机的控制台:

                                                                                                          1)nova-novncproxy,基于 Web 浏览器的VNC 访问;

                                                                                                          2)nova-spicehtml5proxy,基于HTML5 浏览器的 SPICE 访问;

                                                                                                          3)nova-xvpnvncproxy,基于 Java 客户端的 VNC 访问;

                                                                                                        • nova-consoleauth:负责对访问虚机控制台请求提供 Token 认证;
                                                                                                        • nova-cert:提供 x509 证书支持。
                                                                                                          2.3.1.4 Database
                                                                                                          • Nova 会有一些数据需要存放到数据库中,一般使用 MySQL。数据库安装在控制节点上。 Nova 使用命名为 “nova” 的数据库。

                                                                                                            云计算之OpenStack核心 第63张

                                                                                                            2.3.1.5 Message Queue
                                                                                                            • 在前面我们了解到 Nova 包含众多的子服务,这些子服务之间需要相互协调和通信。 为解耦各个子服务,Nova 通过 Message Queue 作为子服务的信息中转站。 所以在架构图上我们看到了子服务之间没有直接的连线,它们都通过 Message Queue 联系。

                                                                                                              云计算之OpenStack核心 第64张

                                                                                                              OpenStack 默认是用 RabbitMQ 作为 Message Queue。MQ 是 OpenStack 的核心基础组件。

                                                                                                              2.3.2 Nova 物理部署方案

                                                                                                              • 对于 Nova,这些服务会部署在两类节点上:计算节点和控制节点。计算节点上安装了 Hypervisor,上面运行虚拟机,由此可知:只有 nova-compute 需要放在计算节点上。其他子服务则是放在控制节点上的。
                                                                                                              • 实验环境的具体部署情况 :

                                                                                                                通过在计算节点和控制节点上运行 ps -elf|grep nova 来查看运行的 nova 子服务:

                                                                                                                1)计算节点上只运行了nova-compute自服务:

                                                                                                                云计算之OpenStack核心 第65张

                                                                                                                2)控制节点上运行了若干 nova-* 子服务,RabbitMQ 和 MySQL 也是放在控制节点上的,我们发现的控制节点上也运行了 nova-compute:这实际上也就意味着controller 既是一个控制节点,同时也是一个计算节点,也可以在上面运行虚机。

                                                                                                                云计算之OpenStack核心 第66张

                                                                                                                云计算之OpenStack核心 第67张

                                                                                                                这也向我们展示了 OpenStack 这种分布式架构部署上的灵活性: 可以将所有服务都放在一台物理机上,作为一个 All-in-One 的测试环境; 也可以将服务部署在多台物理机上,获得更好的性能和高可用。

                                                                                                                另外,可以用 nova service-list 查看 nova-* 子服务都分布在哪些节点上:

                                                                                                                云计算之OpenStack核心 第68张

                                                                                                                2.3.3 从虚机创建流程看 nova-* 子服务如何协同工作

                                                                                                                • 从学习 Nova 的角度看,虚机创建是一个非常好的场景,涉及的 nova-* 子服务很全,下面是流程图:

                                                                                                                  云计算之OpenStack核心 第69张

                                                                                                                  1)客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(nova-api)发送请求:“帮我创建一个虚机”;

                                                                                                                  2)API 对请求做一些必要处理后,向 Messaging(RabbitMQ)发送了一条消息:“让 Scheduler 创建一个虚机”;

                                                                                                                  3)Scheduler(nova-scheduler)从 Messaging 获取到 API 发给它的消息,然后执行调度算法,从若干计算节点中选出节点 A;

                                                                                                                  4)Scheduler 向 Messaging 发送了一条消息:“在计算节点 A 上创建这个虚机”;

                                                                                                                  5)计算节点 A 的 Compute(nova-compute)从 Messaging 中获取到 Scheduler 发给它的消息,然后在本节点的 Hypervisor 上启动虚机;

                                                                                                                  5)在虚机创建的过程中,Compute 如果需要查询或更新数据库信息,会通过 Messaging 向Conductor(nova-conductor)发送消息,Conductor 负责数据库访问。

                                                                                                                  2.3.4 OpenStack 通用设计思路

                                                                                                                  2.3.4.1 API 前端服务
                                                                                                                  • 每个 OpenStack 组件可能包含若干子服务,其中必定有一个 API 服务负责接收客户请求。以 Nova 为例,nova-api 作为 Nova 组件对外的唯一窗口,向客户暴露 Nova 能够提供的功能。当客户需要执行虚机相关的操作,能且只能向 nova-api 发送 REST 请求。这里的客户包括终端用户、命令行和 OpenStack 其他组件。
                                                                                                                  • 设计 API 前端服务的好处在于:对外提供统一接口,隐藏实现细节;API 提供 REST 标准调用服务,便于与第三方系统集成;可以通过运行多个 API 服务实例轻松实现 API 的高可用,比如运行多个 nova-api 进程。
                                                                                                                    2.3.4.2 Scheduler 调度服务
                                                                                                                    • 对于某项操作,如果有多个实体都能够完成任务,那么通常会有一个scheduler 负责从这些实体中挑选出一个最合适的来执行操作。在前面的例子中,Nova 有多个计算节点。当需要创建虚机时,nova-scheduler 会根据计算节点当时的资源使用情况选择一个最合适的计算节点来运行虚机。除了 Nova,块服务组件 Cinder 也有 scheduler 子服务,后面我们会详细讨论。
                                                                                                                      2.3.4.3 Worker工作服务
                                                                                                                      • 调度服务只管分配任务,真正执行任务的是 Worker 工作服务。在 Nova 中,这个 Worker 就是 nova-compute 了。 将 Scheduler 和 Worker 从职能上进行划分使得OpenStack 非常容易扩展:1)当计算资源不够了无法创建虚机时,可以增加计算节点(增加 Worker);2)当客户的请求量太大调度不过来时,可以增加 Scheduler。
                                                                                                                        2.3.4.4 Driver 框架
                                                                                                                        • OpenStack 作为开放的 Infrastracture as a Service 云操作系统,支持业界各种优秀的技术。
                                                                                                                        • 那 OpenStack 的这种开放性体现在哪里呢:一个重要的方面就是采用基于 Driver 的框架。以 Nova 为例,OpenStack 的计算节点支持多种 Hypervisor。 包括 KVM, Hyper-V, VMWare, Xen, Docker, LXC 等。Nova-compute 为这些 Hypervisor 定义了统一的接口,hypervisor 只需要实现这些接口,就可以 driver 的形式即插即用到 OpenStack 中。
                                                                                                                        • 下面是 nova driver 的架构示意图:

                                                                                                                          云计算之OpenStack核心 第70张

                                                                                                                          在 nova-compute 的配置文件 /etc/nova/nova.conf 中由 compute_driver 配置项指定该计算节点使用哪种 Hypervisor 的 driver。

                                                                                                                          云计算之OpenStack核心 第71张

                                                                                                                          在我们的环境中因为是 KVM,所以配置的是 Libvirt 的 driver。不知大家是否还记得我们在学习 Glance 时谈到: OpenStack 支持多种 backend 来存放 image。可以是本地文件系统,Cinder,Ceph,Swift 等。其实这也是一个 driver 架构。 只要符合 Glance 定义的规范,新的存储方式可以很方便的加入到 backend 支持列表中。再后面 Cinder 和 Neutron 中我们还会看到 driver 框架的应用。

                                                                                                                          2.3.4.5 Messaging 服务
                                                                                                                          • 在前面创建虚机的流程示意图中,我们看到 nova-* 子服务之间的调用严重依赖 Messaging。Messaging 是 nova-* 子服务交互的中枢。

                                                                                                                            云计算之OpenStack核心 第72张

                                                                                                                          • 以前没接触过分布式系统的同学可能会不太理解为什么不让 API 直接调用Scheduler,或是让Scheuler 直接调用 Compute,而是非要通过 Messaging 进行中转。
                                                                                                                          • 程序之间的调用通常分两种:同步调用和异步调用:

                                                                                                                            1)同步调用: API 直接调用 Scheduler 的接口就是同步调用。 其特点是 API 发出请求后需要一直等待,直到 Scheduler 完成对 Compute 的调度,将结果返回给 API 后 API 才能够继续做后面的工作。

                                                                                                                            2)异步调用: API 通过 Messaging 间接调用 Scheduler 就是异步调用。 其特点是 API 发出请求后不需要等待,直接返回,继续做后面的工作。Scheduler 从 Messaging 接收到请求后执行调度操作,完成后将结果也通过 Messaging 发送给 API。

                                                                                                                          • 在 OpenStack 这类分布式系统中,通常采用异步调用的方式,其好处是:解耦各子服务:子服务不需要知道其他服务在哪里运行,只需要发送消息给 Messaging 就能完成调用;提高性能:异步调用使得调用者无需等待结果返回。这样可以继续执行更多的工作,提高系统总的吞吐量;提高伸缩性:子服务可以根据需要进行扩展,启动更多的实例处理更多的请求,在提高可用性的同时也提高了整个系统的伸缩性。而且这种变化不会影响到其他子服务,也就是说变化对别人是透明的。
                                                                                                                            2.3.4.6 Database
                                                                                                                            • OpenStack 各组件都需要维护自己的状态信息。比如 Nova 中有虚机的规格、状态,这些信息都是在数据库中维护的。每个 OpenStack 组件在 MySQL 中有自己的数据库。

                                                                                                                              云计算之OpenStack核心 第73张

                                                                                                                              2.3.5 Nova 组件详解

                                                                                                                              2.3.5.1 nova-api
                                                                                                                              • Nova-api 是整个 Nova 组件的门户,所有对 Nova 的请求都首先由 nova-api 处理。

                                                                                                                                Nova-api 向外界暴露若干 HTTP REST API 接口。在 keystone 中我们采用openstack endpoint show nova命令查询 nova-api 的 endponits。客户端就可以将请求发送到 endponits 指定的地址,向 nova-api 请求操作。

                                                                                                                                云计算之OpenStack核心 第74张

                                                                                                                                当然,作为最终用户的我们不会直接发送 Rest AP I请求。OpenStack CLI,Dashboard 和其他需要跟 Nova 交换的组件会使用这些 API。

                                                                                                                              • Nova-api 对接收到的 HTTP API 请求会做如下处理:

                                                                                                                                1)检查客户端传入的参数是否合法有效 ;

                                                                                                                                2)调用 Nova 其他子服务的处理客户端 HTTP 请求 ;

                                                                                                                                3)格式化 Nova 其他子服务返回的结果并返回给客户端。

                                                                                                                              • nova-api 接收哪些请求?

                                                                                                                                简单的说,只要是跟虚拟机生命周期相关的操作,nova-api 都可以响应。大部分操作都可以在 Dashboard 上找到。打开Instance管理界面:

                                                                                                                                云计算之OpenStack核心 第75张

                                                                                                                                点击下拉箭头,列表中就是 nova-api 可执行的操作。

                                                                                                                                云计算之OpenStack核心 第76张

                                                                                                                                OpenStack 用术语 “Instance” 来表示虚拟机。

                                                                                                                                2.3.5.2 nova-conductor
                                                                                                                                • nova-compute 需要获取和更新数据库中 instance 的信息。但 nova-compute 并不会直接访问数据库,而是通过 nova-conductor 实现数据的访问。

                                                                                                                                  云计算之OpenStack核心 第77张

                                                                                                                                • 这样做有两个显著好处:更高的系统安全性;更好的系统伸缩性 。
                                                                                                                                • 更高的安全性:

                                                                                                                                  在 OpenStack 的早期版本中,nova-compute 可以直接访问数据库,但这样存在非常大的安全隐患。因为 nova-compute 这个服务是部署在计算节点上的,为了能够访问控制节点上的数据库,就必须在计算节点的 /etc/nova/nova.conf 中配置访问数据库的连接信息,比如:

                                                                                                                                  云计算之OpenStack核心 第78张

                                                                                                                                  试想任意一个计算节点被黑客入侵,都会导致部署在控制节点上的数据库面临极大风险。为了解决这个问题,从 G 版本开始,Nova 引入了一个新服务 nova-conductor,将 nova-compute 访问数据库的全部操作都放到 nova-conductor 中,而且 nova-conductor 是部署在控制节点上的。这样就避免了 nova-compute 直接访问数据库,增加了系统的安全性。

                                                                                                                                • 更好的伸缩性:

                                                                                                                                  nova-conductor 将 nova-compute 与数据库解耦之后还带来另一个好处:提高了 nova 的伸缩性。nova-compute 与 conductor 是通过消息中间件交互的。这种松散的架构允许配置多个 nova-conductor 实例。在一个大规模的 OpenStack 部署环境里,管理员可以通过增加 nova-conductor 的数量来应对日益增长的计算节点对数据库的访问。

                                                                                                                                  2.3.5.3 nova-scheduler
                                                                                                                                  • 重点介绍 nova-scheduler 的调度机制和实现方法:即解决如何选择在哪个计算节点上启动 instance 的问题。

                                                                                                                                  • 创建 Instance 时,用户会提出资源需求,例如 CPU、内存、磁盘各需要多少。OpenStack 将这些需求定义在 flavor(配额) 中,用户只需要指定用哪个 flavor 就可以了。

                                                                                                                                    云计算之OpenStack核心 第79张

                                                                                                                                  • 可用的 flavor 在 System->Flavors 中管理:

                                                                                                                                    云计算之OpenStack核心 第80张

                                                                                                                                    Flavor 主要定义了 VCPU,RAM,DISK 和 Metadata 这四类。 nova-scheduler 会按照 flavor 去选择合适的计算节点。VCPU,RAM,DISK 比较好理解,而 Metatdata 比较有意思,我们后面会具体讨论。下面介绍 nova-scheduler 是如何实现调度的

                                                                                                                                    在 /etc/nova/nova.conf 中,nova 通过 scheduler_driver,scheduler_available_filters 和 scheduler_default_filters这三个参数来配置 nova-scheduler。

                                                                                                                                  • Filter scheduler: Filter scheduler 是 nova-scheduler 默认的调度器,调度过程分为两步。1)通过过滤器(filter)选择满足条件的计算节点(运行 nova-compute);2)通过权重计算(weighting)选择在最优(权重值最大)的计算节点上创建 Instance。

                                                                                                                                    云计算之OpenStack核心 第81张

                                                                                                                                    Nova 允许使用第三方 scheduler,配置 scheduler_driver 即可。这又一次体现了OpenStack的开放性。Scheduler 可以使用多个 filter 依次进行过滤,过滤之后的节点再通过计算权重选出最适合的节点。

                                                                                                                                    云计算之OpenStack核心 第82张

                                                                                                                                    上图是调度过程的一个示例:最开始有 6 个计算节点 Host1-Host6;通过多个 filter 层层过滤,Host2 和 Host4 没有通过,被刷掉了;Host1,Host3,Host5,Host6 计算权重,结果 Host5 得分最高,最终入选。

                                                                                                                                  • Filter: 当 Filter scheduler 需要执行调度操作时,会让 filter 对计算节点进行判断,filter 返回 True 或 False。Nova.conf 中的 scheduler_available_filters 选项用于配置 scheduler 可用的 filter,默认是所有 nova 自带的 filter 都可以用于过滤操作。

                                                                                                                                    云计算之OpenStack核心 第83张

                                                                                                                                    另外还有一个选项 scheduler_default_filters,用于指定 scheduler 真正使用的 filter,默认值如下 :

                                                                                                                                    云计算之OpenStack核心 第84张

                                                                                                                                    Filter scheduler 将按照列表中的顺序依次过滤。 下面依次介绍每个 filter。

                                                                                                                                    1)RetryFilter:

                                                                                                                                    RetryFilter 的作用是刷掉之前已经调度过的节点。举个例子方便大家理解: 假设 A,B,C 三个节点都通过了过滤,最终 A 因为权重值最大被选中执行操作。但由于某个原因,操作在 A 上失败了。 默认情况下,nova-scheduler 会重新执行过滤操作(重复次数由 scheduler_max_attempts 选项指定,默认是 3)。那么这时候 RetryFilter 就会将 A 直接刷掉,避免操作再次失败。RetryFilter 通常作为第一个 filter。

                                                                                                                                    2)AvailabilityZoneFilter:

                                                                                                                                    为提高容灾性和提供隔离服务,可以将计算节点划分到不同的Availability Zone中。例如把一个机架上的机器划分在一个 Availability Zone 中。OpenStack 默认有一个命名为 “Nova” 的 Availability Zone,所有的计算节点初始都是放在 “Nova” 中。用户可以根据需要创建自己的 Availability Zone。

                                                                                                                                    云计算之OpenStack核心 第85张

                                                                                                                                    创建 Instance 时,需要指定将 Instance 部署到在哪个 Availability Zone中。

                                                                                                                                    云计算之OpenStack核心 第86张

                                                                                                                                    nova-scheduler 在做 filtering 时,会使用 AvailabilityZoneFilter 将不属于指定 Availability Zone 的计算节点过滤掉。

                                                                                                                                    3)RamFilter:

                                                                                                                                    RamFilter 将不能满足 flavor 内存需求的计算节点过滤掉。对于内存有一点需要注意: 为了提高系统的资源使用率,OpenStack 在计算节点可用内存时允许 overcommit(超配),也就是可以超过实际内存大小。 超过的程度是通过 nova.conf 中 ram_allocation_ratio 这个参数来控制的,默认值为 1.5。

                                                                                                                                    云计算之OpenStack核心 第87张

                                                                                                                                    其含义是:如果计算节点的内存有 10GB,OpenStack 则会认为它有 15GB(10*1.5)的内存。

                                                                                                                                    4)DiskFilter:

                                                                                                                                    DiskFilter 将不能满足 flavor 磁盘需求的计算节点过滤掉。Disk 同样允许 overcommit,通过 nova.conf 中 disk_allocation_ratio 控制,默认值为 1。

                                                                                                                                    云计算之OpenStack核心 第88张

                                                                                                                                    5)CoreFilter:

                                                                                                                                    CoreFilter 将不能满足 flavor vCPU 需求的计算节点过滤掉。vCPU 同样允许 overcommit,通过 nova.conf 中 cpu_allocation_ratio 控制,默认值为 16。

                                                                                                                                    云计算之OpenStack核心 第89张

                                                                                                                                    这意味着一个 8 vCPU 的计算节点,nova-scheduler 在调度时认为它有 128 个 vCPU。需要提醒的是: nova-scheduler 默认使用的 filter 并没有包含 CoreFilter。 如果要用,可以将 CoreFilter 添加到 nova.conf 的 scheduler_default_filters 配置选项中。

                                                                                                                                    6)ComputeFilter:

                                                                                                                                    ComputeFilter 保证只有 nova-compute 服务正常工作的计算节点才能够被 nova-scheduler调度。ComputeFilter 显然是必选的 filter。

                                                                                                                                    7)ComputeCapabilitiesFilter:ComputeCapabilitiesFilter 根据计算节点的特性来筛选。这个比较高级,我们举例说明。例如我们的节点有 x86_64 和 ARM 架构的,如果想将 Instance 指定部署到 x86_64 架构的节点上,就可以利用到ComputeCapabilitiesFilter。还记得 flavor 中有个 Metadata 吗,Compute 的 Capabilities就在 Metadata中 指定。

                                                                                                                                    云计算之OpenStack核心 第90张

                                                                                                                                    “Compute Host Capabilities” 列出了所有可设置 Capabilities。

                                                                                                                                    云计算之OpenStack核心 第91张

                                                                                                                                    点击 “Architecture” 后面的 “+”,就可以在右边的列表中指定具体的架构。

                                                                                                                                    云计算之OpenStack核心 第92张

                                                                                                                                    配置好后,ComputeCapabilitiesFilter 在调度时只会筛选出 x86_64 的节点。如果没有设置 Metadata,ComputeCapabilitiesFilter 不会起作用,所有节点都会通过筛选。

                                                                                                                                    8)ImagePropertiesFilter:

                                                                                                                                    ImagePropertiesFilter 根据所选 image 的属性来筛选匹配的计算节点。 跟 flavor 类似,image 也有 metadata,用于指定其属性。

                                                                                                                                    云计算之OpenStack核心 第93张

                                                                                                                                    例如希望某个 image 只能运行在 kvm 的 hypervisor 上,可以通过 “Hypervisor Type” 属性来指定。

                                                                                                                                    云计算之OpenStack核心 第94张

                                                                                                                                    点击 “+”,然后在右边的列表中选择 “kvm”。

                                                                                                                                    云计算之OpenStack核心 第95张

                                                                                                                                    配置好后,ImagePropertiesFilter 在调度时只会筛选出 kvm 的节点。如果没有设置 Image 的Metadata,ImagePropertiesFilter 不会起作用,所有节点都会通过筛选。

                                                                                                                                    9)ServerGroupAntiAffinityFilter:

                                                                                                                                    ServerGroupAntiAffinityFilter 可以尽量将 Instance 分散部署到不同的节点上。例如有 inst1,inst2 和 inst3 三个 instance,计算节点有 A,B 和 C。为保证分散部署,进行如下操作:

                                                                                                                                    创建一个 anti-affinity 策略的 server group “group-1” :

                                                                                                                                    云计算之OpenStack核心 第96张

                                                                                                                                    请注意,这里的 server group 其实是 instance group,并不是计算节点的 group。

                                                                                                                                    依次创建 Instance,将inst1, inst2和inst3放到group-1中:

                                                                                                                                    云计算之OpenStack核心 第97张

                                                                                                                                    因为 group-1 的策略是 AntiAffinity,调度时 ServerGroupAntiAffinityFilter 会将inst1, inst2 和 inst3 部署到不同计算节点 A, B 和 C。目前只能在 CLI 中指定 server group 来创建 instance。创建 instance 时如果没有指定 server group,ServerGroupAntiAffinityFilter 会直接通过,不做任何过滤。

                                                                                                                                    10)ServerGroupAffinityFilter:

                                                                                                                                    与 ServerGroupAntiAffinityFilter 的作用相反,ServerGroupAffinityFilter 会尽量将 instance 部署到同一个计算节点上。方法类似:

                                                                                                                                    创建一个 affinity 策略的 server group “group-2”:

                                                                                                                                    云计算之OpenStack核心 第98张

                                                                                                                                    依次创建 instance,将 inst1, inst2 和 inst3 放到 group-2 中:

                                                                                                                                    云计算之OpenStack核心 第99张

                                                                                                                                    因为 group-2 的策略是 Affinity,调度时 ServerGroupAffinityFilter 会将 inst1, inst2 和 inst3 部署到同一个计算节点。创建 instance 时如果没有指定 server group,ServerGroupAffinityFilter 会直接通过,不做任何过滤。

                                                                                                                                  • Weight:

                                                                                                                                    经过前面一堆 filter 的过滤,nova-scheduler 选出了能够部署 instance 的计算节点。如果有多个计算节点通过了过滤,那么最终选择哪个节点呢?Scheduler 会对每个计算节点打分,得分最高的获胜。打分的过程就是 weight,翻译过来就是计算权重值,那么 scheduler 是根据什么来计算权重值呢?目前 nova-scheduler 的默认实现是根据计算节点空闲的内存量计算权重值:空闲内存越多,权重越大,instance 将被部署到当前空闲内存最多的计算节点上。

                                                                                                                                  • 日志:

                                                                                                                                    1)整个过程都被记录到 nova-scheduler 的日志中。比如当我们部署一个 instance 时,打开 nova-scheduler 的日志 /opt/stack/logs/n-sch.log(非 devstack 安装其日志在 /var/log/nova/scheduler.log):

                                                                                                                                    云计算之OpenStack核心 第100张

                                                                                                                                    日志显示初始有两个 host(在我们的实验环境中就是 devstack-controller 和 devstack-compute1),依次经过 9 个 filter 的过滤(RetryFilter,AvailabilityZoneFilter,RamFilter,DiskFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter, ServerGroupAffinityFilter),两个计算节点都通过了。

                                                                                                                                    2)那么接下来就该 weight 了:

                                                                                                                                    云计算之OpenStack核心 第101张

                                                                                                                                    可以看到因为 devstack-controller 的空闲内存比 devstack-compute1 多(7466 > 3434),权重值更大(1.0 > 0.4599),最终选择 devstack-controller。

                                                                                                                                    注:要显示 DEBUG 日志,需要在 /etc/nova/nova.conf 中打开 debug 选项:

                                                                                                                                    云计算之OpenStack核心 第102张

                                                                                                                                    2.3.5.4 nova-compute
                                                                                                                                    • nova-compute 在计算节点上运行,负责管理节点上的 instance。OpenStack 对 instance 的操作,最后都是交给 nova-compute 来完成的。nova-compute 与 Hypervisor 一起实现 OpenStack 对 instance 生命周期的管理。
                                                                                                                                    • 通过 Driver 架构支持多种 Hypervisor:现在市面上有这么多 Hypervisor,nova-compute 如何与它们配合呢?这就是我们之前讨论过的 Driver 架构。nova-compute 为这些 Hypervisor 定义了统一的接口,Hypervisor 只需要实现这些接口,就可以 Driver 的形式即插即用到 OpenStack 系统中。

                                                                                                                                      下面是Nova Driver的架构示意图:

                                                                                                                                      云计算之OpenStack核心 第103张

                                                                                                                                    • 我们可以在 /opt/stack/nova/nova/virt/ 目录下查看到 OpenStack 源代码中已经自带了上面这几个 Hypervisor 的 Driver:

                                                                                                                                      云计算之OpenStack核心 第104张

                                                                                                                                    • 某个特定的计算节点上只会运行一种 Hypervisor,只需在该节点 nova-compute 的配置文件 /etc/nova/nova.conf 中配置所对应的 compute_driver 就可以了。在我们的环境中因为是 KVM,所以配置的是 Libvirt 的 driver:

                                                                                                                                      云计算之OpenStack核心 第105张

                                                                                                                                    • nova-compute 的功能可以分为两类:1)定时向 OpenStack 报告计算节点的状态 ;2)实现 instance 生命周期的管理。

                                                                                                                                      1)定期向 OpenStack 报告计算节点的状态 :

                                                                                                                                      前面我们看到 nova-scheduler 的很多 Filter 是根据算节点的资源使用情况进行过滤的。比如 RamFilter 要检查计算节点当前可以的内存量;CoreFilter 检查可用的 vCPU 数量;DiskFilter 则会检查可用的磁盘空间。

                                                                                                                                      那这里有个问题:OpenStack 是如何得知每个计算节点的这些信息呢? 答案就是:nova-compute 会定期向 OpenStack 报告。从 nova-compute 的日志 /opt/stack/logs/n-cpu.log 可以发现:每隔一段时间,nova-compute 就会报告当前计算节点的资源使用情况和 nova-compute 服务状态。

                                                                                                                                      如果我们再深入问一个问题:nova-compute 是如何获得当前计算节点的资源使用信息的?

                                                                                                                                      云计算之OpenStack核心 第106张

                                                                                                                                      要得到计算节点的资源使用详细情况,需要知道当前节点上所有 instance 的资源占用信息。这些信息谁最清楚?

                                                                                                                                      当然是 Hypervisor。大家还记得之前我们讨论的 Nova Driver 架构吧,nova-compute 可以通过 Hypervisor 的 driver 拿到这些信息。举例来说,在我们的实验环境下 Hypervisor 是 KVM,用的 Driver 是 LibvirtDriver。LibvirtDriver 可以调用相关的 API 获得资源信息,这些 API 的作用相当于我们在 CLI 里执行 virsh nodeinfo、virsh dominfo 等命令。

                                                                                                                                      2)实现 instance 生命周期的管理:

                                                                                                                                      OpenStack 对 instance 最主要的操作都是通过 nova-compute 实现的:包括 instance 的 launch(部署)、shutdown(关机)、reboot(重启)、suspend(挂起)、resume(恢复)、terminate(终止)、resize(重新分配配额)、migration(迁移)、snapshot(快照) 等。

                                                                                                                                      本小节重点学习 nova-compute 如何实现 instance launch(部署)操作。当 nova-scheduler 选定了部署 instance 的计算节点后,会通过消息中间件 rabbitMQ 向选定的计算节点发出 launch instance 的命令。该计算节点上运行的 nova-compute 收到消息后会执行 instance 创建操作。

                                                                                                                                      日志 /opt/stack/logs/n-cpu.log 记录了整个操作过程。nova-compute 创建 instance 的过程可以分为 4 步:为 instance 准备资源;创建 instance 的镜像文件;创建 instance 的 XML 定义文件 ;创建虚拟网络并启动虚拟机。

                                                                                                                                      第1步-为instance 准备资源:

                                                                                                                                      nova-compute 首先会根据指定的 flavor 依次为 instance 分配内存、磁盘空间和 vCPU。可以在日志中看到这些细节:

                                                                                                                                      云计算之OpenStack核心 第107张

                                                                                                                                      网络资源也会提前分配:

                                                                                                                                      云计算之OpenStack核心 第108张

                                                                                                                                      第2步-创建 instance 的镜像文件 :

                                                                                                                                      资源准备好之后,nova-compute 会为 instance 创建镜像文件,OpenStack 启动一个 instance 时,会选择一个 image,这个 image 由 Glance 管理。nova-compute会:首先将该 image 下载到计算节点;然后将其作为 backing file 创建 instance 的镜像文件。

                                                                                                                                      从 Glance 下载 image:nova-compute 首先会检查 image 是否已经下载(比如之前已经创建过基于相同 image 的 instance)。

                                                                                                                                      如果没有,就从 Glance 下载 image 到本地。由此可知,如果计算节点上要运行多个相同 image 的 instance,只会在启动第一个 instance 的时候从 Glance 下载 image,后面的 instance 启动速度就大大加快了。日志如下:

                                                                                                                                      云计算之OpenStack核心 第109张

                                                                                                                                      可以看到:image(ID为 917d60ef-f663-4e2d-b85b-e4511bb56bc2)是 qcow2格式,nova-compute 将其下载,然后通过 qemu-img 转换成 raw 格式。 转换的原因是下一步需要将其作为 instance的镜像文件的 backing file,而 backing file不能是 qcow2 格式。image 的存放目录是 /opt/stack/data/nova/instances/_base,这是由 /etc/nova/nova.conf 的下面两个配置选项决定的。

                                                                                                                                      instances_path = /opt/stack/data/nova/instances

                                                                                                                                      base_dir_name = _base

                                                                                                                                      下载的 image 文件被命名为 60bba5916c6c90ed2ef7d3263de8f653111dd35f,这是 image id 的 SHA1 哈希值。

                                                                                                                                      为 instance 创建镜像文件:有了 image 之后,instance 的镜像文件直接通过 qemu-img 命令创建,backing file 就是下载的 image:

                                                                                                                                      云计算之OpenStack核心 第110张

                                                                                                                                      这里 instance 的镜像文件位于 /opt/stack/data/nova/instances/f1e22596-6844-4d7a-84a3-e41e6d7618ef/disk,格式为 qcow2,其中 f1e22596-6844-4d7a-84a3-e41e6d7618ef 就是 instance 的 id。

                                                                                                                                      可以通过 qemu-info 查看 disk 文件的属性:

                                                                                                                                      云计算之OpenStack核心 第111张

                                                                                                                                      这里有两个容易搞混淆的术语,在此特别说明一下

                                                                                                                                      image,指的是 Glance 上保存的镜像,作为 instance 运行的模板。 计算节点将下载的 image 存放在 /opt/stack/data/nova/instances/_base 目录下。 镜像文件,指的是 instance 启动盘所对应的文件。二者的关系是:image 是镜像文件 的 backing file。image 不会变,而镜像文件会发生变化。 比如安装新的软件后,镜像文件会变大。因为英文中两者都叫 “image”,为避免混淆,我们用 “image” 和 “镜像文件” 作区分。

                                                                                                                                      第3步-创建 instance 的XML 定义文件 : 创建的 XML 文件会保存到该 instance 目录 /opt/stack/data/nova/instances/f1e22596-6844-4d7a-84a3-e41e6d7618ef,命名为 libvirt.xml:

                                                                                                                                      云计算之OpenStack核心 第112张

                                                                                                                                      第4步-创建虚拟网络并启动 instance :

                                                                                                                                      云计算之OpenStack核心 第113张

                                                                                                                                      本环境用的是 linux-bridge 实现的虚拟网络,在 Neutron 章节我们会详细讨论 OpenStack 虚拟网络的不同实现方式。一切就绪,接下来可以启动 instance 了:

                                                                                                                                      云计算之OpenStack核心 第114张

                                                                                                                                      云计算之OpenStack核心 第115张

                                                                                                                                      至此,instance 已经成功启动。OpenStack 图形界面和 KVM CLI 都可以查看到 instance 的运行状态:云计算之OpenStack核心 第116张

                                                                                                                                      云计算之OpenStack核心 第117张

                                                                                                                                      在计算节点上,instance 并不是以 OpenStack上 的名字命名,而是用 instance-xxxxx 的格式。

                                                                                                                                      2.3.6 看懂 OpenStack 日志

                                                                                                                                      2.3.6.1 日志位置
                                                                                                                                      • 我们实验环境使用的是 devstack,日志都统一放在 /opt/stack/logs 目录下,非 devstack日志在var/log目录下。每个服务有自己的日志文件,从命名上很容易区分。

                                                                                                                                        云计算之OpenStack核心 第118张

                                                                                                                                        2.3.6.2 日志类型
                                                                                                                                        • 比如 nova-* 各个子服务的日志都以 “n-” 开头。n-api.log 是 nova-api 的日志;n-cpu.log 是 nova-compute 的日志。
                                                                                                                                        • Glance 的日志文件都是 “g-” 开头。g-api.log 是 glance-api 的日志;g-reg.log 是 glance-registry 的日志。
                                                                                                                                        • Cinder、Neutron 的日志分别以 “c-” 和 “q-” 开头。对于非 devstack 安装的 OpenStack,日志一般放在 /var/log/xxx/ 目录下

                                                                                                                                          比如 Nova 放在 /var/log/nova/ 下,Glance 放在/var/log/glance下……。各个子服务的日志文件也是单独保存,命名也很规范,容易区分。比如 nova-api 的日志一般就命名为 /var/log/nova/api.log,其他日志类似。

                                                                                                                                          2.3.6.3 日志格式
                                                                                                                                          • OpenStack 的日志格式都是统一的,如下:

                                                                                                                                            简单说明一下:

                                                                                                                                            1)时间戳:日志记录的时间,包括年、月、日、时、分、秒、毫秒;

                                                                                                                                            2)日志等级:有INFO、WARNING、ERROR、DEBUG等;

                                                                                                                                            3)代码模块:当前运行的模块Request ID,日志会记录连续不同的操作,为了便于区分和增加可读性,每个操作都被分配唯一的Request ID,便于查找;

                                                                                                                                            4)日志内容:这是日志的主体,记录当前正在执行的操作和结果等重要信息;

                                                                                                                                            5)源代码位置:日志代码的位置,包括方法名称,源代码文件的目录位置和行号。这一项不是所有日志都有。

                                                                                                                                          • 下面举例说明:
                                                                                                                                            2015-12-10 20:46:49.566 DEBUG nova.virt.libvirt.config [req-5c973fff-e9ba-4317-bfd9-76678cc96584 None None] Generated XML ('\n  x86_64\n  Westmere\n
                                                                                                                                            Intel\n  \n  
                                                                                                                                            \n  \n  \n  
                                                                                                                                            \n  \n  \n
                                                                                                                                            \n  \n  \n  
                                                                                                                                            \n\n',)  to_xml /opt/stack/nova/nova/virt/libvirt/config.py:82
                                                                                                                                            

                                                                                                                                            这条日志我们可以得知:代码模块是 nova.virt.libvirt.config,由此可知应该是 Hypervisor Libvirt 相关的操作;日志内容是生成 XML;如果要跟踪源代码,可以到/opt/stack/nova/nova/virt/libvirt/config.py 的 82 行,方法是 to_xml。

                                                                                                                                            • 又例如下面这条日志:
                                                                                                                                              2015-12-10 20:46:49.671 ERROR nova.compute.manager[req-5c973fff-e9ba-4317-bfd9-76678cc96584 None None]No compute node record for host devstack-controller
                                                                                                                                              

                                                                                                                                              这条日志我们可以得知:这是一个 ERROR 日志;具体内容是 “No compute node record for host devstack-controller”;该日志没有指明源代码位置。

                                                                                                                                              2.3.6.4 日志说明
                                                                                                                                              • 学习 OpenStack 需要看日志吗?这个问题的答案取决于你是谁。果你只是 OpenStack 的最终用户,那么日志对你不重要。你只需要在 GUI上 操作,如果出问题直接找管理员就可以了。

                                                                                                                                                但如果你是 OpenStack 的运维和管理人员,日志对你就非常重要了。因为 OpenStack 操作如果出错,GUI 上给出的错误信息是非常笼统和简要的,日志则提供了大量的线索,特别是当 debug 选项打开之后。如果你正处于 OpenStack 的学习阶段,正如我们现在的状态,那么也强烈建议你多看日志。日志能够帮助你更加深入理解 OpenStack 的运行机制。

                                                                                                                                              • 日志能够帮助我们深入学习 OpenStack 和排查问题。但要想高效的使用日志还得有个前提:必须先掌握 OpenStack 的运行机制,然后针对性的查看日志。 就拿 Instance Launch 操作来说,如果之前不了解 nova-* 各子服务在操作中的协作关系,如果没有理解流程图,面对如此多和分散的日志文件,我们也很难下手不是。
                                                                                                                                              • 对于 OpenStack 的运维和管理员来说,在大部分情况下,我们都不需要看源代码。因为 OpenStack 的日志记录得很详细了,足以帮助我们分析和定位问题。 但还是有一些细节日志没有记录,必要时可以通过查看源代码理解得更清楚。 即便如此,日志也会为我们提供源代码查看的线索,不需要我们大海捞针。

                                                                                                                                                2.3.7 虚拟机生命周期管理

                                                                                                                                                2.3.7.1 Launch-部署虚拟机
                                                                                                                                                • 客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(nova-api)发送请求:“帮我创建一个 Instance”:

                                                                                                                                                  云计算之OpenStack核心 第119张

                                                                                                                                                  1)API对请求做一些必要处理后,向 Messaging(RabbitMQ)发送了一条消息:“让 Scheduler 创建一个 Instance”;

                                                                                                                                                  2)Scheduler(nova-scheduler)从 Messaging 获取 API 发给它的消息,然后执行调度算法,从若干计算节点中选出节点 A;

                                                                                                                                                  3)Scheduler 向 Messaging 发送了一条消息:“在计算节点 A 上创建这个 Instance”;

                                                                                                                                                  4)计算节点 A 的 Compute(nova-compute)从 Messaging 中获取到 Scheduler 发给它的消息,然后通过本节点的 Hypervisor Driver 创建 Instance;

                                                                                                                                                  5)在 Instance 创建的过程中,Compute 如果需要查询或更新数据库信息,会通过 Messaging 向 Conductor(nova-conductor)发送消息,Conductor 负责数据库访问。

                                                                                                                                                  2.3.7.2 Shut Off-关闭虚拟机
                                                                                                                                                  • shut off instance 的流程图如下所示:1)向 nova-api 发送请求;2)nova-api 发送消息;3)nova-compute 执行操作。

                                                                                                                                                    云计算之OpenStack核心 第120张

                                                                                                                                                    1)向 nova-api 发送请求:

                                                                                                                                                    客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(nova-api)发送请求:“帮我关闭这个 Instance”:

                                                                                                                                                    云计算之OpenStack核心 第121张

                                                                                                                                                    查看日志 /opt/stack/logs/n-api.log:

                                                                                                                                                    云计算之OpenStack核心 第122张

                                                                                                                                                    对于初学者,这不是一件容易的事情,因为日志里条目和内容很多,特别是 debug 选项打开之后,容易让人眼花缭乱,无从下手。这里给大家几个小窍门:

                                                                                                                                                    a)先确定大的范围,比如在操作之前用 tail -f 打印日志文件,这样需要查看的日志肯定在操作之后的打印输出的这些内容里。 另外也可以通过时间戳来确定需要的日志范围。

                                                                                                                                                    b)利用 “代码模块” 快速定位有用的信息。 nova-* 子服务都有自己特定的代码模块:

                                                                                                                                                    nova-api :

                                                                                                                                                    nova.api.openstack.compute.servers

                                                                                                                                                    nova.compute.api

                                                                                                                                                    nova.api.openstack.wsgi

                                                                                                                                                    nova-compute:

                                                                                                                                                    nova.compute.manager

                                                                                                                                                    nova.virt.libvirt.*

                                                                                                                                                    nova-scheduler:

                                                                                                                                                    nova.scheduler.*

                                                                                                                                                    c)利用 Request ID 查找相关的日志信息。 在上面的日志中,我们可以利用 “req-1758b389-a2d0-44cc-a95a-6f75e4dc07fd” 这个 Request ID 快速定位 n-api.log 中相与 shut off 操作的其他日志条目。 需要补充说明的是,Request ID 是跨日志文件的,这一个特性能帮助我们在其他子服务的日志文件中找到相关信息,我们后面马上将会看到这个技巧的应用。

                                                                                                                                                    2)nova-api 发送消息:

                                                                                                                                                    nova-api 向 Messaging(RabbitMQ)发送了一条消息:“关闭这个 Instance”。nova-api 没有将发送消息的操作记录到日志中,不过我们可以通过查看源代码来验证。 一提到源代码,大家可能以为要大海捞针了。其实很简单,上面日志已经清楚地告诉我们需要查看的源代码在 /opt/stack/nova/nova/compute/api.py 的 1977 行,方法是 force_stop。

                                                                                                                                                    云计算之OpenStack核心 第123张

                                                                                                                                                    force_stop 方法最后调用的是对象 self.compute_rpcapi 的 stop_instance 方法。 在 OpenStack 源码中,以 xxx_rpcapi 命名的对象,表示的就是 xxx 的消息队列。 xxx_rpcapi.yyy() 方法则表示向 xxx 的消息队列发送 yyy 操作的消息。 所以 self.compute_rpcapi.stop_instance() 的作用就是向 RabbitMQ 上 nova-compute 的消息队列里发送一条 stop instance 的消息。这里补充说明一下: 关闭 instance 的前提是 instance 当前已经在某个计算节点上运行,所以这里不需要 nova-scheduler 再帮我们挑选合适的节点,这个跟 launch 操作不同。

                                                                                                                                                    3)nova-compute 执行操作:

                                                                                                                                                    查看计算节点上的日志 /opt/stack/logs/n-cpu.log

                                                                                                                                                    云计算之OpenStack核心 第124张

                                                                                                                                                    这里我们利用了 Request ID “req-1758b389-a2d0-44cc-a95a-6f75e4dc07fd”在 n-cpu.log 中快速定位到 nova-compute 关闭 instance 的日志条目。

                                                                                                                                                  • 小结:

                                                                                                                                                    分析某个操作时,我们首先要理清该操作的内部流程,然后再到相应的节点上去查看日志

                                                                                                                                                    例如shut off 的流程为:

                                                                                                                                                    1)向 nova-api 发送请求;

                                                                                                                                                    2)nova-api 发送消息;

                                                                                                                                                    3)nova-compute 执行操作。

                                                                                                                                                    1,2 两个步骤是在控制节点上执行的,查看 nova-api 的日志。第 3 步是在计算节点上执行的,查看 nova-compute 的日志。

                                                                                                                                                    2.3.7.3 Start-启动虚拟机
                                                                                                                                                    • 下图是 start instance 的流程图,包含1) 向 nova-api 发送请求;2)nova-api 发送消息;3)nova-compute 执行操作。

                                                                                                                                                      云计算之OpenStack核心 第120张

                                                                                                                                                      1)向 nova-api 发送请求:

                                                                                                                                                      客户(可以是 OpenStack 最终用户,也可以是其他程序)向API(nova-api)发送请求:“帮我启动这个 Instance”:

                                                                                                                                                      云计算之OpenStack核心 第126张

                                                                                                                                                      查看日志 /opt/stack/logs/n-api.log :

                                                                                                                                                      云计算之OpenStack核心 第127张

                                                                                                                                                      2)nova-api 发送消息:

                                                                                                                                                      nova-api 向 Messaging(RabbitMQ)发送了一条消息:“启动这个 Instance”。查看源代码 /opt/stack/nova/nova/compute/api.py 的 2002 行,方法是 start:

                                                                                                                                                      云计算之OpenStack核心 第128张

                                                                                                                                                      self.compute_rpcapi.start_instance() 的作用就是向 RabbitMQ 上 nova-compute 的消息队列里发送一条start instance 的消息。

                                                                                                                                                      3)nova-compute 执行操作:

                                                                                                                                                      查看日志 /opt/stack/logs/n-cpu.log。开始启动:

                                                                                                                                                      云计算之OpenStack核心 第129张

                                                                                                                                                      准备虚拟网卡:

                                                                                                                                                      云计算之OpenStack核心 第130张

                                                                                                                                                      准备 instance 的 XML 文件:

                                                                                                                                                      云计算之OpenStack核心 第131张

                                                                                                                                                      准备 instance 镜像文件:

                                                                                                                                                      云计算之OpenStack核心 第132张

                                                                                                                                                      成功启动:

                                                                                                                                                      云计算之OpenStack核心 第133张

                                                                                                                                                      2.3.7.4 Soft/Hard Reboot-软/硬重启虚拟机
                                                                                                                                                      • Soft/Hard Reboot区别:

                                                                                                                                                        云计算之OpenStack核心 第134张

                                                                                                                                                        1)soft reboot 只是重启操作系统,整个过程中,instance 依然处于运行状态。相当于在 linux 中执行 reboot 命令;

                                                                                                                                                        2)hard reboot 是重启 instance,相当于关机之后再开机。

                                                                                                                                                      • 提示:soft/hard reboot 在 nova-api 的日志里找不到,这是因为 /opt/stack/nova/nova/compute/api.py 的 reboot 方法中没有输出 log。 可以通过关键字 “nova.api.openstack.wsgi” 或者 “reboot” 搜索;在 nova-compute 的日志中可以看到 “soft reboot” 和 “hard reboot” 二者有明显的区别。
                                                                                                                                                        2.3.7.5 Lock/Unlock-加锁/解锁虚拟机
                                                                                                                                                        • 为了避免误操作,比如意外重启或删除 instance,可以将 instance 加锁;对被加锁(Lock)的 instance 执行重启等改变状态的操作会提示操作不允许。执行解锁(Unlock)操作后恢复正常。
                                                                                                                                                        • Lock/Unlock 操作都是在 nova-api 中进行的。操作成功后 nova-api 会更新 instance 加锁的状态。执行其他操作时,nova-api 根据加锁状态来判断是否允许。Lock/Unlock 不需要 nova-compute 的参与。
                                                                                                                                                        • 提示:admin 角色的用户不受 lock 的影响,即无论加锁与否都可以正常执行操作;根据默认 policy 的配置,任何用户都可以 unlock。也就是说如果发现 instance 被加锁了,可以通过 unlock 解锁,然后在执行操作。
                                                                                                                                                          2.3.7.6 Terminate -删除虚拟机
                                                                                                                                                          • 下面是 terminate instance 的流程图,包含:1)向nova-api 发送请;2)nova-api 发送消息;3)nova-compute 执行操作。

                                                                                                                                                            云计算之OpenStack核心 第135张

                                                                                                                                                            1)向 nova-api 发送请求 :

                                                                                                                                                            客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(nova-api)发送请求:“帮我删除这个 Instance”:

                                                                                                                                                            云计算之OpenStack核心 第136张

                                                                                                                                                            云计算之OpenStack核心 第137张

                                                                                                                                                            查看日志 /opt/stack/logs/n-api.log:

                                                                                                                                                            云计算之OpenStack核心 第138张

                                                                                                                                                            2)nova-api 发送消息:

                                                                                                                                                            nova-api 向 Messaging(RabbitMQ)发送了一条消息:“删除这个 Instance”。源代码在 /opt/stack/nova/nova/compute/api.py,方法是 _do_force_delete:

                                                                                                                                                            云计算之OpenStack核心 第139张

                                                                                                                                                            3)nova-compute 执行操作 :

                                                                                                                                                            查看日志 /opt/stack/logs/n-cpu.log,关闭 instance:

                                                                                                                                                            云计算之OpenStack核心 第140张

                                                                                                                                                            删除 instance 的镜像文件:

                                                                                                                                                            云计算之OpenStack核心 第141张

                                                                                                                                                            释放虚拟网络等其他资源:

                                                                                                                                                            云计算之OpenStack核心 第142张

                                                                                                                                                            2.3.7.7 Pause/Resume-暂停(短时间)/恢复(暂停后的恢复,非故障时恢复)虚拟机
                                                                                                                                                            • 有时需要短时间暂停 instance,可以通过 Pause 操作将 instance 的状态保存到宿主机的内存中。当需要恢复的时候,执行 Resume 操作,从内存中读回 instance 的状态,然后继续运行 instance。
                                                                                                                                                            • 下面是 pause instance 的流程图,包含:1)向 nova-api 发送请求;2)nova-api 发送消息;3)nova-compute 执行操作。

                                                                                                                                                              云计算之OpenStack核心 第143张

                                                                                                                                                              1)向nova-api发送请求:

                                                                                                                                                              客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(nova-api)发送请求:“帮我暂停这个 Instance”:

                                                                                                                                                              云计算之OpenStack核心 第144张

                                                                                                                                                              查看日志 /opt/stack/logs/n-api.log:

                                                                                                                                                              云计算之OpenStack核心 第145张

                                                                                                                                                              注:对于 Pause 操作,日志没有前面 Start 记录得那么详细。例如这里就没有记录 nova.api.openstack.compute.servers 和 nova.compute.api 代码模块的日志,这可能是因为这个操作逻辑比较简单,开发人员在编码时没有加入日志。

                                                                                                                                                              2)nova-api 发送消息:

                                                                                                                                                              nova-api 向 Messaging(RabbitMQ)发送了一条消息:“暂停这个 Instance”。查看源代码 /opt/stack/nova/nova/compute/api.py,方法是 pause:

                                                                                                                                                              云计算之OpenStack核心 第146张

                                                                                                                                                              3)nova-compute 执行操作:

                                                                                                                                                              查看日志 /opt/stack/logs/n-cpu.log:

                                                                                                                                                              云计算之OpenStack核心 第147张

                                                                                                                                                              暂停操作成功执行后,instance 的状态变为 Paused:

                                                                                                                                                              云计算之OpenStack核心 第148张

                                                                                                                                                              Resume 操作的日志分析留给大家练习。 提示:这里的 Resume 操作实际上是 Unpause 操作,可以通过关键字“unpause”定位日志。

                                                                                                                                                              2.3.7.8 Suspend/Resume-暂停(长时间)/恢复(暂停后的恢复,非故障时恢复)虚拟机
                                                                                                                                                              • 有时需要长时间暂停 instance,可以通过 Suspend 操作将 instance 的状态保存到宿主机的磁盘上。当需要恢复的时候,执行 Resume 操作,从磁盘读回 instance 的状态,使之继续运行。
                                                                                                                                                              • 这里需要对 Suspend 和 Pause 操作做个比较:

                                                                                                                                                                1)相同点:两者都是暂停 instance 的运行,并保存当前状态,之后可以通过 Resume 操作恢复;

                                                                                                                                                                2)不同点:

                                                                                                                                                                a)Suspend 将 instance 的状态保存在磁盘上;Pause 是保存在内存中,所以 Resume 被 Pause 的 instance 要比 Suspend 快。

                                                                                                                                                                b)Suspend 之后的 instance,其状态是 Shut Down;而被 Pause 的 instance 状态是Paused。

                                                                                                                                                                c)虽然都是通过 Resume 操作恢复,Pause 对应的 Resume 在 OpenStack 内部被叫作 “Unpause”;Suspend 对应的 Resume 才是真正的 “Resume”。这个在日志中能体现出来。

                                                                                                                                                                2.3.7.9 Rescue/Unrescue-恢复(发生故障时恢复)/重新引导虚拟机
                                                                                                                                                                • 从这节开始,我们将讨论几种 instance 故障恢复的方法,不同方法适用于不同的场景。
                                                                                                                                                                • 首先我们考虑操作系统故障:有时候由于误操作或者突然断电,操作系统重启后却起不来了。为了最大限度挽救数据,我们通常会使用一张系统盘将系统引导起来,然后在尝试恢复。问题如果不太严重,完全可以通过这种方式让系统重新正常工作。比如某个系统文件意外删除, root 密码遗忘等。
                                                                                                                                                                • Nova 也提供了这种故障恢复机制,叫做 Rescue。

                                                                                                                                                                  云计算之OpenStack核心 第149张

                                                                                                                                                                  Rescue 用指定的 image 作为启动盘引导 instance,将 instance 本身的系统盘作为第二个磁盘挂载到操作系统上。

                                                                                                                                                                • 下面是 rescue instance 的流程图:包含1)向 nova-api 发送请求;2)nova-api 发送消息;3)nova-compute 执行操作。

                                                                                                                                                                  云计算之OpenStack核心 第150张

                                                                                                                                                                  1)向 nova-api 发送请求:

                                                                                                                                                                  目前 Rescue 操作只能通过 CLI 执行。这里我们没有指明用哪个 image 作为引导盘,nova 将使用 instance 部署时使用的 image:

                                                                                                                                                                  云计算之OpenStack核心 第151张

                                                                                                                                                                  查看日志 /opt/stack/logs/n-api.log:

                                                                                                                                                                  云计算之OpenStack核心 第152张

                                                                                                                                                                  2)nova-api 发送消息:

                                                                                                                                                                  nova-api 向 Messaging(RabbitMQ)发送了一条消息:“Rescue 这个 Instance”。源代码在 /opt/stack/nova/nova/compute/api.py,方法是 rescue:

                                                                                                                                                                  云计算之OpenStack核心 第153张

                                                                                                                                                                  3)nova-compute执行操作:

                                                                                                                                                                  查看日志 /opt/stack/logs/n-cpu.log。关闭 instance:

                                                                                                                                                                  云计算之OpenStack核心 第154张

                                                                                                                                                                  云计算之OpenStack核心 第155张

                                                                                                                                                                  通过 image 创建新的引导盘,命名为 disk.rescue:

                                                                                                                                                                  云计算之OpenStack核心 第156张

                                                                                                                                                                  启动 instance:

                                                                                                                                                                  云计算之OpenStack核心 第157张

                                                                                                                                                                  Rescue 执行成功后,可以通过 virsh edit 查看 instance 的 XML 定义。disk.rescue 作为启动盘 vda,真正的启动盘 disk 作为第二个磁盘 vdb:

                                                                                                                                                                  云计算之OpenStack核心 第158张

                                                                                                                                                                  登录 instance,通过 fdisk 也可确认,fdisk -l是以列表的形式列出磁盘分区情况:

                                                                                                                                                                  云计算之OpenStack核心 第159张

                                                                                                                                                                  此时,instance 处于 Rescue 状态:

                                                                                                                                                                  云计算之OpenStack核心 第160张

                                                                                                                                                                  Rescue 操作让我们有机会修复损坏的操作系统。修好之后,使用 Unrescue 操作从原启动盘重新引导 instance。

                                                                                                                                                                  云计算之OpenStack核心 第161张

                                                                                                                                                                  2.3.7.10 Snapshot -创建虚拟机快照
                                                                                                                                                                  • 有时候操作系统损坏得很严重,通过 Rescue 操作无法修复,那么我们就得考虑通过备份恢复了。当然前提是我们之前对instance做过备份。Nova 备份的操作叫 Snapshot,其工作原理是对 instance 的镜像文件(系统盘)进行全量备份,生成一个类型为 snapshot 的 image,然后将其保存到 Glance 上。从备份恢复的操作叫 Rebuild,将在下一节重点讨论。
                                                                                                                                                                  • 下面是 snapshot instance 的流程图,包含1)向 nova-api 发送请求;2)nova-api 发送消息;3)nova-compute 执行操作。

                                                                                                                                                                    1)向 nova-api 发送请求:

                                                                                                                                                                    客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(nova-api)发送请求:“对这个 Instance做个快照”:

                                                                                                                                                                    云计算之OpenStack核心 第162张

                                                                                                                                                                    云计算之OpenStack核心 第163张

                                                                                                                                                                    查看日志 /opt/stack/logs/n-api.log:

                                                                                                                                                                    云计算之OpenStack核心 第164张

                                                                                                                                                                    2)nova-api 发送消息:

                                                                                                                                                                    nova-api 向 Messaging(RabbitMQ)发送了一条消息:“对这个 Instance 做快照”,源代码在 /opt/stack/nova/nova/compute/api.py,方法是 snapshot:

                                                                                                                                                                    云计算之OpenStack核心 第165张

                                                                                                                                                                    3)nova-compute 执行操作:

                                                                                                                                                                    查看日志 /opt/stack/logs/n-cpu.log。暂停 instance:

                                                                                                                                                                    云计算之OpenStack核心 第166张

                                                                                                                                                                    对 instance 的镜像文件做快照:

                                                                                                                                                                    云计算之OpenStack核心 第167张

                                                                                                                                                                    恢复 instance:

                                                                                                                                                                    云计算之OpenStack核心 第168张

                                                                                                                                                                    云计算之OpenStack核心 第169张

                                                                                                                                                                    将快照上传到 Glance:

                                                                                                                                                                    云计算之OpenStack核心 第170张

                                                                                                                                                                    Snapshot 成功保存在 Glance 中:

                                                                                                                                                                    云计算之OpenStack核心 第171张

                                                                                                                                                                    instance 备份成功,下节我们讨论如何通过 snapshot 恢复。

                                                                                                                                                                    2.3.7.11 Rebuild -通过快照恢复虚拟机
                                                                                                                                                                    • 上一节我们讨论了 snapshot,snapshot 的一个重要作用是对 instance 做备份。如果 instance 损坏了,可以通过 snapshot 恢复,这个恢复的操作就是 Rebuild。

                                                                                                                                                                      Rebuild 会用 snapshot 替换 instance 当前的镜像文件,同时保持 instance 的其他诸如网络,资源分配属性不变。

                                                                                                                                                                    • 下面是 rebuild instance 的流程图 :1)向 nova-api 发送请求;2)nova-api 发送消息;3)nova-compute 执行操作。

                                                                                                                                                                      云计算之OpenStack核心 第172张

                                                                                                                                                                      1)向 nova-api 发送请求:

                                                                                                                                                                      客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(nova-api)发送请求:“Rebuild 这个 Instance”:

                                                                                                                                                                      云计算之OpenStack核心 第173张选择用于恢复的 image:

                                                                                                                                                                      云计算之OpenStack核心 第174张

                                                                                                                                                                      查看日志/opt/stack/logs/n-api.log :

                                                                                                                                                                      云计算之OpenStack核心 第175张

                                                                                                                                                                      2)nova-api 发送消息:

                                                                                                                                                                      nova-api 向 Messaging(RabbitMQ)发送了一条消息:“Rebuild 这个 Instance”,源代码在 /opt/stack/nova/nova/compute/api.py,方法是 rebuild:

                                                                                                                                                                      云计算之OpenStack核心 第176张

                                                                                                                                                                      3)nova-compute 执行操作:

                                                                                                                                                                      查看日志 /opt/stack/logs/n-cpu.log

                                                                                                                                                                      关闭 instance:

                                                                                                                                                                      云计算之OpenStack核心 第177张

                                                                                                                                                                      云计算之OpenStack核心 第178张

                                                                                                                                                                      下载新的 image,并准备 instance 的镜像文件 :

                                                                                                                                                                      云计算之OpenStack核心 第179张

                                                                                                                                                                      云计算之OpenStack核心 第180张

                                                                                                                                                                      启动 instance :

                                                                                                                                                                      云计算之OpenStack核心 第181张

                                                                                                                                                                      Rebuild 后,GUI 显示 instance 已经使用新的 image :

                                                                                                                                                                      云计算之OpenStack核心 第182张

                                                                                                                                                                      2.3.7.12 Shelve-搁置虚拟机
                                                                                                                                                                      • Instance 被 Suspend 后虽然处于 Shut Down 状态,但 Hypervisor 依然在宿主机上为其预留了资源,以便在以后能够成功 Resume。如果希望释放这些预留资源,可以使用 Shelve 操作。Shelve 会将 instance 作为 image 保存到 Glance 中,然后在宿主机上删除该 instance。
                                                                                                                                                                      • 下面是 shelve instance 的流程图 :1)向 nova-api 发送请求;2)nova-api 发送消息;3)nova-compute 执行操作。

                                                                                                                                                                        云计算之OpenStack核心 第183张

                                                                                                                                                                        1)客户(可以是 OpenStack 最终用户,也可以是其他程序)向API(nova-api)发送请求:“帮我 shelve 这个 Instance”:

                                                                                                                                                                        云计算之OpenStack核心 第184张

                                                                                                                                                                        查看日志 /opt/stack/logs/n-api.log:

                                                                                                                                                                        云计算之OpenStack核心 第185张

                                                                                                                                                                        2)nova-api 发送消息:

                                                                                                                                                                        nova-api 向 Messaging(RabbitMQ)发送了一条消息:“shelve 这个 Instance”。查看源代码 /opt/stack/nova/nova/compute/api.py,方法是 shelve:

                                                                                                                                                                        云计算之OpenStack核心 第186张

                                                                                                                                                                        3)nova-compute 执行操作 :

                                                                                                                                                                        查看日志 /opt/stack/logs/n-cpu.log。首先,关闭 instance:

                                                                                                                                                                        云计算之OpenStack核心 第187张

                                                                                                                                                                        然后对 instance 执行 snapshot 操作 :

                                                                                                                                                                        云计算之OpenStack核心 第188张

                                                                                                                                                                        成功后,snapshot 生成的 image 会保存在 Glance 上,命名为 -shelved:

                                                                                                                                                                        云计算之OpenStack核心 第189张

                                                                                                                                                                        最后删除 instance 在宿主机上的资源 :

                                                                                                                                                                        云计算之OpenStack核心 第190张

                                                                                                                                                                        暂停操作成功执行后,instance 的状态变为 Shelved Offloaded,电源状态是 Shut Down:

                                                                                                                                                                        云计算之OpenStack核心 第191张

                                                                                                                                                                        2.3.7.13 Unshelve-取消搁置虚拟机
                                                                                                                                                                        • 上一节我们 shelve instance 到 Glance,本节讨论如何通过 unshelve 操作恢复该 instance。因为 Glance 中保存了 instance 的 image,unshelve 的过程其实就是通过该 image launch 一个新的 instance,nova-scheduler 也会调度合适的计算节点来创建该 instance。instance unshelve 后可能运行在与 shelve 之前不同的计算节点上,但 instance 的其他属性(比如 flavor,IP 等)不会改变。
                                                                                                                                                                        • 下面是 Unshelve instance 的流程图 :1)向 nova-api 发送请求;2)nova-api 发送消息;3)nova-scheduler 执行调度;4)nova-scheduler 发送消息;5)nova-compute 执行操作。

                                                                                                                                                                          云计算之OpenStack核心 第192张

                                                                                                                                                                          1)向 nova-api 发送请求 :

                                                                                                                                                                          客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(nova-api)发送请求:“帮我 Unshelve 这个 Instance”:

                                                                                                                                                                          云计算之OpenStack核心 第193张

                                                                                                                                                                          查看日志 /opt/stack/logs/n-api.log:

                                                                                                                                                                          云计算之OpenStack核心 第194张

                                                                                                                                                                          2)nova-api 发送消息:

                                                                                                                                                                          nova-api 向 Messaging(RabbitMQ)发送了一条消息:“unshelve 这个 Instance”。查看源代码 /opt/stack/nova/nova/compute/api.py,方法是 unshelve:

                                                                                                                                                                          云计算之OpenStack核心 第195张

                                                                                                                                                                          3)nova-scheduler 执行调度:

                                                                                                                                                                          nova-scheduler 收到消息后,会为 instance 选择合适的计算节点;查看日志 /opt/stack/logs/n-sch.log:

                                                                                                                                                                          云计算之OpenStack核心 第196张

                                                                                                                                                                          云计算之OpenStack核心 第197张

                                                                                                                                                                          经过筛选,最终 devstack-controller 被选中 launch instance。

                                                                                                                                                                          4)nova-scheduler 发送消息 :

                                                                                                                                                                          nova-scheduler 发送消息,告诉被选中的计算节点可以 launch instance 了。源代码在/opt/stack/nova/nova/scheduler/filter_scheduler.py 第 95 行,方法为 select_destinations:

                                                                                                                                                                          云计算之OpenStack核心 第198张

                                                                                                                                                                          5) nova-compute 执行操作 :

                                                                                                                                                                          nova-compute 执行 unshelve 的过程与 launch instance 非常类似。一样会经过如下几个步骤:a)为 instance 准备 CPU、内存和磁盘资源;b)创建 instance 镜像文件;c)创建 instance 的 XML 定义文件;d)创建虚拟网络并启动 instance。

                                                                                                                                                                          2.3.7.14 Migrate -迁移虚拟机
                                                                                                                                                                          • Migrate 操作的作用是将 instance 从当前的计算节点迁移到其他节点上。Migrate 不要求源和目标节点必须共享存储,当然共享存储也是可以的。Migrate 前必须满足一个条件:计算节点间需要配置 nova 用户无密码访问。
                                                                                                                                                                          • 下面是 Migrate instance 的流程图:1)向 nova-api 发送请求;2)nova-api 发送消息;3)nova-scheduler 执行调度;4)nova-scheduler 发送消息;5)nova-compute 执行操作。

                                                                                                                                                                            云计算之OpenStack核心 第199张

                                                                                                                                                                            1)向 nova-api 发送请求 :

                                                                                                                                                                            客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(nova-api)发送请求:“帮我迁移这个 Instance”;Migrate 操作是特权操作,只能在 Admin 的 instance 菜单中执行:

                                                                                                                                                                            云计算之OpenStack核心 第200张

                                                                                                                                                                            云计算之OpenStack核心 第201张

                                                                                                                                                                            云计算之OpenStack核心 第202张

                                                                                                                                                                            查看日志 /opt/stack/logs/n-api.log:

                                                                                                                                                                            云计算之OpenStack核心 第203张

                                                                                                                                                                            2) nova-api 发送消息:

                                                                                                                                                                            nova-api 向 Messaging(RabbitMQ)发送了一条消息:“迁移这个 Instance”;查看源代码/opt/stack/nova/nova/compute/api.py,方法是 resize。 没错,是 resize 而非 migrate。 这是由于 migrate 实际上是通过 resize 操作实现的,至于为什么要这样设计,我们会在下一节 resize 中详细分析。

                                                                                                                                                                            云计算之OpenStack核心 第204张

                                                                                                                                                                            3)nova-scheduler 执行调度

                                                                                                                                                                            nova-scheduler 收到消息后,会为 instance 选择合适的目标计算节点。查看日志 /opt/stack/logs/n-sch.log可以看到,因为 devstack-compute1 的权值比 devstack-controller 大,最终选择 devstack-compute1 作为目标节点。

                                                                                                                                                                            云计算之OpenStack核心 第205张

                                                                                                                                                                            看到上面的日志,大家发现什么问题没有?

                                                                                                                                                                            在分析这段日志的时候,我发现 scheduler 选出来的计算节点有可能是当前节点源节点!因为 scheduler 并没在初始的时候将源节点剔除掉,而是与其他节点放在一起做 filter,按照这个逻辑,只要源节点的权值足够大,是有可能成为目标节点的。

                                                                                                                                                                            那紧接着的问题是:如果源节点和目标节点是同一个,migrate 操作会怎样进行呢?

                                                                                                                                                                            实验得知,nova-compute 在做 migrate 的时候会检查目标节点,如果发现目标节点与源节点相同,会抛出 UnableToMigrateToSelf 异常。Nova-compute 失败之后,scheduler 会重新调度,由于有 RetryFilter,会将之前选择的源节点过滤掉,这样就能选到不同的计算节点了。 在上面的操作中 sheduler 选择的目标节点是 devstack-compute1,意味着 instance 将从 devstack-controller 迁移到 devstack-compute1。

                                                                                                                                                                            4)nova-scheduler 发送消息:

                                                                                                                                                                            nova-scheduler 发送消息,通知计算节点可以迁移 instance 了

                                                                                                                                                                            源代码在/opt/stack/nova/nova/scheduler/filter_scheduler.py 第 95 行,方法为 select_destinations(选择目标节点):

                                                                                                                                                                            云计算之OpenStack核心 第206张

                                                                                                                                                                            4)nova-compute 执行操作 :

                                                                                                                                                                            nova-compute 会在源计算节点和目标计算节点上分别执行操作。

                                                                                                                                                                            源计算节点 devstack-controller:

                                                                                                                                                                            迁移操作在源节点上首先会关闭 instance,然后将 instance 的镜像文件传到目标节点上。日志在 /opt/stack/logs/n-cpu.log,具体步骤如下:

                                                                                                                                                                            a)开始 migrate

                                                                                                                                                                            云计算之OpenStack核心 第207张

                                                                                                                                                                            b)在目标节点上创建 instance 的目录:

                                                                                                                                                                            nova-compute 首先会尝试通过 ssh 在目标节点上的 instance 目录里 touch 一个临时文件,日志如下:

                                                                                                                                                                            云计算之OpenStack核心 第208张

                                                                                                                                                                            如果 touch 失败,说明目标节点上还没有该 instance 的目录,也就是说,源节点和目标节点没有共享存储。

                                                                                                                                                                            那么接下来就要在目标节点上创建 instance 的目录,日志如下:

                                                                                                                                                                            云计算之OpenStack核心 第209张

                                                                                                                                                                            关闭 instance:

                                                                                                                                                                            云计算之OpenStack核心 第210张

                                                                                                                                                                            将 instance 的镜像文件通过 scp 传到目标节点上:

                                                                                                                                                                            云计算之OpenStack核心 第211张

                                                                                                                                                                            目标计算节点 devstack-compute1:

                                                                                                                                                                            在目标节点上启动 instance,过程与 launch instance 非常类似。会经过如下几个步骤:为 instance 准备 CPU、内存和磁盘资源;创建 instance 镜像文件;创建 instance 的 XML 定义文件;创建虚拟网络并启动 instance。

                                                                                                                                                                            5)Confirm

                                                                                                                                                                            这时,instance 会处于 “Confirm or Revert Resize/Migrate”状态,需要用户确认或者回退当前的迁移操作,实际上给了用户一个反悔的机会。

                                                                                                                                                                            云计算之OpenStack核心 第212张

                                                                                                                                                                            当我们按下 Confirm 按钮后,会发生如下事情,nova-api 接收到 confirm 的消息:

                                                                                                                                                                            云计算之OpenStack核心 第213张

                                                                                                                                                                            源计算节点删除 instance 的目录,并在 Hypervisor 上删除 instance:

                                                                                                                                                                            云计算之OpenStack核心 第214张

                                                                                                                                                                            云计算之OpenStack核心 第215张

                                                                                                                                                                            目标计算节点不需要做任何事情。

                                                                                                                                                                            6)Revert还原

                                                                                                                                                                            如果执行的是 Revert 操作会发生什么事情呢?

                                                                                                                                                                            云计算之OpenStack核心 第216张

                                                                                                                                                                            nova-api 接收到 revert 的消息: 云计算之OpenStack核心 第217张

                                                                                                                                                                            在目标计算节点上关闭 instance,删除 instance 的目录,并在 Hypervisor 上删除 instance:

                                                                                                                                                                            云计算之OpenStack核心 第218张

                                                                                                                                                                            云计算之OpenStack核心 第219张

                                                                                                                                                                            源计算节点上启动 instance:

                                                                                                                                                                            因为之前迁移的时候只是在源节点上关闭了该 instance,revert 操作只需重新启动 instance。

                                                                                                                                                                            云计算之OpenStack核心 第220张

                                                                                                                                                                            云计算之OpenStack核心 第221张

                                                                                                                                                                            以上是 Migrate 操作的完整流程,这里有一点需要特别注意:迁移过程中源和目标节点之前需要使用 ssh 和 scp,为了使操作顺利进行,必须要保证 nova-compute 进程的启动用户(通常是 nova,也可能是 root,可以通过 ps 命令确认)能够在计算节点之间无密码访问。否则 nova-compute 会等待密码输入,但后台服务是无法输入密码的,迁移操作会一直卡在那里。

                                                                                                                                                                            2.3.7.15 Resize-调整虚拟机的vCPU、内存和磁盘资源
                                                                                                                                                                            • Resize 的作用是调整 instance 的 vCPU、内存和磁盘资源。Instance 需要多少资源是定义在 flavor 中的,resize 操作是通过为 instance 选择新的 flavor 来调整资源的分配。
                                                                                                                                                                            • 有了前面对 Migrate 的分析,再来看 Resize 的实现就非常简单了。因为 instance 需要分配的资源发生了变化,在 resize 之前需要借助 nova-scheduler 重新为 instance 选择一个合适的计算节点,如果选择的节点与当前节点不是同一个,那么就需要做 Migrate。所以本质上讲:Resize 是在 Migrate 的同时应用新的 flavor。 Migrate 可以看做是 resize 的一个特例:flavor 没发生变化的 resize,这也是为什么我们在上一节日志中看到 migrate 实际上是在执行 resize 操作。
                                                                                                                                                                            • 下面是 Resize instance 的流程图:1)向 nova-api 发送请求;2)nova-api 发送消息;3)nova-scheduler 执行调度;4)nova-scheduler 发送消息;5)nova-compute 执行操作。

                                                                                                                                                                              云计算之OpenStack核心 第222张

                                                                                                                                                                            • Resize 分两种情况:

                                                                                                                                                                              1)nova-scheduler 选择的目标节点与源节点是不同节点。操作过程跟上一节 Migrate 几乎完全一样,只是在目标节点启动 instance 的时候按新的 flavor 分配资源。 同时,因为要跨节点复制文件,也必须要保证 nova-compute 进程的启动用户(通常是 nova,也可能是 root,可以通过 ps 命令确认)能够在计算节点之间无密码访问。 对这一种情况我们不再赘述,请参看前面 Migrate 小节。

                                                                                                                                                                              2)目标节点与源节点是同一个节点。则不需要 migrate。下面我们重点讨论这一种情况。

                                                                                                                                                                              a) 向 nova-api 发送请求

                                                                                                                                                                              客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(nova-api)发送请求:“帮我 Resize 这个 Instance”:

                                                                                                                                                                              云计算之OpenStack核心 第223张

                                                                                                                                                                              选择新的 flavor:

                                                                                                                                                                              云计算之OpenStack核心 第224张

                                                                                                                                                                              点击 Resize 按钮:

                                                                                                                                                                              云计算之OpenStack核心 第225张

                                                                                                                                                                              查看日志 /opt/stack/logs/n-api.log:

                                                                                                                                                                              云计算之OpenStack核心 第226张

                                                                                                                                                                              b)nova-api 发送消息:

                                                                                                                                                                              nova-api 向 Messaging(RabbitMQ)发送了一条消息:“Resize 这个 Instance”。查看源代码/opt/stack/nova/nova/compute/api.py,方法是 resize_instance:

                                                                                                                                                                              云计算之OpenStack核心 第227张

                                                                                                                                                                              c)nova-scheduler 执行调度:

                                                                                                                                                                              nova-scheduler 收到消息后,会为 instance 选择合适的目标计算节点。查看日志 /opt/stack/logs/n-sch.log:

                                                                                                                                                                              云计算之OpenStack核心 第228张

                                                                                                                                                                              在本例中,nova-scheduler 选择了 devstack-compute1 作为的目节点,与源节点相同。

                                                                                                                                                                              d)nova-scheduler 发送消息 :

                                                                                                                                                                              nova-scheduler 发送消息,通知计算节点可以迁移 instance 了。源代码在 /opt/stack/nova/nova/scheduler/filter_scheduler.py 第 95 行,方法为 select_destinations:

                                                                                                                                                                              云计算之OpenStack核心 第229张

                                                                                                                                                                              e)nova-compute 执行操作:

                                                                                                                                                                              在目标节点上启动 instance,过程与 launch instance 非常类似。日志记录在 /opt/stack/logs/n-cpu.log。会经过如下几个步骤:

                                                                                                                                                                              按新的 flavor 为 instance 准备 CPU、内存和磁盘资源:

                                                                                                                                                                              云计算之OpenStack核心 第230张

                                                                                                                                                                              关闭 instance:

                                                                                                                                                                              云计算之OpenStack核心 第231张

                                                                                                                                                                              创建 instance 镜像文件:

                                                                                                                                                                              云计算之OpenStack核心 第232张

                                                                                                                                                                              将 instance 的目录备份一份,命名为_resize,以便 revert:

                                                                                                                                                                              云计算之OpenStack核心 第233张

                                                                                                                                                                              创建 instance 的 XML 定义文件:

                                                                                                                                                                              云计算之OpenStack核心 第234张

                                                                                                                                                                              准备虚拟网络:

                                                                                                                                                                              云计算之OpenStack核心 第235张

                                                                                                                                                                              启动 instance:

                                                                                                                                                                              云计算之OpenStack核心 第236张

                                                                                                                                                                              f) Confirm

                                                                                                                                                                              这时,instance 的状态处于“Confirm or Revert Resize/Migrate”状态,需要用户确认或者回退当前的迁移操作,实际上给了用户一个反悔的机会。

                                                                                                                                                                              云计算之OpenStack核心 第237张

                                                                                                                                                                              当我们按下 Confirm 按钮后,会发生如下事情:nova-api 接收到 confirm 的消息:

                                                                                                                                                                              云计算之OpenStack核心 第238张

                                                                                                                                                                              删除计算节上备份的 instance 目录 _resize:

                                                                                                                                                                              云计算之OpenStack核心 第239张

                                                                                                                                                                              云计算之OpenStack核心 第240张

                                                                                                                                                                              g)revert恢复

                                                                                                                                                                              反过来,如果执行 Revert 操作会发生什么事情呢?

                                                                                                                                                                              云计算之OpenStack核心 第241张

                                                                                                                                                                              nova-api 接收到 revert 的消息:

                                                                                                                                                                              云计算之OpenStack核心 第242张

                                                                                                                                                                              在计算节点上关闭 instance:

                                                                                                                                                                              云计算之OpenStack核心 第243张

                                                                                                                                                                              通过备份目录 _resize 恢复 instance 目录:

                                                                                                                                                                              云计算之OpenStack核心 第244张

                                                                                                                                                                              重新启动 instance:

                                                                                                                                                                              云计算之OpenStack核心 第245张

                                                                                                                                                                              2.3.7.16 Live Migrate-在线迁移虚拟机
                                                                                                                                                                              • Migrate 操作会先将 instance 停掉,也就是所谓的“冷迁移”。

                                                                                                                                                                                而 Live Migrate 是“热迁移”,也叫“在线迁移”,instance不会停机。

                                                                                                                                                                              • Live Migrate 分两种:

                                                                                                                                                                                1)源和目标节点没有共享存储,instance 在迁移的时候需要将其镜像文件从源节点传到目标节点,这叫做 Block Migration(块迁移);

                                                                                                                                                                                2)源和目标节点共享存储,instance 的镜像文件不需要迁移,只需要将 instance 的状态迁移到目标节点。

                                                                                                                                                                              • 源和目标节点需要满足一些条件才能支持 Live Migration:

                                                                                                                                                                                1)源和目标节点的 CPU 类型要一致;

                                                                                                                                                                                2)源和目标节点的 Libvirt 版本要一致;

                                                                                                                                                                                3)源和目标节点能相互识别对方的主机名称,比如可以在 /etc/hosts 中加入对方的条目;

                                                                                                                                                                                云计算之OpenStack核心 第246张

                                                                                                                                                                                4)在源和目标节点的 /etc/nova/nova.conf 中指明在线迁移时使用 TCP 协议;

                                                                                                                                                                                云计算之OpenStack核心 第247张

                                                                                                                                                                                5)Instance 使用 config driver 保存其 metadata。在 Block Migration 过程中,该 config driver 也需要迁移到目标节点。由于目前 libvirt 只支持迁移 vfat 类型的 config driver,所以必须在 /etc/nova/nova.conf 中明确指明 launch instance 时创建 vfat 类型的 config driver;

                                                                                                                                                                                云计算之OpenStack核心 第248张

                                                                                                                                                                                6)源和目标节点的 Libvirt TCP 远程监听服务得打开,需要在下面两个配置文件中做一点配置;

                                                                                                                                                                                云计算之OpenStack核心 第249张

                                                                                                                                                                              • 非共享存储 Block Migration:

                                                                                                                                                                                我们先讨论非共享存储的 Block Migration流程图如下:1)向 nova-api 发送请求;2)nova-api 发送消息;3)nova-compute 执行操作。

                                                                                                                                                                                1)向nova-api发送请求 :

                                                                                                                                                                                客户(可以是 OpenStack 最终用户,也可以是其他程序)向API(nova-api)发送请求:“帮我将这个 Instance 从节点 A Live Migrate 到节点 B”

                                                                                                                                                                                云计算之OpenStack核心 第250张

                                                                                                                                                                                云计算之OpenStack核心 第251张

                                                                                                                                                                                这里源节点是 devstack-compute1,目标节点是 devstack-controller,因为是非共享存储,记得将“Block Migration”勾选上。这里还有一个“Disk Over Commit”选项,如果勾选了此选项,nova 在检查目标节点的磁盘空间是否足够时,是以 instance 磁盘镜像文件定义的最大容量为准;否则,以磁盘镜像文件当前的实际大小为准。

                                                                                                                                                                                查看日志 /opt/stack/logs/n-api.log:

                                                                                                                                                                                云计算之OpenStack核心 第252张

                                                                                                                                                                                2)nova-api 发送消息 :

                                                                                                                                                                                nova-api 向 Messaging(RabbitMQ)发送了一条消息:“Live Migrate 这个 Instance” ;源代码在/opt/stack/nova/nova/compute/api.py,方法是 live_migrate:

                                                                                                                                                                                云计算之OpenStack核心 第253张

                                                                                                                                                                                3)nova-compute 执行操作 :

                                                                                                                                                                                源和目标节点执行 Live Migrate 的操作过程如下:目标节点执行迁移前的准备工作,首先将 instance 的数据迁移过来,主要包括镜像文件、虚拟网络等资源,日志在 devstack-controller:/opt/stack/logs/n-cpu.log:

                                                                                                                                                                                云计算之OpenStack核心 第254张

                                                                                                                                                                                云计算之OpenStack核心 第255张

                                                                                                                                                                                源节点启动迁移操作,暂停 instance:

                                                                                                                                                                                云计算之OpenStack核心 第256张

                                                                                                                                                                                在目标节点上 Resume instance:

                                                                                                                                                                                云计算之OpenStack核心 第257张

                                                                                                                                                                                在源节点上执行迁移的后处理工作,删除 instance:

                                                                                                                                                                                云计算之OpenStack核心 第258张

                                                                                                                                                                                云计算之OpenStack核心 第259张

                                                                                                                                                                                在目标节点上执行迁移的后处理工作,创建 XML,在 Hypervisor 中定义 instance,使之下次能够正常启动。

                                                                                                                                                                                云计算之OpenStack核心 第260张

                                                                                                                                                                                Instance 在 Live Migrate 的整个过程中不会停机,我们通过 Ping 操作来观察:

                                                                                                                                                                                云计算之OpenStack核心 第261张

                                                                                                                                                                                可见在迁移过程中,Ping 进程没有中断,只是有一个 ping 包的延迟增加了。

                                                                                                                                                                              • 共享存储 Live Migration:

                                                                                                                                                                                有多种方式可以实现共享存储,比如可以将 instance 的镜像文件放在 NFS 服务器上,或者使用 NAS 服务器,或者分布式文件系统。作为学习和实验,这里我们采用 NFS 方案。其他共享存储方案对于 Live Migration 本质上是一样的,只是在性能和高可用性上更好。

                                                                                                                                                                                1)搭建 NFS 环境

                                                                                                                                                                                将 devstack-controller 作为 NFS 服务器,共享其目录 /opt/stack/data/nova/instances。devstack-compute1 作为 NFS 客户端将此目录 mount 到本机,如下所示:

                                                                                                                                                                                云计算之OpenStack核心 第262张

                                                                                                                                                                                这样,OpenStack 的 instance 在 devstack-controller 和 devstack-compute1 上就实现共享存储了。共享存储的迁移过程与 Block Migrate 基本上一样,只是几个环节有点区别:向 nova-api 提交请求的时候,不能勾选“Block Migrate”:

                                                                                                                                                                                云计算之OpenStack核心 第263张

                                                                                                                                                                                因为源和目标节点都能直接访问 instance 的镜像,所以目标节点在准备阶段不需要传输镜像文件,源节点在迁移后处理阶段也无需删除 instance 的目录。只有 instance 的状态需要从源节点传输到的目标节点,整个迁移速递比 Block Migration 快很多。

                                                                                                                                                                                2.3.7.17 Evacuate-撤离虚拟机
                                                                                                                                                                                • Rebuild 可以恢复损坏的 instance。那如果是宿主机坏了怎么办呢?比如硬件故障或者断电造成整台计算节点无法工作,该节点上运行的 instance 如何恢复呢?用 Shelve 或者 Migrate 可不可以?很不幸,这两个操作都要求 instance 所在计算节点的 nova-compute 服务正常运行。幸运的是,还有 Evacuate 操作。
                                                                                                                                                                                • Evacuate 可在 nova-compute 无法工作的情况下将节点上的 instance 迁移到其他计算节点上。但有个前提是 Instance 的镜像文件必须放在共享存储上。
                                                                                                                                                                                • 下面是 Evacuate instance 的流程图:1)向 nova-api 发送请求;2)nova-api 发送消息;3)nova-scheduler 执行调度;4)nova-scheduler 发送消息;5)nova-compute 执行操作。

                                                                                                                                                                                  云计算之OpenStack核心 第264张

                                                                                                                                                                                  1)向 nova-api 发送请求 :

                                                                                                                                                                                  我们的实验场景如下: Instance c2 运行在 devstack-compute1 上,通过断电模拟计算节点故障,然后执行 Evacuate 操作恢复 instance c2,目前 Evacuate 只能通过 CLI 执行。

                                                                                                                                                                                  云计算之OpenStack核心 第265张

                                                                                                                                                                                  云计算之OpenStack核心 第266张

                                                                                                                                                                                  这里需要指定 –on-shared-storage 这个参数。

                                                                                                                                                                                  查看日志 /opt/stack/logs/n-api.log:

                                                                                                                                                                                  云计算之OpenStack核心 第267张

                                                                                                                                                                                  2)nova-api 发送消息

                                                                                                                                                                                  nova-api 向 Messaging(RabbitMQ)发送了一条消息:“Evacuate 这个 Instance”;查看源代码 /opt/stack/nova/nova/compute/api.py,方法是 evacuate:

                                                                                                                                                                                  云计算之OpenStack核心 第268张

                                                                                                                                                                                  大家注意到没有,evacuate 实际上是通过 rebuild 操作实现的。这是可以理解的,因为 evacuate 是用共享存储上 instance 的镜像文件重新创建虚机

                                                                                                                                                                                  3) nova-scheduler 执行调度 :

                                                                                                                                                                                  nova-scheduler 收到消息后,会为 instance 选择合适的计算节点

                                                                                                                                                                                  查看日志 /opt/stack/logs/n-sch.log:

                                                                                                                                                                                  云计算之OpenStack核心 第269张

                                                                                                                                                                                  nova-scheduler 最后选择在 devstack-controller 计算节点上重建 instance。

                                                                                                                                                                                  4) nova-compute 执行操作 :

                                                                                                                                                                                  计算节点上的工作是用共享存储上的镜像文件重建 instance。日志在 devstack-controller:/opt/stack/logs/n-cpu.log。为instance分配资源:

                                                                                                                                                                                  云计算之OpenStack核心 第270张

                                                                                                                                                                                  使用共享存储上的镜像文件:

                                                                                                                                                                                  云计算之OpenStack核心 第271张

                                                                                                                                                                                  启动 instance:

                                                                                                                                                                                  云计算之OpenStack核心 第272张

                                                                                                                                                                                  Evacuate 操作完成后,instance 在 devstack-controller 上运行。

                                                                                                                                                                                  2.3.7.18 Nova操作总结

                                                                                                                                                                                  云计算之OpenStack核心 第273张

                                                                                                                                                                                  如上图所示,我们把对 Instance 的管理按运维工作的场景分为两类:常规操作和故障处理。

                                                                                                                                                                                  • 常规操作:常规操作中,Launch、Start、Reboot、Shut Off 和 Terminate 都很好理解。 下面几个操作重点回顾一下:

                                                                                                                                                                                    1)Resize:通过应用不同的 flavor 调整分配给 instance 的资源。

                                                                                                                                                                                    2)Lock/Unlock:可以防止对 instance 的误操作。

                                                                                                                                                                                    3)Pause/Suspend/Resume:暂停当前 instance,并在以后恢复。 Pause 和 Suspend 的区别在于 Pause 将 instance 的运行状态保存在计算节点的内存中,而 Suspend 保存在磁盘上。

                                                                                                                                                                                    Pause 的优点是 Resume 的速度比 Suspend 快;缺点是如果计算节点重启,内存数据丢失,就无法 Resume 了,而 Suspend 则没有这个问题。

                                                                                                                                                                                    4)Snapshot:备份 instance 到 Glance。产生的 image 可用于故障恢复,或者以此为模板部署新的 instance。

                                                                                                                                                                                  • 故障处理 :故障处理有两种场景:计划内和计划外。计划内是指提前安排时间窗口做的维护工作,比如服务器定期的微码升级,添加更换硬件等。计划外是指发生了没有预料到的突发故障,比如强行关机造成 OS 系统文件损坏,服务器掉电,硬件故障等。

                                                                                                                                                                                    1) 计划内故障处理:对于计划内的故障处理,可以在维护窗口中将 instance 迁移到其他计算节点。 涉及如下操作:

                                                                                                                                                                                    a)Migrate:将 instance 迁移到其他计算节点。迁移之前,instance 会被 Shut Off,支持共享存储和非共享存储。

                                                                                                                                                                                    b)Live Migrate:与 Migrate 不同,Live Migrate 能不停机在线地迁移 instance,保证了业务的连续性。也支持共享存储和非共享存储(Block Migration)。

                                                                                                                                                                                    c)Shelve/Unshelve:Shelve 将 instance 保存到 Glance 上,之后可通过 Unshelve 重新部署。Shelve 操作成功后,instance 会从原来的计算节点上删除。Unshelve 会重新选择节点部署,可能不是原节点。

                                                                                                                                                                                    2) 计划外故障处理:计划外的故障按照影响的范围又分为两类:Instance 故障和计算节点故障;

                                                                                                                                                                                    a)Instance 故障:Instance故障只限于某一个 instance 的操作系统层面,系统无法正常启动。可以使用如下操作修复 instance:

                                                                                                                                                                                    i)Rescue/Unrescue:用指定的启动盘启动,进入 Rescue 模式,修复受损的系统盘。成功修复后,通过 Unrescue 正常启动 instance。

                                                                                                                                                                                    ii)Rebuild:如果 Rescue 无法修复,则只能通过 Rebuild 从已有的备份恢复。Instance 的备份是通过 snapshot 创建的,所以需要有备份策略定期备份。

                                                                                                                                                                                    b)计算节点故障:Instance 故障的影响范围局限在特定的 instance,计算节点本身是正常工作的。如果计算节点发生故障,OpenStack 则无法与节点的 nova-compute 通信,其上运行的所有 instance 都会受到影响。这个时候,只能通过 Evacuate 操作在其他正常节点上重建 Instance。

                                                                                                                                                                                    i)Evacuate:利用共享存储上 Instance 的镜像文件在其他计算节点上重建 Instance。 所以提前规划共享存储是关键。

                                                                                                                                                                                    2.4 块存储服务Cinder:为 instance 提供虚拟磁盘

                                                                                                                                                                                    云计算之OpenStack核心 第274张

                                                                                                                                                                                    • 理解 Block Storage

                                                                                                                                                                                      操作系统获得存储空间的方式一般有两种:1)通过某种协议(SAS,SCSI,SAN,iSCSI 等)挂接裸硬盘,然后分区、格式化、创建文件系统;或者直接使用裸硬盘存储数据(数据库);2)通过 NFS、CIFS 等 协议,mount 远程的文件系统。

                                                                                                                                                                                      第一种裸硬盘的方式叫做 Block Storage(块存储),每个裸硬盘通常也称作 Volume(卷);

                                                                                                                                                                                      第二种叫做文件系统存储。NAS 和 NFS 服务器,以及各种分布式文件系统提供的都是这种存储。

                                                                                                                                                                                    • 理解 Block Storage Service

                                                                                                                                                                                      Block Storage Service提供对 volume 从创建到删除整个生命周期的管理。从 instance 的角度看,挂载的每一个 Volume 都是一块硬盘。OpenStack 提供 Block Storage Service 的是 Cinder,其具体功能是:1)提供 REST API 使用户能够查询和管理 volume、volume snapshot 以及 volume type;2)提供 scheduler 调度 volume 创建请求,合理优化存储资源的分配;3)通过 driver 架构支持多种 back-end(后端)存储方式,包括 LVM,NFS,Ceph 和其他诸如 EMC、IBM 等商业存储产品和方案。

                                                                                                                                                                                      2.4.1 Cider架构

                                                                                                                                                                                      云计算之OpenStack核心 第275张

                                                                                                                                                                                      • 上图是cider的逻辑架构,包含如下组件:

                                                                                                                                                                                        1)cinder-api:接收 API 请求,调用 cinder-volume 执行操作;

                                                                                                                                                                                        2)cinder-volume:管理 volume 的服务,与 volume provider 协调工作,管理 volume 的生命周期。运行 cinder-volume 服务的节点被称作为存储节点;

                                                                                                                                                                                        3)cinder-scheduler:scheduler 通过调度算法选择最合适的存储节点创建 volume;

                                                                                                                                                                                        4)volume provider:数据的存储设备,为 volume 提供物理存储空间。cinder-volume 支持多种 volume provider,每种 volume provider 通过自己的 driver 与cinder-volume 协调工作。

                                                                                                                                                                                        5)Message Queue:Cinder 各个子服务通过消息队列实现进程间通信和相互协作。因为有了消息队列,子服务之间实现了解耦,这种松散的结构也是分布式系统的重要特征。

                                                                                                                                                                                        6)Database:Cinder 有一些数据需要存放到数据库中,一般使用 MySQL。数据库是安装在控制节点上的,比如在我们的实验环境中,可以访问名称为“cinder”的数据库。

                                                                                                                                                                                        云计算之OpenStack核心 第276张

                                                                                                                                                                                        2.4.2 物理部署方案

                                                                                                                                                                                        • Cinder 的服务会部署在两类节点上,控制节点和存储节点。我们来看看控制节点 devstack-controller 上都运行了哪些 cinder-* 子服务:

                                                                                                                                                                                          云计算之OpenStack核心 第277张

                                                                                                                                                                                          inder-api 和 cinder-scheduler 部署在控制节点上,这个很合理。至于 cinder-volume 也在控制节点上可能有些同学就会迷糊了:cinder-volume 不是应该部署在存储节点上吗?

                                                                                                                                                                                          要回答这个问题,首先要搞清楚一个事实:OpenStack 是分布式系统,其每个子服务都可以部署在任何地方,只要网络能够连通。无论是哪个节点,只要上面运行了 cinder-volume,它就是一个存储节点,当然,该节点上也可以运行其他 OpenStack服务。

                                                                                                                                                                                          cinder-volume 是一顶存储节点帽子,cinder-api 是一顶控制节点帽子。在我们的环境中,devstack-controller 同时戴上了这两顶帽子,所以它既是控制节点,又是存储节点。当然,我们也可以用一个专门的节点来运行 cinder-volume。这再一次展示了 OpenStack 分布式架构部署上的灵活性:可以将所有服务都放在一台物理机上,用作一个 All-in-One 的测试环境;而在生产环境中可以将服务部署在多台物理机上,获得更好的性能和高可用。RabbitMQ 和 MySQL 通常是放在控制节点上的。

                                                                                                                                                                                        • 另外,也可以用 cinder service list 查看 cinder-* 子服务都分布在哪些节点上:

                                                                                                                                                                                          云计算之OpenStack核心 第278张

                                                                                                                                                                                        • 还有一个问题:volume provider 放在那里:一般来讲,volume provider 是独立的。cinder-volume 使用 driver 与 volume provider 通信并协调工作。所以只需要将 driver 与 cinder-volume 放到一起就可以了。在 cinder-volume 的源代码目录下有很多 driver,支持不同的 volume provider。

                                                                                                                                                                                          云计算之OpenStack核心 第279张

                                                                                                                                                                                          后面我们会以 LVM 和 NFS 这两种 volume provider 为例讨论 cinder-volume 的使用,其他 volume provider 可以查看 OpenStack 的 configuration 文档。

                                                                                                                                                                                          2.4.3 Cinder设计思想

                                                                                                                                                                                          • 从 volume 创建流程看 cinder-* 子服务如何协同工作 ,对于 Cinder 学习来说,Volume 创建是一个非常好的场景,涉及各个 cinder-* 子服务,下面是流程图:

                                                                                                                                                                                            云计算之OpenStack核心 第280张

                                                                                                                                                                                            1)客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(cinder-api)发送请求:“帮我创建一个volume”;

                                                                                                                                                                                            2)API 对请求做一些必要处理后,向 Messaging(RabbitMQ)发送了一条消息:“让 Scheduler 创建一个 volume” ;

                                                                                                                                                                                            3)Scheduler(cinder-scheduler)从 Messaging 获取到 API 发给它的消息,然后执行调度算法,从若干计存储点中选出节点 A ;

                                                                                                                                                                                            4)Scheduler 向 Messaging 发送了一条消息:“让存储节点 A 创建这个 volume”;

                                                                                                                                                                                            5)存储节点 A 的 Volume(cinder-volume)从 Messaging 中获取到 Scheduler 发给它的消息,然后通过 driver 在 volume provider 上创建 volume。

                                                                                                                                                                                          • Cinder设计思想:Cinder 延续了 Nova 的以及其他组件的设计思想。

                                                                                                                                                                                            1)API 前端服务:

                                                                                                                                                                                            cinder-api 作为 Cinder 组件对外的唯一窗口,向客户暴露 Cinder 能够提供的功能,当客户需要执行 volume 相关的操作,只能向 cinder-api 发送 REST 请求。这里的客户包括终端用户、命令行和 OpenStack 其他组件。

                                                                                                                                                                                            设计 API 前端服务的好处在于:

                                                                                                                                                                                            a)对外提供统一接口,隐藏实现细节;

                                                                                                                                                                                            b)API 提供 REST 标准调用服务,便于与第三方系统集成;

                                                                                                                                                                                            c)可以通过运行多个 API 服务实例轻松实现 API 的高可用,比如运行多个 cinder-api 进程。

                                                                                                                                                                                            2)Scheduler 调度服务:

                                                                                                                                                                                            Cinder 可以有多个存储节点,当需要创建 volume 时,cinder-scheduler 会根据存储节点的属性和资源使用情况选择一个最合适的节点来创建 volume。

                                                                                                                                                                                            3)Worker 工作服务:

                                                                                                                                                                                            调度服务只管分配任务,真正执行任务的是 Worker 工作服务。 在 Cinder 中,这个 Worker 就是 cinder-volume 了。这种 Scheduler 和 Worker 之间职能上的划分使得 OpenStack 非常容易扩展:当存储资源不够时可以增加存储节点(增加 Worker)。当客户的请求量太大调度不过来时,可以增加 Scheduler。

                                                                                                                                                                                            4)Driver 框架:

                                                                                                                                                                                            以 Cinder 为例,存储节点支持多种 volume provider,包括 LVM, NFS, Ceph, GlusterFS,以及 EMC, IBM 等商业存储系统。cinder-volume 为这些 volume provider 定义了统一的 driver 接口,volume provider 只需要实现这些接口,就可以 driver 的形式即插即用到 OpenStack 中。

                                                                                                                                                                                            下面是 cinder driver 的架构示意图:

                                                                                                                                                                                            云计算之OpenStack核心 第281张

                                                                                                                                                                                            在 cinder-volume 的配置文件 /etc/cinder/cinder.conf 中 volume_driver 配置项设置该存储节点使用哪种 volume provider 的 driver,下面的示例表示使用的是 LVM。

                                                                                                                                                                                            云计算之OpenStack核心 第282张

                                                                                                                                                                                            2.4.4 Cinder 组件详解

                                                                                                                                                                                            2.4.4.1 cinder-api
                                                                                                                                                                                            • cinder-api 是整个 Cinder 组件的门户,所有 cinder 的请求都首先由 cinder-api 处理。cinder-api 向外界暴露若干 HTTP REST API 接口。在 keystone 中我们可以查询 cinder-api 的 endponits。

                                                                                                                                                                                              云计算之OpenStack核心 第283张

                                                                                                                                                                                              客户端可以将请求发送到 endponits 指定的地址,向 cinder-api 请求操作。当然,作为最终用户的我们不会直接发送 Rest API 请求。OpenStack CLI,Dashboard 和其他需要跟 Cinder 交换的组件会使用这些 API。

                                                                                                                                                                                            • cinder-api 对接收到的 HTTP API 请求会做如下处理:1)检查客户端传人的参数是否合法有效;2)调用 cinder 其他子服务的处理客户端请求;3)将 cinder 其他子服务返回的结果序列号并返回给客户端。
                                                                                                                                                                                            • cinder-api 接受哪些请求呢?

                                                                                                                                                                                              简单的说,只要是 Volume 生命周期相关的操作,cinder-api 都可以响应。大部分操作都可以在 Dashboard 上看到。打开 Volume 管理界面:

                                                                                                                                                                                              云计算之OpenStack核心 第284张

                                                                                                                                                                                              点击下拉箭头,列表中就是 cinder-api 可执行的操作:

                                                                                                                                                                                              云计算之OpenStack核心 第285张

                                                                                                                                                                                              2.4.4.2 cinder-scheduler
                                                                                                                                                                                              • 创建 Volume 时,cinder-scheduler 会基于容量、Volume Type 等条件选择出最合适的存储节点,然后让其创建 Volume。
                                                                                                                                                                                              • 在 /etc/cinder/cinder.conf 中,cinder 通过 scheduler_driver, scheduler_default_filters 和 scheduler_default_weighers 这三个参数来配置 cinder-scheduler。

                                                                                                                                                                                                1)Filter scheduler:

                                                                                                                                                                                                Filter scheduler 是 cinder-scheduler 默认的调度器

                                                                                                                                                                                                云计算之OpenStack核心 第286张

                                                                                                                                                                                                与 Nova 一样,Cinder 也允许使用第三方 scheduler,配置 scheduler_driver 即可。

                                                                                                                                                                                                scheduler 调度过程如下:

                                                                                                                                                                                                i)通过过滤器(filter)选择满足条件的存储节点(运行 cinder-volume);

                                                                                                                                                                                                ii)通过权重计算(weighting)选择最优(权重值最大)的存储节点。

                                                                                                                                                                                                可见,cinder-scheduler 的运行机制与 nova-scheduler 完全一样。

                                                                                                                                                                                                2)Filter :

                                                                                                                                                                                                当 Filter scheduler 需要执行调度操作时,会让 filter 对存储节点进行判断,filter 返回 True 或者 False。cinder.conf 中 scheduler_default_filters 选项指定 filter scheduler 使用的 filter,默认值如下:

                                                                                                                                                                                                云计算之OpenStack核心 第287张

                                                                                                                                                                                                a)AvailabilityZoneFilter:

                                                                                                                                                                                                为提高容灾性和提供隔离服务,可以将存储节点和计算节点划分到不同的 Availability Zone 中。例如把一个机架上的机器划分在一个 Availability Zone 中。OpenStack 默认有一个命名为“Nova” Availability Zone 的,所有的节点初始都是放在“Nova”中。用户可以根据需要创建自己的 Availability Zone。

                                                                                                                                                                                                云计算之OpenStack核心 第288张

                                                                                                                                                                                                创建 Volume 时,需要指定 Volume 所属的 Availability Zone。

                                                                                                                                                                                                云计算之OpenStack核心 第289张

                                                                                                                                                                                                cinder-scheduler 在做 filtering 时,会使用 AvailabilityZoneFilter 将不属于指定 Availability Zone 的存储节点过滤掉。

                                                                                                                                                                                                b)CapacityFilter:

                                                                                                                                                                                                创建 Volume 时,用户会指定 Volume 的大小。CapacityFilter 的作用是将存储空间不能满足 Volume 创建需求的存储节点过滤掉。

                                                                                                                                                                                                云计算之OpenStack核心 第290张

                                                                                                                                                                                                c)CapabilitiesFilter:

                                                                                                                                                                                                不同的 Volume Provider 有自己的特性(Capabilities),比如是否支持 thin provision 等。Cinder 允许用户创建 Volume 时通过 Volume Type 指定需要的 Capabilities。

                                                                                                                                                                                                云计算之OpenStack核心 第291张

                                                                                                                                                                                                Volume Type 可以根据需要定义若干 Capabilities,详细描述 Volume 的属性。VolumeVolume Type 的作用与 Nova 的 flavor 类似。Volume Type 在 Admin -> System -> Volume 菜单里管理:

                                                                                                                                                                                                云计算之OpenStack核心 第292张

                                                                                                                                                                                                通过 Volume Type 的 Extra Specs 定义 Capabilities:

                                                                                                                                                                                                云计算之OpenStack核心 第293张

                                                                                                                                                                                                Extra Specs 是用 Key-Value 的形式定义。不同的 Volume Provider 支持的 Extra Specs 不同,需要参考 Volume Provider 的文档。

                                                                                                                                                                                                云计算之OpenStack核心 第294张

                                                                                                                                                                                                上图所示的 Volume Type 只有一个 Extra Specs “volume_backend_name”,这是最重要也是必须的 Extra Specs。cinder-volume 会在自己的配置文件 /etc/cinder/cinder.conf 中设置“volume_backend_name”这个参数,其作用是为存储节点的 Volume Provider 命名。这样,CapabilitiesFilter 就可以通过 Volume Type 的“volume_backend_name”筛选出指定的 Volume Provider。不同的存储节点可以在各自的 cinder.conf 中配置相同的 volume_backend_name,这是允许的。因为虽然存储节点不同,但它们可能使用的是一种 Volume Provider。如果在第一步 filtering 环节选出了多个存储节点,那么接下来的 weighting 环节会挑选出最合适的一个节点。

                                                                                                                                                                                                3)Weighter :

                                                                                                                                                                                                Filter Scheduler 通过 scheduler_default_weighers 指定计算权重的 weigher,默认为 CapacityWeigher。

                                                                                                                                                                                                云计算之OpenStack核心 第295张

                                                                                                                                                                                                如命名所示,CapacityWeigher 基于存储节点的空闲容量计算权重值,空闲容量最大的胜出。

                                                                                                                                                                                                2.4.4.3 cinder-volume
                                                                                                                                                                                                • cinder-volume 在存储节点上运行,OpenStack 对 Volume 的操作,最后都是交给 cinder-volume 来完成的。cinder-volume 自身并不管理真正的存储设备,存储设备是由 volume provider 管理的。cinder-volume 与 volume provider 一起实现 volume 生命周期的管理。
                                                                                                                                                                                                • 通过 Driver 架构支持多种 Volume Provider

                                                                                                                                                                                                  接着的问题是:现在市面上有这么多块存储产品和方案(volume provider),cinder-volume 如何与它们配合呢?

                                                                                                                                                                                                • 这就是我们之前讨论过的 Driver 架构。cinder-volume 为这些 volume provider 定义了统一的接口,volume provider 只需要实现这些接口,就可以 Driver 的形式即插即用到 OpenStack 系统中。

                                                                                                                                                                                                  下面是 Cinder Driver 的架构示意图:

                                                                                                                                                                                                  云计算之OpenStack核心 第296张

                                                                                                                                                                                                  我们可以在 /opt/stack/cinder/cinder/volume/drivers/ 目录下查看到,OpenStack 源代码中已经自带了很多 volume provider 的 Driver:

                                                                                                                                                                                                  云计算之OpenStack核心 第297张

                                                                                                                                                                                                  存储节点在配置文件 /etc/cinder/cinder.conf 中用 volume_driver 选项配置使用的driver:配置使用的driver

                                                                                                                                                                                                  云计算之OpenStack核心 第298张

                                                                                                                                                                                                  这里 LVM 是我们使用的 volume provider。

                                                                                                                                                                                                • 定期向 OpenStack 报告计算节点的状态

                                                                                                                                                                                                  在前面 cinder-scheduler 会用到 CapacityFilter 和 CapacityWeigher,它们都是通过存储节点的空闲容量来做筛选。那这里有个问题:Cinder 是如何得知每个存储节点的空闲容量信息的呢?答案就是:cinder-volume 会定期向 Cinder 报告。

                                                                                                                                                                                                • 从 cinder-volume 的日志 /opt/stack/logs/c-vol.log 可以发现每隔一段时间,cinder-volume 就会报告当前存储节点的资源使用情况。

                                                                                                                                                                                                  云计算之OpenStack核心 第299张

                                                                                                                                                                                                  因为在我们的实验环境中存储节点使用的是 LVM,所以在上面的日志看到存储节点通过“vgs”和”lvs”这两个命令获取 LVM 的容量使用信息。

                                                                                                                                                                                                • 实现 volume 生命周期管理

                                                                                                                                                                                                  Cinder 对 volume 的生命周期的管理最终都是通过 cinder-volume 完成的,包括 volume 的 create、extend、attach、snapshot、delete 等,后面我们会详细讨论。

                                                                                                                                                                                                  2.4.5 通过场景学习Cinder

                                                                                                                                                                                                  2.4.5.1 准备LVM Volume Provider
                                                                                                                                                                                                  • Cinder 真正负责 Volume 管理的组件是 volume provider。cinder 支持多种 volume provider,LVM 是默认的 volume provider。
                                                                                                                                                                                                  • Devstack 安装之后,/etc/cinder/cinder 已经配置好了 LVM,如下图所示:

                                                                                                                                                                                                    云计算之OpenStack核心 第300张

                                                                                                                                                                                                    上面的配置定义了名为“lvmdriver-1”的 volume provider,也称作 back-end。其 driver 是 LVM,LVM 的 volume group 名为“stack-volumes-lvmdriver-1”。

                                                                                                                                                                                                  • Devstack 安装时并没有自动创建 volume group,所以需要我们手工创建。如下步骤演示了在 /dev/sdb 上创建 VG “stack-volumes-lvmdriver-1”:

                                                                                                                                                                                                    1)首先创建 physical volume /dev/sdb:

                                                                                                                                                                                                    云计算之OpenStack核心 第301张

                                                                                                                                                                                                    Linux 的 lvm 默认配置不允许在 /dev/sdb 上创建 PV,需要将 sdb 添加到 /etc/lvm.conf 的 filter 中。

                                                                                                                                                                                                    云计算之OpenStack核心 第302张

                                                                                                                                                                                                    云计算之OpenStack核心 第303张

                                                                                                                                                                                                    2)然后创建 VG stack-volumes-lvmdriver-1:

                                                                                                                                                                                                    云计算之OpenStack核心 第304张

                                                                                                                                                                                                    打开 Web GUI,可以看到 OpenStack 已经创建了 Volume Type “lvmdriver-1”:

                                                                                                                                                                                                    云计算之OpenStack核心 第305张

                                                                                                                                                                                                    其 Extra Specs volume_backend_name 为 lvmdriver-1:

                                                                                                                                                                                                    云计算之OpenStack核心 第306张

                                                                                                                                                                                                    2.4.5.2 创建volume
                                                                                                                                                                                                    • Create 操作流程如下:

                                                                                                                                                                                                      云计算之OpenStack核心 第307张

                                                                                                                                                                                                      1)客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(cinder-api)发送请求:“帮我创建一个 volume”。

                                                                                                                                                                                                      2)API 对请求做一些必要处理后,向 Messaging(RabbitMQ)发送了一条消息:“让 Scheduler 创建一个 volume”。

                                                                                                                                                                                                      3)Scheduler(cinder-scheduler)从 Messaging 获取到 API 发给它的消息,然后执行调度算法,从若干计存储点中选出节点 A。

                                                                                                                                                                                                      4)Scheduler 向 Messaging 发送了一条消息:“让存储节点 A 创建这个 volume”。

                                                                                                                                                                                                      5)存储节点 A 的 Volume(cinder-volume)从 Messaging 中获取到 Scheduler 发给它的消息,然后通过 driver 在 volume provider 上创建 volume。

                                                                                                                                                                                                    • 向 cinder-api 发送请求:

                                                                                                                                                                                                      客户(可以是 OpenStack最终用户,也可以是其他程序)向 cinder-api发送请求:“帮我创建一个 volume。GUI 上操作的菜单为 Project -> Compute -> Volumes -> Create Volume:

                                                                                                                                                                                                      云计算之OpenStack核心 第308张

                                                                                                                                                                                                      设置 volume 的名称,volume type,大小,Availability Zone 等基本信息。这里我们没有设置 Volume Source,这样会创建一个空白的 volume。点击“Create Volume” 按钮,cinder-api 将接收到创建 volume 的请求。

                                                                                                                                                                                                      云计算之OpenStack核心 第309张

                                                                                                                                                                                                      查看 cinder-api 日志 /opt/stack/logs/c-api.log:

                                                                                                                                                                                                      云计算之OpenStack核心 第310张

                                                                                                                                                                                                      日志显示 cinder-api 接收到一个 POST 类型的 REST API,经过对 HTTP body 的分析,该请求是:创建一个 1GB 的 volume。紧接着,cinder-api 启动了一个 Flow(工作流)volume_create_api。Flow 的执行状态依次为 PENDING(待定), RUNNING 和 SUCCESS。volume_create_api 当前的状态由 PENDING 变为 RUNNING。

                                                                                                                                                                                                      云计算之OpenStack核心 第311张

                                                                                                                                                                                                      volume_create_api 工作流包含若干 Task,每个 Task 完成特定的任务

                                                                                                                                                                                                      这些任务依次为 ExtractVolumeRequestTask, QuotaReserveTask, EntryCreateTask, QuotaCommitTask, VolumeCastTask。Task 的执行状态也会经历 PENDING, RUNNING 和 SUCCESS 三个阶段。Task 的名称基本上说明了任务的工作内容,前面几个 Task 主要是做一些创建 volume 的准备工作,比如:

                                                                                                                                                                                                      1)ExtractVolumeRequestTask 获取 request 信息:

                                                                                                                                                                                                      云计算之OpenStack核心 第312张

                                                                                                                                                                                                      2)QuotaReserveTask 预留配额:

                                                                                                                                                                                                      云计算之OpenStack核心 第313张

                                                                                                                                                                                                      3)EntryCreateTask 在数据库中创建 volume 条目:

                                                                                                                                                                                                      云计算之OpenStack核心 第314张

                                                                                                                                                                                                      4)QuotaCommitTask 确认配额:

                                                                                                                                                                                                      云计算之OpenStack核心 第315张

                                                                                                                                                                                                      5)最后 VolumeCastTask 是向 cinder-sheduler 发送消息,开始调度工作:

                                                                                                                                                                                                      云计算之OpenStack核心 第316张

                                                                                                                                                                                                      6)至此,Flow volume_create_api 已经完成,状态由 RUNNING 变为 SUCCESS,volume 创建成功。日志如下:

                                                                                                                                                                                                      云计算之OpenStack核心 第317张

                                                                                                                                                                                                      需要特别注意的是,“volume 创建成功”只是指 cinder-api 已经成功处理了 volume create 请求,将消息发给了 cinder-scheduler,但并不意味 volume 在存储节点上已经成功创建, 这一点是容易引起误解的。我们可以通过 cinder-volume 创建 volume 日志的时间戳验证。

                                                                                                                                                                                                      cinder-api 发送消息:

                                                                                                                                                                                                      cinder-api 向 RabbitMQ 发送了一条消息:“让cinder-scheduler 创建一个 volume”。前面我们提到消息是由 VolumeCastTask 发出的,因为 VolumeCastTask 没有打印相关日志,我们只能通过源代码查看

                                                                                                                                                                                                      /opt/stack/cinder/cinder/volume/flows/api/create_volume.py ,方法为 create_volume。

                                                                                                                                                                                                      云计算之OpenStack核心 第318张

                                                                                                                                                                                                    • cinder-scheduler 执行调度:

                                                                                                                                                                                                      cinder-scheduler 执行调度算法,通过 Filter 和 Weigher 挑选最优的存储节点,日志为 /opt/stack/logs/c-sch.log。

                                                                                                                                                                                                      1)cinder-scheduler 通过 Flow volume_create_scheduler 执行调度工作:

                                                                                                                                                                                                      云计算之OpenStack核心 第319张

                                                                                                                                                                                                      2)该 Flow 依次执行 ExtractSchedulerSpecTask 和 ScheduleCreateVolumeTask:

                                                                                                                                                                                                      云计算之OpenStack核心 第320张

                                                                                                                                                                                                      3)主要的 filter 和 weighting 工作由 ScheduleCreateVolumeTask 完成

                                                                                                                                                                                                      ScheduleCreateVolumeTask:

                                                                                                                                                                                                      云计算之OpenStack核心 第321张

                                                                                                                                                                                                      经过 AvailabilityZoneFilter, CapacityFilter, CapabilitiesFilter 和 CapacityWeigher 的层层筛选,最终选择了存储节点 devstack-controller@lvmdriver-1#lvmdriver-1。

                                                                                                                                                                                                      4)Flow volume_create_scheduler 完成调度,状态变为 SUCCESS:

                                                                                                                                                                                                      云计算之OpenStack核心 第322张5)cinder-scheduler 发送消息 :

                                                                                                                                                                                                      cinder-scheduler 发送消息给 cinder-volume,让其创建 volume。源码 /opt/stack/cinder/cinder/scheduler/filter_scheduler.py,方法为 schedule_create_volume:

                                                                                                                                                                                                      云计算之OpenStack核心 第323张

                                                                                                                                                                                                    • cinder-volume 的处理过程:

                                                                                                                                                                                                      cinder-volume 通过 driver 创建 volume,日志为 /opt/stack/logs/c-vol.log。

                                                                                                                                                                                                      1)与 cinder-api 和 cinder-scheduler 执行方式类似,cinder-volume 也启动了一个 Flow 来完成 volume 创建工作。Flow 的名称为 volume_create_manager:

                                                                                                                                                                                                      云计算之OpenStack核心 第324张

                                                                                                                                                                                                      2)volume_create_manager 执行操作:

                                                                                                                                                                                                      首先执行ExtractVolumeRefTask, OnFailureRescheduleTask, ExtractVolumeSpecTask, NotifyVolumeActionTask 为 volume 创建做准备。

                                                                                                                                                                                                      云计算之OpenStack核心 第325张

                                                                                                                                                                                                      云计算之OpenStack核心 第326张

                                                                                                                                                                                                      云计算之OpenStack核心 第327张

                                                                                                                                                                                                      云计算之OpenStack核心 第328张

                                                                                                                                                                                                      3)接下来 CreateVolumeFromSpecTask 执行 volume 创建任务

                                                                                                                                                                                                      创建任务:

                                                                                                                                                                                                      云计算之OpenStack核心 第329张

                                                                                                                                                                                                      因为 volume provider 为 LVM, CreateVolumeFromSpecTask 通过 lvcreate 命令在 VG stack-volumes-lvmdriver-1 中创建了一个 1G 的 LV,cinder-volume 将这个 LV 作为volume。新创建的 LV 命名为“volume-1e7f6bd7-ce11-4a73-b95e-aabd65a5b188”,其格式为“volume-”。

                                                                                                                                                                                                      云计算之OpenStack核心 第330张

                                                                                                                                                                                                      云计算之OpenStack核心 第331张

                                                                                                                                                                                                      4)最后,CreateVolumeOnFinishTask 完成扫尾工作:

                                                                                                                                                                                                      云计算之OpenStack核心 第332张

                                                                                                                                                                                                      5)至此,volume 成功创建,Flow volume_create_manager 结束:

                                                                                                                                                                                                      云计算之OpenStack核心 第333张

                                                                                                                                                                                                      云计算之OpenStack核心 第334张

                                                                                                                                                                                                      2.4.5.3 Attach附加磁盘

                                                                                                                                                                                                      本节讨论 cinder-volume 和 nova-compute 如何将 volume attach 到 Instance。

                                                                                                                                                                                                      • cinder-volume 初始化 volume 的连接:

                                                                                                                                                                                                        cinder-volume 接收到 initialize_connection 消息后,会通过 tgt 创建 target,并将 volume 所对应的LV 通过 target export 出来。日志为 /opt/stack/logs/c-vol.log:

                                                                                                                                                                                                        云计算之OpenStack核心 第335张

                                                                                                                                                                                                        下面的日志显示:

                                                                                                                                                                                                        通过命令tgtadm –lld iscsi –op show –mode target 看到已经将 1GB(1074MB)的 LV /dev/stack-volumes-lvmdriver-1/volume-1e7f6bd7-ce11-4a73-b95e-aabd65a5b188 通过 Target 1 export 出来了。

                                                                                                                                                                                                        云计算之OpenStack核心 第336张

                                                                                                                                                                                                        Initialize connection 完成:

                                                                                                                                                                                                        云计算之OpenStack核心 第337张

                                                                                                                                                                                                      • nova-compute 将 volume attach 到 instance:

                                                                                                                                                                                                        1)iSCSI是由IBM发明的基于以太网的存储协议,该协议与SUN的NFS协议都是为了解决存储资源共享问题的解决方案。两者意图一致,只不过两者是不同的实现方式,前者在客户机上呈现的是一个块设备,概括的说,iSCSI是一种存储设备远程映射技术,它可以将一个远程服务器上的存储设备映射到本地,并呈现为一个块设备(大白话就是磁盘)。从普通用户的角度,映射过来的磁盘与本地安装的磁盘毫无差异。这种映射方式基于是基于SCSI协议的,SCSI协议是计算机与外围设备(例如硬盘、光盘等)通信的协议。而iSCSI则是通过TCP协议对SCSI进行封装的一种协议,也就是通过以太网传输SCSI协议的内容。

                                                                                                                                                                                                        2)计算节点作为 iSCSI initiator 访问存储节点 Iscsi Target 上的 volume,并将其 attach 到 instance。日志文件为 /opt/stack/logs/n-cpu.log:

                                                                                                                                                                                                        云计算之OpenStack核心 第338张

                                                                                                                                                                                                        3)nova-compute 依次执行 iscsiadm 的 new, update, login, rescan 操作访问 target 上的 volume:(iscsiadm是基于命令行的iscsi管理工具,提供了对iSCSI节点、会话、连接以及发现记录的操作。)

                                                                                                                                                                                                        云计算之OpenStack核心 第339张

                                                                                                                                                                                                        云计算之OpenStack核心 第340张

                                                                                                                                                                                                        云计算之OpenStack核心 第341张

                                                                                                                                                                                                        云计算之OpenStack核心 第342张

                                                                                                                                                                                                        4)计算节点将 iSCSI target 上的 volume 识别为一个磁盘文件:

                                                                                                                                                                                                        云计算之OpenStack核心 第343张

                                                                                                                                                                                                        5)然后通过更新 instance 的 XML 配置文件将 volume 映射给 instance:

                                                                                                                                                                                                        云计算之OpenStack核心 第344张

                                                                                                                                                                                                        6)我们也可以通过 virsh edit 查看更新后的 XML:

                                                                                                                                                                                                        云计算之OpenStack核心 第345张

                                                                                                                                                                                                        可以看到,instance 增加了一个类型为 block 的虚拟磁盘,source 就是要 attach 的 volume,该虚拟磁盘的设备名为 vdb。

                                                                                                                                                                                                        7)手工 Shut off 并 Start instance,通过 fdisk -l 查看到 volume 已经 attach 上来,设备为 vdb:

                                                                                                                                                                                                        云计算之OpenStack核心 第346张

                                                                                                                                                                                                        8)GUI 界面也会更新相关 attach 信息:

                                                                                                                                                                                                        云计算之OpenStack核心 第347张

                                                                                                                                                                                                        现在如果我们在存储节点执行 tgt-admin –show –mode target,会看到计算节点作为 initiator 已经连接到 target 1。cinder-volume 刚刚创建 target 的时候是没有 initiator 连接的,大家可以将下面的截图与之前的日志做个对比。

                                                                                                                                                                                                        云计算之OpenStack核心 第348张

                                                                                                                                                                                                        2.4.5.4 Detach卸载磁盘
                                                                                                                                                                                                        • 下图是Detach操作流程图,包含1)向 cinder-api 发送 detach 请求;2)cinder-api 发送消息;3)nova-compute detach volume;4)cinder-volume 删除 target。

                                                                                                                                                                                                          云计算之OpenStack核心 第349张

                                                                                                                                                                                                          1)向 cinder-api 发送 attach 请求:

                                                                                                                                                                                                          客户(可以是 OpenStack 最终用户,也可以是其他程序)向 cinder-api 发送请求:“请 detach 指定 instance 上的 volume。这里我们将 detach instance “c2”上的 volume “vol-1” 。进入 GUI 操作菜单Project -> Compute -> Volumes:

                                                                                                                                                                                                          云计算之OpenStack核心 第350张

                                                                                                                                                                                                          选择 volume “vol-1”,点击“Manage Attachments” :

                                                                                                                                                                                                          云计算之OpenStack核心 第351张

                                                                                                                                                                                                          点击 “Detach Volume”:

                                                                                                                                                                                                          云计算之OpenStack核心 第352张

                                                                                                                                                                                                          再次确认:

                                                                                                                                                                                                          云计算之OpenStack核心 第353张

                                                                                                                                                                                                          cinder-api 将接收到 detach volume 的请求。日志文件在 /opt/stack/logs/c-api.log:

                                                                                                                                                                                                          云计算之OpenStack核心 第354张

                                                                                                                                                                                                          2)cinder-api 发送消息

                                                                                                                                                                                                          cinder-api 发送消息 detach 消息。cinder-api 没有打印发送消息的日志,只能通过源代码查看 /opt/stack/cinder/cinder/volume/api.py,方法为 detach:

                                                                                                                                                                                                          云计算之OpenStack核心 第355张

                                                                                                                                                                                                          Detach 的操作由 nova-compute 和 cinder-volume 共同完成。首先 nova-compute 将 volume 从 instance 上 detach,然后断开与 iSCSI target 的连接;最后 cinder-volume 删除 volume 相关的 iSCSI target。

                                                                                                                                                                                                          a)nova-compute detach volume:

                                                                                                                                                                                                          nova-compute 首先将 volume 从 instance 上 detach,日志为 /opt/stack/logs/n-cpu.log。

                                                                                                                                                                                                          云计算之OpenStack核心 第356张

                                                                                                                                                                                                          这时通过 virsh edit 可以看到 XML 配置文件中已经不在有 volume 的虚拟磁盘:

                                                                                                                                                                                                          云计算之OpenStack核心 第357张

                                                                                                                                                                                                          接下来断开与 iSCSI target 的连接:

                                                                                                                                                                                                          云计算之OpenStack核心 第358张

                                                                                                                                                                                                          具体步骤如下:

                                                                                                                                                                                                          i)将缓存中的数据 Flush 到 volume。

                                                                                                                                                                                                          云计算之OpenStack核心 第359张

                                                                                                                                                                                                          ii)删除计算节点上 volume 对应的 SCSI 设备。

                                                                                                                                                                                                          云计算之OpenStack核心 第360张

                                                                                                                                                                                                          iii)通过 iscsiadm 的 logout,delete 操作断开与 iSCSI target 的连接。

                                                                                                                                                                                                          云计算之OpenStack核心 第361张

                                                                                                                                                                                                          compue-nova 完成了 detach 工作,接下来 cinder-volume 就可以删除 volume 相关的 target 了。

                                                                                                                                                                                                          b)cinder-volume 删除 target:

                                                                                                                                                                                                          存储节点 cinder-volume 通过 tgt-admin 命令删除 volume 对应的 target;日志文件为 /opt/stack/logs/c-vol.log。

                                                                                                                                                                                                          云计算之OpenStack核心 第362张

                                                                                                                                                                                                          至此 detach volume 操作已经完成,GUI 也会更新 volume 的 attach 信息:

                                                                                                                                                                                                          云计算之OpenStack核心 第363张

                                                                                                                                                                                                          2.4.5.5 Extend扩展磁盘
                                                                                                                                                                                                          • 为了保护现有数据,cinder 不允许缩小 volume。Extend 操作用于扩大 Volume 的容量,状态为 Available 的 volume 才能够被 extend。如果 volume 当前已经 attach 给 instance,需要先 detach 后才能 extend。
                                                                                                                                                                                                          • Extend 实现比较简单,流程图如下所示:1)向 cinder-api 发送 extend 请求;2)cinder-api 发送消息;3)cinder-volume 执行 extend 操作。

                                                                                                                                                                                                            云计算之OpenStack核心 第364张

                                                                                                                                                                                                            1)向 cinder-api 发送 extend 请求:

                                                                                                                                                                                                            客户(可以是 OpenStack 最终用户,也可以是其他程序)向 cinder-api 发送请求:“请 extend 指定的 volume。这里我们将 extend volume “vol-2”。进入 GUI 操作菜单 Project -> Compute -> Volumes:

                                                                                                                                                                                                            云计算之OpenStack核心 第365张

                                                                                                                                                                                                            vol-2 当前大小为 1GB。其在存储节点上对应的 LV 信息如下

                                                                                                                                                                                                            LV 信息如下:

                                                                                                                                                                                                            云计算之OpenStack核心 第366张

                                                                                                                                                                                                            选择 volume “vol-2”,点击 “Extend Volume”:

                                                                                                                                                                                                            云计算之OpenStack核心 第367张

                                                                                                                                                                                                            指定新的容量为 3GB,点击 “Extend Volume”:

                                                                                                                                                                                                            云计算之OpenStack核心 第368张

                                                                                                                                                                                                            cinder-api 将接收到 extend volume 的请求,日志文件在 /opt/stack/logs/c-api.log:

                                                                                                                                                                                                            云计算之OpenStack核心 第369张

                                                                                                                                                                                                            2)cinder-api 发送消息:

                                                                                                                                                                                                            cinder-api 发送extend 消息。cinder-api 没有打印发送消息的日志,只能通过源代码查看。/opt/stack/cinder/cinder/volume/api.py,方法为 extend:

                                                                                                                                                                                                            云计算之OpenStack核心 第370张

                                                                                                                                                                                                            3) cinder-volume extend volume:

                                                                                                                                                                                                            cinder-volume 执行 lvextend 命令 extend volume。日志为 /opt/stack/logs/c-vol.log:

                                                                                                                                                                                                            云计算之OpenStack核心 第371张

                                                                                                                                                                                                            LV 被 extend 到 3GB:

                                                                                                                                                                                                            云计算之OpenStack核心 第372张

                                                                                                                                                                                                            Extend 操作完成后,GUI 也会更新 volume 的状态信息:

                                                                                                                                                                                                            云计算之OpenStack核心 第373张

                                                                                                                                                                                                            2.4.5.6 Delete删除磁盘
                                                                                                                                                                                                            • 今天讨论 cinder 如何删除 volume ,状态为 Available 的 volume 才能够被 delete,如果 volume 当前已经 attach 到 instance,需要先 detach 后才能 delete。
                                                                                                                                                                                                            • Delete操作实现比较简单,流程图如下:1)向 cinder-api 发送delete 请求;2)cinder-api 发送消息;3)cinder-volume 执行 delete 操作。

                                                                                                                                                                                                              云计算之OpenStack核心 第374张

                                                                                                                                                                                                              1)向 cinder-api 发送 delete 请求:

                                                                                                                                                                                                              客户(可以是 OpenStack 最终用户,也可以是其他程序)向 cinder-api 发送请求:“请 delete 指定的 volume。这里我们将 delete volume “vol-2”。进入 GUI 操作菜单 Project -> Compute -> Volumes:

                                                                                                                                                                                                              云计算之OpenStack核心 第375张

                                                                                                                                                                                                              选择volume “vol-2”,点击“Delete Volume”:

                                                                                                                                                                                                              云计算之OpenStack核心 第376张

                                                                                                                                                                                                              再次确认:

                                                                                                                                                                                                              云计算之OpenStack核心 第377张

                                                                                                                                                                                                              cinder-api 将接收到 delete volume 的请求。日志文件在 /opt/stack/logs/c-api.log:

                                                                                                                                                                                                              云计算之OpenStack核心 第378张

                                                                                                                                                                                                              2)cinder-api 发送消息:

                                                                                                                                                                                                              cinder-api 发送消息 delete 消息。cinder-api 没有打印发送消息的日志,只能通过源代码查看。opt/stack/cinder/cinder/volume/api.py,方法为 extend。

                                                                                                                                                                                                              云计算之OpenStack核心 第379张

                                                                                                                                                                                                              3)cinder-volume delete volume:

                                                                                                                                                                                                              cinder-volume 执行 lvremove 命令 delete volume,日志为 /opt/stack/logs/c-vol.log。

                                                                                                                                                                                                              云计算之OpenStack核心 第380张

                                                                                                                                                                                                              这里比较有意思的是:cinder-volume 执行的是“安全”删除。所谓“安全”实际上就是将 volume 中的数据抹掉,LVM driver 使用的是 dd 操作将 LV 的数据清零,日志如下:

                                                                                                                                                                                                              云计算之OpenStack核心 第381张

                                                                                                                                                                                                              然后删除 LV:

                                                                                                                                                                                                              云计算之OpenStack核心 第382张

                                                                                                                                                                                                              2.4.5.7 Snapshot磁盘快照
                                                                                                                                                                                                              • Snapshot 可以为 volume 创建快照,快照中保存了 volume 当前的状态,以后可以通过 snapshot 回溯。
                                                                                                                                                                                                              • snapshot 操作实现比较简单,流程图如下所示:1)向 cinder-api 发送 snapshot 请求;2)cinder-api 发送消息;3)cinder-volume 执行 snapshot 操作。

                                                                                                                                                                                                                云计算之OpenStack核心 第383张

                                                                                                                                                                                                                1)向 cinder-api 发送 snapshot 请求:

                                                                                                                                                                                                                客户(可以是 OpenStack 最终用户,也可以是其他程序)向 cinder-api 发送请求:“请 snapshot 指定的 volume。这里我们将 snapshot volume “vol-1”。进入 GUI 操作菜单 Project -> Compute -> Volumes:

                                                                                                                                                                                                                云计算之OpenStack核心 第384张

                                                                                                                                                                                                                选择 volume “vol-1”,点击 “Create Snapshot”:

                                                                                                                                                                                                                云计算之OpenStack核心 第385张

                                                                                                                                                                                                                为 snapshot 命名:

                                                                                                                                                                                                                云计算之OpenStack核心 第386张

                                                                                                                                                                                                                这里我们看到界面提示当前 volume 已经 attach 到某个 instance,创建 snapshot 可能导致数据不一致。我们可以先 pause instance,或者确认当前 instance 没有大量的磁盘 IO,处于相对稳定的状态,则可以创建 snapshot,否则还是建议先 detach volume 再做 sanpshot。

                                                                                                                                                                                                                cinder-api 将接收到 snapshot volume 的请求,日志文件在 /opt/stack/logs/c-api.log:

                                                                                                                                                                                                                云计算之OpenStack核心 第387张

                                                                                                                                                                                                                2)cinder-api 发送消息:

                                                                                                                                                                                                                cinder-api 发送消息 snapshot 消息。cinder-api 没有打印发送消息的日志,只能通过源代码查看 /opt/stack/cinder/cinder/volume/api.py,方法为 _create_snapshot:

                                                                                                                                                                                                                云计算之OpenStack核心 第388张

                                                                                                                                                                                                                3)cinder-volume 执行 snapshot 操作:

                                                                                                                                                                                                                cinder-volume 执行 lvcreate 命令创建 snapshot。日志为 /opt/stack/logs/c-vol.log:

                                                                                                                                                                                                                云计算之OpenStack核心 第389张

                                                                                                                                                                                                                对于 LVM volume provider,snapshot 实际上也是一个 LV,同时记录了与源 LV 的 snapshot 关系,可以通过 lvdisplay 查看:

                                                                                                                                                                                                                云计算之OpenStack核心 第390张

                                                                                                                                                                                                                GUI 的 Volume Snapshots 标签中可以看到新创建的 “vol-1-snapshot”:

                                                                                                                                                                                                                云计算之OpenStack核心 第391张

                                                                                                                                                                                                                有了 snapshot,我们就可以将 volume 回溯到创建 snapshot 时的状态,方法是通过 snapshot 创建新的 volume:

                                                                                                                                                                                                                云计算之OpenStack核心 第392张

                                                                                                                                                                                                                新创建的 volume 容量必须大于或等于 snapshot 的容量:

                                                                                                                                                                                                                云计算之OpenStack核心 第393张

                                                                                                                                                                                                                其过程与 Create Volume 类似,不同之处在于 LV 创建之后会通过 dd 将 snapshot 的数据 copy 到新的 volume。如果一个 volume 存在 snapshot,则这个 volume 是无法删除的。这是因为 snapshot 依赖于 volume,snapshot 无法独立存在。 在 LVM 作为 volume provider 的环境中,snapshot 是从源 volume 完全 copy 而来,所以这种依赖关系不强。但在其他 volume provider(比如商业存储设备或者分布式文件系统),snapshot 通常是源 volume 创建快照时数据状态的一个引用(指针),占用空间非常小,在这种实现方式里 snapshot 对源 volume 的依赖就非常明显了。

                                                                                                                                                                                                                2.4.5.8 Backup磁盘备份
                                                                                                                                                                                                                • 本节我们讨论 volume 的 Backup 操作。Backup 是将 volume 备份到别的地方(备份设备),将来可以通过 restore 操作恢复。
                                                                                                                                                                                                                • Backup VS Snapshot:

                                                                                                                                                                                                                  初看 backup 功能好像与 snapshot 很相似,都可以保存 volume 的当前状态,以备以后恢复。但二者在用途和实现上还是有区别的,具体表现在:

                                                                                                                                                                                                                  1)Snapshot 依赖于源 volume,不能独立存在;而 backup 不依赖源 volume,即便源 volume 不存在了,也可以 restore。

                                                                                                                                                                                                                  2)Snapshot 与源 volume 通常存放在一起,都由同一个 volume provider 管理;而 backup 存放在独立的备份设备中,有自己的备份方案和实现,与 volume provider 没有关系。

                                                                                                                                                                                                                  3)上面两点决定了 backup 具有容灾功能;而 snapshot 则提供 volume provider 内便捷的回溯功能。

                                                                                                                                                                                                                • 配置 cinder-backup:

                                                                                                                                                                                                                  Cinder 的 backup 功能是由 cinder-backup 服务提供的,devstack 默认没有启用该服务,需要手工启用

                                                                                                                                                                                                                  与 cinder-volume 类似,cinder-backup 也通过 driver 架构支持多种备份 backend,包括 POSIX 文件系统、NFS、Ceph、GlusterFS、Swift 和 IBM TSM。支持的driver 源文件放在 /opt/stack/cinder/cinder/backup/drivers/:

                                                                                                                                                                                                                  云计算之OpenStack核心 第394张

                                                                                                                                                                                                                • 本节我们将以 NFS 为 backend 来研究 backup 操作 :

                                                                                                                                                                                                                  在实验环境中,存放 volume backup 的 NFS 远程目录为 192.168.104.11:/backup,cinder-backup 服务节点上 mount point 为 /backup_mount。需要在 /etc/cinder/cinder.conf 中作相应配置:

                                                                                                                                                                                                                  云计算之OpenStack核心 第395张

                                                                                                                                                                                                                  然后手工启动 cinder-backup 服务:

                                                                                                                                                                                                                  云计算之OpenStack核心 第396张

                                                                                                                                                                                                                • 一切准备就绪,下面我们来看 backup 操作的流程:1)向 cinder-api 发送 backup 请求;2)cinder-api 发送消息;3)cinder-backup 执行 backup 操作。

                                                                                                                                                                                                                  云计算之OpenStack核心 第397张

                                                                                                                                                                                                                  1)向 cinder-api 发送 backup 请求:

                                                                                                                                                                                                                  客户(可以是 OpenStack 最终用户,也可以是其他程序)向 cinder-api 发送请求:“请 backup 指定的 volume。这里我们将 backup volume “vol-1”,目前 backup 只能在 CLI 中执行,采用cinder backup-create vol-1 --force命令。

                                                                                                                                                                                                                  云计算之OpenStack核心 第398张

                                                                                                                                                                                                                  这里因为 vol-1 已经 attach 到 instance,需要使用 –force 选项。cinder-api 接收到 backup volume 的请求。日志文件在 /opt/stack/logs/c-api.log。

                                                                                                                                                                                                                  云计算之OpenStack核心 第399张

                                                                                                                                                                                                                  2)cinder-api 发送消息:

                                                                                                                                                                                                                  cinder-api 发送 backup 消息。cinder-api 没有打印发送消息的日志,只能通过源代码查看

                                                                                                                                                                                                                  /opt/stack/cinder/cinder/backup/api.py,方法为 create:

                                                                                                                                                                                                                  云计算之OpenStack核心 第400张

                                                                                                                                                                                                                  3)cinder-backup 执行 backup 操作:

                                                                                                                                                                                                                  cinder-backup 收到消息后,通过如下步骤完成 backup 操作,日志为 /opt/stack/logs/c-vol.log。

                                                                                                                                                                                                                  i)启动 backup 操作,mount NFS。

                                                                                                                                                                                                                  云计算之OpenStack核心 第401张

                                                                                                                                                                                                                  ii)创建 volume 的临时快照。

                                                                                                                                                                                                                  云计算之OpenStack核心 第402张

                                                                                                                                                                                                                  iii)创建存放 backup 的 container 目录。

                                                                                                                                                                                                                  云计算之OpenStack核心 第403张

                                                                                                                                                                                                                  iv)对临时快照数据进行压缩,并保存到 container 目录。

                                                                                                                                                                                                                  云计算之OpenStack核心 第404张

                                                                                                                                                                                                                  v)创建并保存 sha256(加密)文件和 metadata 文件。

                                                                                                                                                                                                                  云计算之OpenStack核心 第405张

                                                                                                                                                                                                                  vi)删除临时快照。

                                                                                                                                                                                                                  云计算之OpenStack核心 第406张

                                                                                                                                                                                                                  Backup 完成后,我们可以查看一下 container 目录的内容:里面有三个文件,根据前面的日志我们可以知道:backup-00001,压缩后的 backup 文件。backup_metadata,metadata 文件。backup_sha256file,加密文件。

                                                                                                                                                                                                                  云计算之OpenStack核心 第407张

                                                                                                                                                                                                                  可以通过 cinder backup-list 查看当前存在的 backup:

                                                                                                                                                                                                                  云计算之OpenStack核心 第408张

                                                                                                                                                                                                                  另外我们采用cinder help backup-create命令可以查看一下 cinder backup-create 的用法:

                                                                                                                                                                                                                  云计算之OpenStack核心 第409张

                                                                                                                                                                                                                  这里有--incremental 选项,表示可以执行增量备份。如果之前做过普通(全量)备份,之后可以通过增量备份大大减少需要备份的数据量,是个很不错的功能。

                                                                                                                                                                                                                  2.4.5.9 restore磁盘恢复
                                                                                                                                                                                                                  • 前面我们 backup 了 voluem,今天我们将讨论如何 restore volume。restore 的过程其实很简单,两步走:1)在存储节点上创建一个空白 volume。2)将 backup 的数据 copy 到空白 voluem 上。
                                                                                                                                                                                                                  • 下面我们来看 restore 操作的详细流程:1)向 cinder-api 发送 restore 请求;2)cinder-api 发送消息;3)cinder-scheduler 挑选最合适的 cinder-volume;4)cinder-volume 创建空白 volume;5)cinder-backup 将 backup 数据 copy 到空白 volume 上。

                                                                                                                                                                                                                    云计算之OpenStack核心 第410张

                                                                                                                                                                                                                    1) 向 cinder-api 发送 restore 请求:

                                                                                                                                                                                                                    客户(可以是 OpenStack 最终用户,也可以是其他程序)向 cinder-api 发送请求:“请 restore 指定的 backup”。这里我们将 restore 之前创建的 backup,目前 restore 只能在 CLI 中执行,先采用cinder backup-list命令查看backup,采用cinder backup-restore 备份volume的ID命令进行恢复:

                                                                                                                                                                                                                    云计算之OpenStack核心 第411张

                                                                                                                                                                                                                    云计算之OpenStack核心 第412张

                                                                                                                                                                                                                    cinder-api 接收到 restore 请求,日志文件在 /opt/stack/logs/c-api.log:

                                                                                                                                                                                                                    云计算之OpenStack核心 第413张

                                                                                                                                                                                                                    这里看到 cinder-api 转发请求,为 restore 创建 volume。 之后 cinder-scheduler 和 cinder-volume 将创建空白 volume,这个过程与 create volume 一样,不再赘述。

                                                                                                                                                                                                                    2)接下来分析数据恢复的过程

                                                                                                                                                                                                                    a)首先,在 cinder-api 日志中可以看到相关信息:

                                                                                                                                                                                                                    云计算之OpenStack核心 第414张

                                                                                                                                                                                                                    这里注意日志中的 volume_id 和 backup_id 与前面 backup-restore 命令的输出是一致的。

                                                                                                                                                                                                                    b)下面来看 cinder-backup 是如何恢复数据的。cinder-backup 执行 restore 操作:日志为 /opt/stack/logs/c-vol.log。

                                                                                                                                                                                                                    i)启动 restore 操作,mount NFS。

                                                                                                                                                                                                                    云计算之OpenStack核心 第415张

                                                                                                                                                                                                                    ii)读取 container 目录中的 metadata。

                                                                                                                                                                                                                    云计算之OpenStack核心 第416张

                                                                                                                                                                                                                    iii)将数据解压并写到 volume 中。

                                                                                                                                                                                                                    云计算之OpenStack核心 第417张

                                                                                                                                                                                                                    iv)恢复 volume 的 metadata,完成 restore 操作。

                                                                                                                                                                                                                    云计算之OpenStack核心 第418张

                                                                                                                                                                                                                    c)此时,在 GUI 中已经可以看到 restore 创建的 volume:

                                                                                                                                                                                                                    云计算之OpenStack核心 第419张

                                                                                                                                                                                                                    2.4.5.10 Boot From Volume 将Volume作为虚拟机的启动盘
                                                                                                                                                                                                                    • Volume 除了可以用作 instance 的数据盘,也可以作为启动盘(Bootable Volume)。

                                                                                                                                                                                                                      那么如何使 volume 成为 bootable 呢?现在我们打开 instance 的 launch 操作界面:

                                                                                                                                                                                                                      云计算之OpenStack核心 第420张

                                                                                                                                                                                                                      这里有一个下拉菜单“Instance Boot Source”。以前我们 launch(部署)instance 要么直接从 image launch(Boot from image),要么从 instance 的 snapshot launch(Boot from snapshot)。 这两种 launch 方式下,instance 的启动盘 vda 均为镜像文件,存放路径为计算节点 /opt/stack/data/nova/instances//disk,例如:

                                                                                                                                                                                                                      云计算之OpenStack核心 第421张

                                                                                                                                                                                                                      下拉列表的后三项则可以将 volume 作为 instance 的启动盘 vda,分别为:

                                                                                                                                                                                                                      1)Boot from volume:直接从现有的 bootable volume launch;

                                                                                                                                                                                                                      2)Boot from image (create a new volume):创建一个新的 volume,将 image 的数据 copy 到 volume,然后从该 volume launch;

                                                                                                                                                                                                                      3)Boot from volume snapshot (create a new volume):通过指定的 volume snapshot 创建 volume,然后从该 volume launch,当然前提是该snapshot 对应的源 volume 是 bootable 的。

                                                                                                                                                                                                                      下面我们以 Boot from image (create a new volume)为例,看如何从 volume 启动:

                                                                                                                                                                                                                      云计算之OpenStack核心 第422张

                                                                                                                                                                                                                      选择 cirros 作为 image,instance 命名为“c3” ,如果希望 terminate instance 的时候同时删除 volume,可以勾选“Delete on Terminate”。

                                                                                                                                                                                                                      c3 成功 Launch 后,volume 列表中可以看到一个新 bootable volume,以 volume ID 命名,并且已经 attach 到 c3。

                                                                                                                                                                                                                      云计算之OpenStack核心 第423张

                                                                                                                                                                                                                      该 volume 已经配置为 c3 的启动盘 vda:

                                                                                                                                                                                                                      云计算之OpenStack核心 第424张

                                                                                                                                                                                                                      如果用该 volume 创建 snapshot,之后就可以通过 Boot from volume snapshot (create a new volume) 部署新的instance。boot from volume 的 instance 也可以执行 live migrate。前面的实验使用的是 LVM provider,cinder 当然也支持其他 provider。

                                                                                                                                                                                                                      2.4.5.11 NFS Volume Provider
                                                                                                                                                                                                                      • cinder-volume 支持多种 volume provider,前面我们一直使用的是默认的 LVM,本节我们将增加 NFS volume provider。虽然 NFS 更多地应用在实验或小规模 cinder 环境,由于性能和缺乏高可用的原因在生产环境中不太可能使用。

                                                                                                                                                                                                                      • 但是学习 NFS volume provider 的意义在于:

                                                                                                                                                                                                                        1)理解 cinder-volume 如何支持多 backend;

                                                                                                                                                                                                                        2)更重要的,可以理解 cinder-volume,nova-compute 和 volume provider 是如何协同工作,共同为 instance 提供块存储;

                                                                                                                                                                                                                        3)举一反三,能够快速理解并接入其他生产级 backend ,比如 Ceph,商业存储等。

                                                                                                                                                                                                                      • 下图展示了 cinder、nova 是如何与 NFS volume provider 协调工作的:

                                                                                                                                                                                                                        云计算之OpenStack核心 第425张

                                                                                                                                                                                                                        1)NFS Volume Provider:就是我们通常说的 NFS Server,提供远程 NFS 目录,NFS Clinet 可以 mount 这些远程目录到本地,然后像使用本地目录一样创建、读写文件以及子目录。

                                                                                                                                                                                                                        2)cinder-volume:存储节点通过 NFS driver 管理 NFS volume provider 中的 volume,这些 volume 在 NFS 中实际上是一个个文件。

                                                                                                                                                                                                                        3)nova-compute:计算节点将 NFS volume provider 存放 volume 的目录 mount 到本地,然后将 volume 文件作为虚拟硬盘映射给 instance。

                                                                                                                                                                                                                      • 这里有几点需要强调

                                                                                                                                                                                                                        1)在 Cinder 的 driver 架构中,运行 cinder-volume 的存储节点和 Volume Provider 可以是完全独立的两个实体。cinder-volume 通过 driver 与 Volume Provider 通信,控制和管理 volume。

                                                                                                                                                                                                                        2)Instance 读写 volume 时,数据流不需要经过存储节点,而是直接对 Volume Provider 中的 volume 进行读写。 正如上图所示,存储节点与 NFS Volume Provider 的连接只用作 volume 的管理和控制(绿色连线);真正的数据读写,是通过计算节点和 NFS Volume Proiver 之间的连接完成的(紫色连线)。这种设计减少了中间环节,存储节点不直接参与数据传输,保证了读写效率。

                                                                                                                                                                                                                        3)其他 Volume Provider(例如 ceph,swift,商业存储等)均遵循这种控制流与数据流分离的设计。

                                                                                                                                                                                                                      • 配置 NFS Volume Provider:

                                                                                                                                                                                                                        在实验环境中,NFS volume provider 的 NFS 远程目录为 192.168.104.11:/storage,cinder-volume 服务节点上 mount point 为 /nfs_storage。在 /etc/cinder/cinder.conf 中添加 nfs backend:

                                                                                                                                                                                                                        云计算之OpenStack核心 第426张

                                                                                                                                                                                                                        配置enabled_backends = lvmdriver-1,nfs是 让 cinder-volume 使用 nfs backend。[nfs]中详细配置 nfs backend。包括:

                                                                                                                                                                                                                        a) 使用nfs_mount_point_base = /nfs_storage命令,指定存储节点上 /nfs_storage 为 nfs 的 mount point。

                                                                                                                                                                                                                        云计算之OpenStack核心 第427张

                                                                                                                                                                                                                        b) 查看 /etc/cinder/nfs_shares 活动 nfs 共享目录列表。 nfs_shares_config = /etc/cinder/nfs_shares,其内容为:

                                                                                                                                                                                                                        云计算之OpenStack核心 第428张

                                                                                                                                                                                                                        列表中只有 192.168.104.11:/storage。如果希望有多个 nfs 共享目录存放 volume,则可以添加到该文件中。

                                                                                                                                                                                                                        c) nfs volume driver。

                                                                                                                                                                                                                        volume_driver=cinder.volume.drivers.nfs.NfsDriver

                                                                                                                                                                                                                        云计算之OpenStack核心 第429张

                                                                                                                                                                                                                        d) 设置 volume backend name。在 cinder 中需要根据这里的 volume_backend_name 创建对应的 volume type,这个非常重要,volume_backend_name = nfs。

                                                                                                                                                                                                                      • 重启 cinder-volume,cinder service-list 确认 nfs cinder-volume 服务正常工作:

                                                                                                                                                                                                                        云计算之OpenStack核心 第430张

                                                                                                                                                                                                                      • 创建 nfs volume type

                                                                                                                                                                                                                        打开GUI页面Admin -> System -> Volumes -> Volume Types,点击 “Create Volume Type”:

                                                                                                                                                                                                                        云计算之OpenStack核心 第431张

                                                                                                                                                                                                                        命名 nfs,点击“Create Volume Type”:

                                                                                                                                                                                                                        云计算之OpenStack核心 第432张

                                                                                                                                                                                                                        选择 nfs volume type,点击下拉菜单“View Extra Specs”:

                                                                                                                                                                                                                        云计算之OpenStack核心 第433张

                                                                                                                                                                                                                        点击“Create”,Key 输入 volume_backend_name ;Value 输入 nfs:

                                                                                                                                                                                                                        云计算之OpenStack核心 第434张

                                                                                                                                                                                                                        云计算之OpenStack核心 第435张

                                                                                                                                                                                                                        NFS volume provider 准备就绪,下一节我们将创建 NFS 为 backend 的 volume。

                                                                                                                                                                                                                      • 创建volume

                                                                                                                                                                                                                        1)创建 NFS volume 操作方法与 LVM volume 一样,唯一区别是在 volume type 的下拉列表中选择“nfs”:

                                                                                                                                                                                                                        云计算之OpenStack核心 第436张

                                                                                                                                                                                                                        点击“Create Volume”,cinder-api,cinder-scheduler 和 cinder-volume 共同协作创建 volume “nfs-vol-1”。这个流程与 LVM volume 一样。

                                                                                                                                                                                                                        2)分析 cinder-volume 的日志:

                                                                                                                                                                                                                        看看 NFS volume provider 是如何创建 volume 的,日志在 /opt/stack/logs/c-vol.log。

                                                                                                                                                                                                                        i)cinder-volume 也会启动 Flow 来完成 volume 创建工作,Flow 的名称为 volume_create_manager:

                                                                                                                                                                                                                        云计算之OpenStack核心 第437张

                                                                                                                                                                                                                        volume_create_manager 首先执行 ExtractVolumeRefTask, OnFailureRescheduleTask, ExtractVolumeSpecTask, NotifyVolumeActionTask 为 volume创建做准备。

                                                                                                                                                                                                                        ii)然后由 CreateVolumeFromSpecTask 真正创建 volume:

                                                                                                                                                                                                                        云计算之OpenStack核心 第438张

                                                                                                                                                                                                                        iii)首先 mount 远程 NFS 目录:

                                                                                                                                                                                                                        云计算之OpenStack核心 第439张

                                                                                                                                                                                                                        iv)执行 stat、du 命令检查 NFS 目录:

                                                                                                                                                                                                                        云计算之OpenStack核心 第440张

                                                                                                                                                                                                                        v)执行 truncate 创建 volume 文件:

                                                                                                                                                                                                                        云计算之OpenStack核心 第441张

                                                                                                                                                                                                                        vi)采用chmod ugo+rw命令设置 volume 文件为可读写:

                                                                                                                                                                                                                        云计算之OpenStack核心 第442张

                                                                                                                                                                                                                        vii)create 操作完成:

                                                                                                                                                                                                                        云计算之OpenStack核心 第443张

                                                                                                                                                                                                                        viii)Volume 在 NFS 上以文件存在,命名为“volume-”:

                                                                                                                                                                                                                        云计算之OpenStack核心 第444张

                                                                                                                                                                                                                        ix)GUI volume 列表中可以看到新创建的 volume:

                                                                                                                                                                                                                        云计算之OpenStack核心 第445张

                                                                                                                                                                                                                        GUI volume 列表中可以看到新创建的 volume。

                                                                                                                                                                                                                      • nova-compute 如何将“nfs-vol-1” attach 到“c2” :

                                                                                                                                                                                                                        通过日志分析,nova-compute 会将存放 volume 文件的 NFS 目录 mount 到本地 /opt/stack/data/nova/mnt 目录下,然后修改 instance 的 XML 将 volume 文件配置为虚拟磁盘,日志为 /opt/stack/logs/n-cpu.log。

                                                                                                                                                                                                                        1)通过 findmnt 和 mkdir 测试和创建 mount point:

                                                                                                                                                                                                                        云计算之OpenStack核心 第446张

                                                                                                                                                                                                                        2)mount NFS 目录:

                                                                                                                                                                                                                        云计算之OpenStack核心 第447张

                                                                                                                                                                                                                        3)更新 instance 的XML,将 volume 文件映射给 instance:

                                                                                                                                                                                                                        云计算之OpenStack核心 第448张

                                                                                                                                                                                                                        4)我们也可以通过 virsh edit 查看更新后的XML:

                                                                                                                                                                                                                        云计算之OpenStack核心 第449张

                                                                                                                                                                                                                        5)GUI 界面也会更新相关 attach 信息:

                                                                                                                                                                                                                        云计算之OpenStack核心 第450张

                                                                                                                                                                                                                        2.5 网络服务Neutron

                                                                                                                                                                                                                        云计算之OpenStack核心 第451张

                                                                                                                                                                                                                        2.5.1 Neutron概述

                                                                                                                                                                                                                        2.5.1.1 Neutron功能
                                                                                                                                                                                                                        • 二层交换 Switching

                                                                                                                                                                                                                          1)Nova 的 Instance 是通过虚拟交换机连接到虚拟二层网络的。

                                                                                                                                                                                                                          2)Neutron 支持多种虚拟交换机,包括 Linux 原生的 Linux Bridge 和 Open vSwitch。Open vSwitch(OVS)是一个开源的虚拟交换机,它支持标准的管理接口和协议。

                                                                                                                                                                                                                          3)利用 Linux Bridge 和 OVS,Neutron 除了可以创建传统的 VLAN 网络,还可以创建基于隧道技术的 Overlay 网络,比如 VxLAN 和 GRE(Linux Bridge 目前只支持 VxLAN)。

                                                                                                                                                                                                                        • 三层路由 Routing

                                                                                                                                                                                                                          1)Instance 可以配置不同网段的 IP,Neutron 的 router(虚拟路由器)实现 instance 跨网段通信。

                                                                                                                                                                                                                          2)router 通过 IP forwarding,iptables 等技术来实现路由和 NAT。(IP forwarding是IP转发,一种路由协议。IP转发是操作系统的一种选项,支持主机起到路由器的功能。在一个系统中含有两块以上的网卡,并将IP转发选项打开,这样该系统就可以作为路由器进行使用了)。

                                                                                                                                                                                                                        • 负载均衡 Load Balancing

                                                                                                                                                                                                                          1)Openstack 在 Grizzly 版本第一次引入了 Load-Balancing-as-a-Service(LBaaS),提供了将负载分发到多个 instance 的能力。LBaaS 支持多种负载均衡产品和方案,不同的实现以 Plugin(插件) 的形式集成到 Neutron,目前默认的 Plugin 是 HAProxy。

                                                                                                                                                                                                                        • 防火墙 Firewalling

                                                                                                                                                                                                                          Neutron 通过下面两种方式来保障 instance 和网络的安全性。

                                                                                                                                                                                                                          1)Security Group:通过 iptables 限制进出 instance 的网络包。

                                                                                                                                                                                                                          2)Firewall-as-a-Service:FWaaS,限制进出虚拟路由器的网络包,通过 iptables 实现。

                                                                                                                                                                                                                          2.5.1.2 Neutron网络基本概念
                                                                                                                                                                                                                          • network :

                                                                                                                                                                                                                            network 是一个隔离的二层广播域。Neutron 支持多种类型的 network,包括 local, flat, VLAN, VxLAN 和 GRE。

                                                                                                                                                                                                                            1)local

                                                                                                                                                                                                                            local 网络与其他网络和节点隔离。local 网络中的 instance 只能与位于同一节点上同一网络的 instance 通信,local 网络主要用于单机测试。

                                                                                                                                                                                                                            2)flat

                                                                                                                                                                                                                            flat 网络是无 vlan tagging 的网络。flat 网络中的 instance 能与位于同一网络的 instance 通信,并且可以跨多个节点。

                                                                                                                                                                                                                            3)vlan

                                                                                                                                                                                                                            vlan 网络是具有 802.1q tagging 的网络。vlan 是一个二层的广播域,同一 vlan 中的 instance 可以通信,不同 vlan 只能通过 router 通信。vlan 网络可以跨节点,是应用最广泛的网络类型。

                                                                                                                                                                                                                            4)vxlan

                                                                                                                                                                                                                            vxlan 是基于隧道技术的 overlay 网络。vxlan 网络通过唯一的 segmentation ID(也叫 VNI)与其他 vxlan 网络区分。vxlan 中数据包会通过 VNI 封装成 UDP 包进行传输。因为二层的包通过封装在三层传输,能够克服 vlan 和物理网络基础设施的限制。

                                                                                                                                                                                                                            5)gre

                                                                                                                                                                                                                            gre 是与 vxlan 类似的一种 overlay 网络。主要区别在于使用 IP 包而非 UDP 进行封装。

                                                                                                                                                                                                                            6)不同 network 之间在二层上是隔离的

                                                                                                                                                                                                                            以 vlan 网络为例,network A 和 network B 会分配不同的 VLAN ID,这样就保证了 network A 中的广播包不会跑到 network B 中。当然,这里的隔离是指二层上的隔离,借助路由器不同 network 是可能在三层上通信的。network 必须属于某个 Project( Tenant 租户),Project 中可以创建多个 network。 network 与 Project 之间是 1对多 关系。

                                                                                                                                                                                                                          • subnet:

                                                                                                                                                                                                                            subnet 是一个 IPv4 或者 IPv6 地址段。instance 的 IP 从 subnet 中分配。每个 subnet 需要定义 IP 地址的范围和掩码。subnet 与 network 是 1对多 关系。一个 subnet 只能属于某个 network;一个 network 可以有多个 subnet,这些 subnet 可以是不同的 IP 段,但不能重叠。

                                                                                                                                                                                                                            下面的配置是有效的:

                                                                                                                                                                                                                            云计算之OpenStack核心 第452张

                                                                                                                                                                                                                            但下面的配置则无效,因为 subnet 有重叠:

                                                                                                                                                                                                                            云计算之OpenStack核心 第453张

                                                                                                                                                                                                                            这里不是判断 IP 是否有重叠,而是 subnet 的 CIDR 重叠(都是 10.10.1.0/24)。

                                                                                                                                                                                                                            但是,如果 subnet 在不同的 network 中,CIDR 和 IP 都是可以重叠的,比如:

                                                                                                                                                                                                                            云计算之OpenStack核心 第454张

                                                                                                                                                                                                                            这里大家不免会疑惑: 如果上面的IP地址是可以重叠的,那么就可能存在具有相同 IP 的两个 instance,这样会不会冲突? 简单的回答是:不会!具体原因: 因为 Neutron 的 router 是通过 Linux network namespace 实现的。network namespace 是一种网络的隔离机制。通过它,每个 router 有自己独立的路由表。

                                                                                                                                                                                                                            上面的配置有两种结果:

                                                                                                                                                                                                                            1)如果两个 subnet 是通过同一个 router 路由,根据 router 的配置,只有指定的一个 subnet 可被路由。

                                                                                                                                                                                                                            2)如果上面的两个 subnet 是通过不同 router 路由,因为 router 的路由表是独立的,所以两个 subnet 都可以被路由。

                                                                                                                                                                                                                          • port:

                                                                                                                                                                                                                            1)port 可以看做虚拟交换机上的一个端口。port 上定义了 MAC 地址和 IP 地址,当 instance 的虚拟网卡 VIF(Virtual Interface)绑定到 port 时,port 会将 MAC 和 IP 分配给 VIF。

                                                                                                                                                                                                                            2)port 与 subnet 是 1对多 关系。一个 port 必须属于某个 subnet;一个 subnet 可以有多个 port。

                                                                                                                                                                                                                          • 小节

                                                                                                                                                                                                                            下面总结了 Project,Network,Subnet,Port 和 VIF 之间关系。Project 1 : m Network 1 : m Subnet 1 : m Port 1 : 1 VIF m : 1 Instance,即一个租户有多个网络,一个网络有多个子网,一个子网有多个端口,一个端口有一个虚拟网卡,一个虚拟机有多个虚拟网卡。

                                                                                                                                                                                                                            2.5.2 Neutron架构

                                                                                                                                                                                                                            2.5.2.1 Neutron组件概括
                                                                                                                                                                                                                            • 与 OpenStack 的其他服务的设计思路一样,Neutron 也是采用分布式架构,由多个组件(子服务)共同对外提供网络服务。

                                                                                                                                                                                                                              云计算之OpenStack核心 第455张

                                                                                                                                                                                                                            • Neutron由如下组件构成:

                                                                                                                                                                                                                              1)Neutron Server:对外提供 OpenStack 网络 API,接收请求,并调用 Plugin 处理请求。

                                                                                                                                                                                                                              2)Plugin:处理 Neutron Server 发来的请求,维护 OpenStack 逻辑网络的状态, 并调用 Agent 处理请求。

                                                                                                                                                                                                                              3)Agent:处理 Plugin 的请求,负责在 network provider 上真正实现各种网络功能。

                                                                                                                                                                                                                              4)network provider:提供网络服务的虚拟或物理网络设备,例如 Linux Bridge,Open vSwitch 或者其他支持 Neutron 的物理交换机。

                                                                                                                                                                                                                              5)Queue:Neutron Server,Plugin 和 Agent 之间通过 Messaging Queue 通信和调用。

                                                                                                                                                                                                                              6)Database:存放 OpenStack 的网络状态信息,包括 Network, Subnet, Port, Router 等。

                                                                                                                                                                                                                              云计算之OpenStack核心 第456张

                                                                                                                                                                                                                            • 以创建一个 VLAN100 的 network 为例,假设 network provider 是 linux bridge, 流程如下:

                                                                                                                                                                                                                              1)Neutron Server 接收到创建 network 的请求,通过 Message Queue(RabbitMQ)通知已注册的 Linux Bridge Plugin。

                                                                                                                                                                                                                              2)Plugin 将要创建的 network 的信息(例如名称、VLAN ID等)保存到数据库中,并通过 Message Queue 通知运行在各节点上的 Agent。

                                                                                                                                                                                                                              3)Agent 收到消息后会在节点上的物理网卡(比如 eth2)上创建 VLAN 设备(比如 eth2.100),并创建 bridge (比如 brqXXX) 桥接 VLAN 设备。

                                                                                                                                                                                                                            • 这里进行几点说明:

                                                                                                                                                                                                                              1)plugin 解决的是 What 的问题,即网络要配置成什么样子?而至于如何配置 How 的工作则交由 agent 完成。

                                                                                                                                                                                                                              2)plugin,agent 和 network provider 是配套使用的,比如上例中 network provider 是 linux bridge,那么就得使用 linux bridge 的 plungin 和 agent;如果 network provider 换成了 OVS 或者物理交换机,plugin 和 agent 也得替换。

                                                                                                                                                                                                                              3)plugin 的一个主要的职责是在数据库中维护 Neutron 网络的状态信息,这就造成一个问题:所有 network provider 的 plugin 都要编写一套非常类似的数据库访问代码。为了解决这个问题,Neutron 在 Havana 版本实现了一个 ML2(Modular Layer 2)plugin,对 plgin 的功能进行抽象和封装。有了 ML2 plugin,各种 network provider 无需开发自己的 plugin,只需要针对 ML2 开发相应的 driver 就可以了,工作量和难度都大大减少。ML2 会在后面详细讨论。

                                                                                                                                                                                                                              4)plugin 按照功能分为两类: core plugin 和 service plugin。core plugin 维护 Neutron 的 netowrk, subnet 和 port 相关资源的信息,与 core plugin 对应的 agent 包括 linux bridge, OVS 等; service plugin 提供 routing, firewall, load balance 等服务,也有相应的 agent。

                                                                                                                                                                                                                              2.5.2.2 Neutron物理部署方案
                                                                                                                                                                                                                              • 方案1:控制节点 + 计算节点:

                                                                                                                                                                                                                                1)控制节点:部署的服务包括:neutron server, core plugin 的 agent 和 service plugin 的 agent。

                                                                                                                                                                                                                                2)计算节点:部署 core plugin 的agent,负责提供二层网络功能。

                                                                                                                                                                                                                                NOTE:这里有几点需要说明:

                                                                                                                                                                                                                                1)core plugin 和 service plugin 已经集成到 neutron server,不需要运行独立的 plugin 服务。

                                                                                                                                                                                                                                2)控制节点和计算节点都需要部署 core plugin 的 agent,因为通过该 agent 控制节点与计算节点才能建立二层连接。

                                                                                                                                                                                                                                3)可以部署多个控制节点和计算节点。

                                                                                                                                                                                                                                云计算之OpenStack核心 第457张

                                                                                                                                                                                                                              • 方案1:控制节点 +网络节点+ 计算节点:

                                                                                                                                                                                                                                1)控制节点:部署 neutron server 服务。

                                                                                                                                                                                                                                2)网络节点:部署的服务包括:core plugin 的 agent 和 service plugin 的 agent。

                                                                                                                                                                                                                                3)计算节点:部署 core plugin 的agent,负责提供二层网络功能。

                                                                                                                                                                                                                                这个方案的要点是将所有的 agent 从控制节点分离出来,部署到独立的网络节点上。控制节点只负责通过 neutron server 响应 API 请求。由独立的网络节点实现数据的交换,路由以及 load balance等高级网络服务。可以通过增加网络节点承担更大的负载。可以部署多个控制节点、网络节点和计算节点。该方案特别适合规模较大的 OpenStack 环境。

                                                                                                                                                                                                                                云计算之OpenStack核心 第458张

                                                                                                                                                                                                                                2.5.3 Neutron组件详细说明

                                                                                                                                                                                                                                2.5.3.1 Neutron Server
                                                                                                                                                                                                                                • 下图是 Neutron Server 的分层结构,至上而下依次为:

                                                                                                                                                                                                                                  云计算之OpenStack核心 第459张

                                                                                                                                                                                                                                  1)Core API:对外提供管理 network, subnet 和 port 的 RESTful API。

                                                                                                                                                                                                                                  2)Extension API:对外提供管理 router, load balance, firewall 等资源 的 RESTful API。

                                                                                                                                                                                                                                  3)Commnon Service:认证和校验 API 请求。

                                                                                                                                                                                                                                  4)Neutron Core:Neutron server 的核心处理程序,通过调用相应的 Plugin 处理请求。

                                                                                                                                                                                                                                  5)Core Plugin API:定义了 Core Plgin 的抽象功能集合,Neutron Core 通过该 API 调用相应的 Core Plgin。

                                                                                                                                                                                                                                  6)Extension Plugin API:定义了 Service Plgin 的抽象功能集合,Neutron Core 通过该 API 调用相应的 Service Plgin。

                                                                                                                                                                                                                                  7)Core Plugin:实现了 Core Plugin API,在数据库中维护 network, subnet 和 port 的状态,并负责调用相应的 agent 在 network provider 上执行相关操作,比如创建 network。

                                                                                                                                                                                                                                  8)Service Plugin:实现了 Extension Plugin API,在数据库中维护 router, load balance, security group 等资源的状态,

                                                                                                                                                                                                                                  并负责调用相应的 agent 在 network provider 上执行相关操作,比如创建 router。

                                                                                                                                                                                                                                • 归纳起来,Neutron Server 包括两部分:1)提供 API 服务。2)运行 Plugin。

                                                                                                                                                                                                                                  即 Neutron Server = API + Plugins

                                                                                                                                                                                                                                  云计算之OpenStack核心 第460张

                                                                                                                                                                                                                                  2.5.3.2 Neutron如何支持多种network provider
                                                                                                                                                                                                                                  • 根据我们上一节讨论的 Neutron Server 的分层模型,我们需要实现两个东西:linux bridge core plugin 和 linux bridge agent。
                                                                                                                                                                                                                                  • linux bridge core plugin

                                                                                                                                                                                                                                    1)与 neutron server 一起运行。

                                                                                                                                                                                                                                    2)实现了 core plugin API。

                                                                                                                                                                                                                                    3)负责维护数据库信息。

                                                                                                                                                                                                                                    4)通知 linux bridge agent 实现具体的网络功能。

                                                                                                                                                                                                                                  • linux bridge agent

                                                                                                                                                                                                                                    1)在计算节点和网络节点(或控制节点)上运行。

                                                                                                                                                                                                                                    2)接收来自 plugin 的请求。

                                                                                                                                                                                                                                    3)通过配置本节点上的 linux bridge 实现 neutron 网络功能。

                                                                                                                                                                                                                                    云计算之OpenStack核心 第461张

                                                                                                                                                                                                                                  • 同样的道理,如果要支持 open vswitch,只需要实现 open vswitch plugin 和 open vswitch agent

                                                                                                                                                                                                                                    云计算之OpenStack核心 第462张

                                                                                                                                                                                                                                  • 由此可见:Neutron 可以通过开发不同的 plugin 和 agent 支持不同的网络技术。这是一种相当开放的架构。不过随着支持的 network provider 数量的增加,开发人员发现了两个突出的问题:只能在 OpenStack 中使用一种 core plugin,多种 network provider 无法共存。不同 plugin 之间存在大量重复代码,开发新的 plugin 工作量大。
                                                                                                                                                                                                                                    2.5.3.3 ML2 Core Plugin
                                                                                                                                                                                                                                    • Moduler Layer 2(ML2)是 Neutron 在 Havana 版本实现的一个新的 core plugin,用于替代原有的 linux bridge plugin 和 open vswitch plugin。
                                                                                                                                                                                                                                    • ML2 能解决传统 core plugin 的问题。ML2 作为新一代的 core plugin,提供了一个框架,允许在 OpenStack 网络中同时使用多种 Layer 2 网络技术,不同的节点可以使用不同的网络实现机制。

                                                                                                                                                                                                                                      云计算之OpenStack核心 第463张

                                                                                                                                                                                                                                      如上图所示,采用 ML2 plugin 后,可以在不同节点上分别部署 linux bridge agent, open vswitch agent, hyper-v agent 以及其他第三方 agent。(Hyper-V 是 Microsoft 的硬件虚拟化产品。 它用于创建并运行虚拟机。 每个虚拟机都像一台完整的计算机一样运行操作系统和程序。)

                                                                                                                                                                                                                                    • ML2 不但支持异构部署方案,同时能够与现有的 agent 无缝集成:以前用的 agent 不需要变,只需要将 Neutron server 上的传统 core plugin 替换为 ML2。有了 ML2,要支持新的 network provider 就变得简单多了:无需从头开发 core plugin,只需要开发相应的 mechanism driver,大大减少了要编写和维护的代码。
                                                                                                                                                                                                                                    • ML2 对二层网络进行抽象和建模,引入了 type driver 和 mechanism driver。这两类 driver 解耦了 Neutron 所支持的网络类型(type)与访问这些网络类型的机制(mechanism),其结果就是使得 ML2 具有非常好的弹性,易于扩展,能够灵活支持多种 type 和 mechanism。

                                                                                                                                                                                                                                      云计算之OpenStack核心 第464张

                                                                                                                                                                                                                                    • Type Driver:Neutron 支持的每一种网络类型都有一个对应的 ML2 type driver。type driver 负责维护网络类型的状态,执行验证,创建网络等。ML2 支持的网络类型包括 local, flat, vlan, vxlan 和 gre。
                                                                                                                                                                                                                                    • Mechanism Driver:Neutron 支持的每一种网络机制都有一个对应的 ML2 mechanism driver。mechanism driver 负责获取由 type driver 维护的网络状态,并确保在相应的网络设备(物理或虚拟)上正确实现这些状态。
                                                                                                                                                                                                                                    • type 和 mechanisim 都太抽象,现在我们举一个具体的例子:type driver 为 vlan,mechanism driver 为 linux bridge,我们要完成的操作是创建 network vlan100,那么:vlan type driver 会确保将 vlan100 的信息保存到 Neutron 数据库中,包括 network 的名称,vlan ID 等。linux bridge mechanism driver 会确保各节点上的 linux brige agent 在物理网卡上创建 ID 为 100 的 vlan 设备 和 brige 设备,并将两者进行桥接。
                                                                                                                                                                                                                                    • mechanism driver 有三种类型

                                                                                                                                                                                                                                      1)Agent-based:包括 linux bridge, open vswitch 等。

                                                                                                                                                                                                                                      2)Controller-based:包括 OpenDaylight, VMWare NSX 等。

                                                                                                                                                                                                                                      3)基于物理交换机:包括 Cisco Nexus, Arista, Mellanox 等。

                                                                                                                                                                                                                                      比如前面那个例子如果换成 Cisco 的 mechanism driver,则会在 Cisco 物理交换机的指定 trunk 端口上添加 vlan100。

                                                                                                                                                                                                                                    • linux bridge 和 open vswitch 的 ML2 mechanism driver 的作用是配置各节点上的虚拟交换机。linux bridge driver 支持的 type 包括 local, flat, vlan, and vxlan。open vswitch driver 除了这 4 种 type 还支持 gre。L2 population driver 作用是优化和限制 overlay 网络中的广播流量。vxlan 和 gre 都属于 overlay 网络。
                                                                                                                                                                                                                                      2.5.3.4 Service Plugin/Agent
                                                                                                                                                                                                                                      • Core Plugin/Agent 负责管理核心实体:net, subnet 和 port。而对于更高级的网络服务,则由 Service Plugin/Agent 管理。

                                                                                                                                                                                                                                        Service Plugin 及其 Agent 提供更丰富的扩展功能,包括路由,load balance,firewall等。

                                                                                                                                                                                                                                      • Neutron架构如图所示:

                                                                                                                                                                                                                                        云计算之OpenStack核心 第465张

                                                                                                                                                                                                                                        1)DHCP:dhcp agent 通过 dnsmasq 为 instance 提供 dhcp 服务。

                                                                                                                                                                                                                                        2)Routing:l3 agent 可以为 project(租户)创建 router,提供 Neutron subnet 之间的路由服务。路由功能默认通过 IPtables 实现。

                                                                                                                                                                                                                                        3)Firewall:l3 agent 可以在 router 上配置防火墙策略,提供网络安全防护。

                                                                                                                                                                                                                                        另一个与安全相关的功能是 Security Group,也是通过 IPtables 实现。Firewall 与 Security Group 的区别在于:Firewall 安全策略位于 router,保护的是某个 project 的所有 network。Security Group 安全策略位于 instance,保护的是单个 instance。

                                                                                                                                                                                                                                        4)Load Balance:Neutron 默认通过 HAProxy 为 project 中的多个 instance 提供 load balance 服务。

                                                                                                                                                                                                                                        2.5.3.5 小结

                                                                                                                                                                                                                                        云计算之OpenStack核心 第466张

                                                                                                                                                                                                                                        • 与 OpenStack 其他服务一样,Neutron 采用的是分布式架构,包括 Neutorn Server、各种 plugin/agent、database 和 message queue。

                                                                                                                                                                                                                                          1)Neutron server 接收 api 请求。

                                                                                                                                                                                                                                          2)plugin/agent 实现请求。

                                                                                                                                                                                                                                          3)database 保存 neutron 网络状态。

                                                                                                                                                                                                                                          4)message queue 实现组件之间通信。

                                                                                                                                                                                                                                        • metadata-agent 之前没有讲到,这里做个补充:

                                                                                                                                                                                                                                          instance 在启动时需要访问 nova-metadata-api 服务获取 metadata 和 userdata,这些 data 是该 instance 的定制化信息,比如 hostname, ip, public key 等。但 instance 启动时并没有 ip,如何能够通过网络访问到 nova-metadata-api 服务呢?

                                                                                                                                                                                                                                          答案就是 neutron-metadata-agent。该 agent 让 instance 能够通过 dhcp-agent 或者 l3-agent 与 nova-metadata-api 通信

                                                                                                                                                                                                                                        • 如果我们将 Neutron 架构展开,则会得到下面第二张图:

                                                                                                                                                                                                                                          云计算之OpenStack核心 第467张

                                                                                                                                                                                                                                          1)Neutron 通过 plugin 和 agent 提供的网络服务。

                                                                                                                                                                                                                                          2)plugin 位于 Neutron server,包括 core plugin 和 service plugin。

                                                                                                                                                                                                                                          3)agent 位于各个节点,负责实现网络服务。

                                                                                                                                                                                                                                          4)core plugin 提供 L2 功能,ML2 是推荐的 plugin。

                                                                                                                                                                                                                                          5)使用最广泛的 L2 agent 是 linux bridage 和 open vswitch。

                                                                                                                                                                                                                                          6)service plugin 和 agent 提供扩展功能,包括 dhcp, routing, load balance, firewall, vpn 等。

                                                                                                                                                                                                                                          2.5.4 为Neutron准备底层基础设施

                                                                                                                                                                                                                                          • 1个控制节点 +1个计算节点的部署方案:控制节点合并了网络节点的功能,同时也是一个计算节点 。

                                                                                                                                                                                                                                            云计算之OpenStack核心 第468张

                                                                                                                                                                                                                                          • 配置多个网卡区分不同类型的网络数据:Management、API、VM、External。

                                                                                                                                                                                                                                            1)Management 网络

                                                                                                                                                                                                                                            用于节点之间 message queue 内部通信以及访问 database 服务,所有的节点都需要连接到 management 网络。

                                                                                                                                                                                                                                            2)API 网络

                                                                                                                                                                                                                                            OpenStack 各组件通过该网络向用户暴露 API 服务。Keystone, Nova, Neutron, Glance, Cinder, Horizon 的 endpoints 均配置在 API 网络上。通常,管理员也通过 API 网络 SSH 管理各个节点。

                                                                                                                                                                                                                                            3)VM 网络

                                                                                                                                                                                                                                            VM 网络也叫 tenant 网络,用于 instance 之间通信。 VM 网络可以选择的类型包括 local, flat, vlan, vxlan 和 gre。 VM 网络由 Neutron 配置和管理。

                                                                                                                                                                                                                                            4)External网络

                                                                                                                                                                                                                                            External 网络指的是 VM 网络之外的网络,该网络不由 Neutron 管理。 Neutron 可以将 router attach 到 External 网络,为 instance 提供访问外部网络的能力。 External 网络可能是企业的 intranet,也可能是 internet。

                                                                                                                                                                                                                                          • 我们可以为每种网络分配单独的网卡; 也可以多种网络共同使用一个网卡;为提高带宽和硬件冗余,可以使用 bonding 技术将多个物理网卡绑定成一个逻辑的网卡,我们的实验环境采用下面的网卡分配方式:

                                                                                                                                                                                                                                            云计算之OpenStack核心 第469张

                                                                                                                                                                                                                                          • 网络拓扑:(节点安装配置参考:https://www.xjimmy.com/openstack-5min-76.html)

                                                                                                                                                                                                                                            云计算之OpenStack核心 第470张

                                                                                                                                                                                                                                            2.5.5 Linux Bridge实现Neutron网络

                                                                                                                                                                                                                                            云计算之OpenStack核心 第471张

                                                                                                                                                                                                                                            2.5.5.1 配置 Linux-Bridge Mechanism Driver
                                                                                                                                                                                                                                            • 下图中,br0 是 linux bridge,br0 充当虚拟交换机的作用,负责将物理网卡 eth0 和虚拟网卡 tap 设备 vnet0/vent1 连接到同一个二层网络,实现虚拟机 VM1 和 VM2,以及虚拟机与外网之间的通信。

                                                                                                                                                                                                                                              云计算之OpenStack核心 第472张

                                                                                                                                                                                                                                            • 配置linux-bridge mechanism driver

                                                                                                                                                                                                                                              1)要在 Neutron 中使用 linux bridge,首先需要配置 linux-bridge mechanism driver:

                                                                                                                                                                                                                                              Neutron 默认使用 ML2 作为 core plugin,其配置位于 /etc/neutron/neutron.conf。控制节点和计算节点都需要在各自的 neutron.conf 中配置 core_plugin 选项。

                                                                                                                                                                                                                                              云计算之OpenStack核心 第473张

                                                                                                                                                                                                                                              2)然后需要让 ML2 使用 linux-bridge mechanism driver:

                                                                                                                                                                                                                                              ML2 的配置文件位于 /etc/neutron/plugins/ml2/ml2_conf.ini。

                                                                                                                                                                                                                                              云计算之OpenStack核心 第474张

                                                                                                                                                                                                                                              mechanism_drivers 选项指明当前节点可以使用的 mechanism driver,这里可以指定多种 driver,ML2 会负责加载。上面的配置指明我们只使用 linux-bridge driver。控制节点和计算节点都需要在各自的 ml2_conf.ini 中配置 mechanism_drivers 选项。

                                                                                                                                                                                                                                              3)Neutron 服务正常启动后,所有节点上都会运行 neutron-linuxbridge-agent:

                                                                                                                                                                                                                                              云计算之OpenStack核心 第475张

                                                                                                                                                                                                                                              2.5.5.2 初始网络状态
                                                                                                                                                                                                                                              • 控制节点:

                                                                                                                                                                                                                                                云计算之OpenStack核心 第476张

                                                                                                                                                                                                                                                云计算之OpenStack核心 第477张

                                                                                                                                                                                                                                              • 计算节点:

                                                                                                                                                                                                                                                云计算之OpenStack核心 第478张

                                                                                                                                                                                                                                                云计算之OpenStack核心 第479张

                                                                                                                                                                                                                                              • 在 linux bridge 环境中,一个数据包从 instance 发送到物理网卡会经过下面几个类型的设备:

                                                                                                                                                                                                                                                1)tap interface:命名为 tapN (N 为 0, 1, 2, 3……)。

                                                                                                                                                                                                                                                2)linux bridge:命名为 brqXXXX。

                                                                                                                                                                                                                                                3)vlan interface:命名为 ethX.Y(X 为 interface 的序号,Y 为 vlan id)。

                                                                                                                                                                                                                                                4)vxlan interface:命名为 vxlan-Z(z 是 VNI)。

                                                                                                                                                                                                                                                5)物理 interface:命名为 ethX(X 为 interface 的序号)。

                                                                                                                                                                                                                                                linux-bridge 支持 local, flat, vlan 和 vxlan 四种 network type,目前不支持 gre。

                                                                                                                                                                                                                                                2.5.5.3 local network
                                                                                                                                                                                                                                                • local 网络与其他网络和节点隔离。local 网络中的 instance 只能与位于同一节点上同一网络的 instance 通信,local 网络主要用于单机测试。
                                                                                                                                                                                                                                                • local network 的特点是不会与宿主机的任何物理网卡相连,也不关联任何的 VLAN ID。对于每个 local netwrok,ML2 linux-bridge 会创建一个 bridge,instance 的 tap 设备会连接到 bridge。位于同一个 local network 的 instance 会连接到相同的 bridge,这样 instance 之间就可以通信了。因为 bridge 没有与物理网卡连接,所以 instance 无法与宿主机之外的网络通信。同时因为每个 local network 有自己的 bridge,bridge 之间是没有连通的,所以两个 local network 之间也不能通信,即使它们位于同一宿主机上。
                                                                                                                                                                                                                                                • 下图是 local network 的示例:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第480张

                                                                                                                                                                                                                                                  1)创建了两个 local network,分别对应两个网桥 brqXXXX 和 brqYYYY。

                                                                                                                                                                                                                                                  2)VM0 和 VM1 通过 tap0 和 tap1 连接到 brqXXXX。

                                                                                                                                                                                                                                                  3)VM2 通过 tap2 连接到 brqYYYY。

                                                                                                                                                                                                                                                  4)VM0 与 VM1 在同一个 local network中,它们之间可以通信。

                                                                                                                                                                                                                                                  5)VM2 位于另一个 local network,由于 brqXXXX 和 brqYYYY 没有联通,所以 VM2 无法与 VM0 和 VM1 通信。

                                                                                                                                                                                                                                                • 在 ML2 配置中 enable local network:

                                                                                                                                                                                                                                                  1)创建 local 网络之前请先确保 ML2 已经加载了 local type driver,ML2 的配置文件位于 /etc/neutron/plugins/ml2/ml2_conf.ini:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第481张

                                                                                                                                                                                                                                                  2)type_drivers 告诉 ML2 加载所有 5 种网络的 type driver。

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第482张

                                                                                                                                                                                                                                                  3)普通用户和 admin 都可以通过 CLI 或者 Web GUI 创建网络,但只有 amdin 才能指定网络的 type,所以需要用 tenant_network_types 告诉 ML2 当普通用户在自己的 Tenant(Project)中创建网络时,默认创建哪种 type 的网络,这里 type 是 local。tenant_network_types 可以指定多种 type,比如:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第483张

                                                                                                                                                                                                                                                  4)其作用是先创建 vlan 网络,当没有 vlan 可创建时(比如 vlan id 用完),便创建 local 网络。当配置文件发生了变化,需要重启 Neutron 相关服务使之生效。

                                                                                                                                                                                                                                                • 创建第一个 Local Network:

                                                                                                                                                                                                                                                  1)首先确保各个节点上的 neutorn agent 状态正常。GUI 菜单 为 Admin -> System -> System Infomation -> Neutron Agents:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第484张

                                                                                                                                                                                                                                                  2)GUI 中有两个地方可以创建 network :1)Project -> Network -> Networks这是普通用户在自己的 tenant 中创建 network 的地方。2)Admin -> Networks 这是 admin 创建 network 的地方。我们先用第一种方式创建,点击 “Create Network” 按钮:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第485张

                                                                                                                                                                                                                                                  3)在创建网络的向导页面给 network 命名为 “first_local_net”,点击 “Next”:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第486张

                                                                                                                                                                                                                                                  4)创建 subnet,命名为 “subnet_172_16_1_0”,地址为 “172.16.1.0/24”,点击 “Next”。如果 Gateway IP 不设置,默认为 subnet 的第一个 IP,即 172.16.1.1:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第487张

                                                                                                                                                                                                                                                  5)设置 subnet 的 IP 地址范围为 172.16.1.2-172.16.1.100,instance 的 IP 会从这里分配,点击 “Create”。默认会“Enable DHCP”,同时还可以设置 subnet 的 DNS 和添加静态路由条目。

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第488张

                                                                                                                                                                                                                                                  6)network 创建成功:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第489张

                                                                                                                                                                                                                                                  7)点击 “first_local_net” 链接,显示 network 的 subnet 和 port 信息:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第490张

                                                                                                                                                                                                                                                  8)在 Ports 列表中已经创建了一个 port,名称为 “(a5bd3746-3f89)”,IP 为 172.16.1.2, Attached Device 是 network:dhcp。打开控制节点的 shell 终端,用 brctl show 查看当前 linux bridge 的状态:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第491张

                                                                                                                                                                                                                                                  9)可以看到 Neutron 自动创建了如下两个设备:

                                                                                                                                                                                                                                                  brqbb9b6d21-c6 对应 local network “first_local_net”,命名规则为 brqXXX,XXX 为 network ID 的前 11 个字符。tapa5bd3746-3f 对应 port (a5bd3746-3f89),命名规则为 tapYYY, YYY 为 port ID 的前 11 个字符。该 tap 设备已经连接到 bridge,即连接到该 local 网络。

                                                                                                                                                                                                                                                • 将 instance 连接到 first_local_net:

                                                                                                                                                                                                                                                  1)launch 一个 instance,在“Networking”标签页面选择 first_local_net 网络:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第492张

                                                                                                                                                                                                                                                  2)instance 部署成功,分配的 IP 地址为 172.16.1.3:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第493张

                                                                                                                                                                                                                                                  3)对于 instance “cirros-vm1”,Neutron 会在 subnet 中创建一个 port,分配 IP 和 MAC 地址,并将 port 分配给 cirros-vm1:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第494张

                                                                                                                                                                                                                                                  4)如上图所示,port 列表中增加了一个 port “(fa7e090e-a29c)”,IP 为 172.16.1.3。点击 port 名称查看 MAC 信息:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第495张

                                                                                                                                                                                                                                                  5)当 cirros-vm1 启动时,宿主机上的 neutron-linuxbridge-agent 会根据 port 信息创建 tap 设备,并连接到 local 网络所在的 bridge;同时该 tap 会映射成 cirros-vm1 的虚拟网卡,即 virtual interface (VIF)。cirros-vm1 部署到了控制节点,通过 brctl show 查看 bridge 的配置:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第496张

                                                                                                                                                                                                                                                  6)可以看到 bridge brqbb9b6d21-c6 上连接了一个新的 tap 设备 tapfa7e090e-a2 从命名上可知 tapfa7e090e-a2 对应着 port “(fa7e090e-a29c)”。virsh list 中显示的虚拟机 instance-00000001 即为 “cirros-vm1”,命名方式有所不同,需注意。通过 virsh edit 命令查看 cirros-vm1 的配置,确认 VIF 就是 tapfa7e090e-a2:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第497张

                                                                                                                                                                                                                                                  7)另外,VIF 的 MAC 地址为 fa:16:3e:c1:66:a5,这个数据就是从 port “(fa7e090e-a29c)” 取过来的。在 cirros-vm1 中执行 ifconfig,通过 MAC 地址可以确认 eth0 与 tapfa7e090e-a2 对应。

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第498张

                                                                                                                                                                                                                                                  8)下图展示了创建 cirros-vm1 后宿主机当前的网络结构 :

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第499张

                                                                                                                                                                                                                                                • 连接第二个 Insance 到 First_local_net:

                                                                                                                                                                                                                                                  1)以同样的方式 launch instance “cirros-vm2”分配的 IP 为 172.16.1.4:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第500张

                                                                                                                                                                                                                                                  2)cirros-vm2 也被 schedule 到控制节点。virsh list 和 brctl show 输出如下 cirros-vm2 对于的 tap 设备为 tapa5bd3746-3f。

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第501张

                                                                                                                                                                                                                                                  3)在 cirros-vm2 的控制台运行 ifconfig,instance 已经拿到了 DCHP 的 IP 地址:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第502张

                                                                                                                                                                                                                                                  4)能够 Ping 通 cirros-vm1 的 IP 地址 172.16.1.3:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第503张

                                                                                                                                                                                                                                                  5)前宿主机的网络结构如下 :

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第504张

                                                                                                                                                                                                                                                  6)两个 instance 的 VIF 挂在同一个 linux bridge 上,可以相互通信。这里请大家思考一个问题:如果 cirros-vm2 launch 时被 schedule 到计算节点而非控制节点,它能获得 DHCP 的 IP 吗?答案:不能。 因为 DHCP agent 在控制节点上运行,cirros-vm2 在计算节点的 local 网络上,两者位于不同物理节点。由于 local 网络的流量只能局限在本节点之内,发送的 DHCP 请求无法到达控制节点。

                                                                                                                                                                                                                                                • 创建第二个 Local Network:

                                                                                                                                                                                                                                                  1)GUI 中有两个地方可以创建 network:Project -> Network -> Networks这是普通用户在自己的 tenant 中创建 network 的地方、Admin -> Networks 这是 admin 创建 network 的地方。前面我们已经用第一种方式创建了 “first_local_net”。本节将以第二种方式创建 local network “second_local_net” 。菜单路径为 Admin -> Networks,此菜单只有 admin 用户才能够访问,点击 “Create Network” 按钮:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第505张

                                                                                                                                                                                                                                                  2)显示创建页面,点击 “Create Network”,second_local_net 创建成功:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第506张

                                                                                                                                                                                                                                                  3)可以看到几个与普通用户创建 network 不同的地方:

                                                                                                                                                                                                                                                  a)可以选择该 network 属于哪个 Project(租户)。

                                                                                                                                                                                                                                                  b)可以选择 network type。

                                                                                                                                                                                                                                                  c)可以指定 network 是否与其他 Project 共享。

                                                                                                                                                                                                                                                  d)可以指定是否为 external network。

                                                                                                                                                                                                                                                  可见,这种方式赋予 admin 用户创建 network 更大的灵活性,后面我们都将采用这种方式创建 network。

                                                                                                                                                                                                                                                  4)点击 second_local_net 链接,进入 network 配置页面:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第507张

                                                                                                                                                                                                                                                  5)目前还没有 subnet,点击 “Create Subnet” 按钮:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第508张

                                                                                                                                                                                                                                                  6)设置 IP 地址为 “172.16.1.0/24”,点击 “Next”:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第509张

                                                                                                                                                                                                                                                  7)设置 IP 地址范围为 172.16.1.101-172.16.1.200,点击 “Create”:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第510张

                                                                                                                                                                                                                                                  8)subnet 创建成功:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第511张

                                                                                                                                                                                                                                                  9)查看控制节点的网络结构。增加了 second_local_net 对应的网桥 brq161e0b25-58,以及 dhcp 的 tap 设备 tapae547b6b-2a:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第512张

                                                                                                                                                                                                                                                • 将 Instance 连接到 Second_local_net:

                                                                                                                                                                                                                                                  1)launch 新的 instance “cirros-vm3”,网络选择 second_local_net:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第513张

                                                                                                                                                                                                                                                  2)cirros-vm3 分配到的 IP 为 172.16.1.102:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第514张

                                                                                                                                                                                                                                                  3)cirros-vm3 被 schedule 到控制节点,对应的 tap 设备为 tap5395d19b-ed:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第515张

                                                                                                                                                                                                                                                  4)控制台显示 cirros-vm3 已经成功从 DHCP 拿到 IP 地址 172.16.1.102:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第516张

                                                                                                                                                                                                                                                  5)但是 cirros-vm3 无法 Ping 到 cirros-vm1:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第517张

                                                                                                                                                                                                                                                  6)这是在预料之中的,因为 cirros-vm3 和 cirros-vm1 位于不同的 local network,之间没有连通,即使都位于同一个宿主机也不能通信。网络结构如下:

                                                                                                                                                                                                                                                  云计算之OpenStack核心 第518张

                                                                                                                                                                                                                                                  小结:位于同一 local network 的 instance 可以通信; 位于不同 local network 的 instance 无法通信;一个 local network 只能位于一个物理节点,无法跨节点。

                                                                                                                                                                                                                                                  2.5.5.4 flat network
                                                                                                                                                                                                                                                  • flat network 是不带 tag 的网络,要求宿主机的物理网卡直接与 linux bridge 连接,这意味着:每个 flat network 都会独占一个物理网卡。
                                                                                                                                                                                                                                                  • 下图中 eth1 桥接到 brqXXX,为 instance 提供 flat 网络。

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第519张

                                                                                                                                                                                                                                                  • 如果需要创建多个 flat network,就得准备多个物理网卡,如下图所示:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第520张

                                                                                                                                                                                                                                                  • Flat Network 原理与配置:

                                                                                                                                                                                                                                                    1)在 ML2 配置中 enable flat network,在 /etc/neutron/plugins/ml2/ml2_conf.ini 设置 flat network 相关参数:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第521张

                                                                                                                                                                                                                                                    指定普通用户创建的网络类型为 flat。 需要注意的是:因为 flat 网络与物理网卡一一对应,一般情况下租户网络不会采用 flat,这里只是示例。

                                                                                                                                                                                                                                                    2)接着需要指明 flat 网络与物理网卡的对应关系:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第522张

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第523张

                                                                                                                                                                                                                                                    如上所示:a)在 [ml2_type_flat] 中通过 flat_networks 定义了一个 flat 网络,label 为 “default”。b)在 [linux_bridge] 中通过 physical_interface_mappings 指明 default 对应的物理网卡为 eth1。

                                                                                                                                                                                                                                                    3)理解 label 与 ethX 的关系:label 是 flat 网络的标识,在创建 flat 时需要指定 label(后面演示)。label 的名字可以是任意字符串,只要确保各个节点 ml2_conf.ini 中的 label 命名一致就可以了。各个节点中 label 与物理网卡的对应关系可能不一样。这是因为每个节点可以使用不同的物理网卡将 instance 连接到 flat network。

                                                                                                                                                                                                                                                    例如对于 label 为 “default” 的 flat network,节点 A 可能使用 eth1,配置为:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第524张

                                                                                                                                                                                                                                                    而节点 B 则可能使用 eth2,配置为:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第525张

                                                                                                                                                                                                                                                    4)支持多个 flat :如果要创建多个 flat 网络,需要定义多个 label,用逗号隔开,当然也需要用到多个物理网卡,如下所示:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第526张

                                                                                                                                                                                                                                                  • 创建 Flat Network:

                                                                                                                                                                                                                                                    1)打开菜单 Admin -> Networks,点击 “Create Network” 按钮:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第527张

                                                                                                                                                                                                                                                    2)显示创建页面, 点击 “Create Network”,flat_net 创建成功。Provider Network Type 选择 “Flat”。Physical Network 填写 “default”,与 ml2_conf.ini 中 flat_networks 参数保持一致:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第528张

                                                                                                                                                                                                                                                    3)点击 flat_net 链接,进入 network 配置页面:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第529张

                                                                                                                                                                                                                                                    4)目前还没有 subnet,点击 “Create Subnet” 按钮:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第530张

                                                                                                                                                                                                                                                    5)设置 IP 地址为 “172.16.1.0/24”,点击 “Next”:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第531张

                                                                                                                                                                                                                                                    6)设置 IP 地址范围为 172.16.1.101-172.16.1.200,点击 “Create”:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第532张

                                                                                                                                                                                                                                                    7)subnet 创建成功:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第533张

                                                                                                                                                                                                                                                    8)底层网络发生了什么变化 。执行 brctl show,查看控制节点当前的网络结构:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第534张

                                                                                                                                                                                                                                                    Neutron 自动新建了 flat_net 对应的网桥 brqf153b42f-c3,以及 dhcp 的 tap 设备 tap19a0ed3d-fe。另外,tap19a0ed3d-fe 和物理网卡 eth1 都已经连接到 bridge。此时 flat_net 结构如图所示:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第535张

                                                                                                                                                                                                                                                  • 将 Instance 连接到 Flat_net:

                                                                                                                                                                                                                                                    1)launch 新的 instance “cirros-vm1”,选择网络 falt_net:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第536张

                                                                                                                                                                                                                                                    2)cirros-vm1 分配到的 IP 为 172.16.1.103:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第537张

                                                                                                                                                                                                                                                    3)cirros-vm1 被 schedule 到控制节点,对应的 tap 设备为 tapc1875c7f-cb,并且已经连接到 bridge :

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第538张

                                                                                                                                                                                                                                                    4)当前 flat_net 的结构如下:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第539张

                                                                                                                                                                                                                                                    5)继续用同样的方式 launch instance cirros-vm2,分配到的 IP 为 172.16.1.104:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第540张

                                                                                                                                                                                                                                                    6)cirros-vm2 被 schedule 到计算节点,对应的 tap 设备为 tapfb3fb197-24,并且连接到 bridge:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第541张

                                                                                                                                                                                                                                                    这里有两点需要提醒:因为计算节点上没有 dhcp 服务,所以 brctl show 中没有 dhcp 对应的 tap 设备。计算节点上 bridge 的名称与控制节点上一致,都是 brqf153b42f-c3,表明是同一个 network。

                                                                                                                                                                                                                                                    7)当前 flat_net 的结构如下:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第542张

                                                                                                                                                                                                                                                    8)cirros-vm1(172.16.1.103) 与 cirros-vm2(172.16.1.104) 位于不同节点,通过 flat_net 相连,下面执行 PING 验证连通性。 在 cirros-vm1 控制台中执行 ping 172.16.1.104:

                                                                                                                                                                                                                                                    云计算之OpenStack核心 第543张

                                                                                                                                                                                                                                                    2.5.5.5 DHCP服务
                                                                                                                                                                                                                                                    • Neutron 提供 DHCP 服务的组件是 DHCP agent。 DHCP agent 在网络节点运行上,默认通过 dnsmasq 实现 DHCP 功能。

                                                                                                                                                                                                                                                      云计算之OpenStack核心 第544张

                                                                                                                                                                                                                                                    • 配置 DHCP agent:

                                                                                                                                                                                                                                                      1)DHCP agent 的配置文件位于 /etc/neutron/dhcp_agent.ini:

                                                                                                                                                                                                                                                      云计算之OpenStack核心 第545张

                                                                                                                                                                                                                                                      dhcp_driver :使用 dnsmasq 实现 DHCP。

                                                                                                                                                                                                                                                      interface_driver :使用 linux bridge 连接 DHCP namespace interface。

                                                                                                                                                                                                                                                      2)当创建 network 并在 subnet 上 enable DHCP:

                                                                                                                                                                                                                                                      网络节点上的 DHCP agent 会启动一个dnsmasq 进程为该network 提供 DHCP 服务,dnsmasq 是一个提供 DHCP 和 DNS 服务的开源软件。dnsmasq 与 network 是一对一关系,一个 dnsmasq 进程可以为同一 netowrk 中所有 enable 了 DHCP 的 subnet 提供服务。

                                                                                                                                                                                                                                                      3)回到我们的实验环境,之前创建了 flat_net,并且在 subnet 上启用了 DHCP,执行 ps 查看 dnsmasq 进程,如下图所示:

                                                                                                                                                                                                                                                      云计算之OpenStack核心 第546张

                                                                                                                                                                                                                                                      DHCP agent 会为每个 network 创建一个目录 /opt/stack/data/neutron/dhcp/,用于存放该 network 的 dnsmasq 配置文件。

                                                                                                                                                                                                                                                      4)讨论 dnsmasq 重要的启动参数:

                                                                                                                                                                                                                                                      --dhcp-hostsfile:存放 DHCP host 信息的文件,这里的 host 在我们这里实际上就是 instance。dnsmasq 从该文件获取 host 的 IP 与 MAC 的对应关系。每个 host 对应一个条目,信息来源于 Neutron 数据库。对于 flat_net,hostsfile 是 /opt/stack/data/neutron/dhcp/f153b42f-c3a1-4b6c-8865-c09b5b2aa274/host,记录了 DHCP,cirros-vm1 和 cirros-vm2 的 interface 信息。

                                                                                                                                                                                                                                                      云计算之OpenStack核心 第547张

                                                                                                                                                                                                                                                      --interface:指定提供 DHCP 服务的 interface。dnsmasq 会在该 interface 上监听 instance 的 DHCP 请求。对于 flat_net,interface 是 ns-19a0ed3d-fe。或许大家还记得,之前我们看到的 DHCP interface 叫 tap19a0ed3d-fe(如下图所示),并非 ns-19a0ed3d-fe。

                                                                                                                                                                                                                                                      云计算之OpenStack核心 第548张

                                                                                                                                                                                                                                                      从名称上看,ns-19a0ed3d-fe 和 tap19a0ed3d-fe 应该存在某种联系,但那是什么呢?要回答这个问题,需要先搞懂一个概念:Linux Network Namespace,我们下一节详细讨论。

                                                                                                                                                                                                                                                    • 用 Namspace 隔离 DHCP 服务:

                                                                                                                                                                                                                                                      1)Neutron 通过 dnsmasq 提供 DHCP 服务,而 dnsmasq 如何独立的为每个 network 服务呢?

                                                                                                                                                                                                                                                      2)答案是通过 Linux Network Namespace 隔离。在二层网络上,VLAN 可以将一个物理交换机分割成几个独立的虚拟交换机。 类似地,在三层网络上,Linux network namespace 可以将一个物理三层网络分割成几个独立的虚拟三层网络。

                                                                                                                                                                                                                                                      3)每个 namespace 都有自己独立的网络栈,包括 route table,firewall rule,network interface device 等。

                                                                                                                                                                                                                                                      4)Neutron 通过 namespace 为每个 network 提供独立的 DHCP 和路由服务,从而允许租户创建重叠的网络。如果没有 namespace,网络就不能重叠,这样就失去了很多灵活性。

                                                                                                                                                                                                                                                    • 每个 dnsmasq 进程都位于独立的 namespace,命名为 qdhcp-,例如 flat_net,我们有:

                                                                                                                                                                                                                                                      云计算之OpenStack核心 第549张

                                                                                                                                                                                                                                                      1)ip netns list 命令列出所有的 namespace。

                                                                                                                                                                                                                                                      qdhcp-f153b42f-c3a1-4b6c-8865-c09b5b2aa274 就是 flat_net 的 namespace。

                                                                                                                                                                                                                                                      2)其实,宿主机本身也有一个 namespace,叫 root namespace,拥有所有物理和虚拟 interface device。物理interface 只能位于 root namespace。新创建的 namespace 默认只有一个 loopback device。管理员可以将虚拟 interface,例如 bridge,tap 等设备添加到某个 namespace。对于 flat_net 的 DHCP 设备 tap19a0ed3d-fe,需要将其放到 namespace qdhcp-f153b42f-c3a1-4b6c-8865-c09b5b2aa274 中,但这样会带来一个问题: tap19a0ed3d-fe 将无法直接与 root namespace 中的 bridge 设备 brqf153b42f-c3 连接。

                                                                                                                                                                                                                                                    • Neutron 使用 veth pair 解决了这个问题:

                                                                                                                                                                                                                                                      1)veth pair 是一种成对出现的特殊网络设备,它们象一根虚拟的网线,可用于连接两个 namespace。向 veth pair 一端输入数据,在另一端就能读到此数据。

                                                                                                                                                                                                                                                      2)tap19a0ed3d-fe 与 ns-19a0ed3d-fe 就是一对 veth pair,它们将 qdhcp-f153b42f-c3a1-4b6c-8865-c09b5b2aa274 连接到 brqf153b42f-c3。

                                                                                                                                                                                                                                                      云计算之OpenStack核心 第550张

                                                                                                                                                                                                                                                    • 可以通过 ip netns exec 管理 namespace:

                                                                                                                                                                                                                                                      1)例如查看 ns-19a0ed3d-fe 的配置:

                                                                                                                                                                                                                                                      云计算之OpenStack核心 第551张

                                                                                                                                                                                                                                                    • 分析instance如何从dnsmasq获取IP:

                                                                                                                                                                                                                                                      1)在创建 instance 时,Neutron 会为其分配一个 port,里面包含了 MAC 和 IP 地址信息,这些信息会同步更新到 dnsmasq 的 host 文件。如下图所示:

                                                                                                                                                                                                                                                      云计算之OpenStack核心 第552张

                                                                                                                                                                                                                                                      2)同时 nova-compute 会设置 cirros-vm1 VIF 的 MAC 地址:

                                                                                                                                                                                                                                                      云计算之OpenStack核心 第553张

                                                                                                                                                                                                                                                      3)一切准备就绪,instance 获取 IP 的过程如下:

                                                                                                                                                                                                                                                      a)cirros-vm1 开机启动,发出 DHCPDISCOVER 广播,该广播消息在整个 flat_net 中都可以被收到。

                                                                                                                                                                                                                                                      b)广播到达 veth tap19a0ed3d-fe,然后传送给 veth pair 的另一端 ns-19a0ed3d-fe。dnsmasq 在它上面监听,dnsmasq 检查其 host 文件,发现有对应项,于是dnsmasq 以 DHCPOFFER 消息将 IP(172.16.1.103)、子网掩码(255.255.255.0)、地址租用期限等信息发送给 cirros-vm1。

                                                                                                                                                                                                                                                      c)cirros-vm1 发送 DHCPREQUEST 消息确认接受此 DHCPOFFER。

                                                                                                                                                                                                                                                      d)dnsmasq 发送确认消息 DHCPACK,整个过程结束。

                                                                                                                                                                                                                                                    • 这个过程我们可以在 dnsmasq 日志中查看,dnsmasq 默认将日志记录到 /var/log/syslog:

                                                                                                                                                                                                                                                      云计算之OpenStack核心 第554张

                                                                                                                                                                                                                                                      2.5.5.6 vlan network
                                                                                                                                                                                                                                                      • 下图是 vlan100 网络的示例,三个 instance 通过 TAP 设备连接到名为 “brqXXXX” linux bridge。在物理网卡 eth1 上创建了 eth1.100 的 vlan interface,eth1.100 连接到 brqXXXX。instance 通过 eth1.100 发送到 eth1 的数据包就会打上 vlan100 的 tag。

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第555张

                                                                                                                                                                                                                                                      • 如果再创建一个 network vlan101,eth1 上会相应的创建 vlan interface eth1.101,并且连接的新的 lingux bridge “brqYYYY”。

                                                                                                                                                                                                                                                        每个 vlan network 有自己的 bridge,从而也就实现了基于 vlan 的隔离。

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第556张

                                                                                                                                                                                                                                                      • 这里有一点要特别提醒:因为物理网卡 eth1 上面可以走多个 vlan 的数据,那么物理交换机上与 eth1 相连的的 port 要设置成 trunk 模式,而不是 access 模式。
                                                                                                                                                                                                                                                      • 在 ML2 中配置 Vlan Network:

                                                                                                                                                                                                                                                        1)首先在 /etc/neutron/plugins/ml2/ml2_conf.ini 中设置 vlan network 相关参数,指定普通用户创建的网络类型为 vlan:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第557张

                                                                                                                                                                                                                                                        2)然后指定 vlan 的范围:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第558张

                                                                                                                                                                                                                                                        上面配置定义了 label 为 “default” 的 vlan network,vlan id 的范围是 3001 – 4000。这个范围是针对普通用户在自己的租户里创建 network 的范围。因为普通用户创建 network 时并不能指定 vlan id,Neutron 会按顺序自动从这个范围中取值。对于 admin 则没有 vlan id 的限制,admin 可以创建 id 范围为 1-4094 的 vlan network。

                                                                                                                                                                                                                                                        3)接着需要指明 vlan network 与物理网卡的对应关系:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第559张

                                                                                                                                                                                                                                                        如上所示: 在 [ml2_type_vlan] 中定义了 lable “default”,[linux_bridge] 中则指明 default 对应的物理网卡为 eth1。这里 label 的作用与前面 flat network 中的 label 一样,只是一个标识,可以是任何字符串。配置完成,重启 Neutron 服务后生效。

                                                                                                                                                                                                                                                      • 创建第一个 Vlan Network Vlan100:

                                                                                                                                                                                                                                                        1)打开菜单 Admin -> Networks,点击 “Create Network” 按钮:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第560张

                                                                                                                                                                                                                                                        2)显示创建页面,点击 “Create Network”,vlan100 创建成功:

                                                                                                                                                                                                                                                        Provider Network Type 选择 “VLAN”。Physical Network 填写 “default”,必须与 ml2_conf.ini中network_vlan_ranges 参数值保持一致。Segmentation ID 即 VLAN ID,设置为 100。

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第561张

                                                                                                                                                                                                                                                        3)点击 vlan100 链接,进入 network 配置页面:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第562张

                                                                                                                                                                                                                                                        4)目前还没有 subnet,点击 “Create Subnet” 按钮:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第563张

                                                                                                                                                                                                                                                        5)subnet_172_16_100_0,IP 地址为 172.16.100.0/24:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第564张

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第565张

                                                                                                                                                                                                                                                        6)底层网络发生了什么变化:

                                                                                                                                                                                                                                                        在控制节点上执行 brctl show,查看当前网络结构:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第566张

                                                                                                                                                                                                                                                        Neutron 自动新建了三个设备:

                                                                                                                                                                                                                                                        1. vlan100 对应的网桥 brq3fcfdb98-9d。
                                                                                                                                                                                                                                                        2. vlan interface eth1.100。
                                                                                                                                                                                                                                                        3. dhcp 的 tap 设备 tap1180bbe8-06。

                                                                                                                                                                                                                                                          eth1.100 和 tap19a0ed3d-fe 已经连接到了 brq3fcfdb98-9d,VLAN 100 的二层网络就绪

                                                                                                                                                                                                                                                          7)此时 vlan100 结构如图所示:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第567张

                                                                                                                                                                                                                                                      • 将instance连接到vlan100:

                                                                                                                                                                                                                                                        1)launch 新的 instance “cirros-vm1”,网络选择 vlan100:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第568张

                                                                                                                                                                                                                                                        2)cirros-vm1 分配到的 IP 为 172.16.100.3:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第569张

                                                                                                                                                                                                                                                        3)cirros-vm1 被 schedule 到控制节点,对应的 tap 设备为 tapc1875c7f-cb,并且连接到 bridge:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第570张

                                                                                                                                                                                                                                                        4)当前 vlan100 的结构如下 :

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第571张

                                                                                                                                                                                                                                                        5)继续用同样的方式 launch instance cirros-vm2,分配到的 IP 为 172.16.100.104:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第572张

                                                                                                                                                                                                                                                        6)cirros-vm2 被 schedule 到计算节点,对应的 tap 设备为 tap238437b8-50,并且连接到 bridge:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第573张

                                                                                                                                                                                                                                                        因为计算节点上没有 hdcp 服务,所以没有相应的 tap 设备。 另外,bridge 的名称与控制节点上一致,都是 brq3fcfdb98-9d,表明是同一个 network。

                                                                                                                                                                                                                                                        7)当前 vlan100 的结构如下:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第574张

                                                                                                                                                                                                                                                        8)cirros-vm1(172.16.100.3) 与 cirros-vm2(172.16.100.4) 位于不同节点,通过 vlan100 相连,下面执行 PING 验证连通性。 在 cirros-vm1 控制台中执行 ping 172.16.100.4:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第575张

                                                                                                                                                                                                                                                      • 创建第二个 Vlan Network Vlan101:

                                                                                                                                                                                                                                                        1)创建第二个 vlan network vlan101:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第576张

                                                                                                                                                                                                                                                        2)subnet IP 地址为 172.16.101.0/24:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第577张

                                                                                                                                                                                                                                                        3) 底层网络发生了什么变化:

                                                                                                                                                                                                                                                        Neutron 自动创建了 vlan101 对应的网桥 brq1d7040b8-01,vlan interface eth1.101,以及 dhcp 的 tap 设备 tap5b1a2247-32。eth1.101 和 tap5b1a2247-32 已经连接到 brq1d7040b8-01,VLAN 101 的二层网络就绪。

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第578张

                                                                                                                                                                                                                                                        4)网络结构如下:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第579张

                                                                                                                                                                                                                                                      • 连接 Insance 到 Vlan101:

                                                                                                                                                                                                                                                        1)launch 新的 instance “cirros-vm3”,网络选择 vlan101:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第580张

                                                                                                                                                                                                                                                        2)cirros-vm3 分配到的 IP 为 172.16.101.103:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第581张

                                                                                                                                                                                                                                                        3)cirros-vm3 被 schedule 到计算节点,对应的 tap 设备为 tapadb5cc6a-7a,并且连接到 bridge:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第582张

                                                                                                                                                                                                                                                        4)当前网络结构如下:

                                                                                                                                                                                                                                                        云计算之OpenStack核心 第583张

                                                                                                                                                                                                                                                        cirros-vm1 位于控制节点,属于 vlan100。

                                                                                                                                                                                                                                                        cirros-vm2 位于计算节点,属于 vlan100。

                                                                                                                                                                                                                                                        cirros-vm3 位于计算节点,属于 vlan101。

                                                                                                                                                                                                                                                        cirros-vm1 与 cirros-vm2 都在 vlan100,它们之间能通信。

                                                                                                                                                                                                                                                        cirros-vm3 在 vlan101,不能与 cirros-vm1 和 cirros-vm2 通信。

                                                                                                                                                                                                                                                        那怎么样才能让 vlan100 与 vlan101 中的 instance 通信呢?单靠二层 vlan 是不行的,还得在三层通过路由器转发。

                                                                                                                                                                                                                                                        2.5.5.7 Routing
                                                                                                                                                                                                                                                        • Routing 功能概述:

                                                                                                                                                                                                                                                          1)路由服务(Routing)提供跨 subnet 互联互通功能。例如前面我们搭建了实验环境:

                                                                                                                                                                                                                                                          cirros-vm1 172.16.100.3 vlan100

                                                                                                                                                                                                                                                          cirros-vm3 172.16.101.3 vlan101

                                                                                                                                                                                                                                                          这两个 instance 要通信必须借助 router。 可以是物理 router 或者虚拟 router。

                                                                                                                                                                                                                                                          2)物理路由:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第584张

                                                                                                                                                                                                                                                          接入的物理 router 有两个 interface ip:

                                                                                                                                                                                                                                                          172.16.100.1 对应 vlan100 的网关。

                                                                                                                                                                                                                                                          172.16.101.1 对应 vlan101 的网关。

                                                                                                                                                                                                                                                          当 cirros-vm1 要跟 cirros-vm3 通信时,数据包的流向是这样的:a)因为 cirros-vm1 的默认网关指向 172.16.100.1,cirros-vm1 发送到 cirros-vm3 的数据包首先通过 vlan100 的 interface 进入物理 router。b)router 发现目的地址 172.16.101.3 与 172.16.101.1 为同一个 vlan,则从 vlan101 的 interface 发出。c)数据包经过 brq1d7040b8-01 最终到达 cirros-vm3。

                                                                                                                                                                                                                                                          3)虚拟路由:

                                                                                                                                                                                                                                                          虚拟 router 的路由机制与物理 router 一样,只是由软件实现。Neutron 两种方案都支持。如果要使用虚拟 router,需要启用 L3 agent。L3 agent 会在控制节点或者网络节点上运行虚拟 router,为 subnet 提供路由服务。

                                                                                                                                                                                                                                                        • 配置 L3 Agent:

                                                                                                                                                                                                                                                          1)Neutron 的路由服务是由 l3 agent 提供的,除此之外,l3 agent 通过 iptables 提供 firewall 和 floating ip 服务。

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第585张

                                                                                                                                                                                                                                                          2)l3 agent 需要正确配置才能工作,配置文件为 /etc/neutron/l3_agent.ini,位于控制节点或网络节点上:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第586张interface_driver 是最重要的选项,如果 mechanism driver 是 linux bridge,则:interface_driver = neutron.agent.linux.interface.BridgeInterfaceDriver;如果选用 open vswitch,则:interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver。

                                                                                                                                                                                                                                                          3)l3 agent 运行在控制或网络节点上:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第587张

                                                                                                                                                                                                                                                          可以看到 l3 agnet 已经正常启动。

                                                                                                                                                                                                                                                        • 创建 Router 连通 Subnet:

                                                                                                                                                                                                                                                          1)创建虚拟路由器“router_100_101”,打通 vlan100 和 vlan101。打开操作菜单 Project -> Network -> Routers:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第588张

                                                                                                                                                                                                                                                          2)点击 “Create Router” 按钮:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第589张

                                                                                                                                                                                                                                                          3)router 命名为 “router_100_101”,点击 “Create Router” 按钮确认:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第590张

                                                                                                                                                                                                                                                          4)router_100_101 创建成功:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第591张

                                                                                                                                                                                                                                                          5)接下来需要将 vlan100 和 vlan101 连接到 router_100_101 。点击 “router_100_101” 链接进入 router 的配置页面,在 “Interfaces” 标签中点击 “Add Interface” 按钮

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第592张

                                                                                                                                                                                                                                                          6)选择 vlan101 的 subnet_172_16_101_0,点击 “Add Interface” 确认:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第593张

                                                                                                                                                                                                                                                          7)用同样的方法添加 vlan100 的 subnet_172_16_100_0:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第594张

                                                                                                                                                                                                                                                          完成后,可以看到 router_100_101 有了两个 interface,其 IP 正好是 subnet 的 Gateway IP 172.16.100.1 和 172.16.101.1。

                                                                                                                                                                                                                                                          8)router_100_101 已经连接了 subnet_172_16_100_0 和 subnet_172_16_101_0。router_100_101 上已经设置好了两个 subnet 的 Gateway IP。cirros-vm1 和 cirros-vm3 应该可以通信了。通过 PING 测试一下:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第595张

                                                                                                                                                                                                                                                          9)查看 cirros-vm1 的路由表,默认网关为 172.16.100.1。同时 traceroute 告诉我们,cirros-vm1 确实是通过 router_100_101 访问到 cirros-vm3 的:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第596张

                                                                                                                                                                                                                                                        • 虚拟 ​Router 原理分析:

                                                                                                                                                                                                                                                          1)首先我们查看控制节点的 linux bridge 结构发生了什么变化:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第597张

                                                                                                                                                                                                                                                          vlan101 的 bridge 上多了一个 tape17162c5-00,从命名上可以推断该 TAP 设备对应 router_100_101 的 interface (e17162c5-00fa)。vlan100 的 bridge 上多了一个 tapd568ba1a-74,从命名上可以推断该 TAP 设备对应 router_100_101 的 interface (d568ba1a-740e)。

                                                                                                                                                                                                                                                          2)当前网络结构如图所示:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第598张

                                                                                                                                                                                                                                                          3)两个 TAP 设备上并没有配置相应的 Gateway IP:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第599张

                                                                                                                                                                                                                                                          4)如果没有 Gateway IP,router_100_101 是如何完成路由的呢?

                                                                                                                                                                                                                                                          答案是:l3 agent 会为每个 router 创建了一个 namespace,通过 veth pair 与 TAP 相连,然后将 Gateway IP 配置在位于 namespace 里面的 veth interface 上,这样就能提供路由了。

                                                                                                                                                                                                                                                          5)通过 ip netns 查看 namespace:router 对应的 namespace 命名为 qrouter-。

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第600张

                                                                                                                                                                                                                                                          6)通过 ip netns exec ip a 命令查看 router_100_101 namespace 中的 veth interface 配置:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第601张

                                                                                                                                                                                                                                                          namespace 中有两个 interface:qr-e17162c5-00 上设置了 Gateway IP 172.16.101.1,与 root namespace 中的 tape17162c5-00 组成 veth pair。qr-d568ba1a-74 上设置了 Gateway IP 172.16.100.1,与 root namespace 中的 tapd568ba1a-74 组成 veth pair。

                                                                                                                                                                                                                                                          7)网络结构如图所示:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第602张

                                                                                                                                                                                                                                                          8)namespace 中的路由表也保证了 subnet_172_16_100_0 和 subnet_172_16_101_0 之间是可以路由的,命令为ip nets exec IP routing table:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第603张

                                                                                                                                                                                                                                                        • 为什么要使用Namespace:

                                                                                                                                                                                                                                                          1)为什么不直接在 tape17162c5-00 和 tapd568ba1a-74 上配置 Gateway IP,而是引入一个 namespace,在 namespace 里面配置 Gateway IP 呢?首先考虑另外一个问题:如果不用 namespace,直接 Gareway IP 配置到 tape17162c5-00 和 tapd568ba1a-74 上,能不能连通 subnet_172_16_100_0 和 subnet_172_16_101_0 呢?

                                                                                                                                                                                                                                                          答案是可以的,只要控制节点上配置了类似下面的路由:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第604张

                                                                                                                                                                                                                                                          既然不需要 namespace 也可以路由,为什么还要加一层 namespace 增加复杂性呢?其根本原因是:增加namespace是为了支持网络重叠。 云环境下,租户可以按照自己的规划创建网络,不同租户的网络是可能重叠的。 将路由功能放到 namespace 中,就能隔离不同租户的网络,从而支持网络重叠。

                                                                                                                                                                                                                                                          2)通过例子进一步解释:A,B 两个租户定义了完全相同的两个 subnet,网络完全重叠。如下图所示:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第605张

                                                                                                                                                                                                                                                          3)不使用namespace的场景:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第606张

                                                                                                                                                                                                                                                          其特征是网关 IP 配置在 TAP interface 上。因为没有 namespace 隔离,router_100_101 和 router_102_103 的路由条目都只能记录到控制节点操作系统(root namespace)的路由表中,内容如下:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第607张

                                                                                                                                                                                                                                                          这样的路由表是无法工作的。按照路由表优先匹配原则,Tenant B 的数据包总是错误地被 Tenant A 的 router 路由。例如 vlan102 上有数据包要发到 vlan103。选择路由时,会匹配路由表的第二个条目,结果数据被错误地发到了 vlan101。

                                                                                                                                                                                                                                                          4) 使用 namespace 的场景:如果使用 namespace,网络结构如下:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第608张

                                                                                                                                                                                                                                                          其特征是网关 IP 配置在 namespace 中的 veth interface 上。每个 namespace 拥有自己的路由表。router_100_101 的路由表内容如下:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第609张

                                                                                                                                                                                                                                                          router_102_103 的路由表内容如下:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第610张

                                                                                                                                                                                                                                                          这样的路由表是可以工作的。例如 vlan102 上有数据包要发到 vlan103。选择路由时,会查看 router_102_103 的路由表, 匹配第二个条目,数据通过 qr-4 被正确地发送到 vlan103。同样当 vlan100 上有数据包要发到 vlan101时,会匹配 router_100_101 路由表的第二个条目,数据通过 qr-2 被正确地发送到 vlan101。可见,namespace 使得每个 router 有自己的路由表,而且不会与其他 router 冲突,所以能很好地支持网络重叠。

                                                                                                                                                                                                                                                        • instance访问外网 ML2 的配置:

                                                                                                                                                                                                                                                          1)这里的外部网络是指的租户网络以外的网络。租户网络是由 Neutron 创建和维护的网络。 外部网络不由 Neutron 创建。如果是私有云,外部网络通常指的是公司 intranet;如果是公有云,外部网络通常指的是 internet。具体到我们的实验网络环境: 计算节点和控制节点 eth1 提供的是租户网络,IP 段租户可以自由设置。 控制节点 eth2 连接的就是外部网络,IP 网段为 10.10.10.0/24。如下图所示:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第611张

                                                                                                                                                                                                                                                          2)配置准备:为了连接外部网络,需要在配置文件中告诉 Neutron 外部网络的类型以及对应的物理网卡

                                                                                                                                                                                                                                                          因为外部网络是已经存在的物理网络,一般都是 flat 或者 vlan 类型。这里我们将外部网络的 label 命名为 “external”。

                                                                                                                                                                                                                                                          如果类型为 flat,控制节点 /etc/neutron/plugins/ml2/ml2_conf.ini 配置如下:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第612张

                                                                                                                                                                                                                                                          如果类型为 vlan,配置如下

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第613张

                                                                                                                                                                                                                                                          修改配置后,需要重启 neutron 的相关服务。在我们的网络环境中,外部网络是 flat 类型。

                                                                                                                                                                                                                                                        • 创建外网 Ext_net:

                                                                                                                                                                                                                                                          1)进入 Admin -> Networks 菜单,点击 “Create Network” 按钮:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第614张

                                                                                                                                                                                                                                                          2)显示创建页面,点击 “Create Network”,ext_net 创建成功,其中Provider Network Type 选择 “Flat”;Physical Network 填写 “external”,与 ml2_conf.ini 中 flat_networks 参数的设置保持一致;勾选 External Network 选择框。

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第615张

                                                                                                                                                                                                                                                          3)点击 ext_net 链接,进入 network 配置页面:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第616张

                                                                                                                                                                                                                                                          4)目前还没有 subnet,点击 “Create Subnet” 按钮:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第617张

                                                                                                                                                                                                                                                          5)创建 subnet_10_10_10_0,IP 地址为 10.10.10.0/24,点击 “Next”。这里 Gateway 我们使用默认地址 10.10.10.1。

                                                                                                                                                                                                                                                          通常我们需要询问网络管理员外网 subnet 的 Gateway IP,然后填在这里:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第618张

                                                                                                                                                                                                                                                          6)因为我们不会直接为 instance 分配外网 IP,所以一般不需要 enable DHCP,点击 “Create”:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第619张

                                                                                                                                                                                                                                                          7)subnet 创建成功,网关为 10.10.10.1:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第620张

                                                                                                                                                                                                                                                          8)查看控制节点网络结构的变化,执行 brctl show:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第621张

                                                                                                                                                                                                                                                          增加了一个网桥 brqe496d3d2-53,物理网卡 eth2 已经连接到该 bridge。

                                                                                                                                                                                                                                                        • 外网访问原理分析:

                                                                                                                                                                                                                                                          1)将外网连接到 Neutron 的虚拟路由器,这样 instance 才能访问外网 。点击菜单 Project -> Network -> Routers 进入 router 列表,点击 router_100_101 的 “Set Gateway” 按钮:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第622张

                                                                                                                                                                                                                                                          2) “External Network” 下拉列表中选择 ext_net,点击 “Set Gateway” :

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第623张

                                                                                                                                                                                                                                                          3)外网设置成功:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第624张

                                                                                                                                                                                                                                                          4) 我们需要看看 router 发生了什么变化 。点击 “router_100_101” 链接,打开 “Interfaces” 标签页:router 多了一个新的 interface,IP 为 10.10.10.2。 该 interface 用于连接外网 ext_net。

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第625张

                                                                                                                                                                                                                                                          5)查看控制节点的网络结构,外网 bridge 上已经连接了 router 的 tap 设备 tapb8b32a88-03:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第626张

                                                                                                                                                                                                                                                          6)ip netns list 命令列出所有的 namespace。在 router 的 namespace 中查看 tapb8b32a88-03 的 veth pair 设备:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第627张

                                                                                                                                                                                                                                                          该 veth pair 命名为 qg-b8b32a88-03,上面配置了 IP 10.10.10.2。router 的每个 interface 在 namespace 中都有对应的 veth。如果 veth 用于连接租户网络,命名格式为 qr-xxx,比如 qr-d568ba1a-74 和 qr-e17162c5-00。如果 veth 用于连接外部网络,命名格式为 qg-xxx,比如 qg-b8b32a88-03。

                                                                                                                                                                                                                                                          7)查看 router 的路由表信息:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第628张

                                                                                                                                                                                                                                                          可以看到默认网关为 10.10.10.1。 意味着对于访问 vlan100 和 vlan101 租户网络以外的所有流量,router_100_101 都将转发给 ext_net 的网关 10.10.10.1。

                                                                                                                                                                                                                                                          8)现在 router_100_101 已经同时连接了 vlan100, vlan101 和 ext_net 三个网络,如下图所示:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第629张

                                                                                                                                                                                                                                                          9)下面我们在 cirros-vm3 上测试一下:irros-vm3 位于计算节点,现在已经可以 Ping 到 ext_net 网关 10.10.10.1 了。

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第630张

                                                                                                                                                                                                                                                          10)通过 traceroute 查看一下 cirros-vm3 到 10.10.10.1 的路径 :

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第631张

                                                                                                                                                                                                                                                          数据包经过两跳到达 10.10.10.1 网关。数据包首先发送到 router_100_101 连接 vlan101 的 interface(172.16.101.1)。然后通过连接 ext_net 的 interface(10.10.10.2) 转发出去,最后到达 10.10.10.1。

                                                                                                                                                                                                                                                          当数据包从 router 连接外网的接口 qg-b8b32a88-03 发出的时候,会做一次 Source NAT,即将包的源地址修改为 router 的接口地址 10.10.10.2,这样就能够保证目的端能够将应答的包发回给 router,然后再转发回源端 instance。

                                                                                                                                                                                                                                                          11)可以通过 iptables 命令查看 SNAT 的规则:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第632张

                                                                                                                                                                                                                                                          当 cirros-vm3(172.16.101.3) Ping 10.10.10.1 时,可用通过 tcpdump 分别观察 router 两个 interface 的icmp 数据包来验证 SNAT 的行为。

                                                                                                                                                                                                                                                          12)vlan101 interface qr-e17162c5-00 的 tcpdump 输出:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第633张

                                                                                                                                                                                                                                                          13)ext_net interface qg-b8b32a88-03 的 tcpdump 输出:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第634张

                                                                                                                                                                                                                                                          SNAT 让 instance 能够直接访问外网,但外网还不能直接访问 instance。因为 instance 没有外网 IP。这里 “直接访问 instance” 是指通信连接由外网发起,例如从外网 SSH cirros-vm3。 这个问题可以通过 floating IP 解决,下一节我们将讨论浮动 IP。

                                                                                                                                                                                                                                                        • 创建 Floating IP:

                                                                                                                                                                                                                                                          1)先复习一下前面我们讨论的知识:

                                                                                                                                                                                                                                                          当租户网络连接到 Neutron router,通常将 router 作为默认网关。当 router 接收到 instance 的数据包,并将其转发到外网时:a)router 会修改包的源地址为自己的外网地址,这样确保数据包转发到外网,并能够从外网返回。b)router 修改返回的数据包,并转发给真正的 instance。这个行为被称作 Source NAT。

                                                                                                                                                                                                                                                          如果需要从外网直接访问 instance,则可以利用 floating IP。下面是关于 floating IP 必须知道的事实:a)floating IP 提供静态 NAT 功能,建立外网 IP 与 instance 租户网络 IP 的一对一映射。b)floating IP 是配置在 router 提供网关的外网 interface 上的,而非 instance 中。c)router 会根据通信的方向修改数据包的源或者目的地址。

                                                                                                                                                                                                                                                          2)下面我们通过实验深入学习 floating IP 。点击 Project -> Compute -> Access & Security 菜单,打开 Floating IPs 标签页点击 “Allocate IP To Project” 按钮:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第635张

                                                                                                                                                                                                                                                          3)floating IP Pool 为 ext_net,点击 “Allocate IP” 按钮:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第636张

                                                                                                                                                                                                                                                          从 Pool 中成功分配了一个 IP 10.10.10.3。

                                                                                                                                                                                                                                                          4)下面我们将它分配给 cirror-vm3,点击 “Associate” 按钮:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第637张

                                                                                                                                                                                                                                                          5)在下拉列表中选择 cirror-vm3,点击 “Associate” 按钮:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第638张

                                                                                                                                                                                                                                                          6)分配成功,floating IP 10.10.10.3 已经对应到 cirros-vm3 的租户 IP 172.16.101.3:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第639张

                                                                                                                                                                                                                                                          7)执行ip netns exec ip a首先查看 router 的 interface 配置:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第640张

                                                                                                                                                                                                                                                          可以看到,floating IP 已经配置到 router 的外网 interface qg-b8b32a88-03 上。

                                                                                                                                                                                                                                                          8)执行ip netns exec iptables -t nat -S查看 router 的 NAT 规则:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第641张

                                                                                                                                                                                                                                                          iptables 增加了两条处理 floating IP 的规则: a)当 router 接收到从外网发来的包,如果目的地址是 floating IP 10.10.10.3,将目的地址修改为 cirros-vm3 的 IP 172.16.101.3。这样外网的包就能送达到 cirros-vm3。b)当 cirros-vm3 发送数据到外网,源地址 172.16.101.3 将被修改为 floating IP 10.10.10.3。

                                                                                                                                                                                                                                                          9)在我的实验环境中,10.10.10.1 是外网中的物理交换机,现在让它 PING cirros-vm3,能PING通:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第642张

                                                                                                                                                                                                                                                          10)ext_net interface qg-b8b32a88-03 的 tcpdump 输出:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第643张

                                                                                                                                                                                                                                                          可见,在外网接口 qg-b8b32a88-03 上,始终是通过 floating IP 10.10.10.3 与外网通信。

                                                                                                                                                                                                                                                          11)vlan101 interface qr-e17162c5-00 的 tcpdump 输出:

                                                                                                                                                                                                                                                          云计算之OpenStack核心 第644张

                                                                                                                                                                                                                                                          当数据转发到租户网络,地址已经变为 cirros-vm3 的租户 IP 172.16.101.3 了。

                                                                                                                                                                                                                                                          12)小结:

                                                                                                                                                                                                                                                          a)floating IP 能够让外网直接访问租户网络中的 instance。这是通过在 router 上应用 iptalbes 的 NAT 规则实现的。

                                                                                                                                                                                                                                                          b)floating IP 是配置在 router 的外网 interface 上的,而非 instance,这一点需要特别注意。

                                                                                                                                                                                                                                                          至此,我们已经完成了 Neutron L3 服务连接不同 subnet,访问外网,以及 floating IP 的学习。

                                                                                                                                                                                                                                                          2.5.5.8 vxlan network
                                                                                                                                                                                                                                                          • 前言: 除了前面讨论的 local, flat, vlan 这几类网络,OpenStack 还支持 vxlan 和 gre 这两种 overlay network。overlay network 是指建立在其他网络上的网络。 该网络中的节点可以看作通过虚拟(或逻辑)链路连接起来的。 overlay network 在底层可能由若干物理链路组成,但对于节点,不需要关心这些底层实现。例如 P2P 网络就是 overlay network,隧道也是。 vxlan 和 gre 都是基于隧道技术实现的,它们也都是 overlay network。目前 linux bridge 只支持 vxlan,不支持 gre;open vswitch 两者都支持。 vxlan 与 gre 实现非常类似,而且 vxlan 用得较多,所以本教程只介绍 vxlan。
                                                                                                                                                                                                                                                          • VXLAN 全称 Virtual eXtensible Local Area Network(虚拟扩展局域网),VXLAN 提供与 VLAN 相同的以太网二层服务,但是拥有更强的扩展性和灵活性。与 VLAN 相比,VXLAN 有下面几个优势:

                                                                                                                                                                                                                                                            1)支持更多的二层网段。 VLAN 使用 12-bit 标记 VLAN ID,最多支持 4094 个 VLAN,这对于大型云部署会成为瓶颈。VXLAN 的 ID (VNI 或者 VNID)则用 24-bit 标记,支持 16777216 个二层网段;

                                                                                                                                                                                                                                                            2)VXLAN 的数据包是封装到 UDP 通过三层传输和转发的;

                                                                                                                                                                                                                                                            3)避免物理交换机 MAC 表耗尽。 由于采用隧道机制, 交换机无需在 MAC 表中记录虚拟机的信息。

                                                                                                                                                                                                                                                          • VXLAN 封装和包格式:

                                                                                                                                                                                                                                                            1)VXLAN 是将二层建立在三层上的网络。 通过将二层数据封装到 UDP 的方式来扩展数据中心的二层网段数量;

                                                                                                                                                                                                                                                            2)VXLAN 是一种在现有物理网络设施中支持大规模多租户网络环境的解决方案。 VXLAN 的传输协议是 IP + UDP;

                                                                                                                                                                                                                                                            3)VXLAN 定义了一个 MAC-in-UDP 的封装格式。 在原始的 Layer 2 网络包前加上 VXLAN header,然后放到 UDP 和 IP 包中。 通过 MAC-in-UDP 封装,VXLAN 能够在 Layer 3 网络上建立起了一条 Layer 2 的隧道;

                                                                                                                                                                                                                                                            4)VXLAN 包的格式如下:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第645张

                                                                                                                                                                                                                                                            如上图所示,VXLAN 引入了 8-byte VXLAN header,其中 VNI 占 24-bit。VXLAN 和原始的 L2 frame 被封装到 UDP 包中。这 24-bit 的 VNI 用于标示不同的二层网段,能够支持 16777216 个 LAN。

                                                                                                                                                                                                                                                          • VXLAN Tunnel Endpoint

                                                                                                                                                                                                                                                            1)VXLAN 使用 VXLAN tunnel endpoint (VTEP) 设备处理 VXLAN 的封装和解封。每个 VTEP 有一个 IP interface,配置了一个 IP 地址。VTEP 使用该 IP 封装 Layer 2 frame,并通过该 IP interface 传输和接收封装后的 VXLAN 数据包。

                                                                                                                                                                                                                                                            2)下面是 VTEP 的示意图:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第646张

                                                                                                                                                                                                                                                            3)VXLAN 独立于底层的网络拓扑;反过来,两个 VTEP 之间的底层 IP 网络也独立于 VXLAN。 VXLAN 数据包是根据外层的 IP header 路由的,该 header 将两端的 VTEP IP 作为源和目标 IP。

                                                                                                                                                                                                                                                          • VXLAN包转发流程:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第647张

                                                                                                                                                                                                                                                            VXLAN 在 VTEP 间建立隧道,通过 Layer 3 网络传输封装后的 Layer 2 数据。数据传输过程如下:

                                                                                                                                                                                                                                                            1)Host-A 向 Host-B 发送数据时,Host-B 的 MAC 和 IP 作为数据包的目标 MAC 和 IP,Host-A 的 MAC 作为数据包的源 MAC 和 IP,然后通过 VTEP-1 将数据发送出去。

                                                                                                                                                                                                                                                            2)VTEP-1 从自己维护的映射表中找到 MAC-B 对应的 VTEP-2,然后执行 VXLAN 封装,加上 VXLAN头,UDP 头,以及外层 IP 和 MAC 头。此时的外层 IP 头,目标地址为 VTEP-2 的 IP,源地址为 VTEP-1 的IP。同时由于下一跳是 Router-1,所以外层 MAC 头中目标地址为 Router-1 的 MAC。

                                                                                                                                                                                                                                                            3)数据包从 VTEP-1 发送出去后,外部网络的路由器会依据外层 IP 头进行包路由,最后到达与 VTEP-2 连接的路由器 Router-2。

                                                                                                                                                                                                                                                            4)Router-2将数据包发送给 VTEP-2。VTEP-2 负责解封数据包,依次去掉外层 MAC 头,外层 IP 头,UDP 头 和 VXLAN 头。

                                                                                                                                                                                                                                                            5)VTEP-2 依据目标 MAC 地址将数据包发送给 Host-B。

                                                                                                                                                                                                                                                            上面的流程我们看到 VTEP 是 VXLAN 的最核心组件,负责数据的封装和解封。隧道也是建立在 VTEP 之间的,VTEP 负责数据的传送。

                                                                                                                                                                                                                                                          • 在 ML2 中配置 VXLAN:

                                                                                                                                                                                                                                                            1)在 /etc/neutron/plugins/ml2/ml2_conf.ini 设置 vxlan network 相关参数:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第648张

                                                                                                                                                                                                                                                            2)然后指定 vxlan 的范围:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第649张

                                                                                                                                                                                                                                                            上面的配置定义了 vxlan vni 的范围是 1001 – 2000。这个范围是针对普通用户在自己的租户里创建 vxlan network 的范围。因为普通用户创建 network 时并不能指定 vni,Neutron 会按顺序自动从这个范围中取值。对于 admin 则没有 vni 范围的限制,admin 可以创建 vni 范围为 1-16777216 的 vxlan network。

                                                                                                                                                                                                                                                            3)接着需要在 [VXLAN] 中配置 VTEP:

                                                                                                                                                                                                                                                            控制节点 devstack_controller 的 ml2_conf.ini 配置如下:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第650张

                                                                                                                                                                                                                                                            计算节点 devstack_compute01 的 ml2_conf.ini 配置如下:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第651张

                                                                                                                                                                                                                                                            local_ip 指定节点上用作 VTEP 的 IP 地址。devstack_controller 的 VTEP IP 是 166.66.16.10,网卡为 eth1。devstack_compute01 的 VTEP IP 是 166.66.16.11,网卡为 eth1。注意:作为准备工作,这两个 VTEP IP 需要提前配置到节点的 eht1 上,Neutron 并不会帮我们分配这个 IP。

                                                                                                                                                                                                                                                          • 创建 VXLAN:

                                                                                                                                                                                                                                                            1)打开菜单 Admin -> Networks,点击 “Create Network” 按钮

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第652张

                                                                                                                                                                                                                                                            2)显示创建页面,Provider Network Type 选择 “VXLAN” Segmentation ID 即 VNI,设置为 100。点击 “Create Network”,vxlan100 创建成功:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第653张

                                                                                                                                                                                                                                                            3)点击 vxlan100 链接,进入 network 配置页面:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第654张

                                                                                                                                                                                                                                                            4)目前还没有 subnet,点击 “Create Subnet” 按钮:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第655张

                                                                                                                                                                                                                                                            5)创建 subnet_172_16_100_0,IP 地址为 172.16.100.0/24:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第656张

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第657张

                                                                                                                                                                                                                                                            6)底层网络发生了什么变化 。在控制节点上执行 brctl show,查看当前的网络结构:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第658张

                                                                                                                                                                                                                                                            Neutron 创建了:

                                                                                                                                                                                                                                                            a. vxlan100 对应的网桥 brq1762d312-d4

                                                                                                                                                                                                                                                            b. vxlan interface vxlan-100

                                                                                                                                                                                                                                                            c. dhcp 的 tap 设备 tap4df76d0e-59

                                                                                                                                                                                                                                                            d. vxlan-100 和 tap4df76d0e-59 已经连接到 brq1762d312-d4,vxlan100 的二层网络就绪。

                                                                                                                                                                                                                                                            7)执行 ip -d link show dev vxlan-100 查看 vxlan interface 的详细配置

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第659张

                                                                                                                                                                                                                                                            可见,vxlan-100 的 VNI 是 100,对应的 VTEP 网络接口为 eth1。

                                                                                                                                                                                                                                                            8)此时 vxlan100 结构如图所示:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第660张

                                                                                                                                                                                                                                                          • 部署 Instance 到 VXLAN:

                                                                                                                                                                                                                                                            1)launch 新的 instance “cirros-vm1”,网络选择vxlan100:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第661张

                                                                                                                                                                                                                                                            2)cirros-vm1 分配到的 IP 为 172.16.100.3:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第662张

                                                                                                                                                                                                                                                            3)cirros-vm1 被 schedule 到控制节点,对应的 tap 设备为 tap099caa87-cd,并且连接到 bridge brq1762d312-d4:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第663张

                                                                                                                                                                                                                                                            4)当前 vxlan100 的结构如下:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第664张

                                                                                                                                                                                                                                                            5)继续用同样的方式 launch instance cirros-vm2,分配到的 IP 为 172.16.100.4:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第665张

                                                                                                                                                                                                                                                            6)cirros-vm2 被 schedule 到计算节点,对应的 tap 设备为 tap457cc048-aa,并且连接到 bridge brq1762d312-d4:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第666张

                                                                                                                                                                                                                                                            7)因为计算节点上没有 dhcp 服务,所以没有相应的 tap 设备。另外,bridge 的名称与控制节点上一致,都是 brq1762d312-d4,表明是同一个 network。

                                                                                                                                                                                                                                                            8)当前vxlan100的结构如下:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第667张

                                                                                                                                                                                                                                                            9)cirros-vm1(172.16.100.3) 与 cirros-vm2(172.16.100.4) 位于不同节点,通过 vxlan100 相连,下面执行 PING 验证连通性。 在 cirros-vm1 控制台中执行 ping 172.16.100.4:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第668张

                                                                                                                                                                                                                                                            如我们预料,ping 成功。对于多 vxlan 之间的 routing 以及 floating ip,实现方式与 vlan 非常类似。

                                                                                                                                                                                                                                                          • L2 Population 原理:

                                                                                                                                                                                                                                                            1)作用:L2 Population 是用来提高 VXLAN 网络 Scalability 的。通常我们说某个系统的 Scalability 好,其意思是:当系统的规模变大时,仍然能够高效地工作。

                                                                                                                                                                                                                                                            2)L2 Population 到底解决了怎样的 Scalability 问题,请看下图:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第669张

                                                                                                                                                                                                                                                            3)这是一个包含 5 个节点的 VXLAN 网络,每个节点上运行了若干 VM。现在假设 Host 1 上的 VM A 想与 Host 4 上的 VM G 通信。VM A 要做的第一步是获知 VM G 的 MAC 地址。于是 VM A 需要在整个 VXLAN 网络中广播 APR 报文:“VM G 的 MAC 地址是多少?”

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第670张

                                                                                                                                                                                                                                                            4)如果 VXLAN 网络的节点很多,广播的成本会很大,这样 Scalability 就成问题了,幸好 L2 Population 出现了:L2 Population 的作用是在 VTEP 上提供 Porxy ARP 功能,使得 VTEP 能够预先获知 VXLAN 网络中如下信息:VM IP — MAC 对应关系、VM — VTEP 的对应关系:云计算之OpenStack核心 第671张

                                                                                                                                                                                                                                                            5)当 VM A 需要与 VM G 通信时:a)Host 1 上的 VTEP 直接响应 VM A 的 APR 请求,告之 VM G 的 MAC 地址。b)因为 Host 1 上的 VTEP 知道 VM G 位于 Host 4,会将封装好的 VXLAN 数据包直接发送给 Host 4 的 VTEP。这样就解决了 MAC 地址学习和 APR 广播的问题,从而保证了 VXLAN 的 Scalability。

                                                                                                                                                                                                                                                            6)那么下一个关键问题是:VTEP 是如何提前获知 IP — MAC — VTEP 相关信息的呢?

                                                                                                                                                                                                                                                            答案是:a)Neutron 知道每一个 port 的状态和信息; port 保存了 IP,MAC 相关数据。b)instance 启动时,其 port 状态变化过程为:down -> build -> active。c)每当 port 状态发生变化时,Neutron 都会通过 RPC 消息通知各节点上的 Neutron agent,使得 VTEP 能够更新 VM 和 port 的相关信息。VTEP 可以根据这些信息判断出其他 Host 上都有哪些 VM,以及它们的 MAC 地址,这样就能直接与之通信,从而避免了不必要的隧道连接和广播。

                                                                                                                                                                                                                                                          • 配置 L2 Population:

                                                                                                                                                                                                                                                            1)目前 L2 Population 支持 VXLAN with Linux bridge 和 VXLAN/GRE with OVS;

                                                                                                                                                                                                                                                            2)在 /etc/neutron/plugins/ml2/ml2_conf.ini 设置 l2population mechanism driver:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第672张

                                                                                                                                                                                                                                                            3)同时在 [VXLAN] 中配置 enable L2 Population:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第673张

                                                                                                                                                                                                                                                            4)L2 Population 生效后,输入ip -d link show dev vxlan-100命令,发现创建的 vxlan-100 会多一个 Proxy ARP 功能:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第674张

                                                                                                                                                                                                                                                            5)输入bridge fdb show dev vxlan-100命令查看控制节点上的 forwarding database,可以看到 VTEP 保存了 cirros-vm2 的 port 信息:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第675张

                                                                                                                                                                                                                                                            6)cirros-vm2 的 MAC 为 fa:16:3e:1d:23:a3。 VTEP IP 为 166.66.16.11。当需要与 cirros-vm2 通信时,控制节点 VTEP 166.66.16.10 会将封装好的 VXLAN 数据包直接发送给计算节点的 VTEP 166.66.16.11。

                                                                                                                                                                                                                                                            7)输入bridge fdb show dev vxlan-100命令查看计算节点上的 forwarding database:

                                                                                                                                                                                                                                                            云计算之OpenStack核心 第676张

                                                                                                                                                                                                                                                            8)fdb 中保存了 cirros-vm1 和 dhcp 的 port 信息。当需要与它们通信时,计算节点 VTEP 知道应该将数据包直接发送给控制节点的 VTEP。

                                                                                                                                                                                                                                                            2.5.5.9 Security Group
                                                                                                                                                                                                                                                            • Neutron 为 instance 提供了两种管理网络安全的方法:安全组(Security Group)和虚拟防火墙。安全组的原理是通过 iptables 对 instance 所在计算节点的网络流量进行过滤。虚拟防火墙则由 Neutron Firewall as a Service(FWaaS)高级服务提供。其底层也是使用 iptables,在 Neutron Router 上对网络包进行过滤。
                                                                                                                                                                                                                                                            • 默认安全组:每个 Project(租户)都有一个命名为 “default” 的默认安全组。

                                                                                                                                                                                                                                                              1)点击菜单 Project -> Compute -> Access & Security,查看 Security Group 列表:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第677张

                                                                                                                                                                                                                                                              2)点击Manage Rules按钮,查看 “default” 安全组的规则:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第678张

                                                                                                                                                                                                                                                              3)“default” 安全组有四条规则,其作用是:允许所有外出(Egress)的流量,但禁止所有进入(Ingress)的流量。

                                                                                                                                                                                                                                                              4)当我们创建 instance 时,可以在 “Access & Security” 标签页中选择安全组。如果当前只有 “default” 这一个安全组,则会强制使用 “default” :

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第679张

                                                                                                                                                                                                                                                              5)当前在 devstack-controller 上有 instance “cirros-vm1”:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第680张

                                                                                                                                                                                                                                                              6)在 devstack-controller 上执行 iptables-save 命令查看相关规则。iptables 的规则较多,这里我们节选了 cirros-vm1 相关的规则。这些规则是 Neutron 根据安全组自动生成的。cirros-vm1 的 TAP interface 为 tap8bca5b86-23,可以看到:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第681张

                                                                                                                                                                                                                                                              7)iptables 的规则是应用在 Neutron port 上的,port 在这里是 cirros-vm1 的虚拟网卡 tap8bca5b86-23。ingress 规则集中定义在命名为 “neutron-linuxbri-i8bca5b86-2” 的 chain 中。egress 规则集中定义在命名为 “neutron-linuxbri-o8bca5b86-2” 的 chain 中。

                                                                                                                                                                                                                                                              8)我们通过 dhcp namespace 对 cirros-vm1 进行 ping 和 ssh 测试:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第682张

                                                                                                                                                                                                                                                              9)无法 ping 和 ssh cirros-vm1,可见当前的规则实现了 “default” 安全组,所有 ingress 流量都被禁止。

                                                                                                                                                                                                                                                            • 应用新的安全组:Neutron 默认的安全组规则会禁止掉所有从外面访问 instance 的流量。本节我们会修改安全组的配置,允许 ping 和 ssh instance。有两种方法可以达到这个目的:a)修改 “default” 安全组。b)为 cirros-vm1 添加新的安全组。

                                                                                                                                                                                                                                                              1)添加新的安全组,在安全组列表页面点击按钮:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第683张

                                                                                                                                                                                                                                                              2)为安全组命名并点击 “Create Security Group”:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第684张

                                                                                                                                                                                                                                                              3)新的安全组 “allow ping & ssh” 创建成功:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第685张

                                                                                                                                                                                                                                                              4)点击Manage Group按钮,查看 “allow ping & ssh” 的规则:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第686张

                                                                                                                                                                                                                                                              5)系统默认定义了两条规则,运行所有的外出流量。点击Add Rule按钮,添加允许 ping 的规则,“Rule” 选择 “All ICMP”,“Direction” 选择 “Ingress”,然后点击 “Add” 按钮:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第687张

                                                                                                                                                                                                                                                              6)同样的方式添加 ssh 规则:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第688张

                                                                                                                                                                                                                                                              7)在列表中查看添加成功的规则:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第689张

                                                                                                                                                                                                                                                              8)接下来设置 cirros-vm1,使用新的安全组 。进入 instance 列表页面,点击 cirros-vm1 下拉操作列表中的 “Edit Security Groups”:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第690张

                                                                                                                                                                                                                                                              9)可以看到 cirros-vm1 当前使用的安全组为 “default”,可选安全组为 “allow ping & ssh”。点击安全组 “allow ping & ssh” 后面的 “+” 按钮:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第691张

                                                                                                                                                                                                                                                              10)点击 “Save” 保存:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第692张

                                                                                                                                                                                                                                                              11)iptables 会立即更新,下面通过 vimdiff 查看 iptables 前后的变化:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第693张

                                                                                                                                                                                                                                                              12)“allow ping & ssh” 安全组引入了下面两条 iptables 规则。作用是运行 ingress 的 ssh 和 ping 流量:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第694张

                                                                                                                                                                                                                                                              13)测试一下,现在能够 ping 和 ssh cirros-vm1 了:

                                                                                                                                                                                                                                                              云计算之OpenStack核心 第695张

                                                                                                                                                                                                                                                              • 小结-安全组有以下特性:


免责声明
1、本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明。
2、本网站转载文章仅为传播更多信息之目的,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所
提供信息的准确性及可靠性,但不保证信息的正确性和完整性,且不对因信息的不正确或遗漏导致的任何
损失或损害承担责任。
3、任何透过本网站网页而链接及得到的资讯、产品及服务,本网站概不负责,亦不负任何法律责任。
4、本网站所刊发、转载的文章,其版权均归原作者所有,如其他媒体、网站或个人从本网下载使用,请在
转载有关文章时务必尊重该文章的著作权,保留本网注明的“稿件来源”,并白负版权等法律责任。

手机扫描二维码访问

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,5860人围观)

还没有评论,来说两句吧...

目录[+]