OpenStack Queens HA 部署手册 1、基础知识 1.1、高可用(HighAvailability,简称 HA) 高可用性是指提供在本地系统单个组件故障情况下,能继续访问应用的能力,无论这 个故障是业务流程、物理设施、IT 软/硬件的故障。最好的可用性,就是你的一台机器宕机 了,但是使用你的服务的用户完全感觉不到。你的机器宕机了,在该机器上运行的服务肯定 得做故障切换(failover),切换有两个维度的成本:RTO(RecoveryTimeObjective)和 RPO (RecoveryPointObjective)。RTO 是服务恢复的时间,最佳的情况是 0,这意味着服务立即 恢复;最坏是无穷大意味着服务永远恢复不了;RPO 是切换时向前恢复的数据的时间长度, 0 意味着使用同步的数据,大于 0 意味着有数据丢失,比如“RPO=1 天”意味着恢复时使用 一天前的数据,那么一天之内的数据就丢失了。因此,恢复的最佳结果是 RTO=RPO=0,但 是这个太理想,或者要实现的话成本太高,全球估计 Visa 等少数几个公司能实现,或者几 乎实现。 对 HA 来说,往往使用共享存储,这样的话,RPO=0;同时往往使用 Active/Active(双 活集群)HA 模式来使得 RTO 几乎 0,如果使用 Active/Passive 模式的 HA 的话,则需要将 RTO 减少到最小限度。HA 的计算公式是[1-(宕机时间)/(宕机时间+运行时间)],我们常常 用几个 9 表示可用性:  2 个 9:99%=1%365=3.6524 小时/年=87.6 小时/年的宕机时间  4 个 9:99.99%=0.01%3652460=52.56 分钟/年  5 个 9:99.999%=0.001%365=5.265 分钟/年的宕机时间,也就意味着每次停机时间 在一到两分钟。  11 个 9:几乎就是几年才宕机几分钟。据说 AWSS3 的设计高可用性就是 11 个 9。 1.1.1 服务的分类 HA 将服务分为两类:  有状态服务:后续对服务的请求依赖于之前对服务的请求。  无状态服务:对服务的请求之间没有依赖关系,是完全独立的。 1.1.2HA 的种类 HA 需要使用冗余的服务器组成集群来运行负载,包括应用和服务。这种冗余性也可以 将 HA 分为两类:  Active/PassiveHA:集群只包括两个节点简称主备。在这种配置下,系统采用主和备 用机器来提供服务,系统只在主设备上提供服务。在主设备故障时,备设备上的服 务被启动来替代主设备提供的服务。典型地,可以采用 CRM 软件比如 Pacemaker 来控制主备设备之间的切换,并提供一个虚机 IP 来提供服务。  Active/ActiveHA:集群只包括两个节点时简称双活,包括多节点时成为多主 (Multi-master)。在这种配置下,系统在集群内所有服务器上运行同样的负载。以 数据库为例,对一个实例的更新,会被同步到所有实例上。这种配置下往往采用负 载均衡软件比如 HAProxy 来提供服务的虚拟 IP。 1.1.3 云环境的 HA 云环境包括一个广泛的系统,包括硬件基础设施、IaaS 层、虚机和应用。以 OpenStack 云为例: 云环境的 HA 将包括:  应用的 HA  虚机的 HA  云控制服务的 HA  物理 IT 层:包括网络设备比如交换机和路由器,存储设备等  基础设施,比如电力、空调和防火设施等 本文的重点是讨论 OpenStack 作为 IaaS 的 HA。 1.2、灾难恢复(DisasterRecovery) 几个概念:  灾难(Disaster)是由于人为或自然的原因,造成一个数据中心内的信息系统运行严 重故障或瘫痪,使信息系统支持的业务功能停顿或服务水平不可接受、达到特定的 时间的突发性事件,通常导致信息系统需要切换到备用场地运行。  灾难恢复(DiasterRecovery)是指当灾难破坏生产中心时在不同地点的数据中心内 恢复数据、应用或者业务的能力。  容灾是指,除了生产站点以外,用户另外建立的冗余站点,当灾难发生,生产站点 受到破坏时,冗余站点可以接管用户正常的业务,达到业务不间断的目的。为了达 到更高的可用性,许多用户甚至建立多个冗余站点。  衡 量 容 灾 系 统 有 两 个 主 要 指 标 : RPO ( RecoveryPointObjective ) 和 RTO (RecoveryTimeObject),其中 RPO 代表了当灾难发生时允许丢失的数据量,而 RTO 则代表了系统恢复的时间。RPO 与 RTO 越小,系统的可用性就越高,当然用户需要 的投资也越大。 大体上讲,容灾可以分为 3 个级别:数据级别、应用级别以及业务级别。 级 别 定义 RTO CTO 数 指通过建立异地容灾中心,做数据的远程备份, RTO 最长(若干 最低 据 级 在灾难发生之后要确保原有的数据不会丢失或 者遭到破坏。但在数据级容灾这个级别,发生灾 难时应用是会中断的。 在数据级容灾方式下,所建立的异地容灾中心可 以简单地把它理解成一个远程的数据备份中心。 数据级容灾的恢复时间比较长,但是相比其他容 灾级别来讲它的费用比较低,而且构建实施也相 对简单。 但是,“数据源是一切关键性业务系统的生命源 泉”,因此数据级容灾必不可少。 天),因为灾难 发生时,需要 重新部署机 器,利用备份 数据恢复业 务。 应 用 级 在数据级容灾的基础之上,在备份站点同样构建 一套相同的应用系统,通过同步或异步复制技 术,这样可以保证关键应用在允许的时间范围内 恢复运行,尽可能减少灾难带来的损失,让用户 基本感受不到灾难的发生,这样就使系统所提供 的服务是完整的、可靠的和安全的。 RTO 中等(若 干小时) 中等。异地 可以搭建一 样的系统, 或者小些的 系统。 业 务 级 全业务的灾备,除了必要的 IT 相关技术,还要 求具备全部的基础设施。其大部分内容是非 IT 系统(如电话、办公地点等),当大灾难发生后, 原有的办公场所都会受到破坏,除了数据和应用 的恢复,更需要一个备份的工作场所能够正常的 开展业务。 RTO 最小(若 干分钟或者 秒) 最高 1.3、HA 和 DR 的关系 两者相互关联,互相补充,互有交叉,同时又有显著的区别:  HA 往往指本地的高可用系统,表示在多个服务器运行一个或多种应用的情况下, 应确保任意服务器出现任何故障时,其运行的应用不能中断,应用程序和系统应能 迅速切换到其它服务器上运行,即本地系统集群和热备份。HA 往往是用共享存储, 因此往往不会有数据丢失(RPO=0),更多的是切换时间长度考虑即 RTO。  DR 是指异地(同城或者异地)的高可用系统,表示在灾害发生时,数据、应用以 及业务的恢复能力。异地灾备的数据灾备部分是使用数据复制,根据使用的不同数 据复制技术(同步、异步、StrectchedCluster 等),数据往往有损失导致 RPO>0;而 异地的应用切换往往需要更长的时间,这样 RT0>0。因此,需要结合特定的业务需 求,来定制所需要的 RTO 和 RPO,以实现最优的 CTO。 也可以从别的角度上看待两者的区别:  从故障角度,HA 主要处理单组件的故障导致负载在集群内的服务器之间的切换, DR 则是应对大规模的故障导致负载在数据中心之间做切换。  从网络角度,LAN 尺度的任务是 HA 的范畴,WAN 尺度的任务是 DR 的范围。  从云的角度看,HA 是一个云环境内保障业务持续性的机制,DR 是多个云环境间保 障业务持续性的机制。  从目标角度,HA主要是保证业务高可用,DR是保证数据可靠的基础上的业务可用。 一个异地容灾系统,往往包括本地的 HA 集群和异地的 DR 数据中心。一个示例如下: MasterSQLServer 发生故障时,切换到 StandbySQLServer,继续提供数据库服务: 在主机房中心发生灾难时,切换到备份机房(总公司机房中心)上,恢复应用和服务: 1.4、OpenStackHA OpenStack 部署环境中,各节点可以分为几类:  CloudControllerNode ( 云 控 制 节 点 ): 安 装 各 种 API 服 务 和 内 部 工 作 组 件 (workerprocess)。同时,往往将共享的 DB 和 MQ 安装在该节点上。  NeutronControllerNode(网络控制节点):安装 NeutronL3Agent,L2Agent,LBaas, VPNaas,FWaas,MetadataAgent 等 Neutron 组件。  StorageControllerNode(存储控制节点):安装 Cindervolume 以及 Swift 组件。  Computenode(计算节点):安装 Nova-compute 和 NeutronL2Agent,在该节点上创 建虚机。 要实现 OpenStackHA,一个最基本的要求是这些节点都是冗余的。根据每个节点上部 署的软件特点和要求,每个节点可以采用不同的 HA 模式。但是,选择 HA 模式有个基本的 原则:  能 A/A 尽量 A/A,不能的话则 A/P(RedHat 认为 A/PHA 是 NoHA)  有原生(内在实现的)HA 方案尽量选用原生方案,没有的话则使用额外的 HA 软 件比如 Pacemaker 等  需要考虑负载均衡  方案尽可能简单,不要太复杂 OpenStack 官方认为,在满足其 HA 要求的情况下,可以实现 IaaS 的 99.99%HA,但是, 这不包括单个客户机的 HA。 1.5、云控制节点 HA 云控制节点上运行的服务中,API 服务和内部工作组件都是无状态的,因此很容易就可 以实现 A/AHA;这样就要求 Mysql 和 RabbitMQ 也实现 A/AHA,而它们各自都有 A/A 方案。 但是,MysqlGelera 方案要求三台服务器。如果只想用两台服务器的话,则只能实现 A/PHA, 或者引入一个 Arbiter 来做 A/AHA。 1.5.1、云控制节点的 A/AHA 方案 该方案至少需要三台服务器。以 RDO 提供的案例为例,它由三台机器搭建成一个 PacemakerA/A 集群,在该集群的每个节点上运行:  API 服务:包括-api,neutron-server,glance-registry,nova-novncproxy,keystone,httpd 等。由HAProxy提供负载均衡,将请求按照一定的算法转到某个节点上的API服务。 由 Pacemaker 提供 VIP。  内部组件:包括-scheduler,nova-conductor,nova-cert 等。它们都是无状态的,因 此可以在多个节点上部署,它们会使用 HA 的 MQ 和 DB。  RabbitMQ:跨三个节点部署 RabbitMQ 集群和镜像消息队列。可以使用 HAProxy 提 供负载均衡,或者将 RabbitMQhostlist 配置给 OpenStack 组件(使用 rabbit_hosts 和 rabbit_ha_queues 配置项)。  MariaDB:跨三个阶段部署 GeleraMariaDB 多主复制集群。由 HAProxy 提供负载均 衡。  HAProxy:向API,RabbitMQ和MariaDB多活服务提供负载均衡,其自身由Pacemaker 实现 A/PHA,提供 VIP,某一时刻只由一个 HAProxy 提供服务。在部署中,也可以 部署单独的 HAProxy 集群。  Memcached:它原生支持 A/A,只需要在 OpenStack 中配置它所有节点的名称即可, 比如,memcached_servers=controller1:11211,controller2:11211。当 controller1:11211 失效时,OpenStack 组件会自动使用 controller2:11211。 从每个 API 服务来看: 关于共享 DB 的几个说明: (1)根据一个调查,被调查的 220 多个用户中,200 个在用 MysqlGalera,20 多个在用 单 Mysql,只有一个用 PostgreSQL。 (2)以 Nova 为例,Mysql 使用 Write-intentlocks 机制来保证多个连接同时访问数据库 中的同一条记录时的互斥。以给新建虚机分配 IP 地址为例,该锁机制保证了一个 IP 不会分 给两个用户。 (3)使用 MysqlGalera 时,所有节点都是 Master 节点,都可以接受服务,但是这里有 个问题,MysqlGalera 不会复制 Write-intentlocks。两个用户可以在不同节点上获取到同一条 记录,但是只有一个能够修改成功,另一个会得到一个 Deadlock 错误。对于这种情况,Nova 使 用 retry_on_deadlock 机 制 来 重 试 , 比 如 @oslo_db_api.wrap_db_retry(max_retries=5,retry_on_deadlock=True)。默认都是重试 5 次。但 是,这种机制效率不高,本文提供了一种新的机制。 该 HA 方案具有以下优点:  多主,零切换,方便地实现负载均衡  将 API 服务和 DB,MQ 服务无缝整合在一起 由于这些优点,该方案被大量采用。具体配置请参考 OpenStackHighAvailabilityGuide。 1.5.2、云控制节点的 A/PHA 方案 需要的话,可以使用 Pacemaker+Corosync 搭建两节点集群实现 A/PHA 方案。由主服务 器实际提供服务,在其故障时由 Pacemaker 将服务切换到被服务器。OpenStack 给其组件提 供了各种 PacemakerRA。对 Mysql 和 RabbitMQ 来说,可以使用 Pacemaker+Corosync+DRBD 实现 A/PHA。 该 HA 方案的问题是:  主备切换需要较长的时间  只有主提供服务,在使用两个节点的情况下不能做负载均衡  DRBD 脑裂会导致数据丢失的风险。A/P 模式的 Mysql 的可靠性没有 MysqlGalera 高。 因此,可以看到实际部署中,这种方案用得较少,只看到 Oracel 在使用这种方案。 1.6、NeutronHA Neutron 包括很多的组件,比如 L3Agent,L2Agent,LBaas,VPNaas,FWaas,MetadataAgent 等 Neutron 组件,其中部分组件提供了原生的 HA 支持。这些组件之间的联系和区别: 1.6.1、原生 HA 方案 Neutron 提供了多种原生的 HA 方案: (1)L2AgentHA:L2agent 只在所在的网络或者计算节点上提供服务,因此它是不需 要 HA 的。 (2)L3AgentHA L3Agent 比较特殊,因为它是所有 openstack(core)services 中唯一一个有状态的,因 此,不能使用传统的在多个节点上部署多个实例使用 LB 来做 HA。Neutron 本身的调度器 (scheduler)支持在多个网络节点上部署多个L3Agent,但是,由L3Agent管理的VirtualRouter 自身需要有 HA 的实现。它的 HA 的 Neutron 原生实现包括如下几种方式: (a)Juno 中引入的 AutomaticL3AgentFailover(当 VR 所在的 L3Agent 失效的时候, Neutron 自动将它 failover 到其它某个 L3Agent 上) 该方案增加了一个配置项 allow_automatic_l3agent_failover。当它的值为 True 时, L3plugin 去周期性地检查所有有管理 VirtualRouter 的 L3Agent 的状态。如果某 L3Agent 死了, 受它管理的 Router 会重新被 schedule 到别的 L3Agent 上。NeutronL3Plugin 通过判断该 L3Agent 是否在规定时间(agent_down_time)内有发回心跳消息来判断它是否活着。存在多 种 L3Agent 未能及时上报心跳但是 router 依然在转发网络包的可能。因此这种实现可能会存 在 L3Agent 被认为死了但是其 routernamespace 依然在转发网络包和响应 ARP 请求而导致的 问题。如果网络后端不阻止死掉了的 agent 使用 route 的 IP 地址,那新老 namespace 就可能 存在冲突。这种冲突不会断掉 E-W 网络,因为新老 namespace 中的一个都可以承担无状态 网络包的转发任务。然后,南-北网络可能会受影响,因为 NAT 只存在于一个 router 上。而 且,reschedule 后,浮动 IP 也会无法工作,因为它们与 router 的外部端口的绑定关系不会被 设置到新的 router 上。 这种方案要求使用多个网络控制节点,每个节点上运行一个 L3Agent。在某个 Agent 死了时,Router 会被部署到别的 Agent 上。这种方案,除了上述的问题外,切换时间过长是 其主要问题。 (b)Juno 中引入的 VRRP(VirtualRouterRedundancyProtocol)方案(由 VRRP/Keepalived 控制 VR 的 VIP 和 VMAC 的 failover) 该方案使用多余一个的网络控制节点,提供 A/PHA。其主要特点为: (c)Juno 引入的 DVR 该方案将 NAT 和 L3Agent 部署到虚机所在的计算节点,在网络控制节点上只部署 DHCP 和 SNAT。该方案解决了 L3Agent 和 MetadataAgent 的 H/A 问题。目前,将 DHCPAgent 改 成分布式,VPNaas 以及 FWaas 的修改工作已经在进行中。用户需要使用第三方软件提供 SNAT 的 HA 方案。 (3)DHCPAgent 的 HA DHCP 协议自身就支持多个 DHCP 服务器,因此,只需要在多个网卡控制节点上,通 过修改配置,为每个租户网络创建多个 DHCPAgent,就能实现 DHCP 的 HA 了。 (4)Metadataagent 和 proxy 的 HA 跟 metadataservice 相关的组件包括:  neutron-ns-metadata-proxy : 作 为一 个独 立的 进程 运 行在 mastervirtualrouter 的 networknamespace 中。它接受由 qrouter 通过 iptables 控制转交的 instance 访问 metadataservice 的 request。  neutron-metadata-agent:Neutorn 的组件之一,运行在 Neutorn 网络节点上,通过本 地 socket 和 neutron-ns-metadata-proxy 进 程 通 信 , 其 配 置 文 件 是 /etc/neutron/metadata_agent.ini;它会通过 http(s)和 Novametadataservice 通信;它通过 RPC 和 neutron-server 通信。你还可以通过配置 metadata_workers 的值来运行多个独 立的进程。  novametadataapi:这个和 novaapi 类似,是 nova 的 API 的一部分,通常使用的端口 是 8775。它接收 neutron-metadata-agent 的 request。 从 HA 角度来讲:  neutron-ns-metadata-proxy 的 HA 不需要单独考虑,因为它受 Virtualrouter 控制。  neutron-metadata-agent:需要和 neutron-ns-metadata-proxy 通过 soket 通信,因此,简 单地,可以在所有 neutronnetwork 节点上都运行该 agent,只有 virtualrouter 所在的 L3Agent 上的 neutron-metadata-agent 才起作用,别的都 standby。你可以在多个网络 节点上启用该服务。  novametadataapi:同 novaapi 一样是无状态服务,可以部署在那个阶段上,使用 HAProxy 做 A/AHA。 ( http://techbackground.blogspot.com/2013/06/metadata-via-quantum-router.html) (注意,因为虚机在启动过程中需要访问 qrouter,这也就是说,要求虚机所在的子网 必须已经添加到了一个 Virtualrouter 上,否则,它是无法通过 qrouter 走的,除非走 qdhcp) 或者更详细地看出完整的路径(图中红色线条,从 VM 开始,到 NOVA-APIMetadata 结束): ( https://www.hastexo.com/system/files/neutron_packet_flows-notes-handout.pdf) (5)LBaasAgentHA 目前 NeutronLBaaS 代理服务是无法通过其自带的 HAProxy 插件实现高可用的。实现 HAProxy 高可用常见的方案是使用 VRRP(VirtualRouterRedundancyProtocol,虚拟路由冗余 协议),不过 LBaaSHAProxy 插件目前还不支持该协议。因此,只能使用 Pacemaker+共享存 储(放置/var/lib/neutron/lbaas/目录)的方式来部署 A/P 方式的 LBaasAgentHA。 1.6.2、使用 Pacemaker 实现 A/PHA 使用 Pacemaker+Corosync 搭建两节点(或者多节点)A/P 集群。在主节点上,由 Pacemaker 启动 Neutron 的各种服务。 1.6.3、小结 从上面可以看出,除了 DHCPAgent 天生就通过配置可以实现 A/AHA 以及 L3HA 以外, 其它的组件的 HA 都是 A/P 的,而且实现的技术可以是原生的,也可以使用 Pacemaker,也 可以结合起来使用。比如 RDO 的方案: 1.7、存储控制节点 HA 这里只讨论 cinder-volume。 (1)在使用非共享存储时,cinder-volume 进程受 Pacemaker 监控,在其停止的时候重 启。这种方案下,存储控制节点宕机的话,上面的所有卷都会损失掉。因此,在生产环境中, 必须使用下一种方案。 (2)在使用共享存储时,考虑到目前代码中存在的资源竞争,该服务只能实现为 A/PHA 方式,也就是说在某个时刻,只有主节点上的 cinder-volume 在运行。RedHat 这个 ticket 中 有具体的分析。目前,cinder-volume 还没有内在的 HA 实现,只能借助第三方软件比如 Pacemaker。A/A 的实现在 Liberty 中正在进行。 1.8、计算节点和虚机 HA 在测试环境中,我们常常将虚机创建在本地磁盘上,那么,在机器宕机的话,这些虚 机将永远也回不来了。因此,在生产环境中,需要将虚机部署在 cinder-volume 或者共享的 存储比如 RDB 或者 NFS 上。这样的话,在虚机损坏时,可以从共享存储上将其恢复(使用 novaevacuate 功能)。使用 Pacemaker 部署 A/P 方案(类似 2.3 中 cinder-volumeA/PHA)的话, 生产环境中计算节点的数据往往远远超过 Corosync 集群中节点数目的限制。 业界有几个解决方案: (1)Controller 节点通过管理网 Ping 所有 Compute 节点,Controller 节点检查 novaservice-list,对出问题的节点 Evacuate 特征:太简单粗暴,容易引起误杀和数据损坏 (2)Pacemaker-remote:突破 Corosync 的集群规模限制, 特征:启用多个心跳网时,处理策略单一,引起用户业务不必要的中断 (3)集中式检查 (4)分布式健康检查 (以上资料来自基于 Fuel 的超融合一体机 by 周征晟/2015-06-27) OpenStack 的各提供商中,就该需求,RadHat 使用的是上述的第二种方案,具体方案在 计算节点 HA 方案: 部署方式如下:  使用 Pacemaker 集群作为控制平面  将计算节点做为 Partialmembers 加入到 Pacemaker 集群中,受其管理和监控。这时 候,其数目不受 Corosync 集群内节点总数的限制。 HA 实现细节:  Pacemaker 通 过 pacemaker_remote 按 照 顺 序 (neutron-ovs-agent->ceilometer-compute->nova-compute)来启动计算节点上的各种服 务。前面的服务启动失败,后面的服务不会被启动。  Pacemaker 监控和每个计算节点上的 pacemaker_remote 的连接,来检查该节点是否 处于活动状态。发现它不可以连接的话,启动恢复(recovery)过程。  Pacemaker 监控每个服务的状态,如果状态失效,该服务会被重启。重启失败则触 发防护行为(fencingaction);当所有服务都被启动后,虚机的网络会被恢复,因此, 网络只会短时间受影响。 当一个节点失效时,恢复(recovery)过程会被触发,Pacemaker 会依次:

  1. 运行'novaservice-disable'
  2. 将该节点关机
  3. 等待 nova 发现该节点失效了
  4. 将该节点开机
  5. 如果节点启动成功,执行'novaservice-enable'
  6. 如果节点启动失败,则执行‘novaevacuate’把该节点上的虚机移到别的可用计算节点 上。 其中:  步骤(1)和(5)是可选的,其主要目的是防止 nova-scheduler 将新的虚机分配到该 节点。  步骤(2)保证机器肯定会关机。  步骤(3)中目前 nova 需要等待一段较长的超时时间才能判断节点 down 了。Liberty 中有个 Blueprint 来添加一个 NovaAPI 将节点状态直接设置为 down。 其余一些前提条件:  虚机必须部署在 cinder-volume 或者共享的临时存储比如 RBD 或者 NFS 上,这样虚 机 evaculation 将不会造成数据丢失。  如果虚机不使用共享存储,则必须周期性地创建虚机的快照并保存到 Glance 中。在 虚机损坏后,可以从 Glance 快照上恢复。但是,这可能会导致状态或者数据丢失。  控制和计算节点需要安装 RHEL7.1+  计算节点需要有防护机制,比如 IPMI,硬件狗等 1、基础环境 1.1、拓扑(逻辑) congtroller 节点运行 keystone,glance,horizon,nova&neutron&cinder 管理相关组件, ceph-mon&ceph-mgr(非 openstack 服务),另外 openstack 相关的基础服务; compute 节点运行 nova-compute,neutron-linuxbridge-agent,cinder-volume(后经验证, 如果后端使用共享存储,建议部署在 controller 节点,可通过 pacemaker 控制运行模式,但 写文档时,此验证环境的 cinder-volume 部署在 compute 节点)等,另有计算虚拟化 kvm, ceph-osd 等; 控制节点网络: 管理网络:含 host os 管理,api,ceph-public 等网络,如果生产环境允许,建议各逻辑 网络使用独立的物理网络,api 区分 admin/internal/public 接口,对客户端只开放 public 接口; 外部网络:主要针对 guest os 访问 internet/外部的 floating ip; 租户(虚机)隧道网络(与 vlan 网络共存或 2 选 1):guest os 之间通讯的网络,采用 vxlan/gre 等方式; 租户(虚机)vlan 网络(与隧道网络共存或 2 选 1):guest os 之间通讯的网络,采用 vlan 方式; 计算节点网络: 管理网络:含 host os 管理,api,ceph-public 等网络; 存储网络:存储集群内部通讯,数据复制同步网络,与外界没有直接联系; 租户(虚机)隧道网络(与 vlan 网络共存或 2 选 1):guest os 之间通讯的网络,采用 vxlan/gre 等方式; 租户(虚机)vlan 网络(与隧道网络共存或 2 选 1):guest os 之间通讯的网络,采用 vlan 方式; 采用 self-service-networks 提供自助网络服务,provider networks 不支持专有网络,需要 依靠外部基础设施提供 3 层路由与增值服务(如 lbaas,fwaas 等); 前端采用 haproxy 做高可用; 无状态的服务,如 xxx-api,采取 active/active 的模式运行;有状态的服务,如 neturon-xxx-agent,cinder-volume 等,建议采取 active/passive 的模式运行(因前端采用 haproxy, 客户端的多次请求可能会被转发到不同的控制节点,如果客户端请求被负载到无状态信息的 控制节点,可能会导致操作请求失败);自身具有集群机制的服务,如 rabbitmq,memcached 等采用本身的集群机制即可。 1.2、整体规划 主机名 IP 地址 备注 controller01 10.32.24.168 1.控制节点: keystone, glance, horizon, nova&neutron 管 理组件; 2.网络节点:虚机网络,L2/L3,dhcp,route,nat 等; 3.存储节点:调度,监控(ceph)等组件; 4.openstack 基础服务 controller02 10.32.24.171 1.控制节点: keystone, glance, horizon, nova&neutron 管 理组件; 2.网络节点:虚机网络,L2/L3,dhcp,route,nat 等; 3.存储节点:调度,监控(ceph)等组件; 4.openstack 基础服务 controller03 10.32.24.188 1.控制节点: keystone, glance, horizon, nova&neutron 管 理组件; 2.网络节点:虚机网络,L2/L3,dhcp,route,nat 等; 3.存储节点:调度,监控(ceph)等组件; 4.openstack 基础服务 compute01 10.32.24.189 1.计算节点:hypervisor(kvm); 2.网络节点:虚机网络等; 3.存储节点:卷服务等组件 compute02 10.23.24.190 1.计算节点:hypervisor(kvm); 2.网络节点:虚机网络等; 3.存储节点:卷服务等组件 compute03 10.32.25.47 1.计算节点:hypervisor(kvm); 2.网络节点:虚机网络等; 3.存储节点:卷服务等组件 1.3、主机映射

cat /etc/hosts

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 10.32.24.200 controller 10.32.24.168 controller01 10.32.24.171 controller02 10.32.24.188 controller03 10.32.24.189 compute01 10.32.24.190 compute02 10.32.25.47 compute03 1.4、YUM 源

cat /etc/yum.repos.d/ftp.repo

[centos] name=centos baseurl=ftp://10.32.18.195/1804 gpgcheck=0 enabled=1 [iaas] name=iaas baseurl=ftp://10.32.18.195/HA/iaas-repo gpgcheck=0 enabled=1 1.5、时间同步

yum install -y chrony

1.6、防火墙 iptables -F iptables -X iptables -Z /usr/sbin/iptables-save 2、基础服务 2.1、数据库 2.1.1、安装数据库

在全部 controller 节点安装 mariadb,以 controller01 节点为例

[root@controller01 ~]# yum install mariadb mariadb-server python2-PyMySQL -y

安装 galera 相关插件,利用 galera 搭建集群

[root@controller01 ~]# yum install mariadb-server-galera mariadb-galera-common galera xinetd rsync -y yum install boost-devel.x86_64 -y yum install -y nmap-ncat

在全部控制节点初始化数据库密码,以 controller01 节点为例;

root 初始密码为空

systemctl restart mariadb.service

systemctl enable mariadb.service

2.1.2、初始化 mariadb

mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY! In order to log into MariaDB to secure it, we'll need the current password for the root user. If you've just installed MariaDB, and you haven't set the root password yet, the password will be blank, so you should just press enter here. Enter current password for root (enter for none): OK, successfully used password, moving on... Setting the root password ensures that nobody can log into the MariaDB root user without the proper authorisation. Set root password? [Y/n] y New password: Re-enter new password: Password updated successfully! Reloading privilege tables.. ... Success! By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? [Y/n] y ... Success! Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? [Y/n] n ... skipping. By default, MariaDB comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? [Y/n] y

  • Dropping test database... ... Success!
  • Removing privileges on test database... ... Success! Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? [Y/n] y ... Success! Cleaning up... All done! If you've completed all of the above steps, your MariaDB installation should now be secure. Thanks for using MariaDB! 2.1.3、修改数据库配置文件

在全部控制节点/etc/my.cnf.d/目录下新增 OpenStack.cnf 配置文件,主要设置集群同步

相关参数,以 controller01 节点为例,个别涉及 ip 地址/host 名等参数根据实际情况修改

cat /etc/my.cnf.d/OpenStack.cnf

[mysqld] binlog_format = ROW bind-address = 10.32.24.168 default-storage-engine = innodb innodb_file_per_table = on max_connections = 4096 collation-server = utf8_general_ci character-set-server = utf8 [galera] bind-address = 10.32.24.168 wsrep_provider = /usr/lib64/galera/libgalera_smm.so wsrep_cluster_address ="gcomm://controller01,controller02,controller03" wsrep_cluster_name = OpenStack-cluster-01 wsrep_node_name = controller01 wsrep_node_address = 10.32.24.168 wsrep_on=ON wsrep_slave_threads=4 wsrep_sst_method=rsync default_storage_engine=InnoDB [embedded] [mariadb] [mariadb-10.1] 2.2、构建 mariadb 集群

停止全部控制节点的 mariadb 服务,以 controller01 节点为例

[root@controller01 ~]# systemctl stop mariadb.service

任选 1 个控制节点以如下方式启动 mariadb 服务,这里选择 controller01 节点

[root@controller01 ~]# /usr/libexec/mysqld --wsrep-new-cluster --user=root &

其他控制节点加入 mariadb 集群,以 controller02 节点为例;

启动后加入集群,controller02 节点从 controller01 节点同步数据,也可同步查看

mariadb 日志/var/log/mariadb/mariadb.log [root@controller02 ~]# systemctl start mariadb.service [root@controller02 ~]# systemctl status mariadb.service

重新启动 controller01 节点;

启动前删除 contrller01 节点的数据

[root@controller01 ~]# pkill -9 mysql [root@controller01 ~]# rm -rf /var/lib/mysql/*

注意以 system unit 方式启动 mariadb 服务时的权限

[root@controller01 ~]# chown mysql:mysql /var/run/mariadb/mariadb.pid

启动后查看节点所在服务状态,controller01 节点从 controller02 节点同步数据

[root@controller01 ~]# systemctl start mariadb.service [root@controller01 ~]# systemctl status mariadb.service

查看集群状态

[root@controller01 ~]# mysql -uroot -pmysql_pass MariaDB [(none)]> show status like "wsrep_cluster_size"; MariaDB [(none)]> SHOW status LIKE 'wsrep_ready'; MariaDB [(none)]> show status like 'wsrep%'; 集群完整性检查: wsrep_cluster_state_uuid:在集群所有节点的值应该是相同的,有不同值的节点,说明其没 有连接入集群。 wsrep_cluster_conf_id:正常情况下所有节点上该值是一样的。如果值不同,说明该节点 被临时"分区"了。当节点之间网络连接恢复的时候应该会恢复一样的值。 wsrep_cluster_size:如果这个值跟预期的节点数一致,则所有的集群节点已经连接。 wsrep_cluster_status:集群组成的状态。如果不为"Primary",说明出现"分区"或是 "split-brain"状况。 节点状态检查: wsrep_ready: 该值为 ON,则说明可以接受 SQL 负载。如果为 Off,则需要检查 wsrep_connected。 wsrep_connected: 如果该值为 Off,且 wsrep_ready 的值也为 Off,则说明该节点没有连接 到集群。(可能是 wsrep_cluster_address 或 wsrep_cluster_name 等配置错造成的。具体错误需 要查看错误日志) wsrep_local_state_comment:如果 wsrep_connected 为 On,但 wsrep_ready 为 OFF,则可以 从该项查看原因。 复制健康检查: wsrep_flow_control_paused:表示复制停止了多长时间。即表明集群因为 Slave 延迟而 慢的程度。值为 0~1,越靠近 0 越好,值为 1 表示复制完全停止。可优化 wsrep_slave_threads 的值来改善。 wsrep_cert_deps_distance:有多少事务可以并行应用处理。wsrep_slave_threads 设置的 值不应该高出该值太多。 wsrep_flow_control_sent:表示该节点已经停止复制了多少次。 wsrep_local_recv_queue_avg:表示 slave 事务队列的平均长度。slave 瓶颈的预兆。 最慢的节点的 wsrep_flow_control_sent 和 wsrep_local_recv_queue_avg 这两个值最高。 这两个值较低的话,相对更好。 检测慢网络问题: wsrep_local_send_queue_avg:网络瓶颈的预兆。如果这个值比较高的话,可能存在网络 瓶 冲突或死锁的数目: wsrep_last_committed:最后提交的事务数目 wsrep_local_cert_failures 和 wsrep_local_bf_aborts:回滚,检测到的冲突数目 3、RabbitMQ 集群 3.1、 安装 rabbitmq

在全部控制节点,使用 aliyun 的 epel 镜像,以 controller01 节点为例

wget -O /etc/yum.repos.d/epel.repo  http://mirrors.aliyun.com/repo/epel-7.repo

yum install erlang rabbitmq-server -y

设置开机启动

[root@controller01 ~]# systemctl enable rabbitmq-server.service 3.2、 构建 rabbitmq 集群

任选 1 个控制节点首先启动 rabbitmq 服务,这里选择 controller01 节点

[root@controller01 ~]# systemctl start rabbitmq-server.service [root@controller01 ~]# rabbitmqctl cluster_status

分发.erlang.cookie

[root@controller01 ~]# scp /var/lib/rabbitmq/.erlang.cookie root@172.30.200.32:/var/lib/rabbitmq/ [root@controller01 ~]# scp /var/lib/rabbitmq/.erlang.cookie root@172.30.200.33:/var/lib/rabbitmq/

修改 controller02/03 节点.erlang.cookie 文件的用户/组,以 controller02 节点为例

[root@controller02 ~]# chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie

注意修改全部控制节点.erlang.cookie 文件的权限,默认即 400 权限,可不修改

[root@controller02 ~]# ll /var/lib/rabbitmq/.erlang.cookie

启动 controller02/03 节点的 rabbitmq 服务

[root@controller02 ~]# systemctl start rabbitmq-server [root@controller03 ~]# systemctl start rabbitmq-server

构建集群,controller02/03 节点以 ram 节点的形式加入集群

[root@controller02 ~]# rabbitmqctl stop_app [root@controller02 ~]# rabbitmqctl join_cluster --ram rabbit@controller01 [root@controller02 ~]# rabbitmqctl start_app [root@controller03 ~]# rabbitmqctl stop_app [root@controller03 ~]# rabbitmqctl join_cluster --ram rabbit@controller01 [root@controller03 ~]# rabbitmqctl start_app

任意节点可验证集群状态

[root@controller01 ~]# rabbitmqctl cluster_status 3.3、 rabbitmq 账号

在任意节点新建账号并设置密码,以 controller01 节点为例

[root@controller01 ~]# rabbitmqctl add_user OpenStack rabbitmq_pass

设置新建账号的状态

[root@controller01 ~]# rabbitmqctl set_user_tags OpenStack administrator

设置新建账号的权限

[root@controller01 ~]# rabbitmqctl set_permissions -p "/" OpenStack "." "." ".*"

查看账号

[root@controller01 ~]# rabbitmqctl list_users 3.4、 镜像队列 ha

设置镜像队列高可用

[root@controller01 ~]# rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'

查看镜像队列策略

[root@controller01 ~]# rabbitmqctl list_policies 3.5、 安装 web 管理插件

在全部控制节点安装 web 管理插件,以 controller01 节点为例

[root@controller01 ~]# rabbitmq-plugins enable rabbitmq_management 访问任意节点,如: http://10.32.24.168:15672 4、Memcached 集群 Memcached 是无状态的,各控制节点独立部署,OpenStack 各服务模块统一调用多个控 制节点的 memcached 服务即可。 采用 OpenStack 官方的安装方法,如果需要部署最新版本 memcached,可参考:  http://www.cnblogs.com/netonline/p/7805900.html。 以下配置以 controller01 节点为例。 4.1、 安装 memcached

在全部控制节点安装 memcached

[root@controller01 ~]# yum install memcached python-memcached -y 4.2、 设置 memcached

在全部安装 memcached 服务的节点设置服务监听地址

[root@controller01 ~]# sed -i 's|127.0.0.1,::1|0.0.0.0|g' /etc/sysconfig/memcached 4.3、 开机启动 [root@controller01 ~]# systemctl enable memcached.service [root@controller01 ~]# systemctl start memcached.service [root@controller01 ~]# systemctl status memcached.service 5.Pacemaker cluster stack 集群 OpenStack 官网使用开源的 pacemaker cluster stack 做为集群高可用资源管理软件。 详细介绍: https://docs.OpenStack.org/ha-guide/controller-ha-pacemaker.html 5.1、 安装 pacemaker

在全部控制节点安装相关服务,以 controller01 节点为例;

pacemaker:资源管理器(CRM),负责启动与停止服务,位于 HA 集群架构中资源

管理、资源代理层

corosync:消息层组件(Messaging Layer),管理成员关系、消息与仲裁,为高可用环

境中提供通讯服务,位于高可用集群架构的底层,为各节点(node)之间提供心跳信息;

resource-agents:资源代理,在节点上接收 CRM 的调度,对某一资源进行管理的工具,

管理工具通常为脚本;

pcs:命令行工具集;

fence-agents:fencing 在一个节点不稳定或无答复时将其关闭,使其不会损坏集群的

其它资源,其主要作用是消除脑裂 [root@controller01 ~]# yum install pacemaker pcs corosync fence-agents resource-agents -y 5.2、 构建集群

启动 pcs 服务,在全部控制节点执行,以 controller01 节点为例

[root@controller01 ~]# systemctl enable pcsd [root@controller01 ~]# systemctl start pcsd

修改集群管理员 hacluster(默认生成)密码,在全部控制节点执行,以 controller01

节点为例 [root@controller01 ~]# echo pacemaker_pass | passwd --stdin hacluster

认证配置在任意节点操作,以 controller01 节点为例;

节点认证,组建集群,需要采用上一步设置的 password

[root@controller01 ~]# pcs cluster auth controller01 controller02 controller03 -u hacluster -p pacemaker_pass --force

创建并命名集群,在任意节点操作,以 controller01 节点为例;

生成配置文件:/etc/corosync/corosync.conf

[root@controller01 ~]# pcs cluster setup --force --name OpenStack-cluster-01 controller01 controller02 controller03 5.3、 启动

启动集群,以 controller01 节点为例

[root@controller01 ~]# pcs cluster start --all

查看集群状态,也可使用” crm_mon -1”命令;

“DC”:Designated Controller;

通过”cibadmin --query --scope nodes”可查看节点配置

[root@controller01 ~]# pcs status cluster

查看 corosync 状态;

“corosync”表示一种底层状态等信息的同步方式

[root@controller01 ~]# pcs status corosync

查看节点;

或:corosync-cmapctl runtime.totem.pg.mrp.srp.members

[root@controller01 ~]# corosync-cmapctl | grep members

查看集群资源

[root@controller01 ~]# pcs resource 或通过 web 访问任意控制节点: https://10.32.24.168:2224, 账号/密码(即构建集群时生成的密码):hacluster/pacemaker_pass 5.4、 设置属性

在任意控制节点设置属性即可,以 controller01 节点为例;

设置合适的输入处理历史记录及策略引擎生成的错误与警告,在 troulbshoot 时有用

[root@controller01 ~]# pcs property set pe-warn-series-max=1000 \ pe-input-series-max=1000 \ pe-error-series-max=1000

pacemaker 基于时间驱动的方式进行状态处理,” cluster-recheck-interval”默认定义某些

pacemaker 操作发生的事件间隔为 15min,建议设置为 5min 或 3min [root@controller01 ~]# pcs property set cluster-recheck-interval=5

corosync 默认启用 stonith,但 stonith 机制(通过 ipmi 或 ssh 关闭节点)并没有配置相

应的 stonith 设备(通过“crm_verify -L -V”验证配置是否正确,没有输出即正确),此时 pacemaker 将拒绝启动任何资源;

在生产环境可根据情况灵活调整,验证环境下可关闭

[root@controller01 ~]# pcs property set stonith-enabled=false

默认当有半数以上节点在线时,集群认为自己拥有法定人数,是“合法”的,满足公式:

total_nodes < 2 * active_nodes;

以 3 个节点的集群计算,当故障 2 个节点时,集群状态不满足上述公式,此时集群

即非法;当集群只有 2 个节点时,故障 1 个节点集群即非法,所谓的“双节点集群”就没有 意义;

在实际生产环境中,做 2 节点集群,无法仲裁时,可选择忽略;做 3 节点集群,可

根据对集群节点的高可用阀值灵活设置 [root@controller01 ~]# pcs property set no-quorum-policy=ignore

v2 的 heartbeat 为了支持多节点集群,提供了一种积分策略来控制各个资源在集群中

各节点之间的切换策略;通过计算出各节点的的总分数,得分最高者将成为 active 状态来管 理某个(或某组)资源;

默认每一个资源的初始分数(取全局参数 default-resource-stickiness,通过"pcs property

list --all"查看)是 0,同时每一个资源在每次失败之后减掉的分数(取全局参数 default-resource-failure-stickiness)也是 0,此时一个资源不论失败多少次,heartbeat 都只是 执行 restart 操作,不会进行节点切换;

如果针对某一个资源设置初始分数“resource-stickiness”或“resource-failure-stickiness”,

则取单独设置的资源分数;

一般来说,resource-stickiness的值都是正数,resource-failure-stickiness的值都是负数;

有一个特殊值是正无穷大(INFINITY)和负无穷大(-INFINITY),即"永远不切换"与"只要 失败必须切换",是用来满足极端规则的简单配置项;

如果节点的分数为负,该节点在任何情况下都不会接管资源(冷备节点);如果某节

点的分数大于当前运行该资源的节点的分数,heartbeat 会做出切换动作,现在运行该资源的 节点将释 放资源,分数高出的节点将接管该资源

pcs property list 只可查看修改后的属性值,参数“--all”可查看含默认值的全部属性

值;

也可查看/var/lib/pacemaker/cib/cib.xml 文件,或“pcs cluster cib”,或“cibadmin --query

--scope crm_config”查看属性设置,“cibadmin --query --scope resources”查看资源配置 [root@controller01 ~]# pcs property list Cluster Properties: cluster-infrastructure: corosync cluster-name: OpenStack-cluster-01 cluster-recheck-interval: 5 dc-version: 1.1.18-11.el7_5.3-2b07d5c5a9 have-watchdog: false no-quorum-policy: ignore pe-error-series-max: 1000 pe-input-series-max: 1000 pe-warn-series-max: 1000 stonith-enabled: false 5.5、 配置 vip

在任意控制节点设置 vip(resource_id 属性)即可,命名即为“vip”;

ocf(standard 属性):资源代理(resource agent)的一种,另有 systemd,lsb,service

等;

heartbeat:资源脚本的提供者(provider 属性),ocf 规范允许多个供应商提供同一资

源代理,大多数 ocf 规范提供的资源代理都使用 heartbeat 作为 provider;

IPaddr2:资源代理的名称(type 属性),IPaddr2 便是资源的 type;

通过定义资源属性(standard:provider:type),定位”vip”资源对应的 ra 脚本位置;

centos 系统中,符合 ocf 规范的 ra 脚本位于/usr/lib/ocf/resource.d/目录,目录下存放了

全部的 provider,每个 provider 目录下有多个 type;

op:表示 Operations

[root@controller01 ~]# pcs resource create vip ocf:heartbeat:IPaddr2 ip=172.30.200.30 cidr_netmask=24 op monitor interval=30s

查看集群资源

[root@controller01 ~]# pcs resource

通过”pcs resouce”查询,vip 资源在 controller01 节点;

通过”ip a show”可查看 vip

[root@controller01 ~]# ip a show eth0 5.6、 High availability management 通过 web 访问任意控制节点: https://10.32.24.168:2224 账号/密码(即构建集群时生成的密码):hacluster/pacemaker_pass 虽然以 cli 的方式设置了集群,但 web 界面默认并不显示,手动添加集群;实际操作只 需要添加已组建集群的任意节点即可,如下:

如果 api 区分 admin/internal/public 接口,对客户端只开放 public 接口,通常设置两个

vip,如命名为:vip_management 与 vip_public;

建议是将 vip_management 与 vip_public 约束在 1 个节点

[root@controller01 ~]# pcs constraint colocation add vip_management with vip_public

6、Haproxy 6.1、 安装 haproxy

在全部控制节点安装 haproxy,以 controller01 节点为例;

如果需要安装最新版本,可参考:

[root@controller01 ~]# yum install haproxy -y 6.2、 配置 haproxy.cfg

在全部控制节点配置 haproxy.cfg,以 controller01 节点为例;

haproxy 依靠 rsyslog 输出日志,是否输出日志根据实际情况设定;

备份原 haproxy.cfg 文件

[root@controller01 ~]# cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak

集群的 haproxy 文件,涉及服务较多,这里针对涉及到的 OpenStack 服务,一次性设

置完成,如下: [root@controller01 ~]# grep -v ^# /etc/haproxy/haproxy.cfg global chroot /var/lib/haproxy daemon group haproxy user haproxy maxconn 4000 pidfile /var/run/haproxy.pid defaults log global maxconn 4000 option redispatch retries 3 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout check 10s

haproxy 监控页

listen stats bind 0.0.0.0:1080 mode http stats enable stats uri / stats realm OpenStack\ Haproxy stats auth admin:admin stats refresh 30s stats show-node stats show-legends stats hide-version

horizon 服务

listen dashboard_cluster bind 172.30.200.30:80 balance source option tcpka option httpchk option tcplog server controller01 10.32.24.168:80 check inter 2000 rise 2 fall 5 server controller02 172.30.200.32:80 check inter 2000 rise 2 fall 5 server controller03 172.30.200.33:80 check inter 2000 rise 2 fall 5

mariadb 服务;

设置 controller01 节点为 master,controller02/03 节点为 backup,一主多备的架构可规

避数据不一致性;

另外官方示例为检测 9200(心跳)端口,测试在 mariadb 服务宕机的情况下,虽

然”/usr/bin/clustercheck”脚本已探测不到服务,但受 xinetd 控制的 9200 端口依然正常,导致 haproxy 始终将请求转发到 mariadb 服务宕机的节点,暂时修改为监听 3306 端口 listen galera_cluster bind 172.30.200.30:3306 balance source mode tcp server controller01 10.32.24.168:3306 check inter 2000 rise 2 fall 5 server controller02 172.30.200.32:3306 backup check inter 2000 rise 2 fall 5 server controller03 172.30.200.33:3306 backup check inter 2000 rise 2 fall 5

为 rabbirmq 提供 ha 集群访问端口,供 OpenStack 各服务访问;

如果 OpenStack 各服务直接连接 rabbitmq 集群,这里可不设置 rabbitmq 的负载均衡

listen rabbitmq_cluster bind 172.30.200.30:5673 mode tcp option tcpka balance roundrobin timeout client 3h timeout server 3h option clitcpka server controller01 10.32.24.168:5672 check inter 10s rise 2 fall 5 server controller02 172.30.200.32:5672 check inter 10s rise 2 fall 5 server controller03 172.30.200.33:5672 check inter 10s rise 2 fall 5

glance_api 服务

listen glance_api_cluster bind 172.30.200.30:9292 balance source option tcpka option httpchk option tcplog server controller01 10.32.24.168:9292 check inter 2000 rise 2 fall 5 server controller02 172.30.200.32:9292 check inter 2000 rise 2 fall 5 server controller03 172.30.200.33:9292 check inter 2000 rise 2 fall 5

glance_registry 服务

listen glance_registry_cluster bind 172.30.200.30:9191 balance source option tcpka option tcplog server controller01 10.32.24.168:9191 check inter 2000 rise 2 fall 5 server controller02 172.30.200.32:9191 check inter 2000 rise 2 fall 5 server controller03 172.30.200.33:9191 check inter 2000 rise 2 fall 5

keystone_admin_internal_api 服务

listen keystone_admin_cluster bind 172.30.200.30:35357 balance source option tcpka option httpchk option tcplog server controller01 10.32.24.168:35357 check inter 2000 rise 2 fall 5 server controller02 172.30.200.32:35357 check inter 2000 rise 2 fall 5 server controller03 172.30.200.33:35357 check inter 2000 rise 2 fall 5

keystone_public _api 服务

listen keystone_public_cluster bind 172.30.200.30:5000 balance source option tcpka option httpchk option tcplog server controller01 10.32.24.168:5000 check inter 2000 rise 2 fall 5 server controller02 172.30.200.32:5000 check inter 2000 rise 2 fall 5 server controller03 172.30.200.33:5000 check inter 2000 rise 2 fall 5

兼容 aws ec2-api

listen nova_ec2_api_cluster bind 172.30.200.30:8773 balance source option tcpka option tcplog server controller01 10.32.24.168:8773 check inter 2000 rise 2 fall 5 server controller02 172.30.200.32:8773 check inter 2000 rise 2 fall 5 server controller03 172.30.200.33:8773 check inter 2000 rise 2 fall 5 listen nova_compute_api_cluster bind 172.30.200.30:8774 balance source option tcpka option httpchk option tcplog server controller01 10.32.24.168:8774 check inter 2000 rise 2 fall 5 server controller02 172.30.200.32:8774 check inter 2000 rise 2 fall 5 server controller03 172.30.200.33:8774 check inter 2000 rise 2 fall 5 listen nova_placement_cluster bind 172.30.200.30:8778 balance source option tcpka option tcplog server controller01 10.32.24.168:8778 check inter 2000 rise 2 fall 5 server controller02 172.30.200.32:8778 check inter 2000 rise 2 fall 5 server controller03 172.30.200.33:8778 check inter 2000 rise 2 fall 5 listen nova_metadata_api_cluster bind 172.30.200.30:8775 balance source option tcpka option tcplog server controller01 10.32.24.168:8775 check inter 2000 rise 2 fall 5 server controller02 172.30.200.32:8775 check inter 2000 rise 2 fall 5 server controller03 172.30.200.33:8775 check inter 2000 rise 2 fall 5 listen nova_vncproxy_cluster bind 172.30.200.30:6080 balance source option tcpka option tcplog server controller01 10.32.24.168:6080 check inter 2000 rise 2 fall 5 server controller02 172.30.200.32:6080 check inter 2000 rise 2 fall 5 server controller03 172.30.200.33:6080 check inter 2000 rise 2 fall 5 listen neutron_api_cluster bind 172.30.200.30:9696 balance source option tcpka option httpchk option tcplog server controller01 10.32.24.168:9696 check inter 2000 rise 2 fall 5 server controller02 172.30.200.32:9696 check inter 2000 rise 2 fall 5 server controller03 172.30.200.33:9696 check inter 2000 rise 2 fall 5 listen cinder_api_cluster bind 172.30.200.30:8776 balance source option tcpka option httpchk option tcplog server controller01 10.32.24.168:8776 check inter 2000 rise 2 fall 5 server controller02 172.30.200.32:8776 check inter 2000 rise 2 fall 5 server controller03 172.30.200.33:8776 check inter 2000 rise 2 fall 5 检测配置文件是否正确:haproxy -f /etc/haproxy/haproxy.cfg -d 注:HAPROXY 配置文件详解 global chroot dir #工作目录 chroot #全局日志配置,使用 127.0.0.1 的 rsyslog 服务中 local3 日志设备,等级 info log 127.0.0.1 local3 info #每个进程最大并发数 maxconn 4096 #后台进程数量 nbproc 1 #用户 user nobody group nobody #后台程序模式工作 daemon #HAProxy pid 文件存储目录 pidfile /var/run/haproxy-private.pid #tune.bufsize 16384 设置 buffer(B) defaults mode http #默认的模式 mode{tcp|http|health},health 只会返回 OK #retries 2 #两次连接失败就认为是服务器不可用,也可以通过后面设置 option redispatch #当 serverId 对应的服务器挂掉后,强制定向到其他健康的服务器 option abortonclose #当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接 timeout connect 5000ms #连接超时 timeout client 30000ms #客户端超时 timeout server 30000ms #服务器超时 #timeout check 2000 #心跳检测超时 log 127.0.0.1 local0 err #[err warning info debug] balance roundrobin #负载均衡算法 option httplog #日志类别,采用 httplog option httpclose #每次请求完毕后主动关闭 http 通道,ha-proxy 不支持 keep-alive,只能 模拟这种模式的实现 option dontlognull option forwardfor #如果后端服务器需要获得客户端真实 ip 需要配置的参数,可以从 Http Header 中获得客户端 ip listen stats bind 0.0.0.0:8888 #监听端口 option httplog #采用 http 日志格式 stats enable #开启 stats 统计页面 stats uri / #统计页面访问的前缀,后通常要加上?stats stats realm "Haproxy Auth" #开启认证功能 stats auth admin:admin #认证时的账号和密码 stats admin if TRUE #在制定条件下开启 admin 功能 stats refresh 3s #统计页面自动刷新时间间隔 stats show-desc demo #统计页面显示的相关描述信息 stats hide-version #隐藏 haproxy 的版本号 6.3、 配置内核参数

全部控制节点修改内核参数,以 controller01 节点为例;

net.ipv4.ip_nonlocal_bind:是否允许 no-local ip 绑定,关系到 haproxy 实例与 vip 能否

绑定并切换;

net.ipv4.ip_forward:是否允许转发

[root@controller01 ~]# echo "net.ipv4.ip_nonlocal_bind = 1" >>/etc/sysctl.conf [root@controller01 ~]# echo "net.ipv4.ip_forward = 1" >>/etc/sysctl.conf [root@controller01 ~]# sysctl -p 6.4、 启动

开机启动是否设置可自行选择,利用 pacemaker 设置 haproxy 相关资源后,pacemaker

可控制各节点 haproxy 服务是否启动

[root@controller01 ~]# systemctl enable haproxy

[root@controller01 ~]# systemctl restart haproxy [root@controller01 ~]# systemctl status haproxy 访问: http://172.30.200.30:1080/ 6.5、 设置 pcs 资源

任意控制节点操作即可,以 controller01 节点为例;

添加资源 lb-haproxy-clone

[root@controller01 ~]# pcs resource create lb-haproxy systemd:haproxy --clone [root@controller01 ~]# pcs resource

设置资源启动顺序,先 vip 再 lb-haproxy-clone;

通过“cibadmin --query --scope constraints”可查看资源约束配置

[root@controller01 ~]# pcs constraint order start vip then lb-haproxy-clone kind=Optional

官方建议设置 vip 运行在 haproxy active 的节点,通过绑定 lb-haproxy-clone 与 vip 服

务,将两种资源约束在 1 个节点;

约束后,从资源角度看,其余暂时没有获得 vip 的节点的 haproxy 会被 pcs 关闭

[root@controller01 ~]# pcs constraint colocation add lb-haproxy-clone with vip [root@controller01 ~]# pcs resource 通过 high availability management 查看资源相关的设置,如下: 7、Keystone 集群 7.1、 创建 keystone 数据库

在任意控制节点创建数据库,数据库自动同步,以 controller01 节点为例;

在任意控制节点创建数据库,数据库自动同步,以 controller01 节点为例;

[root@controller01 ~]# mysql -uroot -pmysql_pass MariaDB [(none)]> CREATE DATABASE keystone; MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY '000000'; MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY '000000'; MariaDB [(none)]> flush privileges; MariaDB [(none)]> exit; 7.2、 安装 keystone

在全部控制节点安装 keystone,以 controller01 节点为例;

[root@controller01 ~]# yum install openstack-keystone httpd mod_wsgi mod_ssl -y 7.3、 配置 keystone.conf

在全部控制节点设置,以 controller01 节点为例;

红色加粗字体为修改部分

[root@controller01 ~]# cp /etc/keystone/keystone.conf /etc/keystone/keystone.conf.bak [root@controller01 ~]# egrep -v "$|#" /etc/keystone/keystone.conf [DEFAULT] [application_credential] [assignment] [auth] [cache] backend = oslo_cache.memcache_pool enabled = true memcache_servers = controller01:11211,controller02:11211,controller03:11211 [catalog] [cors] [credential] [database] connection = mysql+pymysql://keystone:000000@controller/keystone [domain_config] [endpoint_filter] [endpoint_policy] [eventlet_server] [federation] [fernet_tokens] [healthcheck] [identity] [identity_mapping] [ldap] [matchmaker_redis] [memcache] [oauth1] [oslo_messaging_amqp] [oslo_messaging_kafka] [oslo_messaging_notifications] [oslo_messaging_rabbit] [oslo_messaging_zmq] [oslo_middleware] [oslo_policy] [paste_deploy] [policy] [profiler] [resource] [revoke] [role] [saml] [security_compliance] [shadow_users] [signing] [token] provider = fernet [tokenless_auth] [trust] [unified_limit] 7.4、 同步 keystone 数据库

任意控制节点操作

[root@controller01 ~]# su -s /bin/sh -c "keystone-manage db_sync" keystone

查看验证

[root@controller01 ~]# mysql -h controller01 -ukeystone -p000000 -e "use keystone;show tables;" 7.5、 初始化 fernet 秘钥

选定任意控制节点(controller01)做 fernet 秘钥初始化,在/etc/keystone/生成相关秘

钥及目录 [root@controller01 ~]# keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone [root@controller01 ~]# keystone-manage credential_setup --keystone-user keystone --keystone-group keystone

向 controller02/03 节点同步秘钥

[root@controller01 ~]# scp -r /etc/keystone/fernet-keys/ /etc/keystone/credential-keys/ root@172.30.200.32:/etc/keystone/ [root@controller01 ~]# scp -r /etc/keystone/fernet-keys/ /etc/keystone/credential-keys/ root@172.30.200.33:/etc/keystone/

同步后,注意 controller02/03 节点上秘钥权限

[root@controller02 ~]# chown keystone:keystone /etc/keystone/credential-keys/ -R [root@controller02 ~]# chown keystone:keystone /etc/keystone/fernet-keys/ -R [root@controller03 ~]# chown keystone:keystone /etc/keystone/credential-keys/ -R [root@controller03 ~]# chown keystone:keystone /etc/keystone/fernet-keys/ -R 7.6、 配置 httpd.conf

在全部控制节点设置,以 controller01 节点为例;

[root@controller01 ~]# cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.bak [root@controller01 ~]# sed -i "s/#ServerName  www.example.com:80/ServerName ${HOSTNAME}/" /etc/httpd/conf/httpd.conf

注意不同的节点替换不同的 ip 地址

[root@controller01 ~]# sed -i "s/Listen\ 80/Listen\ 10.32.24.168:80/g" /etc/httpd/conf/httpd.conf [root@controller02 ~]# sed -i "s/Listen\ 80/Listen\ 172.30.200.32:80/g" /etc/httpd/conf/httpd.conf [root@controller03 ~]# sed -i "s/Listen\ 80/Listen\ 172.30.200.33:80/g" /etc/httpd/conf/httpd.conf 7.7、 配置 wsgi-keystone.conf

在全部控制节点操作,以 controller01 节点为例;

复制 wsgi-keystone.conf 文件;

或者针对 wsgi-keystone.conf 创建软链接

[root@controller01 ~]# cp /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/

修改 wsgi-keystone.conf 文件,注意各节点对应的 ip 地址或主机名等,以 controller01

节点为例 [root@controller01 ~]# sed -i "s/Listen\ 5000/Listen\ 10.32.24.168:5000/g" /etc/httpd/conf.d/wsgi-keystone.conf [root@controller01 ~]# sed -i "s/Listen\ 35357/Listen\ 10.32.24.168:35357/g" /etc/httpd/conf.d/wsgi-keystone.conf [root@controller01 ~]# sed -i "s/:5000/10.32.24.168:5000/g" /etc/httpd/conf.d/wsgi-keystone.conf [root@controller01 ~]# sed -i "s/:35357/10.32.24.168:35357/g" /etc/httpd/conf.d/wsgi-keystone.conf 7.8、 认证引导

任意控制节点操作;

初始化 admin 用户(管理用户)与密码,3 种 api 端点,服务实体可用区等

[root@controller01 ~]# keystone-manage bootstrap --bootstrap-password admin_pass \ --bootstrap-admin-url http://controller:35357/v3/ \ --bootstrap-internal-url http://controller:5000/v3/ \ --bootstrap-public-url http://controller:5000/v3/ \ --bootstrap-region-id RegionTest 7.9、 启动服务

在全部控制节点操作,以 controller01 节点为例

[root@controller01 ~]# systemctl enable httpd.service [root@controller01 ~]# systemctl restart httpd.service root@controller01 ~]# systemctl status httpd.service 7.10、 创建 domain, projects, users, 与 roles 1)domain

projrct/user 等基于 domain 存在;

在”认证引导”章节中,初始化 admin 用户即生成”default” domain

[root@controller01 ~]# openstack domain list

如果需要生成新的 domain,

[root@controller01 ~]# openstack domain create --description "An Example Domain" example [root@controller01 ~]# openstack domain list 2)projects

project 属于某个 domain;

以创建 demo 项目为例,demo 项目属于”default” domain

[root@controller01 ~]# openstack project create --domain default --description "Demo Project" demo 3)users

user 属于某个 domain;

以创建 demo 用户为例,demo 用户属于”default” domain

[root@controller01 ~]# openstack user create --domain default --password=demo_pass demo 4)roles

创建普通用户角色(区别于 admin 用户)

[root@controller01 ~]# openstack role create user

向 demo 项目的 demo 用户赋予 user 权限,

[root@controller01 ~]# openstack role add --project demo --user demo user

查看权限分配

[root@controller01 ~]# openstack user list [root@controller01 ~]# openstack role list [root@controller01 ~]# openstack role assignment list 7.11、 openstack client 环境变量脚本 1)admin-openrc

openstack client 环境脚本定义 client 调用 openstack api 环境变量,以方便 api 的调用(不

必在命令行中携带环境变量);

根据不同的用户角色,需要定义不同的脚本;

这里以“认证引导”章节定义的 admin 用户为例,设置其环境脚本,再根据需要分发到

需要运行 openstack client 工具的节点;

一般将脚本创建在用户主目录

[root@controller01 ~]# touch admin-openrc [root@controller01 ~]# chmod u+x admin-openrc [root@controller01 ~]# vim admin-openrc export OS_PROJECT_DOMAIN_NAME=Default export OS_USER_DOMAIN_NAME=Default export OS_PROJECT_NAME=admin export OS_USERNAME=admin export OS_PASSWORD=admin_pass export OS_AUTH_URL=http://controller:5000/v3

从安全角度考虑,一般不对 client 暴露 admin-api,这里 admin-api 与 public-api 共用 1

个 vip 地址

export OS_AUTH_URL=http://controller:35357/v3

export OS_IDENTITY_API_VERSION=3 export OS_IMAGE_API_VERSION=2

验证

[root@controller01 ~]# openstack token issue 2)demo-openrc

同 admin-openrc,注意 project/user/password 的区别

[root@controller01 ~]# touch demo-openrc [root@controller01 ~]# chmod u+x demo-openrc [root@controller01 ~]# vim demo-openrc export OS_PROJECT_DOMAIN_NAME=Default export OS_USER_DOMAIN_NAME=Default export OS_PROJECT_NAME=demo export OS_USERNAME=demo export OS_PASSWORD=demo_pass export OS_AUTH_URL=http://controller:5000/v3 export OS_IDENTITY_API_VERSION=3 export OS_IMAGE_API_VERSION=2

验证

[root@controller01 ~]# openstack token issue

分发脚本

[root@controller01 ~]# scp admin-openrc demo-openrc root@172.30.200.32:~/ [root@controller01 ~]# scp admin-openrc demo-openrc root@172.30.200.33:~/ 7.12、 设置 pcs 资源

在任意控制节点操作;

添加资源 openstack-keystone-clone;

pcs 实际控制的是各节点 system unit 控制的 httpd 服务

[root@controller01 ~]# pcs resource create openstack-keystone systemd:httpd --clone interleave=true [root@controller01 ~]# pcs resource 8、Glance 集群 8.1、创建 glance 数据库

在任意控制节点创建数据库,后台数据自动同步,以 controller01 节点为例

[root@controller01 ~]# mysql -u root -pmysql_pass MariaDB [(none)]> CREATE DATABASE glance; MariaDB [(none)]> GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' IDENTIFIED BY 'glance_dbpass'; MariaDB [(none)]> GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' IDENTIFIED BY 'glance_dbpass'; MariaDB [(none)]> flush privileges; MariaDB [(none)]> exit; 8.2. 创建 glance-api

在任意控制节点操作,以 controller01 节点为例;

调用 keystone 服务需要认证信息,加载环境变量脚本即可

[root@controller01 ~]# . admin-openrc 8.2.1、创建 service 项目

创建 1 个 project,glance/nova/neutron 等服务加入到此 project;

service 项目在”default” domain 中

[root@controller01 ~]# openstack project create --domain default --description "Service Project" service 8.2.2、创建 glance 用户

glance 用户在”default” domain 中

[root@controller01 ~]# openstack user create --domain default --password=glance_pass glance 8.2.3、glance 用户赋权

为 glance 用户赋予 admin 权限

[root@controller01 ~]# openstack role add --project service --user glance admin 8.2.4、创建 glance 服务实体

服务实体类型”image”

[root@controller01 ~]# openstack service create --name glance --description "OpenStack Image" image 8.2.5、创建 glance-api

注意--region 与初始化 admin 用户时生成的 region 一致;

api 地址统一采用 vip,如果 public/internal/admin 分别使用不同的 vip,请注意区分;

服务类型为 image;

public api

[root@controller01 ~]# openstack endpoint create --region RegionTest image public http://controller:9292

internal api

[root@controller01 ~]# openstack endpoint create --region RegionTest image internal http://controller:9292

internal api

[root@controller01 ~]# openstack endpoint create --region RegionTest image internal http://controller:9292 8.3、安装 glance

在全部控制节点安装 glance,以 controller01 节点为例

[root@controller01 ~]# yum install openstack-glance python-glance python-glanceclient -y 8.4、配置 glance-api.conf

在全部控制节点操作,以 controller01 节点为例;

注意”bind_host”参数,根据节点修改;

注意 glance-api.conf 文件的权限:root:glance

[root@controller01 ~]# cp /etc/glance/glance-api.conf /etc/glance/glance-api.conf.bak [root@controller01 ~]# egrep -v "$|#" /etc/glance/glance-api.conf [DEFAULT] enable_v1_api = false bind_host = 10.32.24.168 [cors] [database] connection = mysql+pymysql://glance:glance_dbpass@controller/glance [glance_store] stores = file,http default_store = file filesystem_store_datadir = /var/lib/glance/images/ [image_format] [keystone_authtoken] auth_uri = http://controller:5000 auth_url = http://controller:35357 memcached_servers = controller01:11211,controller02:11211,controller03:11211 auth_type = password project_domain_name = default user_domain_name = default project_name = service username = glance password = glance_pass [matchmaker_redis] [oslo_concurrency] [oslo_messaging_amqp] [oslo_messaging_kafka] [oslo_messaging_notifications] [oslo_messaging_rabbit] [oslo_messaging_zmq] [oslo_middleware] [oslo_policy] [paste_deploy] flavor = keystone [profiler] [store_type_location_strategy] [task] [taskflow_executor]

创建镜像存储目录并赋权限;

/var/lib/glance/images 是默认的存储目录

[root@controller01 ~]# mkdir -p /var/lib/glance/images [root@controller01 ~]# chown glance:nobody /var/lib/glance/images 8.5、配置 glance-registry.conf(optional)

官方文档指出:glance-registry 服务与其 api 在 Q 版已经弃用,并且在 S 版时完全删

除,本章节可忽略;

在全部控制节点操作,以 controller01 节点为例;

注意”bind_host”参数,根据节点修改;

注意 glance-registry.conf 文件的权限:root:glance

[root@controller01 ~]# cp /etc/glance/glance-registry.conf /etc/glance/glance-registry.conf.bak [root@controller01 ~]# egrep -v "$|#" /etc/glance/glance-registry.conf [DEFAULT] bind_host = 10.32.24.168 [database] connection = mysql+pymysql://glance:glance_dbpass@controller/glance [keystone_authtoken] auth_uri = http://controller:5000 auth_url = http://controller:35357 memcached_servers = controller01:11211,controller02:11211,controller03:11211 auth_type = password project_domain_name = default user_domain_name = default project_name = service username = glance password = glance_pass [matchmaker_redis] [oslo_messaging_amqp] [oslo_messaging_kafka] [oslo_messaging_notifications] [oslo_messaging_rabbit] [oslo_messaging_zmq] [oslo_policy] [paste_deploy] flavor = keystone [profiler] 8.6、同步 glance 数据库

任意控制节点操作;

忽略输出的“deprecated”信息

[root@controller01 ~]# su -s /bin/sh -c "glance-manage db_sync" glance

查看验证

[root@controller01 ~]# mysql -h controller01 -uglance -pglance_dbpass -e "use glance;show tables;" 8.7、启动服务

在全部控制节点操作,以 controller01 节点为例;

glance-registry 在 Q 版已弃用;

[root@controller01 ~]# systemctl enable openstack-glance-api.service openstack-glance-registry.service [root@controller01 ~]# systemctl restart openstack-glance-api.service openstack-glance-registry.service

查看服务状态

[root@controller01 ~]# systemctl status openstack-glance-api.service openstack-glance-registry.service

查看端口

[root@controller01 ~]# netstat -tunlp | grep python2 8.8、 验证 在不启用 ceph 存储时,通常采用 nfs 共享存储做 image 的后端存储,如可将 controller01 节点的本地存储做共享,controller02/03 节点远端挂载即可。 这里后续使用 ceph 存储,暂时使用本地验证,以 controller01 节点为例。 8.8.1、下载镜像 [root@controller01 ~]# wget  http://download.cirros-cloud.net/0.3.5/cirros-0.3.5-x86_64-disk.img 8.8.2、上传镜像 [root@controller01 ~]# . admin-openrc

“上传”指将已下载的原始镜像经过一定的格式转换上传到 image 服务;

格式指定为 qcow2,bare;设置 public 权限;

镜像生成后,在指定的存储目录下生成以镜像 id 命名的镜像文件

[root@controller01 ~]# openstack image create "cirros-qcow2" \ --file ~/cirros-0.3.5-x86_64-disk.img \ --disk-format qcow2 --container-format bare \ --public 8.8.3、查看镜像 [root@controller01 ~]# openstack image list 8.9、 设置 pcs 资源

在任意控制节点操作;

添加资源 openstack-glance-api 与 openstack-glance-registry

[root@controller01 ~]# pcs resource create openstack-glance-api systemd:openstack-glance-api --clone interleave=true [root@controller01 ~]# pcs resource create openstack-glance-registry systemd:openstack-glance-registry --clone interleave=true

查看 pcs 资源

[root@controller01 ~]# pcs resource 9、Nova 控制节点集群 9.1、创建 nova 相关数据库

在任意控制节点创建数据库,后台数据自动同步,以 controller01 节点为例;

nova 服务含 4 个数据库,统一授权到 nova 用户;

placement 主要涉及资源统筹,较常用的 api 接口是获取备选资源与 claim 资源等

[root@controller01 ~]# mysql -u root -pmysql_pass MariaDB [(none)]> CREATE DATABASE nova_api; MariaDB [(none)]> CREATE DATABASE nova; MariaDB [(none)]> CREATE DATABASE nova_cell0; MariaDB [(none)]> CREATE DATABASE nova_placement; MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost' IDENTIFIED BY 'nova_dbpass'; MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%' IDENTIFIED BY 'nova_dbpass'; MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' IDENTIFIED BY 'nova_dbpass'; MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' IDENTIFIED BY 'nova_dbpass'; MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'localhost' IDENTIFIED BY 'nova_dbpass'; MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'%' IDENTIFIED BY 'nova_dbpass'; MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_placement.* TO 'nova'@'localhost' IDENTIFIED BY 'nova_dbpass'; MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_placement.* TO 'nova'@'%' IDENTIFIED BY 'nova_dbpass'; MariaDB [(none)]> flush privileges; MariaDB [(none)]> exit; 9.2、创建 nova/placement-api

在任意控制节点操作,以 controller01 节点为例;

调用 nova 相关服务需要认证信息,加载环境变量脚本即可

[root@controller01 ~]# . admin-openrc 9.2.1、创建 nova/plcement 用户

service 项目已在 glance 章节创建;

nova/placement 用户在”default” domain 中

[root@controller01 ~]# openstack user create --domain default --password=nova_pass nova [root@controller01 ~]# openstack user create --domain default --password=placement_pass placement 9.2.2、nova/placement 赋权

为 nova/placement 用户赋予 admin 权限

[root@controller01 ~]# openstack role add --project service --user nova admin [root@controller01 ~]# openstack role add --project service --user placement admin 9.2.3、创建 nova/placement 服务实体

nova 服务实体类型”compute”;

placement 服务实体类型”placement”

[root@controller01 ~]# openstack service create --name nova --description "OpenStack Compute" compute [root@controller01 ~]# openstack service create --name placement --description "Placement API" placement 4)创建 nova/placement-api

注意--region 与初始化 admin 用户时生成的 region 一致;

api 地址统一采用 vip,如果 public/internal/admin 分别使用不同的 vip,请注意区分;

nova-api 服务类型为 compute,placement-api 服务类型为 placement;

nova public api

[root@controller01 ~]# openstack endpoint create --region RegionTest compute public http://controller:8774/v2.1

nova internal api

[root@controller01 ~]# openstack endpoint create --region RegionTest compute internal http://controller:8774/v2.1

nova admin api

[root@controller01 ~]# openstack endpoint create --region RegionTest compute admin http://controller:8774/v2.1

placement public api

[root@controller01 ~]# openstack endpoint create --region RegionTest placement public http://controller:8778

placement internal api

[root@controller01 ~]# openstack endpoint create --region RegionTest placement internal http://controller:8778

placement admin api

[root@controller01 ~]# openstack endpoint create --region RegionTest placement admin http://controller:8778 9.3、安装 nova

在全部控制节点安装 nova 相关服务,以 controller01 节点为例

[root@controller01 ~]# yum install openstack-nova-api openstack-nova-conductor \ openstack-nova-console openstack-nova-novncproxy \ openstack-nova-scheduler openstack-nova-placement-api -y 9.4、配置 nova.conf

在全部控制节点操作,以 controller01 节点为例;

注意”my_ip”参数,根据节点修改;

注意 nova.conf 文件的权限:root:nova

[root@controller01 ~]# cp /etc/nova/nova.conf /etc/nova/nova.conf.bak [root@controller01 ~]# egrep -v "^OpenStack Queens HA 部署手册_服务器my_ip osapi_compute_listen_port=8774 metadata_listen=$my_ip metadata_listen_port=8775

前端采用 haproxy 时,服务连接 rabbitmq 会出现连接超时重连的情况,可通过各服务

与 rabbitmq 的日志查看;

transport_url=rabbit://openstack:rabbitmq_pass@controller:5673

rabbitmq 本身具备集群机制,官方文档建议直接连接 rabbitmq 集群;但采用此方式时

服务启动有时会报错,原因不明;如果没有此现象,强烈建议连接 rabbitmq 直接对接集群 而非通过前端 haproxy transport_url=rabbit://openstack:rabbitmq_pass@controller01:5672,controller02:5672,contro ller03:5672 [api] auth_strategy=keystone [api_database] connection=mysql+pymysql://nova:nova_dbpass@controller/nova_api [barbican] [cache] backend=oslo_cache.memcache_pool enabled=True memcache_servers=controller01:11211,controller02:11211,controller03:11211 [cells] [cinder] [compute] [conductor] [console] [consoleauth] [cors] [crypto] [database] connection = mysql+pymysql://nova:nova_dbpass@controller/nova [devices] [ephemeral_storage_encryption] [filter_scheduler] [glance] api_servers = http://controller:9292 [guestfs] [healthcheck] [hyperv] [ironic] [key_manager] [keystone] [keystone_authtoken] auth_uri = http://controller:5000 auth_url = http://controller:35357 memcached_servers = controller01:11211,controller02:11211,controller03:11211 auth_type = password project_domain_name = default user_domain_name = default project_name = service username = nova password = nova_pass [libvirt] [matchmaker_redis] [metrics] [mks] [neutron] [notifications] [osapi_v21] [oslo_concurrency] lock_path=/var/lib/nova/tmp [oslo_messaging_amqp] [oslo_messaging_kafka] [oslo_messaging_notifications] [oslo_messaging_rabbit] [oslo_messaging_zmq] [oslo_middleware] [oslo_policy] [pci] [placement] region_name = RegionTest project_domain_name = Default project_name = service auth_type = password user_domain_name = Default auth_url = http://controller:35357/v3 username = placement password = placement_pass [quota] [rdp] [remote_debug] [scheduler] [serial_console] [service_user] [spice] [upgrade_levels] [vault] [vendordata_dynamic_auth] [vmware] [vnc] enabled=true server_listen=OpenStack Queens HA 部署手册_sql_02my_ip novncproxy_base_url=http://OpenStack Queens HA 部署手册_数据_03my_ip novncproxy_port=6080 [workarounds] [wsgi] [xenserver] [xvp] 9.5、配置 00-nova-placement-api.conf

在全部控制节点操作,以 controller01 节点为例;

注意根据不同节点修改监听地址

[root@controller01 ~]# cp /etc/httpd/conf.d/00-nova-placement-api.conf /etc/httpd/conf.d/00-nova-placement-api.conf.bak [root@controller01 ~]# sed -i "s/Listen\ 8778/Listen\ 10.32.24.168:8778/g" /etc/httpd/conf.d/00-nova-placement-api.conf [root@controller01 ~]# sed -i "s/*:8778/10.32.24.168:8778/g" /etc/httpd/conf.d/00-nova-placement-api.conf [root@controller01 ~]# echo " #Placement API <Directory /usr/bin> = 2.4> Require all granted

重启 httpd 服务,启动 placement-api 监听端口

[root@controller01 ~]# systemctl restart httpd 9.6、同步 nova 相关数据库 9.6.1、同步 nova 相关数据库

任意控制节点操作;

同步 nova-api 数据库

[root@controller01 ~]# su -s /bin/sh -c "nova-manage api_db sync" nova

注册 cell0 数据库

[root@controller01 ~]# su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova

创建 cell1 cell

[root@controller01 ~]# su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova

同步 nova 数据库;

忽略”deprecated”信息

[root@controller01 ~]# su -s /bin/sh -c "nova-manage db sync" nova 补充: 此版本在向数据库同步导入数据表时,报错: /usr/lib/python2.7/site-packages/oslo_db/sqlalchemy/enginefacade.py:332: NotSupportedWarning: Configuration option(s) ['use_tpool'] not supported exception.NotSupportedWarning 解决方案如下: bug: https://bugs.launchpad.net/nova/+bug/1746530 pacth :  https://github.com/openstack/oslo.db/commit/c432d9e93884d6962592f6d19aaec3f8f66ac3a2 9.6.2、验证

cell0 与 cell1 注册正确

[root@controller01 ~]# nova-manage cell_v2 list_cells

查看数据表

[root@controller01 ~]# mysql -h controller01 -u nova -pnova_dbpass -e "use nova_api;show tables;" [root@controller01 ~]# mysql -h controller01 -u nova -pnova_dbpass -e "use nova;show tables;" [root@controller01 ~]# mysql -h controller01 -u nova -pnova_dbpass -e "use nova_cell0;show tables;" 9.7、启动服务

在全部控制节点操作,以 controller01 节点为例;

开机启动

[root@controller01 ~]# systemctl enable openstack-nova-api.service \ openstack-nova-consoleauth.service \ openstack-nova-scheduler.service \ openstack-nova-conductor.service \ openstack-nova-novncproxy.service

启动

[root@controller01 ~]# systemctl restart openstack-nova-api.service [root@controller01 ~]# systemctl restart openstack-nova-consoleauth.service [root@controller01 ~]# systemctl restart openstack-nova-scheduler.service [root@controller01 ~]# systemctl restart openstack-nova-conductor.service [root@controller01 ~]# systemctl restart openstack-nova-novncproxy.service

查看状态

[root@controller01 ~]# systemctl status openstack-nova-api.service \ openstack-nova-consoleauth.service \ openstack-nova-scheduler.service \ openstack-nova-conductor.service \ openstack-nova-novncproxy.service

查看端口

[root@controller01 ~]# netstat -tunlp | egrep '8774|8775|8778|6080' 9.8、验证 [root@controller01 ~]# . admin-openrc

列出各服务组件,查看状态;

也可使用命令” nova service-list”

[root@controller01 ~]# openstack compute service list

展示 api 端点

[root@controller01 ~]# openstack catalog list

检查 cell 与 placement api 运行正常

[root@controller01 ~]# nova-status upgrade check 9.9、设置 pcs 资源

在任意控制节点操作;

添加资源 openstack-nova-api,openstack-nova-consoleauth,openstack-nova-scheduler,

openstack-nova-conductor 与 openstack-nova-novncproxy [root@controller01 ~]# pcs resource create openstack-nova-api systemd:openstack-nova-api --clone interleave=true [root@controller01 ~]# pcs resource create openstack-nova-consoleauth systemd:openstack-nova-consoleauth --clone interleave=true [root@controller01 ~]# pcs resource create openstack-nova-scheduler systemd:openstack-nova-scheduler --clone interleave=true [root@controller01 ~]# pcs resource create openstack-nova-conductor systemd:openstack-nova-conductor --clone interleave=true [root@controller01 ~]# pcs resource create openstack-nova-novncproxy systemd:openstack-nova-novncproxy --clone interleave=true

经验证,建议openstack-nova-api,openstack-nova-consoleauth,openstack-nova-conductor

与 openstack-nova-novncproxy 等无状态服务以 active/active 模式运行;

openstack-nova-scheduler 等服务以 active/passive 模式运行

查看 pcs 资源;

[root@controller01 ~]# pcs resource 10、Neutron 控制/网络节点集群

  1. 创建 neutron 数据库

在任意控制节点创建数据库,后台数据自动同步,以 controller01 节点为例;

[root@controller01 ~]# mysql -u root -pmysql_pass MariaDB [(none)]> CREATE DATABASE neutron; MariaDB [(none)]> GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY 'neutron_dbpass'; MariaDB [(none)]> GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY 'neutron_dbpass'; MariaDB [(none)]> flush privileges; MariaDB [(none)]> exit; 2. 创建 neutron-api

在任意控制节点操作,以 controller01 节点为例;

调用 neutron 服务需要认证信息,加载环境变量脚本即可

[root@controller01 ~]# . admin-openrc 1)创建 neutron 用户

service 项目已在 glance 章节创建;

neutron 用户在”default” domain 中

[root@controller01 ~]# openstack user create --domain default --password=neutron_pass neutron 2)neutron 赋权

为 neutron 用户赋予 admin 权限

[root@controller01 ~]# openstack role add --project service --user neutron admin 3)创建 neutron 服务实体

neutron 服务实体类型”network”

[root@controller01 ~]# openstack service create --name neutron --description "OpenStack Networking" network 4)创建 neutron-api

注意--region 与初始化 admin 用户时生成的 region 一致;

api 地址统一采用 vip,如果 public/internal/admin 分别使用不同的 vip,请注意区分;

neutron-api 服务类型为 network;

public api

[root@controller01 ~]# openstack endpoint create --region RegionTest network public http://controller:9696

internal api

[root@controller01 ~]# openstack endpoint create --region RegionTest network internal http://controller:9696

admin api

[root@controller01 ~]# openstack endpoint create --region RegionTest network admin http://controller:9696 3. 安装 neutron

在全部控制节点安装 neutron 相关服务,以 controller01 节点为例

[root@controller01 ~]# yum install openstack-neutron openstack-neutron-ml2 openstack-neutron-linuxbridge python-neutronclient ebtables ipset -y 4. 配置 neutron.conf

在全部控制节点操作,以 controller01 节点为例;

注意”bind_host”参数,根据节点修改;

注意 neutron.conf 文件的权限:root:neutron

[root@controller01 ~]# cp /etc/neutron/neutron.conf /etc/neutron/neutron.conf.bak [root@controller01 ~]# egrep -v "$|#" /etc/neutron/neutron.conf [DEFAULT] bind_host = 10.32.24.168 auth_strategy = keystone core_plugin = ml2 service_plugins = router allow_overlapping_ips = True notify_nova_on_port_status_changes = true notify_nova_on_port_data_changes = true

l3 高可用,可以采用 vrrp 模式或者 dvr 模式;

vrrp 模式下,在各网络节点(此处网络节点与控制节点混合部署)以 vrrp 的模式设置

主备 virtual router;mater 故障时,virtual router 不会迁移,而是将 router 对外服务的 vip 漂 移到 standby router 上;

dvr 模式下,三层的转发(L3 Forwarding)与 nat 功能都会被分布到计算节点上,即

计算节点也有了网络节点的功能;但是,dvr 依然不能消除集中式的 virtual router,为了节 省 IPV4 公网地址,仍将 snat 放在网络节点上提供;

vrrp 模式与 dvr 模式不可同时使用

Neutron L3 Agent HA 之 虚 拟 路 由 冗 余 协 议 ( VRRP ) :

 http://www.cnblogs.com/sammyliu/p/4692081.html

Neutron 分布式虚拟路 由 ( Neutron Distributed Virtual Routing ) :

 http://www.cnblogs.com/sammyliu/p/4713562.html

“l3_ha = true“参数即启用 l3 ha 功能

l3_ha = true

最多在几个 l3 agent 上创建 ha router

max_l3_agents_per_router = 3

可创建 ha router 的最少正常运行的 l3 agnet 数量

min_l3_agents_per_router = 2

vrrp 广播网络

l3_ha_net_cidr = 169.254.192.0/18

”router_distributed “参数本身的含义是普通用户创建路由器时,是否默认创建 dvr;此

参数默认值为“false”,这里采用 vrrp 模式,可注释此参数

虽然此参数在 mitaka(含)版本后,可与 l3_ha 参数同时打开,但设置 dvr 模式还同

时需要设置网络节点与计算节点的 l3_agent.ini 与 ml2_conf.ini 文件

router_distributed = true

dhcp 高可用,在 3 个网络节点各生成 1 个 dhcp 服务器

dhcp_agents_per_network = 3

前端采用 haproxy 时,服务连接 rabbitmq 会出现连接超时重连的情况,可通过各服务

与 rabbitmq 的日志查看;

transport_url = rabbit://openstack:rabbitmq_pass@controller:5673

rabbitmq 本身具备集群机制,官方文档建议直接连接 rabbitmq 集群;但采用此方式时

服务启动有时会报错,原因不明;如果没有此现象,强烈建议连接 rabbitmq 直接对接集群 而非通过前端 haproxy transport_url=rabbit://openstack:rabbitmq_pass@controller01:5672,controller02:5672,contro ller03:5672 [agent] [cors] [database] connection = mysql+pymysql://neutron:neutron_dbpass@controller/neutron [keystone_authtoken] auth_uri = http://controller:5000 auth_url = http://controller:35357 memcached_servers = controller01:11211,controller:11211,controller:11211 auth_type = password project_domain_name = default user_domain_name = default project_name = service username = neutron password = neutron_pass [matchmaker_redis] [nova] auth_url = http://controller:35357 auth_type = password project_domain_name = default user_domain_name = default region_name = RegionTest project_name = service username = nova password = nova_pass [oslo_concurrency] lock_path = /var/lib/neutron/tmp [oslo_messaging_amqp] [oslo_messaging_kafka] [oslo_messaging_notifications] [oslo_messaging_rabbit] [oslo_messaging_zmq] [oslo_middleware] [oslo_policy] [quotas] [ssl] 5. 配置 ml2_conf.ini

在全部控制节点操作,以 controller01 节点为例;

ml2_conf.ini 文件的权限:root:neutron

[root@controller01 ~]# cp /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugins/ml2/ml2_conf.ini.bak [root@controller01 ~]# egrep -v "$|#" /etc/neutron/plugins/ml2/ml2_conf.ini [DEFAULT] [l2pop] [ml2] type_drivers = flat,vlan,vxlan

ml2 mechanism_driver 列表,l2population 对 gre/vxlan 租户网络有效

mechanism_drivers = linuxbridge,l2population

可同时设置多种租户网络类型,第一个值是常规租户创建网络时的默认值,同时也

默认是 master router 心跳信号的传递网络类型 tenant_network_types = vlan,vxlan,flat extension_drivers = port_security [ml2_type_flat]

指定 flat 网络类型名称为”external”,”*”表示任意网络,空值表示禁用 flat 网络

flat_networks = external [ml2_type_geneve] [ml2_type_gre] [ml2_type_vlan]

指定 vlan 网络类型的网络名称为”vlan”;如果不设置 vlan id 则表示不受限

network_vlan_ranges = vlan:3001:3500 [ml2_type_vxlan] vni_ranges = 10001:20000 [securitygroup] enable_ipset = true

服务初始化调用 ml2_conf.ini 中的配置,但指向/etc/neutron/olugin.ini 文件

[root@controller01 ~]# ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini 6. 配置 linuxbridge_agent.ini 1)配置 linuxbridge_agent.ini

在全部控制节点操作,以 controller01 节点为例;

linuxbridge_agent.ini 文件的权限:root:neutron

[root@controller01 ~]# cp /etc/neutron/plugins/ml2/linuxbridge_agent.ini /etc/neutron/plugins/ml2/linuxbridge_agent.ini.bak [root@controller01 ~]# egrep -v "$|#" /etc/neutron/plugins/ml2/linuxbridge_agent.ini [DEFAULT] [agent] [linux_bridge]

网络类型名称与物理网卡对应,这里 flat external 网络对应规划的 eth1,vlan 租户网

络对应规划的 eth3,在创建相应网络时采用的是网络名称而非网卡名称;

需要明确的是物理网卡是本地有效,根据主机实际使用的网卡名确定;

另有” bridge_mappings”参数对应网桥

physical_interface_mappings = external:eth1,vlan:eth3 [network_log] [securitygroup] firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver enable_security_group = true [vxlan] enable_vxlan = true

tunnel 租户网络(vxlan)vtep 端点,这里对应规划的 eth2(的地址),根据节点做相

应修改 local_ip = 10.0.0.31 l2_population = true 2)配置内核参数

bridge:是否允许桥接;

如果“sysctl -p”加载不成功,报” No such file or directory”错误,需要加载内核模块

“br_netfilter”;

命令“modinfo br_netfilter”查看内核模块信息;

命令“modprobe br_netfilter”加载内核模块

[root@controller01 ~]# echo "# bridge" >> /etc/sysctl.conf [root@controller01 ~]# echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf [root@controller01 ~]# echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf [root@controller01 ~]# sysctl -p 7. 配置 l3_agent.ini(self-networking)

在全部控制节点操作,以 controller01 节点为例;

l3_agent.ini 文件的权限:root:neutron

[root@controller01 ~]# cp /etc/neutron/l3_agent.ini /etc/neutron/l3_agent.ini.bak [root@controller01 ~]# egrep -v "$|#" /etc/neutron/l3_agent.ini [DEFAULT] interface_driver = linuxbridge [agent] [ovs] 8. 配置 dhcp_agent.ini

在全部控制节点操作,以 controller01 节点为例;

使用 dnsmasp 提供 dhcp 服务;

dhcp_agent.ini 文件的权限:root:neutron

[root@controller01 ~]# cp /etc/neutron/dhcp_agent.ini /etc/neutron/dhcp_agent.ini.bak [root@controller01 ~]# egrep -v "$|#" /etc/neutron/dhcp_agent.ini [DEFAULT] interface_driver = linuxbridge dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq enable_isolated_metadata = true [agent] [ovs] 9. 配置 metadata_agent.ini

在全部控制节点操作,以 controller01 节点为例;

metadata_proxy_shared_secret:与/etc/nova/nova.conf 文件中参数一致;

metadata_agent.ini 文件的权限:root:neutron

[root@controller01 ~]# cp /etc/neutron/metadata_agent.ini /etc/neutron/metadata_agent.ini.bak [root@controller01 ~]# egrep -v "$|#" /etc/neutron/metadata_agent.ini [DEFAULT] nova_metadata_host = controller metadata_proxy_shared_secret = neutron_metadata_secret [agent] [cache] 10. 配置 nova.conf

在全部控制节点操作,以 controller01 节点为例;

配置只涉及 nova.conf 的”[neutron]”字段;

metadata_proxy_shared_secret:与/etc/neutron/metadata_agent.ini 文件中参数一致

[root@controller01 ~]# vim /etc/nova/nova.conf [neutron] url = http://controller:9696 auth_url = http://controller:35357 auth_type = password project_domain_name = default user_domain_name = default region_name = RegionTest project_name = service username = neutron password = neutron_pass service_metadata_proxy = true metadata_proxy_shared_secret = neutron_metadata_secret 11. 同步 neutron 数据库

任意控制节点操作;

[root@controller01 ~]# su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron

验证

[root@controller01 ~]# mysql -h controller01 -u neutron -pneutron_dbpass -e "use neutron;show tables;" 12. 启动服务

全部控制节点操作;

变更 nova 配置文件,首先需要重启 nova 服务

[root@controller01 ~]# systemctl restart openstack-nova-api.service

开机启动

[root@controller01 ~]# systemctl enable neutron-server.service \ neutron-linuxbridge-agent.service \ neutron-l3-agent.service \ neutron-dhcp-agent.service \ neutron-metadata-agent.service

启动

[root@controller01 ~]# systemctl restart neutron-server.service [root@controller01 ~]# systemctl restart neutron-linuxbridge-agent.service [root@controller01 ~]# systemctl restart neutron-l3-agent.service [root@controller01 ~]# systemctl restart neutron-dhcp-agent.service [root@controller01 ~]# systemctl restart neutron-metadata-agent.service 13. 验证 [root@controller01 ~]# . admin-openrc

查看加载的扩展服务

[root@controller01 ~]# openstack extension list --network

查看 agent 服务

[root@controller01 ~]# openstack network agent list 14. 设置 pcs 资源

在任意控制节点操作;

添加资源neutron-server,neutron-linuxbridge-agent,neutron-l3-agent,neutron-dhcp-agent

与 neutron-metadata-agent [root@controller01 ~]# pcs resource create neutron-server systemd:neutron-server --clone interleave=true [root@controller01 ~]# pcs resource create neutron-linuxbridge-agent systemd:neutron-linuxbridge-agent --clone interleave=true [root@controller01 ~]# pcs resource create neutron-l3-agent systemd:neutron-l3-agent --clone interleave=true [root@controller01 ~]# pcs resource create neutron-dhcp-agent systemd:neutron-dhcp-agent --clone interleave=true [root@controller01 ~]# pcs resource create neutron-metadata-agent systemd:neutron-metadata-agent --clone interleave=true

查看 pcs 资源

[root@controller01 ~]# pcs resource 11、Horizon 集群

  1. 安装 dashboard

在全部控制节点安装 dashboard 服务,以 controller01 节点为例

[root@controller01 ~]# yum install openstack-dashboard -y 2. 配置 local_settings

在全部控制节点操作,以 controller01 节点为例;

注意 local_settings 文件的权限:root:apache

[root@controller01 ~]# cp /etc/openstack-dashboard/local_settings /etc/openstack-dashboard/local_settings.bak

列出修改处的行数

[root@controller01 ~]# vim /etc/openstack-dashboard/local_settings

允许所有主机访问

ALLOWED_HOSTS = ['*', 'localhost']

强制使用相应版本的 api

OPENSTACK_API_VERSIONS = {

"data-processing": 1.1,

"identity": 3, "image": 2, "volume": 2,

"compute": 2,

}

在多域模式运行时开启,登陆时除账号/密码外还需要输入域

OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True

取消注释

OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = 'Default'

取消 158~163 行注释,并使用 memcached 集群

CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': 'controller01:11211,controller02:11211,controller03:11211', }, }

注释 165~169 行

#CACHES = {

'default': {

'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',

},

#}

监听地址使用 vip;

keystone 认证使用 v3;

设置通过 dashboard 创建的用户具有”user”角色权限,”user”角色在 keystone 章节已创

建 OPENSTACK_HOST = "controller" OPENSTACK_KEYSTONE_URL = "http://%s:5000/v3" % OPENSTACK_HOST OPENSTACK_KEYSTONE_DEFAULT_ROLE = "user"

修改时区

TIME_ZONE = "Asia/Shanghai" 3. 配置 openstack-dashboard.conf

在全部控制节点操作;

bug: https://bugs.launchpad.net/horizon/+bug/1708655,此问题会导致 dashboard 网页挂

赋权,在第 3 行后新增” WSGIApplicationGroup %{GLOBAL}”

[root@controller01 ~]# cp /etc/httpd/conf.d/openstack-dashboard.conf /etc/httpd/conf.d/openstack-dashboard.conf.bak [root@controller01 ~]# sed -i '3a WSGIApplicationGroup\ %{GLOBAL}' /etc/httpd/conf.d/openstack-dashboard.conf 4. 启动服务

全部控制节点操作;

[root@controller01 ~]# systemctl restart httpd.service memcached.service 5. 验证 登陆: http://172.30.200.30/dashboard 域/账号/密码:default/admin/admin_pass,或:default/demo/demo_pass 登陆页: 系统信息-服务: 系统信息-计算服务: 系统信息-网络服务: 12、Cinder 控制节点集群

  1. 创建 cinder 数据库

在任意控制节点创建数据库,后台数据自动同步,以 controller01 节点为例;

[root@controller01 ~]# mysql -uroot -pmysql_pass MariaDB [(none)]> CREATE DATABASE cinder; MariaDB [(none)]> GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' IDENTIFIED BY 'cinder_dbpass'; MariaDB [(none)]> GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' IDENTIFIED BY 'cinder_dbpass'; MariaDB [(none)]> flush privileges; MariaDB [(none)]> exit; 2. 创建 cinder-api

在任意控制节点操作,以 controller01 节点为例;

调用 cinder 服务需要认证信息,加载环境变量脚本即可

[root@controller01 ~]# . admin-openrc 1)创建 cinder 用户

service 项目已在 glance 章节创建;

neutron 用户在”default” domain 中

[root@controller01 ~]# openstack user create --domain default --password=cinder_pass cinder 2)cinder 赋权

为 cinder 用户赋予 admin 权限

[root@controller01 ~]# openstack role add --project service --user cinder admin 3)创建 cinder 服务实体

cinder 服务实体类型”volume”;

创建 v2/v3 两个服务实体

[root@controller01 ~]# openstack service create --name cinderv2 --description "OpenStack Block Storage" volumev2 [root@controller01 ~]# openstack service create --name cinderv3 --description "OpenStack Block Storage" volumev3 4)创建 cinder-api

注意--region 与初始化 admin 用户时生成的 region 一致;

api 地址统一采用 vip,如果 public/internal/admin 分别使用不同的 vip,请注意区分;

cinder-api 服务类型为 volume;

cinder-api 后缀为用户 project-id,可通过”openstack project list”查看

v2 public api

[root@controller01 ~]# openstack endpoint create --region RegionTest volumev2 public http://controller:8776/v2/%\(project_id\)s

v2 internal api

[root@controller01 ~]# openstack endpoint create --region RegionTest volumev2 internal http://controller:8776/v2/%\(project_id\)s

v2 admin api

[root@controller01 ~]# openstack endpoint create --region RegionTest volumev2 admin http://controller:8776/v2/%\(project_id\)s

v2 admin api

[root@controller01 ~]# openstack endpoint create --region RegionTest volumev2 admin http://controller:8776/v2/%\(project_id\)s# v3 public api [root@controller01 ~]# openstack endpoint create --region RegionTest volumev3 public http://controller:8776/v3/%\(project_id\)s

v3 internal api

[root@controller01 ~]# openstack endpoint create --region RegionTest volumev3 internal http://controller:8776/v3/%\(project_id\)s

v3 admin api

[root@controller01 ~]# openstack endpoint create --region RegionTest volumev3 admin http://controller:8776/v3/%\(project_id\)s 3. 安装 cinder

在全部控制节点安装 cinder 服务,以 controller01 节点为例

[root@controller01 ~]# yum install openstack-cinder -y 4. 配置 cinder.conf

在全部控制节点操作,以 controller01 节点为例;

注意”my_ip”参数,根据节点修改;

注意 cinder.conf 文件的权限:root:cinder

[root@controller01 ~]# cp /etc/cinder/cinder.conf /etc/cinder/cinder.conf.bak [root@controller01 ~]# egrep -v "$|#" /etc/cinder/cinder.conf [DEFAULT] state_path = /var/lib/cinder my_ip = 10.32.24.168 glance_api_servers = http://controller:9292 auth_strategy = keystone osapi_volume_listen = $my_ip osapi_volume_listen_port = 8776 log_dir = /var/log/cinder

前端采用 haproxy 时,服务连接 rabbitmq 会出现连接超时重连的情况,可通过各服务

与 rabbitmq 的日志查看;

transport_url = rabbit://openstack:rabbitmq_pass@controller:5673

rabbitmq 本身具备集群机制,官方文档建议直接连接 rabbitmq 集群;但采用此方式时

服务启动有时会报错,原因不明;如果没有此现象,强烈建议连接 rabbitmq 直接对接集群 而非通过前端 haproxy transport_url=rabbit://openstack:rabbitmq_pass@controller01:5672,controller02:5672,contro ller03:5672 [backend] [backend_defaults] [barbican] [brcd_fabric_example] [cisco_fabric_example] [coordination] [cors] [database] connection = mysql+pymysql://cinder:cinder_dbpass@controller/cinder [fc-zone-manager] [healthcheck] [key_manager] [keystone_authtoken] www_authenticate_uri = http://controller:5000 auth_url = http://controller:35357 memcached_servers = controller01:11211,controller02:11211,controller03:11211 auth_type = password project_domain_id = default user_domain_id = default project_name = service username = cinder password = cinder_pass [matchmaker_redis] [nova] [oslo_concurrency] lock_path = $state_path/tmp [oslo_messaging_amqp] [oslo_messaging_kafka] [oslo_messaging_notifications] [oslo_messaging_rabbit] [oslo_messaging_zmq] [oslo_middleware] [oslo_policy] [oslo_reports] [oslo_versionedobjects] [profiler] [service_user] [ssl] [vault] 5. 配置 nova.conf

在全部控制节点操作,以 controller01 节点为例;

配置只涉及 nova.conf 的”[cinder]”字段;

加入对应 regiong

[root@controller01 ~]# vim /etc/nova/nova.conf [cinder] os_region_name=RegionTest 6. 同步 cinder 数据库

任意控制节点操作;

忽略部分”deprecation”信息

[root@controller01 ~]# su -s /bin/sh -c "cinder-manage db sync" cinder

验证

[root@controller01 ~]# mysql -h controller -ucinder -pcinder_dbpass -e "use cinder;show tables;" 7. 启动服务

全部控制节点操作;

变更 nova 配置文件,首先需要重启 nova 服务

[root@controller01 ~]# systemctl restart openstack-nova-api.service

开机启动

[root@controller01 ~]# systemctl enable openstack-cinder-api.service openstack-cinder-scheduler.service

启动

[root@controller01 ~]# systemctl restart openstack-cinder-api.service [root@controller01 ~]# systemctl restart openstack-cinder-scheduler.service 8. 验证 [root@controller01 ~]# . admin-openrc

查看 agent 服务;

或:cinder service-list

[root@controller01 ~]# openstack volume service list 9. 设置 pcs 资源

在任意控制节点操作;

添加资源 cinder-api 与 cinder-scheduler

[root@controller01 ~]# pcs resource create openstack-cinder-api systemd:openstack-cinder-api --clone interleave=true [root@controller01 ~]# pcs resource create openstack-cinder-scheduler systemd:openstack-cinder-scheduler --clone interleave=true

cinder-api 与 cinder-scheduler 以 active/active 模式运行;

openstack-nova-volume 以 active/passive 模式运行

查看资源

[root@controller01 ~]# pcs resource 13、Nova 计算节点

  1. 安装 nova-compute

在全部计算节点安装 nova-compute 服务,以 compute01 节点为例

[root@compute01 ~]# yum install python-openstackclient openstack-utils openstack-selinux -y [root@compute01 ~]# yum install openstack-nova-compute -y 2. 配置 nova.conf

在全部计算节点操作,以 computer01 节点为例;

注意”my_ip”参数,根据节点修改;

注意 nova.conf 文件的权限:root:nova

[root@compute01 ~]# cp /etc/nova/nova.conf /etc/nova/nova.conf.bak [root@compute01 ~]# egrep -v "$|#" /etc/nova/nova.conf [DEFAULT] my_ip=172.30.200.41 use_neutron=true firewall_driver=nova.virt.firewall.NoopFirewallDriver enabled_apis=osapi_compute,metadata

前端采用 haproxy 时,服务连接 rabbitmq 会出现连接超时重连的情况,可通过各服务

与 rabbitmq 的日志查看;

transport_url=rabbit://openstack:rabbitmq_pass@controller:5673

rabbitmq 本身具备集群机制,官方文档建议直接连接 rabbitmq 集群;但采用此方式时

服务启动有时会报错,原因不明;如果没有此现象,强烈建议连接 rabbitmq 直接对接集群 而非通过前端 haproxy transport_url=rabbit://openstack:rabbitmq_pass@controller01:5672,controller02:5672,contro ller03:5672 [api] auth_strategy=keystone [api_database] [barbican] [cache] [cells] [cinder] [compute] [conductor] [console] [consoleauth] [cors] [crypto] [database] [devices] [ephemeral_storage_encryption] [filter_scheduler] [glance] api_servers=http://controller:9292 [guestfs] [healthcheck] [hyperv] [ironic] [key_manager] [keystone] [keystone_authtoken] auth_uri = http://controller:5000 auth_url = http://controller:35357 memcached_servers = controller01:11211,controller02:11211,controller03:11211 auth_type = password project_domain_name = default user_domain_name = default project_name = service username = nova password = nova_pass [libvirt]

通过“egrep -c '(vmx|svm)' /proc/cpuinfo”命令查看主机是否支持硬件加速,返回 1 或者

更大的值表示支持,返回 0 表示不支持;

支持硬件加速使用”kvm”类型,不支持则使用”qemu”类型;

一般虚拟机不支持硬件加速

virt_type=qemu [matchmaker_redis] [metrics] [mks] [neutron] [notifications] [osapi_v21] [oslo_concurrency] lock_path=/var/lib/nova/tmp [oslo_messaging_amqp] [oslo_messaging_kafka] [oslo_messaging_notifications] [oslo_messaging_rabbit] [oslo_messaging_zmq] [oslo_middleware] [oslo_policy] [pci] [placement] os_region_name=RegionTest auth_type=password auth_url=http://controller:35357/v3 project_name=service project_domain_name=Default username=placement user_domain_name=Default password=placement_pass [quota] [rdp] [remote_debug] [scheduler] [serial_console] [service_user] [spice] [upgrade_levels] [vault] [vendordata_dynamic_auth] [vmware] [vnc] enabled=true vncserver_listen=0.0.0.0 vncserver_proxyclient_address=$my_ip

因某些未做主机绑定的客户端不能访问”controller”名字,改为使用具体的 ip 地址

novncproxy_base_url= http://172.30.200.30:6080/vnc_auto.html [workarounds] [wsgi] [xenserver] [xvp] 3. 启动服务

全部计算节点操作;

开机启动

[root@compute01 ~]# systemctl enable libvirtd.service openstack-nova-compute.service

启动

[root@compute01 ~]# systemctl restart libvirtd.service [root@compute01 ~]# systemctl restart openstack-nova-compute.service 查看状态 [root@compute01 ~]# systemctl status libvirtd.service [root@compute01 ~]# systemctl status openstack-nova-compute.service 4. 向 cell 数据库添加计算节点

在任意控制节点操作

[root@controller01 ~]# . admin-openrc

确认数据库中含有主机

[root@controller01 ~]# openstack compute service list --service nova-compute 1)手工发现计算节点

手工发现计算节点主机,即添加到 cell 数据库

[root@controller01 ~]# su -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova 2)自动发现计算节点

在全部控制节点操作;

为避免新加入计算节点时,手动执行注册操作”nova-manage cell_v2 discover_hosts”,

可设置控制节点定时自动发现主机;

涉及控制节点 nova.conf 文件的[scheduler]字段;

如下设置自动发现时间为 5min,可根据实际环境调节

[root@controller01 ~]# vim /etc/nova/nova.conf [scheduler] discover_hosts_in_cells_interval=300

重启 nova 服务,配置生效

[root@controller01 ~]# systemctl restart openstack-nova-api.service 5. 验证 登陆 dashboard,管理员-->计算-->虚拟机管理器 如果已注册成功,在"虚拟机管理器"标签下可发现计算节点,并能展示出各计算节点的 资源;如果未注册或注册失败,则"虚拟机管理器"标签下无主机。 14、Neutron 计算节点

  1. 安装 neutron-linuxbridge

在全部计算节点安装 neutro-linuxbridge 服务,以 compute01 节点为例

[root@compute01 ~]# yum install openstack-neutron-linuxbridge ebtables ipset -y 2. 配置 neutron.conf

在全部计算节点操作,以 computer01 节点为例;

注意”bind_host”参数,根据节点修改;

注意 neutron.conf 文件的权限:root:neutron

[root@compute01 ~]# cp /etc/neutron/neutron.conf /etc/neutron/neutron.conf.bak [root@compute01 ~]# egrep -v "$|#" /etc/neutron/neutron.conf [DEFAULT] state_path = /var/lib/neutron bind_host = 172.30.200.41 auth_strategy = keystone

前端采用 haproxy 时,服务连接 rabbitmq 会出现连接超时重连的情况,可通过各服务

与 rabbitmq 的日志查看;

transport_url = rabbit://openstack:rabbitmq_pass@controller:5673

rabbitmq 本身具备集群机制,官方文档建议直接连接 rabbitmq 集群;但采用此方式时

服务启动有时会报错,原因不明;如果没有此现象,强烈建议连接 rabbitmq 直接对接集群 而非通过前端 haproxy transport_url=rabbit://openstack:rabbitmq_pass@controller01:5672,controller02:5672,contro ller03:5672 [agent] [cors] [database] [keystone_authtoken] www_authenticate_uri = http://controller:5000 auth_url = http://controller:35357 memcached_servers = controller01:11211,controller:11211,controller:11211 auth_type = password project_domain_name = default user_domain_name = default project_name = service username = neutron password = neutron_pass [matchmaker_redis] [nova] [oslo_concurrency] lock_path = $state_path/lock [oslo_messaging_amqp] [oslo_messaging_kafka] [oslo_messaging_notifications] [oslo_messaging_rabbit] [oslo_messaging_zmq] [oslo_middleware] [oslo_policy] [quotas] [ssl] 3. 配置 linuxbridge_agent.ini 1)配置 linuxbridgr_agent.ini

在全部计算节点操作,以 compute01 节点为例;

linuxbridge_agent.ini 文件的权限:root:neutron

[root@compute01 ~]# cp /etc/neutron/plugins/ml2/linuxbridge_agent.ini /etc/neutron/plugins/ml2/linuxbridge_agent.ini.bak [root@compute01 ~]# egrep -v "$|#" /etc/neutron/plugins/ml2/linuxbridge_agent.ini [DEFAULT] [agent] [linux_bridge]

网络类型名称与物理网卡对应,这里 vlan 租户网络对应规划的 eth3;

需要明确的是物理网卡是本地有效,需要根据主机实际使用的网卡名确定;

另有”bridge_mappings”参数对应网桥

physical_interface_mappings = vlan:eth3 [network_log] [securitygroup] firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver enable_security_group = true [vxlan] enable_vxlan = true

tunnel 租户网络(vxlan)vtep 端点,这里对应规划的 eth2(的地址),根据节点做相

应修改 local_ip = 10.0.0.41 l2_population = true 2)配置内核参数

bridge:是否允许桥接;

如果“sysctl -p”加载不成功,报” No such file or directory”错误,需要加载内核模块

“br_netfilter”;

命令“modinfo br_netfilter”查看内核模块信息;

命令“modprobe br_netfilter”加载内核模块

[root@compute01 ~]# echo "# bridge" >> /etc/sysctl.conf [root@compute01 ~]# echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf [root@compute01 ~]# echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf [root@compute01 ~]# sysctl -p 4. 配置 nova.conf

在全部计算节点操作,以 compute01 节点为例;

配置只涉及 nova.conf 的”[neutron]”字段

[root@compute ~]# vim /etc/nova/nova.conf [neutron] url=http://controller:9696 auth_type=password auth_url=http://controller:35357 project_name=service project_domain_name=default username=neutron user_domain_name=default password=neutron_pass region_name=RegionTest 5. 启动服务

nova.conf 文件已变更,首先需要重启全部计算节点的 nova 服务

[root@compute01 ~]# systemctl restart openstack-nova-compute.service

开机启动

[root@compute01 ~]# systemctl enable neutron-linuxbridge-agent.service

启动

[root@compute01 ~]# systemctl restart neutron-linuxbridge-agent.service 6. 验证

任意控制节点(或具备客户端的节点)操作

[root@controller01 ~]# . admin-openrc

查看 neutron 相关的 agent;

或:openstack network agent list --agent-type linux-bridge

[root@controller01 ~]# openstack network agent list 15、Cinder 计算节点 在采用ceph或其他商业/非商业后端存储时,建议将cinder-volume服务部署在控制节点, 通过 pacemaker 将服务运行在 active/passive 模式。 以下配置文件可供参考,但部署模式(经验证后发现)并不是"最佳"实践。

  1. 安装 cinder

在全部计算点安装 cinder 服务,以 compute01 节点为例

[root@compute02 ~]# yum install -y openstack-cinder targetcli python-keystone 2. 配置 cinder.conf

在全部计算点操作,以 compute01 节点为例;

注意”my_ip”参数,根据节点修改;

注意 cinder.conf 文件的权限:root:cinder

[root@compute01 ~]# cp /etc/cinder/cinder.conf /etc/cinder/cinder.conf.bak [root@compute01 ~]# egrep -v "$|#" /etc/cinder/cinder.conf [DEFAULT] state_path = /var/lib/cinder my_ip = 172.30.200.41 glance_api_servers = http://controller:9292 auth_strategy = keystone

简单的将 cinder 理解为存储的机头,后端可以采用 nfs,ceph 等共享存储

enabled_backends = ceph

前端采用 haproxy 时,服务连接 rabbitmq 会出现连接超时重连的情况,可通过各服务

与 rabbitmq 的日志查看;

transport_url = rabbit://openstack:rabbitmq_pass@controller:5673

rabbitmq 本身具备集群机制,官方文档建议直接连接 rabbitmq 集群;但采用此方式时

服务启动有时会报错,原因不明;如果没有此现象,强烈建议连接 rabbitmq 直接对接集群 而非通过前端 haproxy transport_url=rabbit://openstack:rabbitmq_pass@controller01:5672,controller02:5672,contro ller03:5672 [backend] [backend_defaults] [barbican] [brcd_fabric_example] [cisco_fabric_example] [coordination] [cors] [database] connection = mysql+pymysql://cinder:cinder_dbpass@controller/cinder [fc-zone-manager] [healthcheck] [key_manager] [keystone_authtoken] www_authenticate_uri = http://controller:5000 auth_url = http://controller:35357 memcached_servers = controller01:11211,controller02:11211,controller03:11211 auth_type = password project_domain_id = default user_domain_id = default project_name = service username = cinder password = cinder_pass [matchmaker_redis] [nova] [oslo_concurrency] lock_path = $state_path/tmp [oslo_messaging_amqp] [oslo_messaging_kafka] [oslo_messaging_notifications] [oslo_messaging_rabbit] [oslo_messaging_zmq] [oslo_middleware] [oslo_policy] [oslo_reports] [oslo_versionedobjects] [profiler] [service_user] [ssl] [vault] 3. 启动服务

在全部计算点操作;

开机启动

[root@compute01 ~]# systemctl enable openstack-cinder-volume.service target.service

启动

[root@compute01 ~]# systemctl restart openstack-cinder-volume.service [root@compute01 ~]# systemctl restart target.service 4. 验证

在任意控制节点(或具备客户端的节点)操作

[root@controller01 ~]# . admin-openrc

查看 agent 服务;

或:cinder service-list;

此时后端存储服务为 ceph,但 ceph 相关服务尚未启用并集成到 cinder-volume,导致

cinder-volume 服务的状态也是”down” [root@controller01 ~]# openstack volume service list 16、分布式存储 Ceph

  1. 设置 yum 源

在全部控制与计算节点设置 epel 与 ceph yum 源(base yum 源已更新),以 controller01

节点为例;

epel: http://mirrors.aliyun.com/repo/

[root@controller01 ~]# wget -O /etc/yum.repos.d/epel-7.repo  http://mirrors.aliyun.com/repo/epel-7.repo

ceph: http://mirrors.aliyun.com/ceph/

编辑 ceph.repo 文件,使用 luminous 版本

[root@controller01 ~]# vim /etc/yum.repos.d/ceph.repo [ceph] name=ceph baseurl= http://mirrors.aliyun.com/ceph/rpm-luminous/el7/x86_64/ enabled=1 gpgcheck=1 type=rpm-md gpgkey= http://mirrors.aliyun.com/ceph/keys/release.asc [ceph-noarch] name=cephnoarch baseurl= http://mirrors.aliyun.com/ceph/rpm-luminous/el7/noarch/ enabled=1 gpgcheck=1 type=rpm-md gpgkey= http://mirrors.aliyun.com/ceph/keys/release.asc [ceph-source] name=ceph-source baseurl= http://mirrors.aliyun.com/ceph/rpm-luminous/el7/SRPMS/ enabled=1 gpgcheck=1 type=rpm-md gpgkey= http://mirrors.aliyun.com/ceph/keys/release.asc# 重新加载 yum 源 [root@controller01 ~]# yum clean all [root@controller01 ~]# yum makecache

查看 yum 源

[root@controller01 ~]# yum repolist 2. 环境 基础环境,如 hosts,时间同步 ntp,开放端口 iptables 等相关操作 3. 创建用户 1)创建用户 [root@controller01 ~]# useradd -d /home/ceph -m cephde [root@controller01 ~]# passwd cephde New password: storage_pass Retype new password: storage_pass

修改 visudo 文件,使 cephde 用户在 sudo 列表中;

在 92 行” root ALL=(ALL) ALL”下新增一行:” cephde ALL=(ALL)

ALL” [root@controller01 ~]# visudo cephde ALL=(ALL) ALL 2)用户赋权

设置 cephde 用户具备无密码 sudo(root)权限;

切换到 cephde 用户下操作

[root@controller01 ~]# su - cephde [cephde@controller01 ~]$ echo "cephde ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/cephde [sudo] password for cephde:storage_pass [cephde@controller01 ~]$ sudo chmod 0440 /etc/sudoers.d/cephde 4. 设置 ssh 免密登陆 1)生成秘钥

ceph-deploy 不支持密码输入,需要在管理控制节点生产 ssh 秘钥,并将公钥分发到各

ceph 节点;

在用户 cephde 下生成秘钥,不能使用 sudo 或 root 用户;

默认在用户目录下生成~/.ssh 目录,含生成的秘钥对;

“Enter passphrase”时,回车,口令为空;

另外 3 个控制节点均设置为 ceph 管理节点,应该使 3 各控制管理节点都可以 ssh 免

密登陆到其他所有控制与存储节点 [root@controller01 ~]# su - cephde [cephde@controller01 ~]$ ssh-keygen -t rsa Enter file in which to save the key (/home/ceph/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: 2)分发密钥

前提是各控制与存储节点已生成相关用户;

初次连接其他节点时需要确认;

首次分发公钥需要密码;

分发成功后,在~/.ssh/下生成 known_hosts 文件,记录相关登陆信息;

以 controller01 节点免密登陆 controller02 节点为例;另外 3 个控制节点均设置为 ceph

管理节点,应该使 3 各控制管理节点都可以 ssh 免密登陆到其他所有控制与存储节点 [cephde@controller01 ~]$ ssh-copy-id cephde@controller02 Are you sure you want to continue connecting (yes/no)? yes cephde@controller02's password: 3)设置环境变量(optional)

在 root 账号主目录下,生成 ~/.ssh/config 文件,这样在控制管理节点上执

行”ceph-deploy”时可不切换用户或指定”--username {username}”; [root@controller01 ~]# cat ~/.ssh/config

ceph-deploy

Host controller02 Hostname controller02 User cephde Host controller03 Hostname controller03 User cephde Host compute01 Hostname compute01 User cephde Host compute02 Hostname compute02 User cephde Host compute03 Hostname compute03 User cephde 5. 安装 ceph-deploy

在规划的全部控制管理节点安装 ceph-deploy 工具,以 controller01 节点为例

[root@controller01 ~]# yum install ceph-deploy -y 6. 创建 ceph 集群 1)创建集群

在 cephde 账户下操作,切忌使用 sudo 操作;

在管理节点上生成一个目录用于存放集群相关配置文件;

[root@controller01 ~]# su - cephde [cephde@controller01 ~]$ mkdir cephcluster

后续 ceph-deploy 相关操作全部在所创建的目录执行;

将规划中的 MON(monitor)节点纳入集群,即创建集群

[cephde@controller01 ~]$ cd ~/cephcluster/ [cephde@controller01 cephcluster]$ ceph-deploy new controller01 controller02 controller03 2)修改集群配置文件(optional)

生成集群后在集群目录下生成 3 个文件,其中 ceph.conf 即是配置文件;

默认可不修改,为使服务按规划启动,可做适当修改;

以下红色字体部分是在默认生成的 conf 文件上新增的配置

[cephde@controller01 cephcluster]$ cat ceph.conf [global] fsid = 9b606fef-1cde-4d4c-b269-90079d1d45dd mon_initial_members = controller01, controller02, controller03 mon_host = 10.32.24.168,172.30.200.32,172.30.200.33 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx

public network:前端 mon 网络,client 访问网络;确保 public network 与 mon_host 在

相同网段,否则初始化时可能会有错误;

cluster network:后端 osd 心跳,数据/流复制恢复等网络

public network = 172.30.200.0/24 cluster network = 10.0.0.0/24

默认的副本数为 3,实验环境变更为 2

osd pool default size = 2

默认保护机制不允许删除 pool,根据情况设置

mon_allow_pool_delete = true 7. 安装 ceph

在全部控制管理与存储节点安装 ceph;

理论上在控制节点的 ceph 集群目录使用 ceph-deploy 可统一安装,命令:ceph-deploy

install controller01 controller02 controller03 compute01 compute02 compute03;

但由于网速原因大概率会失败,可在各存储节点独立安装 ceph 与 ceph-radosgw,以

controller01 节点为例 [root@controller01 ~]# yum install -y ceph ceph-radosgw

查看版本

[root@controller01 ~]# ceph -v 8. 初始化 ceph_mon

在控制管理节点初始化 monitor

[cephde@controller01 cephcluster]$ ceph-deploy mon create-initial

初始化完成后,在集群目录下新增多个秘钥文件

[cephde@controller01 cephcluster]$ ls -l

查看状态

[cephde@controller01 cephcluster]$ sudo systemctl status ceph-mon@controller01 9. 分发 ceph.conf 与秘钥

分发 ceph 配置文件与秘钥到其他控制管理节点与存储节点;

注意分发节点本身也需要包含在内,默认没有秘钥文件,需要分发;

如果被分发节点已经配置文件(统一变更配置文件场景),可以使用如下命令:

ceph-deploy --overwrite-conf admin xxx

分发的配置文件与秘钥在各节点/etc/ceph/目录

[cephde@controller01 cephcluster]$ ceph-deploy admin controller01 controller02 controller03 compute01 compute02 compute03 10. 安装 ceph_mgr 1)安装 mgr

luminous 版本必须安装 mgr(dashboard)

[cephde@controller01 cephcluster]$ ceph-deploy mgr create controller01:controller01_mgr controller02:controller02_mgr controller03:controller03_mgr

查看状态;

[cephde@controller01 cephcluster]$ systemctl status ceph-mgr@controller01_mgr [cephde@controller01 cephcluster]$ sudo netstat -tunlp | grep mgr 2)启动 mgr

可查看 mgr 默认开启的服务:(sudo) ceph mgr module ls;

默认 dashboard 服务在可开启列表中,但并未启动,需要手工开启

[cephde@controller01 cephcluster]$ sudo ceph mgr module enable dashboard

dashboard 服务已开启,默认监听全部地址的 tcp7000 端口;

如果需要设置 dashboard 的监听地址与端口,如下:

设置监听地址:(sudo) ceph config-key put mgr/dashboard/server_addr x.x.x.x

设置监听端口:(sudo) ceph config-key put mgr/dashboard/server_port x

[cephde@controller01 cephcluster]$ sudo netstat -tunlp | grep mgr web 登陆: http://10.32.24.168:7000/ 11. 查看集群状态

查看 monitor 状态

[cephde@controller01 cephcluster]$ sudo ceph mon stat

查看 ceph 状态:ceph health (detail),ceph -s,ceph -w 等;

状态显示 mgr 处于 active-standby 模式

[cephde@controller01 cephcluster]$ sudo ceph -s

可在各节点查看认证信息等

[cephde@controller01 cephcluster]$ sudo ceph auth list 12. 创建 osd(存储) 1)创建 osd

osd 位于存储节点,可查看存储节点磁盘状况,以 compute01 节点为例

[root@compute01 ~]# lsblk

实际创建 osd 时,可通过管理节点使用 ceph-deploy 创建;

本例中有 3 个 osd 节点,每个 osd 节点可运行 4 个 osd 进程(在 6800~7300 端口范围

内,每进程监听 1 个本地端口) [cephde@controller01 cephcluster]$ ceph-deploy osd create compute01 --data /dev/sdb [cephde@controller01 cephcluster]$ ceph-deploy osd create compute01 --data /dev/sdc [cephde@controller01 cephcluster]$ ceph-deploy osd create compute01 --data /dev/sdd [cephde@controller01 cephcluster]$ ceph-deploy osd create compute01 --data /dev/sde [cephde@controller01 cephcluster]$ ceph-deploy osd create compute02 --data /dev/sdb [cephde@controller01 cephcluster]$ ceph-deploy osd create compute02 --data /dev/sdc [cephde@controller01 cephcluster]$ ceph-deploy osd create compute02 --data /dev/sdd [cephde@controller01 cephcluster]$ ceph-deploy osd create compute02 --data /dev/sde [cephde@controller01 cephcluster]$ ceph-deploy osd create compute03 --data /dev/sdb [cephde@controller01 cephcluster]$ ceph-deploy osd create compute03 --data /dev/sdc [cephde@controller01 cephcluster]$ ceph-deploy osd create compute03 --data /dev/sdd [cephde@controller01 cephcluster]$ ceph-deploy osd create compute03 --data /dev/sde 2)查看 osd 状态

在管理节点查看

[cephde@controller01 cephcluster]$ ceph-deploy osd list compute01

在管理节点查看 osd 状态等

[cephde@controller01 cephcluster]$ sudo ceph osd stat [cephde@controller01 cephcluster]$ sudo ceph osd tree

在管理节点查看容量及使用情况

[cephde@controller01 cephcluster]$ sudo ceph df

在 osd 节点查看

[root@compute01 ~]# lsblk

ceph-osd 进程,根据启动顺序,每个 osd 进程有特定的序号

[root@compute01 ~]# systemctl status ceph-osd@0

osd 进程端口号;

或:ps aux | grep osd | grep -v grep

[root@compute01 ~]# netstat -tunlp | grep osd 或登陆 mgr_dashboard: http://10.32.24.168:7000 17、Openstack 集成 Ceph 准备 penstack 环境中,数据存储可分为临时性存储与永久性存储。 临时性存储:主要由本地文件系统提供,并主要用于 nova 虚拟机的本地系统与临时数 据盘,以及存储 glance 上传的系统镜像; 永久性存储:主要由 cinder 提供的块存储与 swift 提供的对象存储构成,以 cinder 提供 的块存储应用最为广泛,块存储通常以云盘的形式挂载到虚拟机中使用。 Openstack 中需要进行数据存储的三大项目主要是 nova 项目(虚拟机镜像文件),glance 项目(共用模版镜像)与 cinder 项目(块存储)。 下图为 cinder,glance 与 nova 访问 ceph 集群的逻辑图:

  1. ceph 与 openstack 集成主要用到 ceph 的 rbd 服务,ceph 底层为 rados 存储集群,ceph 通过 librados 库实现对底层 rados 的访问;
  2. openstack 各项目客户端调用 librbd,再由 librbd 调用 librados 访问底层 rados;
  3. 实际使用中,nova 需要使用 libvirtdriver 驱动以通过 libvirt 与 qemu 调用 librbd;cinder 与 glance 可直接调用 librbd;
  4. 写入 ceph 集群的数据被条带切分成多个 object,object 通过 hash 函数映射到 pg(构 成 pg 容器池 pool),然后 pg 通过几圈 crush 算法近似均匀地映射到物理存储设备 osd (osd 是基于文件系统的物理存储设备,如 xfs,ext4 等)。
  5. 创建 pool

Ceph 默认使用 pool 的形式存储数据,pool 是对若干 pg 进行组织管理的逻辑划分,pg

里的对象被映射到不同的 osd,因此 pool 分布到整个集群里。

可以将不同的数据存入 1 个 pool,但如此操作不便于客户端数据区分管理,因此一

般是为每个客户端分别创建 pool。

为 cinder,nova,glance 分别创建 pool,命名为:volumes,vms,images

创建 pool,需要覆盖默认的 pg num,官方文档对 pg num 的数量有如下建议:

 http://docs.ceph.com/docs/master/rados/operations/placement-groups/;

同时综 合考 量全部 pool 的 pg num 总 和的上 限: pg num * 副 本数 量 <

mon_max_pg_per_osd(默认 200) * num_in_osds(osd 总进程数);

pool 创建在 monitor 节点操作,以 controller01 节点为例;

这里 volumes 池是永久性存储,vms 是实例临时后端存储,images 是镜像存储

[root@controller01 ~]# su - cephde [cephde@controller01 ~]$ sudo ceph osd pool create volumes 256 [cephde@controller01 ~]$ sudo ceph osd pool create vms 256 [cephde@controller01 ~]$ sudo ceph osd pool create images 256

查看状态

[cephde@controller01 ~]$ sudo ceph pg stat [cephde@controller01 ~]$ sudo ceph osd lspools 2. 安装 Ceph 客户端

glance-api 服务所在节点需要安装 python-rbd;

这里 glance-api 服务运行在 3 个控制节点,以 controller01 节点为例

[root@controller01 ~]# yum install python-rbd -y

cinder-volume 与 nova-compute 服务所在节点需要安装 ceph-common;

这里 cinder-volume 与 nova-compute 服务运行在 3 个计算(存储)节点,以 compute01

节点为例 [root@compute01 ~]# yum install ceph-common -y 3. 授权设置 1)创建用户

ceph 默认启用 cephx authentication(见 ceph.conf),需要为 nova/cinder 与 glance 客户

端创建新的用户并授权;

可在管理节点上分别为运行 cinder-volume 与 glance-api 服务的节点创建 client.glance

与 client.cinder 用户并设置权限;

针对 pool 设置权限,pool 名对应创建的 pool

[root@controller01 ~]# ceph auth get-or-create client.cinder mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=volumes, allow rwx pool=vms, allow rx pool=images' [root@controller01 ~]# ceph auth get-or-create client.glance mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=images' 2)推送 client.glance 秘钥

将创建 client.glance 用户生成的秘钥推送到运行 glance-api 服务的节点

[root@controller01 ~]# ceph auth get-or-create client.glance | tee /etc/ceph/ceph.client.glance.keyring [root@controller01 ~]# ceph auth get-or-create client.glance | ssh root@controller02 tee /etc/ceph/ceph.client.glance.keyring [root@controller01 ~]# ceph auth get-or-create client.glance | ssh root@controller03 tee /etc/ceph/ceph.client.glance.keyring

同时修改秘钥文件的属主与用户组

[root@controller01 ~]# chown glance:glance /etc/ceph/ceph.client.glance.keyring [root@controller01 ~]# ssh root@controller02 chown glance:glance /etc/ceph/ceph.client.glance.keyring [root@controller01 ~]# ssh root@controller03 chown glance:glance /etc/ceph/ceph.client.glance.keyring 3)推送 client.cinder 秘钥(nova-volume)

将创建 client.cinder 用户生成的秘钥推送到运行 cinder-volume 服务的节点

[root@controller01 ~]# ceph auth get-or-create client.cinder | ssh root@compute01 tee /etc/ceph/ceph.client.cinder.keyring [root@controller01 ~]# ceph auth get-or-create client.cinder | ssh root@compute02 tee /etc/ceph/ceph.client.cinder.keyring [root@controller01 ~]# ceph auth get-or-create client.cinder | ssh root@compute03 tee /etc/ceph/ceph.client.cinder.keyring

同时修改秘钥文件的属主与用户组

[root@controller01 ~]# ssh root@compute01 chown cinder:cinder /etc/ceph/ceph.client.cinder.keyring [root@controller01 ~]# ssh root@compute02 chown cinder:cinder /etc/ceph/ceph.client.cinder.keyring [root@controller01 ~]# ssh root@compute03 chown cinder:cinder /etc/ceph/ceph.client.cinder.keyring 4)推送 client.cinder 秘钥(nova-compute) 这里 nova-compute 服务与 nova-volume 服务运行在相同节点,不必重复操作。 5)libvirt 秘钥 nova-compute所在节点需要将client.cinder用户的秘钥文件存储到libvirt中;当基于ceph 后端的 cinder 卷被 attach 到虚拟机实例时,libvirt 需要用到该秘钥以访问 ceph 集群;

在管理节点向计算(存储)节点推送 client.cinder 秘钥文件,生成的文件是临时性的,

将秘钥添加到 libvirt 后可删除 [root@controller01 ~]# ceph auth get-key client.cinder | ssh root@compute01 tee /etc/ceph/client.cinder.key [root@controller01 ~]# ceph auth get-key client.cinder | ssh root@compute02 tee /etc/ceph/client.cinder.key [root@controller01 ~]# ceph auth get-key client.cinder | ssh root@compute03 tee /etc/ceph/client.cinder.key

在计算(存储)节点将秘钥加入 libvirt,以 compute01 节点为例;

首先生成 1 个 uuid,全部计算(存储)节点可共用此 uuid(其他节点不用操作此步);

uuid 后续配置 nova.conf 文件时也会用到,请保持一致

[root@compute01 ~]# uuidgen

添加秘钥

[root@compute01 ~]# cd /etc/ceph [root@compute01 ceph]# touch secret.xml [root@compute01 ceph]# vim secret.xml 10744136-583f-4a9c-ae30-9bfb3515526b client.cinder secret

  1. 配置 glance-api.conf

在运行 glance-api 服务的节点修改 glance-api.conf 文件,含 3 个控制节点,以

controller01 节点为例

以下只列出涉及 glance 集成 ceph 的 section

[root@controller01 ~]# vim /etc/glance/glance-api.conf

打开 copy-on-write 功能

[DEFAULT] show_image_direct_url = True

变更默认使用的本地文件存储为 ceph rbd 存储;

注意红色字体部分前后一致

[glance_store] #stores = file,http #default_store = file #filesystem_store_datadir = /var/lib/glance/images/ stores = rbd default_store = rbd rbd_store_chunk_size = 8 rbd_store_pool = images rbd_store_user = glance rbd_store_ceph_conf = /etc/ceph/ceph.conf

变更配置文件,重启服务

[root@controller01 ~]# systemctl restart openstack-glance-api.service [root@controller01 ~]# systemctl restart openstack-glance-registry.service 2. 上传镜像

镜像上传后,默认地址为 ceph 集群(ID)的 images pool 下

[root@controller01 ~]# openstack image create "cirros-qcow2" \ --file ~/cirros-0.3.5-x86_64-disk.img \ --disk-format qcow2 --container-format bare \ --public

检查

[root@controller01 ~]# rbd ls images 3. 定义 pool 类型

images 启用后,ceph 集群状态变为:HEALTH_WARN

[root@controller01 ~]# ceph -s

使用”ceph health detail”,能给出解决办法;

未定义 pool 池类型,可定义为'cephfs', 'rbd', 'rgw'等

[root@controller01 ~]# ceph health detail

同时解决 volumes 与 vms 两个 pool 的问题

[root@controller01 ~]# ceph osd pool application enable images rbd [root@controller01 ~]# ceph osd pool application enable volumes rbd [root@controller01 ~]# ceph osd pool application enable vms rbd

查看

[root@controller01 ~]# ceph health detail [root@controller01 ~]# ceph osd pool application get images [root@controller01 ~]# ceph osd pool application get volumes [root@controller01 ~]# ceph osd pool application get vms 19、Cinder 集成 Ceph

  1. 配置 cinder.conf

cinder 利用插件式结构,支持同时使用多种后端存储;

在 cinder-volume 所在节点设置 cinder.conf 中设置相应的 ceph rbd 驱动即可;

含 3 个计算(存储)节点,以 compute01 节点为例;

以下只列出涉及 cinder 集成 ceph 的 section

[root@compute01 ~]# vim /etc/cinder/cinder.conf

后端使用 ceph 存储

[DEFAULT] enabled_backends = ceph

新增[ceph] section;

注意红色字体部分前后一致

[ceph]

ceph rbd 驱动

volume_driver = cinder.volume.drivers.rbd.RBDDriver rbd_pool = volumes rbd_ceph_conf = /etc/ceph/ceph.conf rbd_flatten_volume_from_snapshot = false rbd_max_clone_depth = 5 rbd_store_chunk_size = 4 rados_connect_timeout = -1

如果配置多后端,则“glance_api_version”必须配置在[DEFAULT] section

glance_api_version = 2 rbd_user = cinder rbd_secret_uuid = 10744136-583f-4a9c-ae30-9bfb3515526b volume_backend_name = ceph

变更配置文件,重启服务

[root@controller01 ~]# systemctl restart openstack-glance-api.service [root@controller01 ~]# systemctl restart openstack-glance-registry.service 2. 验证

查看 cinder 服务状态,cinder-volume 集成 ceph 后,状态”up”;

或:cinder service-list

[root@controller01 ~]# openstack volume service list 3. 生成 volume 1)设置卷类型

在控制节点为 cinder 的 ceph 后端存储创建对应的 type,在配置多存储后端时可区分

类型;

可通过“cinder type-list”查看

[root@controller01 ~]# cinder type-create ceph

为 ceph type 设置扩展规格,键值” volume_backend_name”,value 值”ceph”

[root@controller01 ~]# cinder type-key ceph set volume_backend_name=ceph [root@controller01 ~]# cinder extra-specs-list 2)生成 volume

生成 volume;

最后的数字”1”代表容量为 1G

[root@controller01 ~]# cinder create --volume-type ceph --name ceph-volume1 1

检查生成的 volume;

或:cinder list

[root@controller01 ~]# openstack volume list

检查 ceph 集群的 volumes pool

[root@controller01 ~]# rbd ls volumes 20、Nova 集成 Ceph

  1. 配置 ceph.conf

如果需要从 ceph rbd 中启动虚拟机,必须将 ceph 配置为 nova 的临时后端;

推荐在计算节点的配置文件中启用 rbd cache 功能;

为了便于故障排查,配置 admin socket 参数,这样每个使用 ceph rbd 的虚拟机都有 1

个 socket 将有利于虚拟机性能分析与故障解决;

相关配置只涉及全部计算节点 ceph.conf 文件的[client]与[client.cinder]字段,以

compute01 节点为例 [root@compute01 ~]# vim /etc/ceph/ceph.conf [client] rbd cache = true rbd cache writethrough until flush = true admin socket = /var/run/ceph/guests/OpenStack Queens HA 部署手册_服务器_04type.OpenStack Queens HA 部署手册_服务器_05pid.OpenStack Queens HA 部署手册_数据_06pid.log rbd concurrent management ops = 20 [client.cinder] keyring = /etc/ceph/ceph.client.cinder.keyring

创建 ceph.conf 文件中指定的 socker 与 log 相关的目录,并更改属主

[root@compute01 ~]# mkdir -p /var/run/ceph/guests/ /var/log/qemu/ [root@compute01 ~]# chown qemu:libvirt /var/run/ceph/guests/ /var/log/qemu/ 2. 配置 nova.conf

在全部计算节点配置 nova 后端使用 ceph 集群的 vms 池,以 compute01 节点为例

[root@compute01 ~]# vim /etc/nova/nova.conf [libvirt] images_type = rbd images_rbd_pool = vms images_rbd_ceph_conf = /etc/ceph/ceph.conf rbd_user = cinder

uuid 前后一致

rbd_secret_uuid = 10744136-583f-4a9c-ae30-9bfb3515526b disk_cachemodes="network=writeback" live_migration_flag="VIR_MIGRATE_UNDEFINE_SOURCE,VIR_MIGRATE_PEER2PE ER,VIR_MIGRATE_LIVE,VIR_MIGRATE_PERSIST_DEST,VIR_MIGRATE_TUNNELLED"

禁用文件注入

inject_password = false inject_key = false inject_partition = -2

虚拟机临时 root 磁盘 discard 功能,”unmap”参数在 scsi 接口类型磁盘释放后可立即

释放空间 hw_disk_discard = unmap

原有配置

virt_type=kvm

变更配置文件,重启计算服务

[root@compute01 ~]# systemctl restart libvirtd.service openstack-nova-compute.service [root@compute01 ~]# systemctl status libvirtd.service openstack-nova-compute.service 3. 配置 live-migration 1)修改/etc/libvirt/libvirtd.conf

在全部计算节点操作,以 compute01 节点为例;

以下给出 libvirtd.conf 文件的修改处所在的行 num

[root@compute01 ~]# egrep -vn "$|#" /etc/libvirt/libvirtd.conf

取消以下三行的注释

22:listen_tls = 0 33:listen_tcp = 1 45:tcp_port = "16509"

取消注释,并修改监听端口

55:listen_addr = "172.30.200.41"

取消注释,同时取消认证

158:auth_tcp = "none" 2)修改/etc/sysconfig/libvirtd

在全部计算节点操作,以 compute01 节点为例;

以下给出 libvirtd 文件的修改处所在的行 num

[root@compute01 ~]# egrep -vn "$|#" /etc/sysconfig/libvirtd

取消注释

9:LIBVIRTD_ARGS="--listen" 3)设置 iptables

live-migration 时,源计算节点主动连接目的计算节点 tcp16509 端口,可以使用”virsh -c

qemu+tcp://{node_ip or node_name}/system”连接目的计算节点测试;

迁移前后,在源目计算节点上的被迁移 instance 使用 tcp49152~49161 端口做临时通

信;

因虚拟机已经启用 iptables 相关规则,此时切忌随意重启 iptables 服务,尽量使用插

入的方式添加规则;

同时以修改配置文件的方式写入相关规则,切忌使用”iptables saved”命令;

在全部计算节点操作,以 compute01 节点为例

[root@compute01 ~]# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 16509 -j ACCEPT [root@compute01 ~]# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 49152:49161 -j ACCEPT 4)重启服务

libvirtd 与 nova-compute 服务都需要重启

[root@compute01 ~]# systemctl restart libvirtd.service openstack-nova-compute.service

查看服务

[root@compute01 ~]# netstat -tunlp | grep 16509 4. 验证 如果使用 ceph 提供的 volume 做启动盘,即虚拟机运行镜像文件存放在共享存储上,此 时可以方便地进行 live-migration。 1)创建基于 ceph 存储的 bootable 存储卷

当 nova 从 rbd 启动 instance 时,镜像格式必须是 raw 格式,否则虚拟机在启动时

glance-api 与 cinder 均会报错;

首先进行格式转换,将*.img 文件转换为*.raw 文件

[root@controller01 ~]# qemu-img convert -f qcow2 -O raw ~/cirros-0.3.5-x86_64-disk.img ~/cirros-0.3.5-x86_64-disk.raw

生成 raw 格式镜像

[root@controller01 ~]# openstack image create "cirros-raw" \ --file ~/cirros-0.3.5-x86_64-disk.raw \ --disk-format raw --container-format bare \ --public

使用新镜像创建 bootable 卷

[root@controller01 ~]# cinder create --image-id a95cee9a-4493-42ae-98e9-e5d34e4dee7a --volume-type ceph --name ceph-bootable1 2

查看新创建的 bootable 卷

[root@controller01 ~]# cinder list

从基于 ceph 后端的 volumes 新建实例;

“--boot-volume”指定具有”bootable”属性的卷,启动后,虚拟机运行在 volumes 卷

[root@controller01 ~]# nova boot --flavor m1.tiny \ --boot-volume db0f83c0-14f7-4548-8807-4b1f593630a4 \ --nic net-id=91e78b9c-cfcd-4af2-851a-a27839edf571 \ --security-group default \ cirros-cephvolumes-instance1 2)从 ceph rbd 启动虚拟机

--nic:net-id 指网络 id,非 subnet-id;

最后“cirros-cephrbd-instance1”为 instance 名

[root@controller01 ~]# nova boot --flavor m1.tiny --image cirros-raw --nic net-id=91e78b9c-cfcd-4af2-851a-a27839edf571 --security-group default cirros-cephrbd-instance1

查询生成的 instance

[root@controller01 ~]# nova list

查看生成的 instance 的详细信息

[root@controller01 ~]# nova show 7648251c-62a1-4f98-ba3f-e5f30f5804b4

验证是否从 ceph rbd 启动

[root@controller01 ~]# rbd ls vms 3)对 rbd 启动的虚拟机进行 live-migration

使用”nova show 7648251c-62a1-4f98-ba3f-e5f30f5804b4”得知从 rbd 启动的 instance 在

迁移前位于 compute02 节点;

或使用”nova hypervisor-servers compute02”进行验证;

[root@controller01 ~]# nova live-migration cirros-cephrbd-instance1 compute01

迁移过程中可查看状态

[root@controller01 ~]# nova list

迁移完成后,查看 instacn 所在节点;

或使用”nova show 7648251c-62a1-4f98-ba3f-e5f30f5804b4”命令查看”hypervisor_hostname”

[root@controller01 ~]# nova hypervisor-servers compute02 [root@controller01 ~]# nova hypervisor-servers compute01 21、一些问题

  1. kvm 实例获取不到 dhcp 地址 1)现象
  2. 使用 vmware vsphere 搭建的 openstack 环境,控制/计算节点分离;
  3. 通过 dashboard 控制台下发 kvm 实例时,实例不能获取 ip 地址。 2)分析
  4. 控制/计算节点分离时,计算节点生成的 kvm 实例会通过 dhcp 向 neutron 网络控制节 点(含 dhcp-agnet,metadata-agent,l3-agnet 等服务)的 dhcp-agent(dnsmasq 提供) 获取 ip,kvm 实例获取 ip 地址流程如下(vlan 网络): 计算节点( instance_vif---vifyyy---brqyyy---ethy.vlan_id---ethy ) --- ( ethx--- ethx.vlan_id---brqxxx---vifxxx---dnsmasq_vif)neutron 控制节点
  5. 观察 kvm 实例启动日志,发现实例主动发起的 dhcp 请求(dhcp request,属于 udp 68);
  6. 同时在网络控制节点的相关网卡抓包(通过"brctl show"可查询到相关网卡):

对接 dnsmasq_vif 的网卡;

dnsmasq 收到 dhcp 广播并回复了 dhcp offer(udp 67)

[root@controller01 ~]# tcpdump -i tap004b787f-9b -ne port 67 or 68

网桥;

网桥收到 dhcp 广播,正常转发到 dnsmasq,且收到 dnsmasq 回复的 dhcp offer

[root@controller01 ~]# tcpdump -i brq91e78b9c-cf -ne port 67 or 68

物理网卡(带 tag);

物理网卡收到 dhcp 广播,正常转发到网桥,但并未收到应该从网桥转发过来的 dhcp

offer [root@controller01 ~]# tcpdump -i eth3.3092 -ne port 67 or 68 证明从网桥到物理网卡的转发有问题。 3)原因 iptables 默认规则下,在 forward 表中有一条链: -A FORWARD -j REJECT --reject-with icmp-host-prohibited 即:iptables 默认不转发数据包,且阻断后回复消息"icmp-host-prohibited"。 4)解决方案

在 neutron 网络控制节点,删除禁止转发的默认规则

[root@controller01 ~]# iptables -D FORWARD -j REJECT --reject-with icmp-host-prohibited

同时在 neutron 网络控制节点,修改 iptables 规则文件,注释禁止转发的默认规则

[root@controller01 ~]# vim /etc/sysconfig/iptables #-A FORWARD -j REJECT --reject-with icmp-host-prohibited ps:常规情况下尽量不要随意重启 iptables 服务;如果重启了 iptables 服务,需要重启 neutron-linuxbridge-agent 服务,重新向 iptables 注入 neutron 相关转发规则。 2. 相同子网不同计算节点的两台 kvm 实例不能 ping 通 1)环境

  1. 使用 vmware vsphere 搭建的 openstack 环境,控制/计算节点均为虚拟机;
  2. Openstack 环境下,设置 kvm 虚拟机基于 vlan 通信,宿主机上行到交换机的端口做 trunk,并已放行通信 vlan;
  3. 在相同子网(vlan)不同计算节点生成两台实例,各自已获得相同子网的 ip,且已 形成 vm_vif---tapxxx---brqxxx---ethx.vlan_id---ethx---switch_port 的逻辑关系。 2)现象 上述环境中的两台实例不能互相 ping 通,通过 tcpdump 抓包观察,具体表现为:
  4. 两 台 实 例 发 出 的 arp request 包 ( 首 包 ) , 通 过 vm_vif---tapxxx---brqxxx---ethx.vlan_id---ethx,但在 switch_port 上未抓到包; 2.在 switch 上针对 vlan_id 设置 vlanif,从 switch 主动 ping 两台实例(swith 是外部 环境,需提前设置安全组,允许外部环境 ping 内部主机),arp request 包(首包)到达 kvm 虚拟机,且 kvm 实例的 arp reply 包正常回到 ethx 接口,但在 switch_port 上未抓到 arp reply 包。 证明计算节点宿主机的"物理"接口与 switch 之间的通信有问题。 3)原因 环境是基于 vmware vsphere 搭建的,其 vss/vds 有 3 个安全选项设置:
  5. 混杂模式:vSphere 知道所有接入 vss/vds 的接口 mac 地址,不需要根据数据包的源 mac 来更新 mac 与 port 的映射,所以 vss/vds 不具备 mac 学习功能(与传统交换机不 同)。混杂模式未开启时,如果目标 mac 不属于该 vss/vds,那么 vss/vds 将丢弃该数 据包;vss/vds 开启混杂模式时,所属的 port 将收到 vss/vds 上 vlan 策略所允许的所 有流量。
  6. MAC 地址更改:设置为拒绝时,若 vm 的接口 mac 地址被更改,与 vm 的.vmx 配置 文件中的地址不一致,则所有进入该接口的数据帧都会被丢弃。
  7. 伪传输:设置为拒绝时,若 vm 发送的数据包源 mac 地址与当前适配器的 mac 地址 不一致,该数据包会被丢弃。 结论:
  8. 由于 kvm 实例的 vif 是通过桥接的方式直接与外部通信,其源 mac 直接暴露到宿主 机网卡,但 vmware vsphere 默认设置 vss/vds 的"伪传输"选项为"拒绝",导致从 kvm 虚拟机发送的数据包在宿主机的"物理"网卡上即被丢弃。
  9. 加入 bridge 网桥的宿主机网卡自动进入 promiscuous mode,并进入 forwarding state (可以使用 dmesg 查看),但 vmware vsphere 默认设置 vss/vds 的"混杂模式"选项 为"拒绝",也会导致丢包 4)解决方案 设置 vss/vds 安全选项中的"混杂模式"与"伪传输"参数为"接受",
  10. 打开实例 console 失败 1)现象 通过 dashboard 实例---控制台,打开实例 console 失败。 报错:Failed to connect to server(code: 1006) 2)分析

查看观察 vnc 日志,日志文件/var/log/nova/nova-novncproxy.log

[root@controller01 ~]# tailf /var/log/nova/nova-novncproxy.log 实例 console 是通过 vnc 打开的,访问 horizondashboard 后,nova 控制节点将请求定向 到实例所在 计算节 tcp5900 端 口 , 即 kvm 服 务 监 听 端 口 , 如 这 里 实 例 位 于 172.30.200.41(compute01) 节 点 , 但 默 认 计 算 节 点 的 tcp5900 端 口 未 打 开 , 返 回 "handlerexception:[Errno113]EHOSTUNREACH"信息。 参考:  https://ask.openstack.org/en/question/520/vnc-console-in-dashboard-fails-to-connect-ot-serve r-code-1006/ 3)解决方案

放开所有计算节点的 tcp 5900 端口;如无必要,不要随意重启 iptables 服务;

同时更新/etc/sysconfig/iptables 文件,以免服务重启后端口实效

[root@compute01 ~]# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 5900 -j ACCEPT 4. 通过 dashboard 创建的实例被删除后,实例挂载的 volume 不能删除 1)现象 通过 dashboard 创建的实例,在删除实例后,对应绑定的 volume 不会自动删除。 2)分析 创建实例与创建并挂载 volume 是独立的步骤(通过 cli 方式的"nova boot"启动实例时, 不指定"--block-device"选项,不会挂载已创建的持久性存储),理论上创建的实例是有临时 存储;而 volume 只是 dashboard 在创建实例的同时创建的,然后将 volume 挂载到实例。所 以在删除实例时,持久性存储 volume 不会同步删除。 持久性存储 volume 不会同步被删除的好处在于,如果 volume 存有重要数据,通过新 启动的实例还可被挂载。 所以是否允许 volume 随实例一起创建需要根据实际环境确定。 在 dashboard 中创建实例时,是否同步删除 volume 是可选项,如下: 3)解决方案

取消 288~296 行注释;

变更’create_volume’的默认值“True”为“False”,即创建实例的同时不同步创建 volume

并挂载 LAUNCH_INSTANCE_DEFAULTS = { 'config_drive': False, 'enable_scheduler_hints': True, 'disable_image': False, 'disable_instance_snapshot': False, 'disable_volume': False, 'disable_volume_snapshot': False, 'create_volume': False, } 5. 创建的卷不能删除 1)现象 在客户端 A 创建 volume 成功后,在客户端 B 不能删除;或者运行在 active/standby 模 式的 cinder-volume 服务故障切换后,在原客户端不能删除 volume。 2)分析 上述现象分两个纬度:

  1. 如果 cinder-volume 运行在 active/active 模式,不同的客户端请求会通过前端 haproxy (取决于负载方式)分配到不同的后端 cinder-volume 服务器,由于 cinder-volume 是有状态的服务,会导致在 2 号 cinder-volume 服务器上没有在 1 号 cinder-volume 服务器创建的 volume 的状态,导致 volume 无法删除;
  2. 如果 cinder-volume 运行在 active/standby 模式,可以避免上述问题,但只是治标;如 果 active 服务故障,导致故障切换,standby 服务升 active,原 active 服务创建的 volume 状态不会同步到新 active 服务器,也会导致 volume 无法删除。 3)解决方案

后端使用共享存储时,建议将 cinder-volume 部署在控制节点,并运行在 active/standby

(通过 pacemaker 实现)模式的同时,在 cinder-volume 配置的 deafault 字段,设置主机名标 识符,使 volume 状态同步;

主机自定义名标识;

集群中 cinder-volume 所在主机都需要设置;

理论上,设置主机名标识后,cinder-volume 可运行在 active/standby 或 active/active

模式 [root@compute01 ~]# vim /etc/cinder/cinder.con [DEFAULT] host = node-volume

验证;

原 host 的”state”会”down”,新启动的 host 名同配置文件中的 host 参数

[root@controller01 ~]# openstack volume service list