OpenStack学习笔记
OpenStack是一个开源的IaaS解决方案,使用它,你可以通过仪表盘或者利用OpenStack API控制/Provision大规模的计算、存储、网络资源池。
通过“驱动”,OpenStack支持大量商业、开源的计算、存储、网络相关技术框架,从而能够管理各种各样的基础设施。不管是裸金属机器、虚拟机、还是容器,都可以基于OpenStack进行管理,并共享网络、存储等底层资源:
Kubernetes、CloudFoundry等PaaS平台可以构建在OpenStack之上。
OpenStack由若干子项目组成,它们围绕着计算、存储、网络这三个核心概念组织:
- 计算:提供并管理网络中大量的虚拟机,主要由Nova子项目负责
- 存储:供服务器、应用程序使用的对象存储、块存储,分别由Swift、Cinder子项目负责
- 网络:可拔插、可扩容、API驱动的网络和IP管理
这三类子项目还具有一些共享的服务:identity、镜像管理(image management)、一个基于Web的UI接口。
OpenStack项目的总览图如下,其中粗体标出了它的核心子项目,包括Horizon、Heat、Nova、Neutron、Swift、Cinder等:
以Bigdata as Service场景为例,各子项目的交互关系如下图:
简单的说明一下:
- Keystone提供身份验证服务
- Ceilometer提供监控服务
- Horizon提供一个管理UI
- Nova负责分配虚拟机
- Glance提供镜像服务,镜像文件存放在Swift中
- Cinder为虚拟机提供块存储卷
- Cinder将卷备份到Swift中
- Neuron为虚拟机提供网络连接
每个子项目,或者叫OpenStack服务,都通过公共的Identity Service进行身份验证,服务之间通过公共API进行交互。每个服务至少包含一个API进程,此进程监听API请求,进行预处理然后转交给服务的其它部分进行处理。
每个服务可以有多个进程,这些进程之间的通信方式通常是AMQP。服务的状态持久化在数据库中。多种消息代理、RDBMS被支持,例如RabbitMQ、MySQL、MariaDB。
用户访问OpenStack的方式有几种:
- 通过Horizon提供的Web仪表盘
- 提供CLI客户端
- 提供SDK进行编程
不管是何种方式,在底层都会向不同的OpenStack服务发送REST请求。
Nova是OpenStack云中的计算组织控制器。支持OpenStack云中实例(instances)生命周期的所有活动都由Nova处理。这样使得Nova成为一个负责管理计算资源、网络、认证、所需可扩展性的平台。
Neutron是openstack核心项目之一,提供云计算环境下的虚拟网络功能。OpenStack网络(neutron)管理OpenStack环境中所有虚拟网络基础设施(VNI),物理网络基础设施(PNI)的接入层。
Cinder接口提供了一些标准功能,允许创建和附加块设备到虚拟机,如“创建卷”,“删除卷”和“附加卷”。还有更多高级的功能,支持扩展容量的能力,快照和创建虚拟机镜像克隆。
Octavia 是 openstack lbaas的支持的一种后台程序,提供为虚拟机流量的负载均衡。实质是类似于trove,调用 nova 以及neutron的api生成一台安装好haproxy和keepalived软件的虚拟机,并连接到目标网路。
Swift 不是文件系统或者实时的数据存储系统,而是对象存储,用于长期存储永久类型的静态数据。这些数据可以检索、调整和必要时进行更新。Swift最适合虚拟机镜像、图片、邮件和存档备份这类数据的存储。
Glance(OpenStack Image Service)是一个提供发现,注册,和下载镜像的服务。Glance提供了虚拟机镜像的集中存储。通过 Glance 的 RESTful API,可以查询镜像元数据、下载镜像。虚拟机的镜像可以很方便的存储在各种地方,从简单的文件系统到对象存储系统(比如 OpenStack Swift)。
Horizon 为 Openstack 提供一个 WEB 前端的管理界面 (UI 服务 )通过 Horizon 所提供的 DashBoard 服务 , 管理员可以使用通过 WEB UI 对 Openstack 整体云环境进行管理 , 并可直观看到各种操作结果与运行状态。
Ironic包含一个API和多个插件,用于安全性和容错性地提供物理服务器。它可以和nova结合被使用为hypervisor驱动,或者用bifrost使用为独立服务。默认情况下,它会使用PXE和IPMI去与裸金属机器去交互。Ironic也支持使用供应商的插件而实现额外的功能。
Cyborg(以前称为Nomad)旨在为加速资源(即FPGA,GPU,SoC, NVMe SSD,DPDK/SPDK,eBPF/XDP …)提供通用管理框架。
kolla 的使命是为 openstack 云平台提供生产级别的、开箱即用的交付能力。kolla 的基本思想是一切皆容器,将所有服务基于 Docker 运行,并且保证一个容器只跑一个服务(进程),做到最小粒度的运行 docker。
Kubernetes Kuryr是 OpenStack Neutron 的子项目,其主要目标是通过该项目来整合 OpenStack 与Kubernetes 的网络。该项目在 Kubernetes 中实现了原生 Neutron-based 的网络,因此使用 Kuryr-Kubernetes 可以让你的 OpenStack VM 与 Kubernetes Pods 能够选择在同一个子网上运作,并且能够使用 Neutron 的 L3 与 Security Group 来对网络进行路由,以及阻挡特定来源 Port。
Manila项目全称是File Share Service,文件共享即服务,用来提供云上的文件共享,支持CIFS协议和NFS协议。
Tacker是一个在OpenStack内部孵化的项目, 他的作用是NVF管理器,用于管理NVF的生命周期。Tacker的重点是配置VNF, 并监视他们。如果需要,还可重启和/或扩展(自动修复)NVF。整个进程贯穿ETSIMANO所描述的整个生命周期。
显示详细配置信息:
1 2 |
# --unmask表示明文显示密码 openstack configuration show [--mask | --unmask] |
一个Domain,是用户、组、项目的集合。任何组、项目仅仅属于单个Domain。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
openstack domain create [--description <description>] [--enable | --disable] [--or-show] # 禁止删除或修改,除非去掉此标记 [--immutable | --no-immutable] <domain-name> openstack domain delete <domain> [<domain> ...] openstack domain list [--sort-column SORT_COLUMN] [--name <name>] [--enabled] openstack domain set [--name <name>] [--description <description>] [--enable | --disable] [--immutable | --no-immutable] <domain> openstack domain show <domain> |
管理项目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
openstack project create [--domain <domain>] [--parent <project>] [--description <description>] [--enable | --disable] [--property <key=value>] [--or-show] [--immutable | --no-immutable] [--tag <tag>] <project-name> openstack project delete [--domain <domain>] <project> [<project> ...] openstack project list [--sort-column SORT_COLUMN] [--domain <domain>] [--parent <parent>] [--user <user>] [--my-projects] [--long] [--sort <key>[:<direction>]] [--tags <tag>[,<tag>,...]] [--tags-any <tag>[,<tag>,...]] [--not-tags <tag>[,<tag>,...]] [--not-tags-any <tag>[,<tag>,...]] openstack project set [--name <name>] [--domain <domain>] [--description <description>] [--enable | --disable] [--property <key=value>] [--immutable | --no-immutable] [--tag <tag>] [--clear-tags] [--remove-tag <tag>] <project> openstack project show [--domain <domain>] [--parents] [--children] <project> |
清除和指定项目关联的资源
1 2 3 4 5 |
openstack project purge [--dry-run] [--keep-project] (--auth-project | --project <project>) [--project-domain <project-domain>] |
用户的组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# 添加用户到组 openstack group add user [--group-domain <group-domain>] [--user-domain <user-domain>] <group> <user> [<user> ...] openstack group remove user [--group-domain <group-domain>] [--user-domain <user-domain>] <group> <user> [<user> ...] # 检查组是否包含用户 openstack group contains user [--group-domain <group-domain>] [--user-domain <user-domain>] <group> <user> # 创建组 openstack group create [--domain <domain>] [--description <description>] [--or-show] <group-name> openstack group delete [--domain <domain>] <group> [<group> ...] openstack group list [--sort-column SORT_COLUMN] [--domain <domain>] [--user <user>] [--user-domain <user-domain>] [--long] openstack group show [--domain <domain>] <group> openstack group set [--domain <domain>] [--name <name>] [--description <description>] <group> |
用户管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
openstack user create # 用户的默认domain [--domain <domain>] # 用户的默认project [--project <project>] [--project-domain <project-domain>] # 指定密码 [--password <password>] # 交互的输入密码 [--password-prompt] [--email <email-address>] [--description <description>] # 禁止连续身份验证失败后,锁定用户 [--ignore-lockout-failure-attempts] [--no-ignore-lockout-failure-attempts] # 禁止密码过期 [--ignore-password-expiry] [--no-ignore-password-expiry] # 禁止首次使用必须修改密码 [--ignore-change-password-upon-first-use] [--no-ignore-change-password-upon-first-use] # 锁定密码,不给修改 [--enable-lock-password] [--disable-lock-password] # 启用多因子身份验证 [--enable-multi-factor-auth] [--disable-multi-factor-auth] [--multi-factor-auth-rule <rule>] # 启用/禁用 [--enable | --disable] # 显示已有的用户 [--or-show] <name> openstack user delete [--domain <domain>] <user> [<user> ...] openstack user list [--sort-column SORT_COLUMN] [--domain <domain>] [--group <group> | --project <project>] [--long] openstack user show [--domain <domain>] <user> # 修改密码 openstack user password set [--password <new-password>] [--original-password <original-password>] openstack user set [--name <name>] [--domain <domain>] [--project <project>] [--project-domain <project-domain>] [--password <password>] [--password-prompt] [--email <email-address>] [--description <description>] [--ignore-lockout-failure-attempts] [--no-ignore-lockout-failure-attempts] [--ignore-password-expiry] [--no-ignore-password-expiry] [--ignore-change-password-upon-first-use] [--no-ignore-change-password-upon-first-use] [--enable-lock-password] [--disable-lock-password] [--enable-multi-factor-auth] [--disable-multi-factor-auth] [--multi-factor-auth-rule <rule>] [--enable | --disable] <user> |
可以创建角色,将角色映射给用户或组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# 将角色赋予组或用户 openstack role add [--system <system> | --domain <domain> | --project <project>] [--user <user> | --group <group>] [--group-domain <group-domain>] [--project-domain <project-domain>] [--user-domain <user-domain>] [--inherited] [--role-domain <role-domain>] <role> openstack role remove [--system <system> | --domain <domain> | --project <project>] [--user <user> | --group <group>] [--group-domain <group-domain>] [--project-domain <project-domain>] [--user-domain <user-domain>] [--inherited] [--role-domain <role-domain>] <role> # 创建角色 openstack role create [--description <description>] [--domain <domain>] [--or-show] [--immutable | --no-immutable] <role-name> openstack role delete [--domain <domain>] <role> [<role> ...] openstack role list [--sort-column SORT_COLUMN] [--domain <domain>] openstack role set [--description <description>] [--domain <domain>] [--name <name>] [--immutable | --no-immutable] <role> openstack role show [--domain <domain>] <role> |
角色和用户的映射关系。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
openstack role assignment list [--role <role>] [--role-domain <role-domain>] [--user <user>] [--user-domain <user-domain>] [--group <group>] [--group-domain <group-domain>] [--domain <domain>] [--project <project>] [--project-domain <project-domain>] [--effective] [--inherited] [--names] |
指定角色之间的包含关系。
1 2 3 4 5 6 |
# 被隐含的角色 目标角色 openstack implied role create --implied-role <role> <role> openstack implied role delete --implied-role <role> <role> openstack implied role list [--sort-column SORT_COLUMN] |
提供特定项目中,用户之间的角色代理,支持可选的替身机制(impersonation)。需要 OS-TRUST扩展。
在Identity服务的OS-OAUTH1扩展中使用,用于创建request token 、access token,仅仅支持Identity v3。
1 2 3 4 5 |
openstack consumer create [--description <description>] openstack consumer delete <consumer> [<consumer> ...] openstack consumer list [--sort-column SORT_COLUMN] openstack consumer set [--description <description>] <consumer> openstack consumer show <consumer> |
管理凭证:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
openstack credential create [--type <type>] [--project <project>] <user> <data> openstack credential delete <credential-id> [<credential-id> ...] openstack credential list [--sort-column SORT_COLUMN] [--user <user>] [--user-domain <user-domain>] [--type <type>] openstack credential set --user <user> --type <type> --data <data> [--project <project>] <credential-id> openstack credential show <credential-id> |
使用应用凭证,用户可以给自己的应用程序授予对云资源的有限访问权限。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# 创建新的凭证 openstack application credential create [--secret <secret>] [--role <role>] [--expiration <expiration>] [--description <description>] [--unrestricted] [--restricted] [--access-rules <access-rules>] <name> openstack application credential delete <application-credential> [<application-credential> ...] openstack application credential list [--sort-column SORT_COLUMN] [--user <user>] [--user-domain <user-domain>] openstack application credential show <application-credential> |
对应用程序凭证的权限进行细粒度控制。每个访问规则包含一下要素:
服务类型 + 请求路径 + 请求方法
1 2 3 4 5 6 7 |
openstack access rule delete <access-rule> [<access-rule> ...] openstack access rule list [--user <user>] [--user-domain <user-domain>] openstack access rule show <access-rule> |
创建或吊销一个令牌
1 2 3 |
openstack token issue openstack token revoke <token> |
Identity服务的OS-OAUTH1扩展使用访问令牌。consumer可以代表被授权用户来获得新的Identity API token。
1 2 3 4 5 6 7 |
openstack access token create # consumer的键/密钥 --consumer-key <consumer-key> --consumer-secret <consumer-secret> --request-key <request-key> --request-secret <request-secret> --verifier <verifier> |
Identity服务的OS-OAUTH1扩展使用请求令牌。consumer使用此令牌来请求access token
1 2 3 4 5 6 7 8 9 10 11 |
# 验证请求令牌 openstack request token authorize --request-key <request-key> --role <role> # 创建请求令牌 openstack request token create --consumer-key <consumer-key> --consumer-secret <consumer-secret> --project <project> [--domain <domain>] |
策略是一组规则,可以被远程服务消费。
1 2 3 4 5 6 7 8 9 |
openstack policy create [--type <type>] <filename> openstack policy delete <policy> [<policy> ...] openstack policy list [--sort-column SORT_COLUMN] [--long] openstack policy set [--type <type>] [--rules <filename>] <policy> openstack policy show <policy> |
基于RBAC的、针对网络资源的授权控制策略。让用户获得某个项目的网络资源的访问权限
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
openstack network rbac create --type <type> --action <action> (--target-project <target-project> | --target-all-projects) [--target-project-domain <target-project-domain>] [--project <project>] [--project-domain <project-domain>] <rbac-object> openstack network rbac delete <rbac-policy> [<rbac-policy> ...] openstack network rbac list [--sort-column SORT_COLUMN] [--type <type>] [--action <action>] [--long] openstack network rbac set [--target-project <target-project>] [--target-project-domain <target-project-domain>] <rbac-policy> openstack network rbac show <rbac-policy> |
很多API都支持资源配额
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
openstack quota set # 为指定的class设置配额 [--class] # 核心数配额 [--cores <cores>] # 固定IP数量配额 [--fixed-ips <fixed-ips>] [--injected-file-size <injected-file-size>] [--injected-path-size <injected-path-size>] [--injected-files <injected-files>] [--instances <instances>] [--key-pairs <key-pairs>] [--properties <properties>] [--ram <ram>] [--server-groups <server-groups>] [--server-group-members <server-group-members>] [--backups <backups>] [--backup-gigabytes <backup-gigabytes>] [--gigabytes <gigabytes>] [--per-volume-gigabytes <per-volume-gigabytes>] [--snapshots <snapshots>] [--volumes <volumes>] [--floating-ips <floating-ips>] [--secgroup-rules <secgroup-rules>] [--secgroups <secgroups>] [--networks <networks>] [--subnets <subnets>] [--ports <ports>] [--routers <routers>] [--rbac-policies <rbac-policies>] [--subnetpools <subnetpools>] [--volume-type <volume-type>] [--force] # 此配额针对的项目或者class <project/class> openstack quota list [--sort-column SORT_COLUMN] [--project <project>] [--detail] (--compute | --volume | --network) openstack quota show [--class | --default] [<project/class>] # 显示针对所有项目的默认配额 openstack quota show --default # 增大默认安装下admin项目的资源配额 openstack quota set --cores 32 admin openstack quota set --ram 131072 admin openstack quota set --gigabytes 8192 admin openstack quota set --volumes 32 admin openstack quota set --snapshots 32 admin openstack quota set --instances 16 admin |
用于在项目级别进行资源配额。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# 创建一个配额 openstack limit create [--description <description>] # 此配额影响的区域 [--region <region>] # 此配额针对的项目 --project <project> # 负责资源的服务 --service <service> # 资源额度 --resource-limit <resource-limit> <resource-name> openstack limit delete <limit-id> [<limit-id> ...] openstack limit list [--sort-column SORT_COLUMN] [--service <service>] [--resource-name <resource-name>] [--region <region>] [--project <project>] openstack limit set [--description <description>] [--resource-limit <resource-limit>] <limit-id> openstack limit show <limit-id> |
用于定义OpenStack部署中的默认资源限制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
openstack registered limit create [--description <description>] [--region <region>] --service <service> --default-limit <default-limit> <resource-name> openstack registered limit delete <registered-limit-id> [<registered-limit-id> ...] openstack registered limit list [--sort-column SORT_COLUMN] [--service <service>] [--resource-name <resource-name>] [--region <region>] openstack registered limit set [--service <service>] [--resource-name <resource-name>] [--default-limit <default-limit>] [--description <description>] [--region <region>] <registered-limit-id> openstack registered limit show <registered-limit-id> |
显示计算、存储资源用量的限制
1 2 3 4 5 6 |
openstack limits show [--sort-column SORT_COLUMN] (--absolute | --rate) [--reserved] [--project <project>] [--domain <domain>] |
显示项目的资源用量
1 2 3 4 5 6 7 8 9 10 11 |
openstack usage list [--sort-column SORT_COLUMN] # 用量统计的起始时间,默认4周前 [--start <start>] # 用量统计的结束日期,默认明天 [--end <end>] openstack usage show [--project <project>] [--start <start>] [--end <end>] |
区域是OpenStack部署中的最大的分区。你可以配置多个sub-region,甚至形成树形结构。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
openstack region create [--parent-region <region-id>] [--description <description>] <region-id> openstack region delete <region-id> [<region-id> ...] openstack region list [--sort-column SORT_COLUMN] [--parent-region <region-id>] openstack region set [--parent-region <region-id>] [--description <description>] <region-id> openstack region show <region-id> |
可用区是云存储、计算、网络服务的逻辑分区。对等的AZ具有构成HA的效果,这和Region不同。
1 2 3 4 5 6 7 |
# 列出可用区 openstack availability zone list [--sort-column SORT_COLUMN] [--compute] [--network] [--volume] [--long] |
聚合是一组分组host的机制:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# 添加/删除主机到聚合中 openstack aggregate add host <aggregate> <host> openstack aggregate remove host <aggregate> <host> # 为聚合请求缓存镜像 openstack aggregate cache image <aggregate> <image> [<image> ...] # 创建一个聚合,可以看到聚合是在某个AZ内部的 openstack aggregate create [--zone <availability-zone>] [--property <key=value>] <name> openstack aggregate delete <aggregate> [<aggregate> ...] # 为聚合设置元数据(键值对),然后为Flavor设置scope为aggregate_instance_extra_specs的 # 额外规格,规格键值和元数据一致,可以将Flavor映射到聚合。从Flavor创建的实例将位于聚合的主机中 openstack aggregate set [--name <name>] [--zone <availability-zone>] [--property <key=value>] [--no-property] <aggregate> openstack aggregate unset [--property <key>] <aggregate> openstack aggregate show <aggregate> openstack aggregate list [--sort-column SORT_COLUMN] [--long] |
运行Hypervisor的物理机器。
1 2 3 4 5 6 7 8 |
openstack host list [--sort-column SORT_COLUMN] [--zone <zone>] openstack host set [--enable | --disable] [--enable-maintenance | --disable-maintenance] <host> openstack host show [--sort-column SORT_COLUMN] <host> |
1 2 3 4 5 6 |
openstack hypervisor list [--sort-column SORT_COLUMN] [--matching <hostname>] [--long] openstack hypervisor show <hypervisor> |
1 |
openstack hypervisor stats show |
OpenSSH公钥管理,用于访问创建的server(虚拟机)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# 创建公钥 # 如果什么参数都不指定,则生成新的公钥 openstack keypair create [--public-key <file> | --private-key <file>] [--type <type>] [--user <user>] [--user-domain <user-domain>] <name> openstack keypair delete [--user <user>] [--user-domain <user-domain>] <key> [<key> ...] openstack keypair list [--sort-column SORT_COLUMN] [--user <user>] [--user-domain <user-domain>] [--project <project>] [--project-domain <project-domain>] openstack keypair show [--public-key] [--user <user>] [--user-domain <user-domain>] <key> |
显示所有服务的版本、端点、是否弃用之类的信息
1 |
openstack versions show |
显示服务的类型、名称、端点列表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
openstack catalog list [--sort-column SORT_COLUMN] openstack catalog show <service> openstack catalog list # +-----------+-----------+-----------------------------------------+ # | Name | Type | Endpoints | # +-----------+-----------+-----------------------------------------+ # | glance | image | zircon | # | | | public: http://os.gmem.cc:9292 | # | | | | # | keystone | identity | zircon | # | | | internal: http://os.gmem.cc:5000/v3/ | # | | | zircon | # | | | public: http://os.gmem.cc:5000/v3/ | # | | | zircon | # | | | admin: http://os.gmem.cc:5000/v3/ | # | | | | # | nova | compute | zircon | # | | | internal: http://os.gmem.cc:8774/v2.1 | # | | | zircon | # | | | public: http://os.gmem.cc:8774/v2.1 | # | | | zircon | # | | | admin: http://os.gmem.cc:8774/v2.1 | # | | | | # | placement | placement | zircon | # | | | public: http://os.gmem.cc:8778 | # | | | zircon | # | | | admin: http://os.gmem.cc:8778 | # | | | zircon | # | | | internal: http://os.gmem.cc:8778 | # | | | | # +-----------+-----------+-----------------------------------------+ |
很多OpenStack API包含API扩展,这些扩展提供额外的功能。
1 2 3 4 5 6 7 8 9 10 11 |
# 列出API扩展 openstack extension list [--sort-column SORT_COLUMN] [--compute] [--identity] [--network] [--volume] [--long] # 显示API扩展 openstack extension show <extension> |
管理服务的API端点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# 关联项目到端点 openstack endpoint add project [--project-domain <project-domain>] <endpoint> <project> openstack endpoint remove project [--project-domain <project-domain>] <endpoint> <project> # 创建新的端点 openstack endpoint create # 所属的区域 [--region <region-id>] [--enable | --disable] # 端点所属的服务 <service> # admin, public 还是 internal <interface> <url> openstack endpoint delete <endpoint-id> [<endpoint-id> ...] openstack endpoint list [--sort-column SORT_COLUMN] [--service <service>] [--interface <interface>] [--region <region-id>] [--endpoint <endpoint-group> | --project <project>] [--project-domain <project-domain>] openstack endpoint set [--region <region-id>] [--interface <interface>] [--url <url>] [--service <service>] [--enable | --disable] <endpoint-id> openstack endpoint show <endpoint> |
一组端点,可以一起关联到项目。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# 关联端点组到项目 openstack endpoint group add project [--project-domain <project-domain>] <endpoint-group> <project> openstack endpoint group remove project [--project-domain <project-domain>] <endpoint-group> <project> # 创建端点组 openstack endpoint group create [--description DESCRIPTION] <name> <filename> openstack endpoint group delete <endpoint-group> [<endpoint-group> ...] openstack endpoint group set [--name <name>] [--filters <filename>] [--description <description>] <endpoint-group> openstack endpoint group list [--sort-column SORT_COLUMN] [--endpointgroup <endpoint-group> | --project <project>] [--domain <domain>] openstack endpoint group show <endpointgroup> |
表示一种虚拟机的规格。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
openstack flavor create [--id <id>] # 内存大小,MB [--ram <size-mb>] # 磁盘大小,GB [--disk <size-gb>] # 临时磁盘大小 [--ephemeral <size-gb>] # 交换分区大小 [--swap <size-mb>] # VCPU数量,默认1 [--vcpus <vcpus>] # RX/TX 因子,默认1.0 [--rxtx-factor <factor>] # 是否可以被其它项目使用 [--public | --private] [--property <key=value>] # 所属项目 [--project <project>] [--description <description>] [--project-domain <project-domain>] # 传统的名字是 XX.SIZE_NAME 格式,现在已经没有要求。不排除某些工具依赖于这种名称格式 <flavor-name> openstack flavor list [--sort-column SORT_COLUMN] [--public | --private | --all] [--long] [--marker <flavor-id>] [--limit <num-flavors>] openstack flavor set [--no-property] [--property <key=value>] [--project <project>] [--description <description>] [--project-domain <project-domain>] <flavor> openstack flavor unset [--property <key>] [--project <project>] [--project-domain <project-domain>] <flavor> openstack flavor show <flavor> # 创建一个Flavor openstack flavor create FLAVOR_NAME --id FLAVOR_ID \ --ram RAM_IN_MB --disk ROOT_DISK_IN_GB --vcpus NUMBER_OF_VCPUS # 创建Flavor并分配给一个租户 openstack flavor create --public m1.extra_tiny --id auto \ --ram 256 --disk 0 --vcpus 1 openstack flavor set --project PROJECT_ID m1.extra_tiny # 列出所有flavor openstack flavor create --id 0 --vcpus 1 --ram 64 --disk 1 m1.nano openstack flavor create --id 1 --vcpus 1 --ram 512 --disk 8 m1.tiny openstack flavor create --id 2 --vcpus 1 --ram 2048 --disk 32 m1.small openstack flavor create --id 3 --vcpus 2 --ram 4096 --disk 64 m1.medium openstack flavor create --id 4 --vcpus 4 --ram 8192 --disk 128 m1.large openstack flavor create --id 5 --vcpus 8 --ram 16384 --disk 256 m1.xlarge openstack flavor list # +----+-----------+-------+------+-----------+-------+-----------+ # | ID | Name | RAM | Disk | Ephemeral | VCPUs | Is Public | # +----+-----------+-------+------+-----------+-------+-----------+ # | 0 | m1.nano | 64 | 1 | 0 | 1 | True | # | 1 | m1.tiny | 512 | 8 | 0 | 1 | True | # | 2 | m1.small | 2048 | 32 | 0 | 1 | True | # | 3 | m1.medium | 4096 | 64 | 0 | 2 | True | # | 4 | m1.large | 8192 | 128 | 0 | 4 | True | # | 5 | m1.xlarge | 16384 | 256 | 0 | 8 | True | # +----+-----------+-------+------+-----------+-------+-----------+ |
管理镜像。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# 允许项目访问镜像 openstack image add project [--project-domain <project-domain>] <image> <project> openstack image remove project [--project-domain <project-domain>] <image> <project> # 创建镜像 openstack image create [--id <id>] # 镜像容器格式:ami, ari, aki, bare, docker, ova, ovf。默认bare [--container-format <container-format>] # 镜像磁盘格式:ami, ari, aki, vhd, vmdk, raw, qcow2, vhdx, vdi, iso, ploop。默认raw [--disk-format <disk-format>] # 启动镜像需要的最小磁盘尺寸 [--min-disk <disk-gb>] # 启动镜像需要的最小内存 [--min-ram <ram-mb>] # 镜像文件 从卷生成镜像 [--file <file> | --volume <volume>] # 从卷生成镜像时,即便卷正在使用,也强制生成镜像 [--force] # 使用本地私钥签名镜像 [--sign-key-path <sign-key-path>] # 用于镜像签名校验的,位于key manager中的certificate的UUID [--sign-cert-id <sign-cert-id>] # 保护镜像防止被删除 [--protected | --unprotected] # 公共 项目私有 可被社区使用 共享 [--public | --private | --community | --shared] [--property <key=value>] [--tag <tag>] [--project <project>] [--import] [--project-domain <project-domain>] <image-name> # 设置镜像属性 openstack image set [--name <name>] [--min-disk <disk-gb>] [--min-ram <ram-mb>] [--container-format <container-format>] [--disk-format <disk-format>] [--protected | --unprotected] [--public | --private | --community | --shared] [--property <key=value>] [--tag <tag>] [--architecture <architecture>] [--instance-id <instance-id>] [--kernel-id <kernel-id>] [--os-distro <os-distro>] [--os-version <os-version>] [--ramdisk-id <ramdisk-id>] [--deactivate | --activate] [--project <project>] [--project-domain <project-domain>] [--accept | --reject | --pending] <image> openstack image unset [--tag <tag>] [--property <property-key>] <image> # 删除镜像 openstack image delete <image> [<image> ...] # 将镜像保存到本地 openstack image save [--file <filename>] <image> # 列出镜像 openstack image member list [--sort-column SORT_COLUMN] [--project-domain <project-domain>] <image> # 显示镜像信息 openstack image show [--human-readable] <image> # 示例 # 上传镜像 openstack image create --public --disk-format qcow2 --container-format bare \ --file cirros-0.5.1-x86_64-disk.img cirros-0.5.1-amd64 # 将卷上传为镜像,上传的QCOW2镜像,会自动shrink # 注意,默认情况下只有Available状态的卷能够上传为镜像,In-use的用--force也不行 # Force upload to image is disabled, Force option will be ignored. openstack image create --volume 840e9e25-192c-401b-83f5-898fd82839c4 --force centos8-amd64-prepared |
计算代理是和Hypervisor相关的,且仅仅被 XenAPI hypervisor driver支持。
Nova相关的服务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
openstack compute service delete <service> [<service> ...] openstack compute service list [--sort-column SORT_COLUMN] [--host <host>] [--service <service>] [--long] openstack compute service set [--enable | --disable] [--disable-reason <reason>] [--up | --down] <host> <service> |
显示虚拟机的控制台日志:
1 |
openstack console log show [--lines <num-lines>] <server> |
打印各种类型的控制台URL:
1 2 3 |
openstack console url show [--novnc | --xvpvnc | --spice | --rdp | --serial | --mks] <server> |
基于某种策略对服务器进行分组。
1 2 3 4 5 6 7 8 9 10 |
openstack server group create [--policy <policy>] <name> openstack server group delete <server-group> [<server-group> ...] openstack server group list [--sort-column SORT_COLUMN] [--all-projects] [--long] openstack server group show <server-group> |
创建一个实例(虚拟机,也叫服务器server)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
openstack server create # --image 从镜像创建服务器的启动磁盘 # --volume 将卷作为服务器的启动磁盘,会自动创建一个块设备,映射boot index为0 # 在很多Hypervisor(例如libvirt/kvm)这个磁盘将是vda # 不要使用 –block-device-mapping 选项来为此磁盘创建重复的映射 (--image <image> | --image-property <key=value> | --volume <volume>) # 服务器的密码 [--password <password>] # 服务器的风格 --flavor <flavor> # 加入安全组,可以指定多个 [--security-group <security-group>] # 注入到此服务器的OpenSSH公钥 [--key-name <key-name>] # 设置属性 [--property <key=value>] # 在启动之前,注入到镜像中的文件。可以指定多个 [--file <dest-filename=source-filename>] # 从metadata服务器来serve的用户数据文件。用于配置新实例 [--user-data <user-data>] [--description <description>] # 在哪个AZ中创建此服务器,可以指定: # <zone-name>:<host-name>:<node-name> # <zone-name>::<node-name> # <zone-name>:<host-name> # <zone-name> [--availability-zone <zone-name>] # 指定在某个宿主机上创建实例 [--host <host>] [--hypervisor-hostname <hypervisor-hostname>] # 和 --image 或 --image-property 一起使用时,该选项自动创建boot index 为0的块设备 # 并且告知计算服务,从镜像创建卷+卷的大小(GB)。此卷在实例销毁后不会删除 # 不能和 --volume 联用 [--boot-from-volume <volume-size>] # 在服务器上创建额外的块设备,格式: # <dev-name>=<id>:<type>:<size(GB)>:<delete-on-terminate> # dev-name 为块设备名称,例如vdb xvdc # id 为卷、卷快照、镜像的名字或ID # type:volume, snapshot 或 image。默认volume # size:卷的大小 # delete-on-terminate:true或false [--block-device-mapping <dev-name=mapping>] # 在服务器上创建NIC。要创建多个NIC,则指定多次 # net-id和port-id互斥,不能同时指定 # v4-fixed-ip 此NIC的IPv4固定IP地址 # v6-fixed-ip 此NIC的IPv6固定IP地址 # auto 由计算服务自动分配一个网络。不能和其它参数一起使用 # none 不连接到网络。不能和其它参数一起使用 [--nic <net-id=net-uuid,v4-fixed-ip=ip-addr,v6-fixed-ip=ip-addr,port-id=port-uuid,auto,none>] # 创建一个NIC,并且连接到该网络。可以指定多次,以创建多个NIC并连接到多个网络 [--network <network>] # 创建一个NIC,并且连接到该端口。可以指定多次,以创建多个NIC并连接到多个端口 [--port <port>] # 提供给nova-scheduler的提示信息 [--hint <key=value>] # 启用config drive [--use-config-drive | --no-config-drive | --config-drive <config-drive-volume>|True] # 启动的实例数量 [--min <count>] [--max <count>] # 等待实例构建完成 [--wait] [--tag <tag>] # 实例的名字 <server-name> # 从镜像启动虚拟机,并挂载一个非启动磁盘 ## 创建非启动磁盘 openstack volume create --size 8 my-volume ## 创建虚拟机 从镜像创建 nova boot --flavor 2 --image 98901246-af91-43d8-b5e6-a4506aa8f369 \ # 添加块设备 源是卷 卷的ID 挂载为卷 虚拟机删除后保留卷 --block-device source=volume,id=d620d971-b160-4c4e-8652-2513d74e2080,dest=volume,shutdown=preserve \ myInstanceWithVolume # 从SOURCE创建启动卷,并从该卷启动虚拟机 # SOURCE: volume, snapshot, image, 或者 blank # DEST:volume或local nova boot --flavor FLAVOR --block-device \ source=SOURCE,id=ID,dest=DEST,size=SIZE,shutdown=PRESERVE,bootindex=INDEX NAME # 从镜像创建一个可启动卷。如果指定--image参数,则Cinder自动将卷标记为可启动的 openstack volume create --image IMAGE_ID --size SIZE_IN_GB bootable_volume # 挂载Swap或者临时磁盘到虚拟机 nova boot --flavor FLAVOR --image IMAGE_ID --swap 512 --ephemeral size=2 NAME |
为服务器添加固定IP地址:
1 2 3 4 5 6 7 8 |
openstack server add fixed ip # 请求的固定IP地址 [--fixed-ip-address <ip-address>] [--tag <tag>] <server> <network> openstack server remove fixed ip <server> <ip-address> |
为服务器添加浮动IP地址:
1 2 3 4 5 6 7 8 |
openstack server add floating ip # 和此浮动IP地址关联的固定IP地址,使用第一个具有此固定IP地址的、此服务器上的port [--fixed-ip-address <ip-address>] <server> # 分配给上述第一个服务器port的浮动IP地址 <ip-address> openstack server remove floating ip <server> <ip-address> |
将服务器连接到某个网络
1 2 3 |
openstack server add network [--tag <tag>] <server> <network> openstack server remove network <server> <network> |
将某个端口连接到服务器
1 2 3 |
openstack server add port [--tag <tag>] <server> <port> openstack server remove port <server> <port> |
将服务器添加到安全组
1 2 3 |
openstack server add security group <server> <group> openstack server remove security group <server> <group> |
挂载(Attach)一个卷给服务器
1 2 3 4 5 6 7 8 9 10 11 12 13 |
openstack server add volume # 服务器上的内部设备名 [--device <device>] [--tag <tag>] # 如果服务器被销毁,此卷是否被删除 [--enable-delete-on-termination | --disable-delete-on-termination] <server> <volume> openstack server remove volume <server> <volume> # 示例 openstack server add volume cirros-amd64 cirros-amd64-diskb |
服务器迁移,就是将一台宿主机上的实例,转移到另外一台上运行。
OpenStack支持四种迁移模式:热迁移、冷迁移、升降配(resize)、重建(evacuation)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 显示迁移历史的列表 openstack server migration list [--sort-column SORT_COLUMN] [--server <server>] [--host <host>] [--status <status>] [--type <type>] [--marker <marker>] [--limit <limit>] [--changes-since <changes-since>] [--changes-before <changes-before>] [--project <project>] [--user <user>] |
扩/缩容服务器为新的flavor。实现方式是:
- 创就一个新的服务器
- 复制文件到新服务器
扩/缩容操作分为两步完成:第一步迁移,第二步确认
1 2 3 4 |
openstack server resize [--flavor <flavor> | --confirm | --revert] [--wait] <server> |
1 |
openstack server resize confirm <server> |
1 |
openstack server resize revert <server> |
将服务器迁移到另外一个宿主机上。
迁移操作是基于resize操作实现的:
- 创建一个新的实例,使用相同的flavor
- 从原始磁盘上拷贝内容到新磁盘
和resize一样,迁移操作是分两步完成的:
- 执行上述两步的迁移操作
- 让用户确认,迁移是否成功并移除酒实例,还是执行revert操作 —— 删除新实例并重启老的
1 2 3 4 5 6 7 8 9 |
openstack server migrate # 不宕机迁移 [--live-migration] # 目标主机 [ --host <hostname>] [--shared-migration | --block-migration] [--disk-overcommit | --no-disk-overcommit] [--wait] <server> |
确认迁移
1 |
openstack server migrate confirm <server> |
撤销迁移
1 |
openstack server migrate revert <server> |
将服务器在另外一个宿主机上重建。这个命令的使用场景是:实例已经运行,但是后来它所在的宿主机宕掉了。 也就是说,仅当管理此实例的compute service宕机了,才可以使用此命令。
如果服务器实例使用临时的(ephemeral)root磁盘,此磁盘位于非共享存储上,则使用原始的glance镜像重建服务器。连接到原实例的port、挂载的卷被保留。
如果服务器实例从volume启动,或者跟磁盘位于共享存储上,则新建实例会重用此启动盘。
暂停服务器,状态保存在内存中
1 |
openstack server pause <server> [<server> ...] |
取消暂停服务器
1 |
openstack server unpause <server> [<server> ...] |
暂停服务器,状态保存在磁盘中
1 |
openstack server suspend <server> [<server> ...] |
从暂停中恢复
1 |
openstack server resume <server> [<server> ...] |
回退状态为软删除的服务器
1 |
openstack server restore <server> [<server> ...] |
重启服务器
1 2 |
# 强行立即重启 openstack server reboot [--hard | --soft] [--wait] <server> |
启动服务器
1 |
openstack server start <server> [<server> ...] |
停止服务器
1 |
openstack server stop <server> [<server> ...] |
重建服务器
1 2 3 4 5 6 7 8 |
openstack server rebuild [--image <image>] [--password <password>] [--property <key=value>] [--description <description>] [--key-name <key-name> | --key-unset] [--wait] <server> |
让服务器进入rescue模式
1 2 3 4 |
openstack server rescue [--image <image>] [--password <password>] <server> |
从rescue模式恢复:
1 |
openstack server unrescue <server> |
将服务器实例作为镜像,保存在glance中,然后在宿主机上删除此服务器
1 |
openstack server shelve <server> [<server> ...] |
将shelve的实例恢复
1 2 3 4 |
openstack server unshelve [--availability-zone AVAILABILITY_ZONE] <server> [<server> ...] |
通过SSH连接到服务器
1 2 3 4 5 6 7 8 9 10 11 12 |
openstack server ssh [--login <login-name>] [--port <port>] [--identity <keyfile>] [--option <config-options>] [-4 | -6] [--public | --private | --address-type <address-type>] <server> # 自动使用当前用户的SSH key openstack server ssh --private -4 --login cirros cirros-amd64-0 |
创建服务器的Dump文件。这会触发一个crash dump(例如Linux的kdump)
1 |
openstack server dump create <server> [<server> ...] |
(软)删除服务器
1 |
openstack server delete [--wait] <server> [<server> ...] |
设置服务器属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
openstack server set [--name <new-name>] [--root-password] [--property <key=value>] [--state <state>] [--description <description>] [--tag <tag>] <server> openstack server unset [--property <key>] [--description] [--tag <tag>] <server> |
锁定实例,这样非admin用户就不能对它进行任何操作。
1 |
openstack server lock [--reason <reason>] <server> [<server> ...] |
解锁服务器
1 |
openstack server unpause <server> [<server> ...] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
openstack server list [--sort-column SORT_COLUMN] [--availability-zone <availability-zone>] [--reservation-id <reservation-id>] [--ip <ip-address-regex>] [--ip6 <ip-address-regex>] [--name <name-regex>] [--instance-name <server-name>] [--status <status>] [--flavor <flavor>] [--image <image>] [--host <hostname>] [--all-projects] [--project <project>] [--project-domain <project-domain>] [--user <user>] [--user-domain <user-domain>] [--long] [-n | --name-lookup-one-by-one] [--marker <server>] [--limit <num-servers>] [--deleted] [--changes-before <changes-before>] [--changes-since <changes-since>] [--locked | --unlocked] [--tags <tag>] [--not-tags <tag>] |
1 2 |
# 显示诊断信息 openstack server show [--diagnostics] <server> |
备份一个运行中的服务器实例,将其磁盘保存为镜像,存放在Glance中。
1 2 3 4 5 6 7 8 9 10 |
# 创建备份 openstack server backup create # 备份镜像的名字,默认为服务器名 [--name <image-name>] # 填充镜像的backup_type字段 [--type <backup-type>] # 保存的备份数量 [--rotate <count>] [--wait] <server> |
从运行中的实例创建磁盘镜像,并存放到Glance中。
1 |
openstack server image create [--name <image-name>] [--wait] <server> |
服务器事件,记录了针对服务器的各种操作。事件由操作类型(create, delete, reboot ...)+ 操作结果(success, error) + 开始/结束时间组成。
1 2 3 4 5 6 7 8 |
# 事件列表 openstack server event list [--sort-column SORT_COLUMN] [--long] <server> # 显示事件 openstack server event show <server> <request-id> |
一个网络服务提供者,表示一个特定的、实现了网络服务的驱动:
1 |
openstack network service provider list [--sort-column SORT_COLUMN] |
所谓网络,是指一个独立的(isolated)的L2网段。OpenStack具有两种类型的网络:
- project:完全隔离的、不和其它项目共享的网络。自服务网络
- provider:映射到现有的、数据中心中的物理网络,为server或其它资源提供外部网络访问
仅仅管理员可以创建provider网络
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
openstack network create # 是否允许跨项目共享 [--share | --no-share] # 是否启用网络 [--enable | --disable] # 所属项目 [--project <project>] [--description <description>] # MTU设置 [--mtu <mtu>] [--project-domain <project-domain>] # 在什么AZ中创建此网络。需要Network Availability Zone扩展 # 此选项可以指定多次,表示网络跨越多个AZ [--availability-zone-hint <availability-zone>] # 是否启用端口安全,如果指定,则此网络上创建的端口自动应用安全设置 [--enable-port-security | --disable-port-security] # 是否外部网络,如果是,则需要external-net扩展 [--external | --internal] # 是否作为默认外部网络 [--default | --no-default] # 应用到此网络的QoS策略 [--qos-policy <qos-policy>] # 指定此网络是VLAN透明的 [--transparent-vlan | --no-transparent-vlan] # 此虚拟网络所基于其实现的物理机制(physical mechanism) # 例如 flat, geneve, gre, local, vlan, vxlan [--provider-network-type <provider-network-type>] # 此虚拟网络所基于的物理网络的名字 [--provider-physical-network <provider-physical-network>] # 对于VLAN网络,指定VLAN ID # 对于GENEVE/GRE/VXLAN,指定Tunnel ID [--provider-segment <provider-segment>] # 此网络的DNS domain,需要DNS integration扩展 [--dns-domain <dns-domain>] [--tag <tag> | --no-tag] # IPv4的CIDR --subnet <subnet> <name> openstack network delete <network> [<network> ...] openstack network list [--sort-column SORT_COLUMN] [--external | --internal] [--long] [--name <name>] [--enable | --disable] [--project <project>] [--project-domain <project-domain>] [--share | --no-share] [--status <status>] [--provider-network-type <provider-network-type>] [--provider-physical-network <provider-physical-network>] [--provider-segment <provider-segment>] [--agent <agent-id>] [--tags <tag>[,<tag>,...]] [--any-tags <tag>[,<tag>,...]] [--not-tags <tag>[,<tag>,...]] [--not-any-tags <tag>[,<tag>,...]] openstack network set [--name <name>] [--enable | --disable] [--share | --no-share] [--description <description] [--mtu <mtu] [--enable-port-security | --disable-port-security] [--external | --internal] [--default | --no-default] [--qos-policy <qos-policy> | --no-qos-policy] [--tag <tag>] [--no-tag] [--provider-network-type <provider-network-type>] [--provider-physical-network <provider-physical-network>] [--provider-segment <provider-segment>] [--dns-domain <dns-domain>] <network> openstack network unset [--tag <tag> | --all-tag] <network> openstack network show <network> |
子网是一段IP地址以及关联的配置状态。当新的Port接入到网络中时,子网用于向Port分配IP地址。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
openstack subnet create [--project <project>] [--project-domain <project-domain>] # --subnet-pool 该子网从此池中获得自己的CIDR # --use-default-subnet-pool 使用默认的子网池 [--subnet-pool <subnet-pool> | --use-prefix-delegation USE_PREFIX_DELEGATION | --use-default-subnet-pool] # 从子网池中分配子网时,前缀的长度 [--prefix-length <prefix-length>] # CIDR格式的子网IP地址范围 [--subnet-range <subnet-range>] # 是否启用DHCP [--dhcp | --no-dhcp] # 是否在DNS中发布固定IP [--dns-publish-fixed-ip | --no-dns-publish-fixed-ip] # 指定子网的网关。三种形式: # <ip-address> 将指定的IP地址作为网关 # auto 自动在子网内部选择网关地址,默认 # none 不使用网关 [--gateway <gateway>] # 子网的IP版本,如果使用了subnet pool,则IP版本取决于子网池,该选项被忽略 [--ip-version {4,6}] # IPv6 RA(Router Advertisement)模式 [--ipv6-ra-mode {dhcpv6-stateful,dhcpv6-stateless,slaac}] # IPv6地址模式 [--ipv6-address-mode {dhcpv6-stateful,dhcpv6-stateless,slaac}] # 关联到此子网的网段,网段属于某个网络 [--network-segment <network-segment>] # 此子网所属的网络 --network <network> [--description <description>] # 此子网的DHCP自动分配IP地址的范围。可以指定多个 [--allocation-pool start=<ip-address>,end=<ip-address>] # 此子网使用的DNS服务器 [--dns-nameserver <dns-nameserver>] # 为子网添加额外的路由,示例 destination=10.10.0.0/16,gateway=192.168.71.254 网关为下一跳地址 [--host-route destination=<subnet>,gateway=<ip-address>] # 子网的服务类型,必须指定为有效的、某个网络端口的device owner,例如network:floatingip_agent_gateway # 可以指定多个,以支持多个服务类型 [--service-type <service-type>] [--tag <tag> | --no-tag] <name> openstack subnet delete <subnet> [<subnet> ...] openstack subnet list [--sort-column SORT_COLUMN] [--long] [--ip-version <ip-version>] [--dhcp | --no-dhcp] [--service-type <service-type>] [--project <project>] [--project-domain <project-domain>] [--network <network>] [--gateway <gateway>] [--name <name>] [--subnet-range <subnet-range>] [--tags <tag>[,<tag>,...]] [--any-tags <tag>[,<tag>,...]] [--not-tags <tag>[,<tag>,...]] [--not-any-tags <tag>[,<tag>,...]] openstack subnet show <subnet> openstack subnet set [--name <name>] [--dhcp | --no-dhcp] [--dns-publish-fixed-ip | --no-dns-publish-fixed-ip] [--gateway <gateway>] [--network-segment <network-segment>] [--description <description>] [--tag <tag>] [--no-tag] [--allocation-pool start=<ip-address>,end=<ip-address>] [--no-allocation-pool] [--dns-nameserver <dns-nameserver>] [--no-dns-nameservers] [--host-route destination=<subnet>,gateway=<ip-address>] [--no-host-route] [--service-type <service-type>] <subnet> openstack subnet unset [--allocation-pool start=<ip-address>,end=<ip-address>] [--dns-nameserver <dns-nameserver>] [--host-route destination=<subnet>,gateway=<ip-address>] [--service-type <service-type>] [--tag <tag> | --all-tag] <subnet> |
子网池中包含若干CIDR格式的子网前缀,这些前缀用于分配给子网。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# 创建一个子网池 openstack subnet pool create # 子网池的前缀 --pool-prefix <pool-prefix> # 子网池默认前缀长度 [--default-prefix-length <default-prefix-length>] # 最小/最大前缀长度 [--min-prefix-length <min-prefix-length>] [--max-prefix-length <max-prefix-length>] [--project <project>] [--project-domain <project-domain>] # 关联到此池的address scope对象的名字或ID [--address-scope <address-scope>] # 是否作为默认子网池 [--default | --no-default] [--share | --no-share] [--description <description>] # 默认的,每个项目的配额 —— 可以从池中分配的IP数量 [--default-quota <num-ip-addresses>] [--tag <tag> | --no-tag] <name> openstack subnet pool delete <subnet-pool> [<subnet-pool> ...] openstack subnet pool list [--sort-column SORT_COLUMN] [--long] [--share | --no-share] [--default | --no-default] [--project <project>] [--project-domain <project-domain>] [--name <name>] [--address-scope <address-scope>] [--tags <tag>[,<tag>,...]] [--any-tags <tag>[,<tag>,...]] [--not-tags <tag>[,<tag>,...]] [--not-any-tags <tag>[,<tag>,...]] openstack subnet pool show <subnet-pool> openstack subnet pool set [--name <name>] [--pool-prefix <pool-prefix>] [--default-prefix-length <default-prefix-length>] [--min-prefix-length <min-prefix-length>] [--max-prefix-length <max-prefix-length>] [--address-scope <address-scope> | --no-address-scope] [--default | --no-default] [--description <description>] [--default-quota <num-ip-addresses>] [--tag <tag>] [--no-tag] <subnet-pool> openstack subnet pool unset [--tag <tag> | --all-tag] <subnet-pool> |
表示IPv4或IPv6的地址范围,属于某个特定项目,可以被多个项目共享。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# 创建地址范围 openstack address scope create [--ip-version {4,6}] [--project <project>] [--project-domain <project-domain>] # 是否可以在项目之间共享 [--share | --no-share] <name> openstack address scope delete <address-scope> [<address-scope> ...] openstack address scope list [--sort-column SORT_COLUMN] [--name <name>] [--ip-version <ip-version>] [--project <project>] [--project-domain <project-domain>] [--share | --no-share] openstack address scope set [--name <name>] [--share | --no-share] <address-scope> openstack address scope show <address-scope> |
虚拟路由器是一个逻辑组件,能够在不同网络之间分发数据包。虚拟路由器也提供L3和NAT转发功能,让虚拟网络中的服务器能够访问外部流量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# 将端口添加到路由器 openstack router add port <router> <port> openstack router remove port <router> <port> # 将子网连接到路由器 openstack router add subnet <router> <subnet> openstack router remove subnet <router> <subnet> # 在路由器的路由表中添加一个静态路由 openstack router add route [--route destination=<subnet>,gateway=<ip-address>] <router> openstack router remove route [--route destination=<subnet>,gateway=<ip-address>] <router> # 创建路由器 openstack router create [--enable | --disable] # 集中还是分布式的 [--distributed | --centralized] # 是否高可用 [--ha | --no-ha] [--description <description>] [--project <project>] [--project-domain <project-domain>] [--availability-zone-hint <availability-zone>] [--tag <tag> | --no-tag] <name> # 删除路由器 openstack router delete <router> [<router> ...] # 列出路由器 openstack router list [--sort-column SORT_COLUMN] [--name <name>] [--enable | --disable] [--long] [--project <project>] [--project-domain <project-domain>] [--agent <agent-id>] [--tags <tag>[,<tag>,...]] [--any-tags <tag>[,<tag>,...]] [--not-tags <tag>[,<tag>,...]] [--not-any-tags <tag>[,<tag>,...]] # 设置属性 openstack router set [--name <name>] [--description <description>] [--enable | --disable] [--distributed | --centralized] [--route destination=<subnet>,gateway=<ip-address>] [--no-route] [--ha | --no-ha] [--external-gateway <network>] [--fixed-ip subnet=<subnet>,ip-address=<ip-address>] [--enable-snat | --disable-snat] [--qos-policy <qos-policy> | --no-qos-policy] [--tag <tag>] [--no-tag] <router> openstack router unset [--route destination=<subnet>,gateway=<ip-address>] [--external-gateway] [--qos-policy] [--tag <tag> | --all-tag] <router> # 显示路由器信息 openstack router show <router> |
端口是网络上的接入点,它可以将单个设备(例如server上的NIC)连接到网络。端口也描述了其关联的网络配置,例如MAC地址、IP地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
openstack port create # 端口所属的网络 --network <network> [--description <description>] # 端口的设备ID [--device <device-id>] # 端口的MAC地址 [--mac-address <mac-address>] # 使用端口的实体,例如network:dhcp [--device-owner <device-owner>] # 端口的VNIC类型。默认normal # direct | direct-physical | macvtap | normal | baremetal | virtio-forwarder [--vnic-type <vnic-type>] # 在宿主机上分配端口 [--host <host-id>] # 此端口所属的DNS域 [--dns-domain dns-domain] # 此端口的DNS名称 [--dns-name <dns-name>] # 调度此端口所需的NUMA亲和性策略 [--numa-policy-required | --numa-policy-preferred | --numa-policy-legacy] # 此端口期望的IP和/或子网。可以指定多次 [--fixed-ip subnet=<subnet>,ip-address=<ip-address> | --no-fixed-ip] [--binding-profile <binding-profile>] # 启用/禁用端口 [--enable | --disable] # 启用uplink状态传播 [--enable-uplink-status-propagation | --disable-uplink-status-propagation] [--project <project>] [--project-domain <project-domain>] # 额外分配给此端口的DHCP选项 [--extra-dhcp-option name=<name>[,value=<value>,ip-version={4,6}]] # 关联到此端口的安全组 [--security-group <security-group> | --no-security-group] # 关联到此端口的QoS策略 [--qos-policy <qos-policy>] # 是否启用端口安全 [--enable-port-security | --disable-port-security] # 添加允许的IP/MAC地址。可以指定多次 # 不被允许的IP地址,不能作为发往此端口的IP目的地址 [--allowed-address ip-address=<ip-address>[,mac-address=<mac-address>]] [--tag <tag> | --no-tag] <name> openstack port delete <port> [<port> ...] openstack port list [--sort-column SORT_COLUMN] [--device-owner <device-owner>] [--host <host-id>] [--network <network>] [--router <router> | --server <server> | --device-id <device-id>] [--mac-address <mac-address>] [--long] [--project <project>] [--project-domain <project-domain>] [--fixed-ip subnet=<subnet>,ip-address=<ip-address>,ip-substring=<ip-substring>] [--tags <tag>[,<tag>,...]] [--any-tags <tag>[,<tag>,...]] [--not-tags <tag>[,<tag>,...]] [--not-any-tags <tag>[,<tag>,...]] openstack port set [--description <description>] [--device <device-id>] [--mac-address <mac-address>] [--device-owner <device-owner>] [--vnic-type <vnic-type>] [--host <host-id>] [--dns-domain dns-domain] [--dns-name <dns-name>] [--numa-policy-required | --numa-policy-preferred | --numa-policy-legacy] [--enable | --disable] [--name <name>] [--fixed-ip subnet=<subnet>,ip-address=<ip-address>] [--no-fixed-ip] [--binding-profile <binding-profile>] [--no-binding-profile] [--qos-policy <qos-policy>] [--security-group <security-group>] [--no-security-group] [--enable-port-security | --disable-port-security] [--allowed-address ip-address=<ip-address>[,mac-address=<mac-address>]] [--no-allowed-address] [--data-plane-status <status>] [--tag <tag>] [--no-tag] <port> openstack port unset [--fixed-ip subnet=<subnet>,ip-address=<ip-address>] [--binding-profile <binding-profile-key>] [--security-group <security-group>] [--allowed-address ip-address=<ip-address>[,mac-address=<mac-address>]] [--qos-policy] [--data-plane-status] [--numa-policy] [--tag <tag> | --all-tag] <port> openstack port show <port> |
安全组是虚拟的网络防火墙,网络中的服务器、端口等资源可以受其影响。
安全组是安全组规则的容器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# 创建安全组 openstack security group create [--description <description>] [--project <project>] # 是否五状态 [--stateful | --stateless] [--project-domain <project-domain>] [--tag <tag> | --no-tag] <name> openstack security group delete <group> [<group> ...] openstack security group list [--sort-column SORT_COLUMN] [--project <project>] [--project-domain <project-domain>] [--tags <tag>[,<tag>,...]] [--any-tags <tag>[,<tag>,...]] [--not-tags <tag>[,<tag>,...]] [--not-any-tags <tag>[,<tag>,...]] [--all-projects] openstack security group set [--name <new-name>] [--description <description>] [--stateful | --stateless] [--tag <tag>] [--no-tag] <group> openstack security group unset [--tag <tag> | --all-tag] <group> openstack security group show <group> |
安全组中的一条规则。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# 创建一条规则 openstack security group rule create # 此规则针对的远程IP,可以使用CIDR # 0.0.0.0/0 表示默认IPv4规则 # ::/0 表示默认IPv6规则 [--remote-ip <ip-address> | --remote-group <group>] # 目标(远程)端口。可以使用端口范围,例如 137:139 # 对于TCP/UDP必须,对于ICMP忽略此字段 [--dst-port <port-range>] # 协议: 默认any表示任何协议 # ah, dccp, egp, esp, gre, icmp, igmp, ipv6-encap, ipv6-frag, ipv6-icmp, ipv6-nonxt, # ipv6-opts, ipv6-route, ospf, pgm, rsvp, sctp, tcp, udp, udplite, vrrp [--protocol <protocol>] [--description <description>] # 针对特定的ICMP类型 [--icmp-type <icmp-type>] [--icmp-code <icmp-code>] # 此规则针对入站还是出站流量,默认ingress [--ingress | --egress] # 以太网上的流量类型 IPv4, IPv6 [--ethertype <ethertype>] [--project <project>] [--project-domain <project-domain>] # 所属的组 <group> openstack security group rule delete <rule> [<rule> ...] openstack security group rule list [--sort-column SORT_COLUMN] [--protocol <protocol>] [--ethertype <ethertype>] [--ingress | --egress] [--long] [--all-projects] [<group>] openstack security group rule show <rule> # 完全开放默认安全组 openstack security group rule create --remote-ip 0.0.0.0/0 --protocol any --ingress --ethertype IPv4 default openstack security group rule create --remote-ip ::/0 --protocol any --ingress --ethertype IPv6 default openstack security group rule create --remote-ip 0.0.0.0/0 --protocol any --egress --ethertype IPv4 default openstack security group rule create --remote-ip ::/0 --protocol any --egress --ethertype IPv6 default |
可以让管理员快速的设置某个项目的外部连接性。每个项目只能有一个此对象。
1 2 3 4 5 6 7 8 9 |
openstack network auto allocated topology create [--project <project>] [--project-domain <project-domain>] [--check-resources] [--or-show] openstack network auto allocated topology delete [--project <project>] [--project-domain <project-domain>] |
扩展network flavor允许用户在创建资源时,选择管理员配置的“网络风格”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# 添加一个service profile到network flavor openstack network flavor add profile <flavor> <service-profile> openstack network flavor remove profile <flavor> <service-profile> # 创建network flavor openstack network flavor create # 此flavor应用到的网络服务类型,例如VPN # 执行 openstack network service provider list 获得网络服务类型列表 --service-type <service-type> [--description DESCRIPTION] [--project <project>] [--project-domain <project-domain>] [--enable | --disable] <name> openstack network flavor delete <flavor> [<flavor> ...] openstack network flavor list [--sort-column SORT_COLUMN] openstack network flavor set [--description DESCRIPTION] [--disable | --enable] [--name <name>] <flavor> openstack network flavor show <flavor> |
用于管理员创建/删除/列出/显示网络服务的profile。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
openstack network flavor profile create [--project <project>] [--project-domain <project-domain>] [--description <description>] [--enable | --disable] [--driver DRIVER] [--metainfo METAINFO] openstack network flavor profile delete <flavor-profile> [<flavor-profile> ...] openstack network flavor profile list [--sort-column SORT_COLUMN] openstack network flavor profile set [--project-domain <project-domain>] [--description <description>] [--enable | --disable] [--driver DRIVER] [--metainfo METAINFO] <flavor-profile> openstack network flavor profile show <flavor-profile> |
允许管理员来度量某个IP范围的流量。需要L3 metering extension
1 2 3 4 5 6 7 8 9 10 11 12 |
openstack network meter create [--description <description>] [--project <project>] [--project-domain <project-domain>] [--share | --no-share] <name> openstack network meter delete <meter> [<meter> ...] openstack network meter list [--sort-column SORT_COLUMN] openstack network meter show <meter> |
为某个meter设置度量网络流量的规则。需要L3 metering extension
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
openstack network meter rule create [--project <project>] [--project-domain <project-domain>] [--exclude | --include] [--ingress | --egress] [--remote-ip-prefix <remote-ip-prefix>] [--source-ip-prefix <remote-ip-prefix>] [--destination-ip-prefix <remote-ip-prefix>] <meter> openstack network meter rule delete <meter-rule-id> [<meter-rule-id> ...] openstack network meter rule list [--sort-column SORT_COLUMN] openstack network meter rule show <meter-rule-id> |
将一组网络QoS规则组合到一起,可以应用到一个网络或端口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
openstack network qos policy create [--description <description>] [--share | --no-share] [--project <project>] [--project-domain <project-domain>] [--default | --no-default] <name> openstack network qos policy delete <qos-policy> [<qos-policy> ...] openstack network qos policy list [--sort-column SORT_COLUMN] [--project <project>] [--project-domain <project-domain>] [--share | --no-share] openstack network qos policy set [--name <name>] [--description <description>] [--share | --no-share] [--default | --no-default] <qos-policy> openstack network qos policy show <qos-policy> |
上述policy中的一个规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
openstack network qos rule create # QoS规则类型 # minimum-bandwidth, dscp-marking, bandwidth-limit [--type <type>] # 最大带宽 [--max-kbps <max-kbps>] # 最大突发带宽。如果不指定或者设置为0表示自动,为80%的最大带宽,适合于典型的TCP流量 [--max-burst-kbits <max-burst-kbits>] # DSCP标记,可以是0,或者8-56之间的偶数(42 44 50 52 54不可以) [--dscp-mark <dscp-mark>] # 最小保障的带宽 [--min-kbps <min-kbps>] # 此规则是用于入站还是出站的流量(从当前项目的角度) [--ingress | --egress] # 此规则加到哪个策略中 <qos-policy> openstack network qos rule delete <qos-policy> <rule-id> openstack network qos rule list [--sort-column SORT_COLUMN] <qos-policy> openstack network qos rule set [--max-kbps <max-kbps>] [--max-burst-kbits <max-burst-kbits>] [--dscp-mark <dscp-mark>] [--min-kbps <min-kbps>] [--ingress | --egress] <qos-policy> <rule-id> openstack network qos rule show <qos-policy> <rule-id> |
表示一个网络中的隔离的L2的段。一个(虚拟)网络可以包含多个段,同一个网络中的段的L2通信不被保证。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# 创建一个网络段 openstack network segment create [--description <description>] # 物理网络的名字 [--physical-network <physical-network>] # 段的名字 [--segment <segment>] # 此段属于的虚拟网络的名字 --network <network> # 此段的网络类型:flat, geneve, gre, local, vlan, vxlan --network-type <network-type> <name> openstack network segment delete <network-segment> [<network-segment> ...] openstack network segment list [--sort-column SORT_COLUMN] [--long] [--network <network>] openstack network segment set [--description <description>] [--name <name>] <network-segment> openstack network segment show <network-segment> |
用于多租户下的网络段分配。可以让管理员全局的,或者基于用户的,来控制网络段范围。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
openstack network segment range create [--private | --shared] [--project <project>] [--project-domain <project-domain>] --network-type <network-type> [--physical-network <physical-network-name>] --minimum <minimum-segmentation-id> --maximum <maximum-segmentation-id> <name> openstack network segment range delete <network-segment-range> [<network-segment-range> ...] openstack network segment range list [--sort-column SORT_COLUMN] [--long] [--used | --unused] [--available | --unavailable] openstack network segment range set [--name <name>] [--minimum <minimum-segmentation-id>] [--maximum <maximum-segmentation-id>] <network-segment-range> openstack network segment range show <network-segment-range> |
所谓网络代理,负责(在节点上)处理各种任务,以实现虚拟网络。网络代理包括:
- neutron-dhcp-agent,负责提供DHCP服务给虚拟机
- neutron-l3-agent,负责在自服务网络中提供路由
- neutron-metering-agent
- neutron-lbaas-agent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# 添加网络到代理 openstack network agent add network [--dhcp] <agent-id> <network> openstack network agent remove network [--dhcp] <agent-id> <network> # 添加路由器到代理 openstack network agent add router [--l3] <agent-id> <router> openstack network agent remove router [--l3] <agent-id> <router> # 删除代理 openstack network agent delete <network-agent> [<network-agent> ...] # 设置代理属性 openstack network agent set [--description <description>] [--enable | --disable] <network-agent> # 列出代理 openstack network agent list [--sort-column SORT_COLUMN] [--agent-type <agent-type>] [--host <host>] [--network <network> | --router <router>] [--long] # 显示代理详细信息 openstack network agent show <network-agent> |
显示网络可用的IP地址
1 2 3 4 5 |
# IP可用数量 openstack ip availability list # 显示详细信息 openstack ip availability show <network> |
管理浮动IP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# 创建一个浮动IP openstack floating ip create # 在哪个子网上创建浮动IP [--subnet <subnet>] # 浮动IP授予哪个端口 [--port <port>] # 浮动IP的值 [--floating-ip-address <ip-address>] # 映射到浮动IP的固定IP [--fixed-ip-address <ip-address>] # 浮动IP的QoS策略 [--qos-policy <qos-policy>] [--description <description>] [--project <project>] # 浮动IP的DNS名 [--dns-domain <dns-domain>] [--dns-name <dns-name>] [--project-domain <project-domain>] # 添加标记 [--tag <tag> | --no-tag] # 从什么网络来分配浮动IP <network> openstack floating ip unset [--port] [--qos-policy] [--tag <tag> | --all-tag] <floating-ip> openstack floating ip delete <floating-ip> [<floating-ip> ...] openstack floating ip set [--port <port>] [--fixed-ip-address <ip-address>] [--description <description>] [--qos-policy <qos-policy> | --no-qos-policy] [--tag <tag>] [--no-tag] <floating-ip> openstack floating ip show <floating-ip> openstack floating ip list [--sort-column SORT_COLUMN] [--network <network>] [--port <port>] [--fixed-ip-address <ip-address>] [--floating-ip-address <ip-address>] [--long] [--status <status>] [--project <project>] [--project-domain <project-domain>] [--router <router>] [--tags <tag>[,<tag>,...]] [--any-tags <tag>[,<tag>,...]] [--not-tags <tag>[,<tag>,...]] [--not-any-tags <tag>[,<tag>,...]] |
浮动IP池管理
1 |
openstack floating ip pool list [--sort-column SORT_COLUMN] |
创建浮动IP端口转发规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
openstack floating ip port forwarding create # 端口上的固定IPv4地址,浮动IP将其作为转发目标 --internal-ip-address <internal-ip-address> # 转发到的端口 --port <port> # 固定地址上的端口 --internal-protocol-port <port-number> # 浮动IP上的端口 --external-protocol-port <port-number> # 协议 --protocol <protocol> [--description <description>] # 此转发规则针对的浮动IP(的IP或ID) <floating-ip> |
管理卷服务
1 2 3 4 5 6 7 8 9 10 |
openstack volume service list [--host <host>] [--service <service>] [--long] openstack volume service set [--enable | --disable] [--disable-reason <reason>] <host> <service> |
管理卷
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# 创建卷 openstack volume create # 卷的大小,单位GB [--size <size>] # 卷的类型 [--type <volume-type>] # 将镜像、快照或者另外一个卷,作为新卷的数据来源 [--image <image> | --snapshot <snapshot> | --source <volume> ] [--description <description>] # 指定一个alternate用户、项目 [--user <user>] [--project <project>] # 在指定可用区中创建卷 [--availability-zone <availability-zone>] # 将卷加入到一致性组 [--consistency-group <consistency-group>] [--property <key=value> [...] ] # 提供给卷调度器的提示信息 [--hint <key=value> [...] ] # 卷是否需要支持多重挂载 [--multi-attach] # 是否将卷标记为可启动磁盘 [--bootable | --non-bootable] # 是否只读卷 [--read-only | --read-write] <name> # 删除卷 openstack volume delete [--force | --purge] <volume> [<volume> ...] # 列出卷 openstack volume list [--project <project> [--project-domain <project-domain>]] [--user <user> [--user-domain <user-domain>]] [--name <name>] [--status <status>] [--all-projects] [--long] [--limit <num-volumes>] [--marker <volume>] # 显示卷的详细信息 openstack volume show <volume> # 设置卷属性 openstack volume set [--name <name>] [--size <size>] [--description <description>] [--no-property] [--property <key=value> [...] ] [--image-property <key=value> [...] ] [--state <state>] [--attached | --detached ] [--type <volume-type>] [--retype-policy <retype-policy>] [--bootable | --non-bootable] [--read-only | --read-write] <volume> openstack volume unset [--property <key>] [--image-property <key>] <volume> |
管理卷类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
openstack volume type create [--description <description>] [--public | --private] [--property <key=value> [...] ] [--project <project>] [--project-domain <project-domain>] [--encryption-provider <provider>] [--encryption-cipher <cipher>] [--encryption-key-size <key-size>] [--encryption-control-location <control-location>] <name> openstack volume type delete <volume-type> [<volume-type> ...] openstack volume type list [--long] [--default | --public | --private] [--encryption-type] openstack volume type show [--encryption-type] <volume-type> openstack volume type set [--name <name>] [--description <description>] [--property <key=value> [...] ] [--project <project>] [--project-domain <project-domain>] [--encryption-provider <provider>] [--encryption-cipher <cipher>] [--encryption-key-size <key-size>] [--encryption-control-location <control-location>] <volume-type> openstack volume type unset [--property <key> [...] ] [--project <project>] [--project-domain <project-domain>] [--encryption-type] <volume-type> |
1 2 3 4 5 6 7 |
# 显示卷后端特性 openstack volume backend capability show [--sort-column SORT_COLUMN] <host> # 列出后端池 openstack volume backend pool list [--sort-column SORT_COLUMN] [--long] |
将卷迁移到一个新的宿主机
1 2 3 4 5 6 7 8 |
openstack volume migrate # 目标主机 --host <host> # 使用一般性的,基于复制的迁移。跳过存储驱动可能的优化 [--force-host-copy] # 锁定卷,防止迁移被其它操作中止 [--lock-volume] <volume> |
管理卷的快照
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# 创建一个卷快照 openstack volume snapshot create # 目标卷 [--volume <volume>] [--description <description>] # 即使在使用中,也创建快照 [--force] [--property <key=value> [...] ] [--remote-source <key=value> [...]] <snapshot-name> openstack volume snapshot delete [--force] <snapshot> [<snapshot> ...] # 列出和显示 openstack volume snapshot list [--all-projects] [--project <project> [--project-domain <project-domain>]] [--long] [--limit <num-snapshots>] [--marker <snapshot>] [--name <name>] [--status <status>] [--volume <volume>] openstack volume snapshot show <snapshot> # 设置属性 openstack volume snapshot set [--name <name>] [--description <description>] [--no-property] [--property <key=value> [...] ] [--state <state>] <snapshot> openstack volume snapshot unset [--property <key>] <snapshot> |
管理卷备份
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# 创建卷备份 openstack volume backup create [--name <name>] [--description <description>] # 保存到哪个对象容器 [--container <container>] # 备份快照 [--snapshot <snapshot>] # 允许备份使用中的卷 [--force] # 进行增量备份 [--incremental] <volume> # 删除卷备份 openstack volume backup delete [--force] <backup> [<backup> ...] # 列出卷备份 openstack volume backup list [--sort-column SORT_COLUMN] [--long] [--name <name>] [--status <status>] [--volume <volume>] [--marker <volume-backup>] [--limit <num-backups>] [--all-projects] # 显示备份详细信息 openstack volume backup show <backup> # 导出卷备份详细信息 openstack volume backup record export <backup> # 导入卷备份详细信息 openstack volume backup record import <backup_service> <backup_metadata> # 设置属性 openstack volume backup set [--name <name>] [--description <description>] [--state <state>] <backup> |
从备份中恢复卷
1 |
openstack volume backup restore <backup> <volume> |
管理卷关联的QoS规格,将QoS规格关联到卷类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# 关联QoS规格到一个卷类型 openstack volume qos associate <qos-spec> <volume-type> volume qos disassociate # 创建一个QoS规格 openstack volume qos create [--consumer <consumer>] [--property <key=value> [...] ] <name> # 删除一个QoS规格 volume qos delete # 列出和显示 volume qos list openstack volume qos show <qos-spec> # 设置属性 openstack volume qos set [--property <key=value> [...] ] <qos-spec> openstack volume qos unset [--property <key> [...] ] <qos-spec> |
可以让一组卷同时进行快照,以保证数据一致性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# 将卷加入/移除一致性组 openstack consistency group add volume <consistency-group> <volume> [<volume> ...] openstack consistency group remove volume <consistency-group> <volume> [<volume> ...] # 创建一致性组 openstack consistency group create --volume-type <volume-type> | --consistency-group-source <consistency-group> | --consistency-group-snapshot <consistency-group-snapshot> [--description <description>] [--availability-zone <availability-zone>] [<name>] # 删除一致性组 openstack consistency group delete # 即使出错也强制删除 [--force] <consistency-group> [<consistency-group> ...] openstack consistency group list [--all-projects] [--long] openstack consistency group set [--name <name>] [--description <description>] <consistency-group> openstack consistency group show <consistency-group> |
定义Object Storage V1中的一个命名空间。
管理对象存储中的对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# 上传对象到container openstack object create [--sort-column SORT_COLUMN] [--name <name>] <container> <filename> [<filename> ...] # 删除对象 openstack object delete <container> <object> [<object> ...] # 列出对象 openstack object list [--sort-column SORT_COLUMN] [--delimiter <delimiter>] [--marker <marker>] [--end-marker <end-marker>] [--limit <num-objects>] [--long] [--all] <container> # 下载对象到本地 openstack object save [--file <filename>] <container> <object> # 设置对象属性 openstack object set --property <key =value> <container> <object> openstack object unset --property <key> <container> <object> # 显示对象信息 openstack object show <container> <object> |
账户是container - objects树结构的最根部。
1 2 3 4 |
openstack object store account set --property <key =value> openstack object store account unset --property <key> openstack object store account show |
很多功能和openstack命令重复,建议使用openstack命令,仅仅在使用某些高级特性时,才需要底层的nova命令。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
OS_USERNAME OS_PASSWORD OS_PROJECT_NAME OS_PROJECT_ID OS_PROJECT_DOMAIN_NAME OS_PROJECT_DOMAIN_ID OS_USER_DOMAIN_NAME OS_USER_DOMAIN_ID # Keystone端点URL OS_AUTH_URL OS_COMPUTE_API_VERSION OS_REGION_NAME # 逗号分隔的,受信任的镜像证书ID OS_TRUSTED_IMAGE_CERTIFICATE_IDS |
为虚拟机添加安全组
列出指定虚拟机的安全组
将虚拟机从安全组移除
创建agent build, 类似的agent-delete、agent-list、agent-modify命令完成相关CRUD操作
管理服务器聚合, 类似的aggregate-delete、aggregate-list、aggregate-update、aggregate-show命令完成相关CRUD操作
添加虚拟机到聚合中。类似的aggregate-remove-host用于移除虚拟机
缓存镜像到聚合的所有虚拟机中
更新和聚合关联的元数据
创建(基于策略的)虚拟机分组。 类似的server-group-delete、server-group-list、server-group-get命令完成相关CRUD操作
列出可用区
列出虚拟机
修改虚拟机的名字或描述
显示单个虚拟机的详细信息
SSH到虚拟机
启动虚拟机
停止虚拟机
通过创建backup类型的快照,来备份一个虚拟机
启动一个新的虚拟机
从元数据服务器上清除某个虚拟机的管理密码,不会改变实例的密码
获取虚拟机的管理密码,调用元数据服务器,而不是虚拟机自身
设置虚拟机密码
获取虚拟机控制台日志
重置虚拟机状态
锁定虚拟机,非管理员将无法对虚拟机进行操作
解锁虚拟机
在内存中暂停虚拟机
解除内存中暂停的虚拟机
暂停虚拟机到磁盘
恢复暂停到磁盘的虚拟机
重启虚拟机
重启虚拟机进入救援模式 —— 从虚拟机的初始镜像或另外一个特定镜像启动虚拟机,将当前book disk挂载为非boot disk
重启虚拟机,进入正常模式
触发虚拟机crash dump
立即关机,同时删除实例
恢复一个软删除的实例
强制删除一个虚拟机
重建(关机、re-image、启动)虚拟机
保存虚拟机为镜像
将镜像化的虚拟机恢复
将shelved的虚拟机从宿主机上删除
设置/删除虚拟机的元数据
获取虚拟机诊断信息
重建失败宿主机上的某个虚拟机
迁移虚拟机
修改虚拟机规格,即flavor
确认修改规格操作
撤销尚未确认的resize操作,虚拟机恢复原状
对指定的虚拟机进行在线迁移
中止正在进行的在线迁移。需要Nova API版本2.24+
强制结束正在进行的在线迁移
显示某次虚拟机迁移的详细信息
列出指定虚拟机的迁移
列出所有迁移
添加一个或多个tag到虚拟机,类似的server-tag-delete、server-tag-delete-all、server-tag-list、server-tag-set完成相应CRUD操作
为某个租户增加某个flavor的权限。类似的flavor-access-remove移除某个租户访问某个flavor的权限
查看某个flavor的访问权限列表
创建一个flavor。类似的 flavor-delete、flavor-list、flavor-update、flavor-show命令完成相关CRUD操作。
为某个flavor设置或清除extra_spec。
达到虚拟机的RDP控制台
得到寻机的串口控制台
得到虚拟机的Spice控制台
得到虚拟机的VNC控制台
重建失败宿主机上的所有实例
对指定宿主机上所有虚拟机执行在线迁移操作
对指定宿主机上所有虚拟机执行迁移操作
设置/删除宿主机上所有的虚拟机的元数据
列出可用的Hypervisor
列出基于指定Hypervisor的虚拟机
查看Hypervisor的详细信息
显示所有Hypervisor的总和统计信息
显示指定Hypervisor的已启动时间
通过获取虚拟机快照,来创建新的镜像
列出针对指定虚拟机的操作历史
为虚拟机添加一个网络接口(Port)
列出连接到虚拟机的Port
刷新虚拟机的网络信息
重置虚拟机的网络
添加一个卷给虚拟机
将某个卷从虚拟机移除
列出所有添加到虚拟机的卷
将指定的、已经添加到虚拟机的卷的数据,拷贝到另外一个可用(没有被其它虚拟机使用)的卷上,然后将当前挂载的卷换成新的(接收数据拷贝的哪个)
添加访问虚拟机的密钥。类似的 keypair-delete、keypair-list、keypair-show命令完成相关CRUD操作。
显示一个quota class的配额信息
更新quota class的配额值
列出租户的默认配额
为一个用户/租户删除配额,配额值恢复为默认
显示指定用户/租户的配额
为指定用户/租户更新配额
显示单个租户的用量信息
列出所有租户的用量信息
列出所有API 版本
删除服务
禁用服务
启用服务
强制停止服务
列出运行中的服务
用于bash自动补全。脚本文件位于:/etc/bash_completion.d/nova,可以直接拷贝到其它机器使用
列出针对某个用户的,存储(总计、备份、快照、卷等)用量的硬限制
创建一个卷的备份
删除一个卷备份
导出备份元数据
导入备份元数据
列出所有备份
显式的更新备份状态
从一个备份恢复
显示备份详细信息
更新一个备份
创建一个卷
删除一个或多个卷
尝试扩展一个卷的尺寸
进行故障转移,要求卷是replicated
强制删除卷,不管其状态如何
冻结并且禁用指定的卷主机
显示卷的后端的统计信息、属性
显示卷的池信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
cinder get-pools +----------+---------------------+ | Property | Value | +----------+---------------------+ | name | openstack-3@lvm#LVM | +----------+---------------------+ +----------+---------------------+ | Property | Value | +----------+---------------------+ | name | openstack-4@lvm#LVM | +----------+---------------------+ +----------+---------------------+ | Property | Value | +----------+---------------------+ | name | openstack-2@lvm#LVM | +----------+---------------------+ +----------+---------------------+ | Property | Value | +----------+---------------------+ | name | openstack-2@nfs#nfs | +----------+---------------------+ |
每个主机上的lvm后端,独立作为一个池。但是在各主机上都配置了的、指向同一NFS export的,只显示了一个池
列出所有卷
将卷迁移到一个新的主机上
为指定的卷类型设置QoS规格
创建一个QoS规格
删除一个QoS规格
解除一个QoS规格和一个卷类型的关联
解除一个QoS规格的所有关联
列出QoS规格的关联
设置/删除QoS规格的某个属性
列出所有的QoS规格
列出一个配额类(quota class)的所有配额属性
更新配额类的属性
列出租户的默认配额
为一个租户删除配额
显示某个租户的当前配额
更新一个租户的配额
列出一个租户的配额使用情况
列出一个租户的速率限制
重命名卷
在Cinder数据库中显式的重置卷的状态
修改卷的类型
将某个卷回退到某个快照
禁用一个卷服务:
1 |
cinder service-disable openstack-4@nfs cinder-volume |
要删除卷服务,需要:
1 |
cinder-manage service remove cinder-volume openstack-4@nfs |
创建卷快照
删除卷快照
列出卷快照
管理卷快照
设置或删除快照元数据
查看快照元数据
重命名快照
显式的重置快照状态
显示卷快照的信息
停止管理卷快照
接受一个卷转移(volume transfer)
创建一个卷转移
撤销一个卷转移
列出所有卷转移
显示卷转移的信息
授予指定项目(租户)访问某个卷类型的权限
列出卷类型的访问权限
移除卷类型的访问权限
配置好一个卷后端后,需要使用该命令,创建对应的卷类型,并且将类型关联到后端:
1 2 3 4 5 |
cinder type-create nfs-fast cinder type-key nfs-fast set volume_backend_name=nfs-fast cinder type-create nfs-slow cinder type-key nfs-slow set volume_backend_name=nfs-slow |
显示默认使用的卷类型:
1 2 3 4 5 6 |
cinder type-default +--------------------------------------+-------------+---------------------+-----------+ | ID | Name | Description | Is_Public | +--------------------------------------+-------------+---------------------+-----------+ | 464dc192-cc63-4aab-8466-6d4f41cd0fb4 | __DEFAULT__ | Default Volume Type | True | +--------------------------------------+-------------+---------------------+-----------+ |
通过type-update修改默认卷类型的名字,会导致出错。你必须同步修改控制节点的cinder.conf:
1 |
default_volume_type = lvm |
删除卷类型
设置/删除卷类型的额外规格(extra_spec)
列出所有卷类型
显示一个卷类型的详细信息
根据ID来更新一个卷类型的名字、描述、是否公开:
1 |
cinder type-update --name __DEFAULT__ 464dc192-cc63-4aab-8466-6d4f41cd0fb4 |
停止管理卷
将卷上传到镜像服务,作为镜像使用
本章按照官网的样例架构,搭建最小化的OpenStack集群。此集群和生产环境架构的不同之处是:
- 网络代理(networking agents)部署在控制器节点上,而非专用的网络节点
- 自服务网络(self-service networks)的隧道(Overlay)流量,通过管理网络(management network)而非专用网络传递
此集群包含如下角色的节点:
- Controller:要求2张NIC
- 部署Identity Service、Image Service、计算服务的管理部分、网络服务的管理部分、Web仪表盘,以及多种网络代理
- 部署支持性服务,包括SQL数据库、消息代理、NTP
- 可选的,部署块存储服务、对象存储服务、编排服务、遥测服务的部分组件
- Compute:要求2张NIC
- 部署计算服务的Hypervisor部分,能够操控Instance。默认Hypervisor是KVM
- 部署一个网络代理,用于将Instance连接到虚拟网络,并通过安全组为Instance提供防火墙服务
- Block Storage:可选的,为Instance提供块存储、共享文件系统服务。在本示例环境中,计算节点和块存储节点之间的流量通过管理网络传输,生产环境下应该有独立的存储网络
- Object Storage:可选的,用于对象存储的服务
推荐使用两套物理网络:
- 管理网络(management network,10.1.0.0/16):通过NAT连接到互联网。绝大部分情况下,节点需要连接到外网(例如安装软件包)时,都应该通过管理网
- 提供者网络(provider network,10.0.0.0/16):这是虚拟机的工作负载流量所使用的网络,在:
- 网络选项一(提供者网络)下,虚拟机直接连接到此网络
- 网络选项二(自服务网络)下,虚拟机连接到自服务网络,然后NAT到此网络以获得外部连接
此集群可以选用两种虚拟网络之一。
Provider networks,也就是外部网络。以最简单的方式部署OpenStack网络服务,通常基于L2(桥接/交换)服务和网络VLAN分段实现。这种选项将虚拟网络桥接到物理网络,依赖于物理网络基础设施完成L3服务。
此外,一个DHCP服务用于为Instance提供IP地址。
这种选项不支持一些高级特性,例如LBaaS、FWaaS。
所谓自服务,是指非特权账户在不需要管理员介入的情况下,管理虚拟化基础设施 —— 例如网络的能力。
这种选项通过提供L3(路由)服务来增强提供者网络,使用的是类似VXLAN之类的overlay segmentation技术。虚拟网络到物理网络的路由通过NAT实现。
OpenStack用户可以在不了解数据网络(data network)底层基础设施的情况下,创建虚拟网络。包括VLAN网络(如果L2插件被相应的配置)。
安装软件:
1 2 3 4 5 6 7 |
sudo -H pip install python-openstackclient --ignore-installed PyYAML # placement插件 sudo -H pip install osc-placement # 修复错误,将下面两个文件开头的import queue 改为 import Queue as queue sudo vim /usr/local/lib/python2.7/dist-packages/openstack/utils.py sudo vim /usr/local/lib/python2.7/dist-packages/openstack/cloud/openstackcloud.py |
配置Shell自动完成:
1 |
openstack complete | sudo tee /etc/bash_completion.d/osc.bash_completion > /dev/null |
OpenStack由一系列独立安装的、相互协作的组件构成。
1 2 3 4 |
dnf -y install centos-release-openstack-ussuri yum config-manager --set-enabled powertools dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm dnf -y upgrade |
1 |
dnf -y install telnet htop bridge-utils xterm |
略,参考Ubuntu的时钟同步
Keystone为OpenStack提供身份(Identity)服务。Keystone可以提供四种Token(代表请求者身份),样例环境使用Fernet Token,同时基于Apache HTTP Server来处理请求。
首先,你需要安装一个数据库:
1 2 |
# 安装mariadb模块 dnf -y install mariadb mariadb-server python2-PyMySQL |
创建并修改配置文件:
1 2 3 4 5 6 7 8 |
[mysqld] bind-address = 10.1.0.10 default-storage-engine = innodb innodb_file_per_table = on max_connections = 4096 collation-server = utf8_general_ci character-set-server = utf8 |
启用服务:
1 2 |
systemctl enable mariadb.service systemctl start mariadb.service |
启用安全配置:
1 |
mysql_secure_installation |
安装RabbitMQ:
1 2 3 4 |
dnf -y install rabbitmq-server systemctl enable rabbitmq-server.service systemctl start rabbitmq-server.service |
创建一个RabbitMQ用户:
1 |
rabbitmqctl add_user openstack openstack |
为用户openstack授予配置、读写权限:
1 |
rabbitmqctl set_permissions openstack ".*" ".*" ".*" |
Identity Service使用Memcached来缓存Tokens。
安装软件:
1 |
dnf -y install memcached python3-memcached |
修改配置:
1 |
OPTIONS="-l 0.0.0.0" |
启动服务:
1 2 |
systemctl enable memcached.service systemctl start memcached.service |
OpenStack组件可能需要使用Etcd来实现分布式键锁定、配置存储、跟踪服务是否存活。
安装软件:
1 |
dnf -y install etcd |
修改配置文件:
1 2 3 4 5 6 7 8 9 10 11 |
#[Member] ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="http://10.1.0.10:2380" ETCD_LISTEN_CLIENT_URLS="http://10.1.0.10:2379" ETCD_NAME="openstack" #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.1.0.10:2380" ETCD_ADVERTISE_CLIENT_URLS="http://10.1.0.10:2379" ETCD_INITIAL_CLUSTER="openstack=http://10.1.0.10:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-01" ETCD_INITIAL_CLUSTER_STATE="new" |
启动服务:
1 2 |
systemctl enable etcd systemctl start etcd |
为Keystone创建数据库和用户:
1 2 3 4 5 |
CREATE DATABASE IF NOT EXISTS keystone; GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'keystone'; GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'keystone'; |
然后,安装以下包:
1 2 |
dnf -y install openstack-keystone httpd dnf -y install python3-mod_wsgi |
编辑Keystone配置文件:
1 2 3 4 5 6 7 |
[database] # ... connection = mysql+pymysql://keystone:keystone@os.gmem.cc/keystone [token] provider = fernet |
初始化数据库:
1 |
su -s /bin/sh -c "keystone-manage db_sync" keystone |
初始化Fernet密钥存储库:
1 2 3 |
# 运行keystone的操作系统用户和组 keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone keystone-manage credential_setup --keystone-user keystone --keystone-group keystone |
启动Identity服务:
1 2 3 4 5 |
keystone-manage bootstrap --bootstrap-password keystone \ --bootstrap-admin-url http://os.gmem.cc:5000/v3/ \ --bootstrap-internal-url http://os.gmem.cc:5000/v3/ \ --bootstrap-public-url http://os.gmem.cc:5000/v3/ \ --bootstrap-region-id china |
编辑Apache配置文件:
1 |
ServerName os.gmem.cc |
将Keystone的配置文件链接到Apache配置目录:
1 |
ln -s /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/ |
启动Apache服务:
1 2 |
systemctl enable httpd.service systemctl start httpd.service |
为了后续使用OpenStack工具时进行身份验证,你需要设置环境变量(密码来自上面的 keystone-manage bootstrap 步骤):
1 2 3 4 5 6 7 |
export OS_USERNAME=admin export OS_PASSWORD=keystone export OS_PROJECT_NAME=admin export OS_USER_DOMAIN_NAME=Default export OS_PROJECT_DOMAIN_NAME=Default export OS_AUTH_URL=http://os.gmem.cc:5000/v3 export OS_IDENTITY_API_VERSION=3 |
现在,我们需要需要创建一些OpenStack对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 创建一个域 # openstack domain create --description "An Example Domain" example # 创建一个项目 # 示例环境为每个服务创建一个用户,这些用户在此项目中获得授权 openstack project create --domain default --description "Service Project" service # 常规操作(非管理)应该使用非特权的项目和用户进行 openstack project create --domain default --description "Gmem Project" gmem openstack user create --domain default --password gmem gmem openstack role create gmem openstack role add --project gmem --user gmem gmem |
Glance为OpenStack提供(虚拟机)镜像服务,Glance支持多种后端存储,本样例环境下我们直接存放在文件系统中。
首先,需要为Glance创建数据库:
1 2 3 4 |
CREATE DATABASE IF NOT EXISTS glance; GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' IDENTIFIED BY 'glance'; GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' IDENTIFIED BY 'glance'; |
使用OpenStack命令行来创建Glance的凭证信息,注意需要进行上述环境变量设置:
1 |
openstack user create --domain default --password glance glance |
为service项目中的glance用户添加admin角色:
1 |
openstack role add --project service --user glance admin |
创建Glance服务:
1 2 |
# 服务的类型 openstack service create --name glance --description "OpenStack Image" image |
为Glance服务添加一个端点:
1 |
openstack endpoint create --region china image public http://os.gmem.cc:9292 |
下面,需要安装和配置Glance组件。安装软件包:
1 |
dnf -y install openstack-glance |
修改配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
[database] connection = mysql+pymysql://glance:glance@os.gmem.cc/glance [keystone_authtoken] www_authenticate_uri = http://os.gmem.cc:5000 auth_url = http://os.gmem.cc:5000 memcached_servers = os.gmem.cc:11211 auth_type = password project_domain_name = Default user_domain_name = Default project_name = service username = glance password = glance [paste_deploy] flavor = keystone [glance_store] stores = file,http default_store = file filesystem_store_datadir = /var/lib/glance/images/ |
初始化Glance数据库:
1 |
su -s /bin/sh -c "glance-manage db_sync" glance |
启动服务:
1 2 |
systemctl enable openstack-glance-api.service systemctl start openstack-glance-api.service |
为了测试OpenStack,建议使用CirrOS镜像。
1 2 3 4 |
wget http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img openstack image create --public --disk-format qcow2 --container-format bare \ --file cirros-0.4.0-x86_64-disk.img cirros-0.4.0-amd64 |
在Stein版本之前,placement 的代码在Nova中,服务在compute REST API(nova-api)中。
Placement提供了WSGI脚本placement-api,可以在Apache/Nginx之类的WSGI-capable服务器中使用。取决于你的安装方式,该脚本可能位于/usr/bin或/usr/local/bin下面。
为Placement创建数据库:
1 2 3 |
CREATE DATABASE IF NOT EXISTS placement; GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'localhost' IDENTIFIED BY 'placement'; GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'%' IDENTIFIED BY 'placement'; |
创建用户和端点:
1 2 3 4 5 6 7 8 9 |
openstack user create --domain default --password placement placement openstack role add --project service --user placement admin openstack service create --name placement --description "Placement API" placement openstack endpoint create --region china placement public http://os.gmem.cc:8778 openstack endpoint create --region china placement internal http://os.gmem.cc:8778 openstack endpoint create --region china placement admin http://os.gmem.cc:8778 |
安装和配置Placement组件:
1 |
dnf -y install openstack-placement-api |
修改配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[placement_database] connection = mysql+pymysql://placement:placement@os.gmem.cc/placement [api] auth_strategy = keystone [keystone_authtoken] auth_url = http://os.gmem.cc:5000/v3 memcached_servers = os.gmem.cc:11211 auth_type = password project_domain_name = Default user_domain_name = Default project_name = service username = placement password = placement |
初始化数据库:
1 |
su -s /bin/sh -c "placement-manage db sync" placement |
修改Apache配置文件(否则可能计算节点nova报 You don't have permission to access this resource):
1 2 3 |
<Directory /usr/bin> Require all granted </Directory> |
重启Apache服务:
1 |
systemctl restart httpd |
创建数据库:
1 2 3 4 5 6 7 8 9 10 11 12 |
CREATE DATABASE IF NOT EXISTS nova_api; CREATE DATABASE IF NOT EXISTS nova; CREATE DATABASE IF NOT EXISTS nova_cell0; GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost' IDENTIFIED BY 'nova'; GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%' IDENTIFIED BY 'nova'; GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' IDENTIFIED BY 'nova'; GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' IDENTIFIED BY 'nova'; GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'localhost' IDENTIFIED BY 'nova'; GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'%' IDENTIFIED BY 'nova'; |
创建用户和端点:
1 2 3 4 5 6 7 |
openstack user create --domain default --password nova nova openstack role add --project service --user nova admin openstack service create --name nova --description "OpenStack Compute" compute openstack endpoint create --region china compute public http://os.gmem.cc:8774/v2.1 openstack endpoint create --region china compute internal http://os.gmem.cc:8774/v2.1 openstack endpoint create --region china compute admin http://os.gmem.cc:8774/v2.1 |
安装组件:
1 |
dnf -y install openstack-nova-api openstack-nova-conductor openstack-nova-novncproxy openstack-nova-scheduler |
修改配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
[DEFAULT] enabled_apis = osapi_compute,metadata transport_url = rabbit://openstack:openstack@os.gmem.cc:5672/ ; 管理网络的IP地址 my_ip = 10.1.0.10 [api_database] connection = mysql+pymysql://nova:nova@os.gmem.cc/nova_api [database] connection = mysql+pymysql://nova:nova@os.gmem.cc/nova [api] auth_strategy = keystone [keystone_authtoken] www_authenticate_uri = http://os.gmem.cc:5000/ auth_url = http://os.gmem.cc:5000/ memcached_servers = os.gmem.cc:11211 auth_type = password project_domain_name = Default user_domain_name = Default project_name = service username = nova password = nova [vnc] enabled = true server_listen = $my_ip server_proxyclient_address = $my_ip [glance] api_servers = http://os.gmem.cc:9292 [oslo_concurrency] lock_path = /var/lib/nova/tmp [placement] region_name = china project_domain_name = Default project_name = service auth_type = password user_domain_name = Default auth_url = http://os.gmem.cc:5000/v3 username = placement password = placement [neutron] ; 参考:安装Neutron [cinder] ; 参考:安装Cinder |
初始化数据库:
1 2 3 4 5 6 7 |
su -s /bin/sh -c "nova-manage api_db sync" nova su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova su -s /bin/sh -c "nova-manage db sync" nova |
校验一下,确保cell0和cell1正确的注册了:
1 |
su -s /bin/sh -c "nova-manage cell_v2 list_cells" nova |
启动服务:
1 2 3 4 5 6 7 8 9 10 11 |
systemctl enable \ openstack-nova-api.service \ openstack-nova-scheduler.service \ openstack-nova-conductor.service \ openstack-nova-novncproxy.service systemctl start \ openstack-nova-api.service \ openstack-nova-scheduler.service \ openstack-nova-conductor.service \ openstack-nova-novncproxy.service |
安装软件:
1 |
dnf -y install openstack-nova-compute |
修改配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
[DEFAULT] enabled_apis = osapi_compute,metadata ; 替换为该计算节点上,管理网络的IP my_ip = 10.1.0.10 [DEFAULT] transport_url = rabbit://openstack:openstack@os.gmem.cc [api] auth_strategy = keystone [keystone_authtoken] www_authenticate_uri = http://os.gmem.cc:5000/ auth_url = http://os.gmem.cc:5000/ memcached_servers = os.gmem.cc:11211 auth_type = password project_domain_name = Default user_domain_name = Default project_name = service username = nova password = nova [vnc] enabled = true server_listen = 0.0.0.0 server_proxyclient_address = $my_ip novncproxy_base_url = http://os.gmem.cc:6080/vnc_auto.html [glance] api_servers = http://os.gmem.cc:9292 [oslo_concurrency] lock_path = /var/lib/nova/tmp [placement] region_name = china project_domain_name = Default project_name = service auth_type = password user_domain_name = Default auth_url = http://os.gmem.cc:5000/v3 username = placement password = placement [libvirt] virt_type = kvm [neutron] ; 参考:安装Neutron [cinder] ; 参考:安装Cinder |
启动服务:
1 2 |
systemctl enable libvirtd.service openstack-nova-compute.service systemctl start libvirtd.service openstack-nova-compute.service |
如果nova-compute启动失败,检查日志: /var/log/nova/nova-compute.log。
最后,将该节点加入到cell数据库中:
1 2 3 4 5 6 7 8 9 10 |
# 检查计算服务列表 openstack compute service list --service nova-compute # 发现计算服务主机 # 需要在控制节点上执行 su -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova # 如果希望自动发现新的主机,可以配置控制节点的/etc/nova/nova.conf: # [scheduler] # discover_hosts_in_cells_interval = 300 |
创建数据库:
1 2 3 4 |
CREATE DATABASE IF NOT EXISTS neutron; GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY 'neutron'; GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY 'neutron'; |
创建用户和端点:
1 2 3 4 5 6 7 8 9 |
openstack user create --domain default --password neutron neutron openstack role add --project service --user neutron admin openstack service create --name neutron --description "OpenStack Networking" network openstack endpoint create --region china network public http://os.gmem.cc:9696 openstack endpoint create --region china network internal http://os.gmem.cc:9696 openstack endpoint create --region china network admin http://os.gmem.cc:9696 |
如果使用提供者网络,也就是直接将VM添加到外部网络,不提供自服务网络(以及路由器、浮动IP等),则需要使用admin或其它特权账户。步骤如下:
- 安装软件:
1dnf -y install openstack-neutron openstack-neutron-ml2 openstack-neutron-linuxbridge ebtables - 配置Neutron:
12345678910111213141516171819202122232425262728293031323334353637[database]connection = mysql+pymysql://neutron:neutron@os.gmem.cc/neutron[DEFAULT]core_plugin = ml2service_plugins =transport_url = rabbit://openstack:openstack@os.gmem.ccauth_strategy = keystonenotify_nova_on_port_status_changes = truenotify_nova_on_port_data_changes = true[keystone_authtoken]www_authenticate_uri = http://os.gmem.cc:5000auth_url = http://os.gmem.cc:5000memcached_servers = os.gmem.cc:11211auth_type = passwordproject_domain_name = defaultuser_domain_name = defaultproject_name = serviceusername = neutronpassword = neutron[nova]auth_url = http://os.gmem.cc:5000auth_type = passwordproject_domain_name = defaultuser_domain_name = defaultregion_name = chinaproject_name = serviceusername = novapassword = nova[oslo_concurrency]lock_path = /var/lib/neutron/tmp -
配置Modular Layer2(ML2)插件。此插件使用Linux bridge来为虚拟机构建L2 VNI:
1234567891011121314151617[ml2]; 启用Flat/VLAN网络type_drivers = flat,vlan; 禁用自服务网络tenant_network_types =; 启用 Linux bridge mechanismmechanism_drivers = linuxbridge; 启用端口安全扩展驱动extension_drivers = port_security[ml2_type_flat]; 配置提供者虚拟网络为Flat网络flat_networks = provider[securitygroup]; 增强安全组规则的性能enable_ipset = true -
配置Linux Bridge agent,此Agent为VM构建L2 VNI,并处理安全组:
123456789101112[linux_bridge]; 这里填写底层的提供者网络的设备名physical_interface_mappings = provider:eth0[vxlan]; 禁用VXLANenable_vxlan = false[securitygroup]; 启用安全组,配置基于iptables的防火墙驱动enable_security_group = truefirewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver -
确保宿主机内核支持Network bridge filters:
123# 二层的网桥在转发包时也会被iptables的FORWARD规则所过滤net.bridge.bridge-nf-call-iptables 1net.bridge.bridge-nf-call-ip6tables 1此外,为了支持网桥,需要加载内核模块 br_netfilter
-
配置DHCP代理,此代理为虚拟网络提供DHCP服务:
1234[DEFAULT]interface_driver = linuxbridgedhcp_driver = neutron.agent.linux.dhcp.Dnsmasqenable_isolated_metadata = true
如果使用自服务网络,不需要特权用户就可以管理网络(包括路由)并在自服务网络和提供者网络之间创建连接,也可以为VM提供浮动IP,以便从外部访问VM。步骤如下:
- 安装软件,同上
- 配置Neutron,基本同上:
12345678910111213141516171819202122232425262728293031323334353637383940[database]connection = mysql+pymysql://neutron:neutron@os.gmem.cc/neutron[DEFAULT]; 同样使用ML2插件core_plugin = ml2; 启用路由服务,允许IP重叠service_plugins = routerallow_overlapping_ips = truetransport_url = rabbit://openstack:openstack@os.gmem.ccauth_strategy = keystonenotify_nova_on_port_status_changes = truenotify_nova_on_port_data_changes = true[keystone_authtoken]www_authenticate_uri = http://os.gmem.cc:5000auth_url = http://os.gmem.cc:5000memcached_servers = os.gmem.cc:11211auth_type = passwordproject_domain_name = defaultuser_domain_name = defaultproject_name = serviceusername = neutronpassword = neutron[nova]auth_url = http://os.gmem.cc:5000auth_type = passwordproject_domain_name = defaultuser_domain_name = defaultregion_name = chinaproject_name = serviceusername = novapassword = nova[oslo_concurrency]lock_path = /var/lib/neutron/tmp -
配置Modular Layer2(ML2)插件:
123456789101112131415161718192021[ml2]; 启用Flat/VLAN/VXLANtype_drivers = flat,vlan,vxlan; 启用自服务网络,基于VXLANtenant_network_types = vxlan; 启用Linux网桥,以及Layer-2 Populationmechanism_drivers = linuxbridge,l2population; 启用端口安全扩展驱动extension_drivers = port_security[ml2_type_flat]; 配置提供者虚拟网络为Flat网络flat_networks = provider[ml2_type_vxlan]; 设置VXLAN网络标识符的范围vni_ranges = 1:1000[securitygroup]; 增强安全组规则的性能enable_ipset = true - 配置Linux Bridge agent:
123456789101112131415[linux_bridge]; 这里填写底层的提供者网络的设备名physical_interface_mappings = provider:eth0[vxlan]; 启用VXLANenable_vxlan = true; 用于处理Overlay网络的底层网络的本机IP地址local_ip = 10.1.0.10l2_population = true[securitygroup]; 启用安全组,配置基于iptables的防火墙驱动enable_security_group = truefirewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver -
确保宿主机内核支持Network bridge filters,同上
-
配置DHCP,同上
- 配置L3代理,此代理为自服务VNI提供路由、NAT:
12[DEFAULT]interface_driver = linuxbridge
自服务网络是overlay网络,使用VXLAN之类的协议,这些协议具有额外的头,导致实际可能负载减小,如果VM不知道此VNI的特征,会自动设置过大的MTU 1500。Neutron提供的DHCP能自动给VM提供正确的MTU。但是,某些云镜像不使用DHCP,或者忽略DHCP的MTU选项,需要注意。
执行完上述两种网络选项之一后,继续配置元数据代理(metadata agent) ,元数据代理代替虚拟机(附加Instance ID、Tenant ID等请求头)访问Nova metadata API,获取虚拟机镜像的配置信息:
1 2 3 4 |
[DEFAULT] nova_metadata_host = os.gmem.cc ; 设置适当的共享密钥 metadata_proxy_shared_secret = openstack |
配置计算服务(Nova)来使用网络服务:
1 2 3 4 5 6 7 8 9 10 11 |
[neutron] auth_url = http://os.gmem.cc:5000 auth_type = password project_domain_name = default user_domain_name = default region_name = china project_name = service username = neutron password = neutron service_metadata_proxy = true metadata_proxy_shared_secret = openstack |
将ML2配置链接为Neutron插件主配置文件:
1 |
ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini |
初始化数据库:
1 2 |
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 |
重启Nova:
1 |
systemctl restart openstack-nova-api.service |
启动Neutron:
1 2 3 4 5 6 |
systemctl enable neutron-server.service \ neutron-linuxbridge-agent.service neutron-dhcp-agent.service \ neutron-metadata-agent.service systemctl start neutron-server.service \ neutron-linuxbridge-agent.service neutron-dhcp-agent.service \ neutron-metadata-agent.service |
如果使用自服务网络选项,还需要启用L3服务:
1 2 |
systemctl enable neutron-l3-agent.service systemctl start neutron-l3-agent.service |
安装软件:
1 |
dnf -y install openstack-neutron-linuxbridge ebtables ipset |
配置身份验证、消息队列:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[DEFAULT] transport_url = rabbit://openstack:openstack@os.gmem.cc auth_strategy = keystone [keystone_authtoken] www_authenticate_uri = http://os.gmem.cc:5000 auth_url = http://os.gmem.cc:5000 memcached_servers = os.gmem.cc:11211 auth_type = password project_domain_name = default user_domain_name = default project_name = service username = neutron password = neutron [oslo_concurrency] lock_path = /var/lib/neutron/tmp |
配置网络选项。如果使用提供者网络:
- 配置Linux bridge Agent:
123456789[linux_bridge]physical_interface_mappings = provider:eth0[vxlan]enable_vxlan = false[securitygroup]enable_security_group = truefirewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver -
确保内核参数(通常需要保证内核模块br_netfilter已加载 ):
12net.bridge.bridge-nf-call-iptables 1net.bridge.bridge-nf-call-ip6tables 1
如果使用自服务网络:
- 配置Linux bridge Agent:
1234567891011[linux_bridge]physical_interface_mappings = provider:eth0[vxlan]enable_vxlan = truelocal_ip = 10.1.0.11l2_population = true[securitygroup]enable_security_group = truefirewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver -
同上
配置计算服务,让它使用网络服务:
1 2 3 4 5 6 7 8 9 |
[neutron] auth_url = http://os.gmem.cc:5000 auth_type = password project_domain_name = default user_domain_name = default region_name = china project_name = service username = neutron password = neutron |
重启Nova: systemctl restart openstack-nova-compute.service
启动Linux bridge Agent:
1 2 |
systemctl enable neutron-linuxbridge-agent.service systemctl start neutron-linuxbridge-agent.service |
列出已加载的扩展列表,确保Neutron相关进程启动:
1 |
openstack extension list --network |
校验Neutron代理都已经启动:
1 |
openstack network agent list |
应该启动的代理包括:
- 控制节点的元数据代理、DHCP代理、Linux bridge代理
- 计算节点的Linux bridge代理
- 如果使用自服务网络,控制节点还有L3代理
样例环境中,使用存储节点上的空白磁盘/dev/sdb ,基于LVM划分初逻辑卷,然后通过iSCSI协议暴露给虚拟机。
1 2 3 4 |
CREATE DATABASE IF NOT EXISTS cinder; GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' IDENTIFIED BY 'cinder'; GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' IDENTIFIED BY 'cinder'; |
创建用户和端点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
openstack user create --domain default --password cinder cinder openstack role add --project service --user cinder admin openstack service create --name cinderv2 --description "OpenStack Block Storage" volumev2 openstack service create --name cinderv3 --description "OpenStack Block Storage" volumev3 openstack endpoint create --region china volumev2 public http://os.gmem.cc:8776/v2/%\(project_id\)s openstack endpoint create --region china volumev2 internal http://os.gmem.cc:8776/v2/%\(project_id\)s openstack endpoint create --region china volumev2 admin http://os.gmem.cc:8776/v2/%\(project_id\)s openstack endpoint create --region china volumev3 public http://os.gmem.cc:8776/v3/%\(project_id\)s openstack endpoint create --region china volumev3 internal http://os.gmem.cc:8776/v3/%\(project_id\)s openstack endpoint create --region china volumev3 admin http://os.gmem.cc:8776/v3/%\(project_id\)s |
安装组件:
1 |
dnf -y install openstack-cinder |
修改配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
[DEFAULT] transport_url = rabbit://openstack:openstack@os.gmem.cc auth_strategy = keystone ; 管理网络接口的IP地址 my_ip = 10.1.0.10 [database] connection = mysql+pymysql://cinder:cinder@os.gmem.cc/cinder [keystone_authtoken] www_authenticate_uri = http://os.gmem.cc:5000 auth_url = http://os.gmem.cc:5000 memcached_servers = os.gmem.cc:11211 auth_type = password project_domain_name = default user_domain_name = default project_name = service username = cinder password = cinder [oslo_concurrency] lock_path = /var/lib/cinder/tmp |
初始化数据库:
1 |
su -s /bin/sh -c "cinder-manage db sync" cinder |
配置Nova来使用存储服务:
1 2 |
[cinder] os_region_name = china |
重新启动Nova:
1 |
systemctl restart openstack-nova-api.service |
启动Cinder服务:
1 2 |
systemctl enable openstack-cinder-api.service openstack-cinder-scheduler.service systemctl start openstack-cinder-api.service openstack-cinder-scheduler.service |
在本样例环境下,需要LVM支持:
1 2 3 4 |
yum install lvm2 device-mapper-persistent-data systemctl enable lvm2-lvmetad.service systemctl start lvm2-lvmetad.service |
在/dev/sdb上创建LVM物理卷,并创建名为cinder-volumes的卷组:
1 2 3 |
pvcreate /dev/sdb vgcreate cinder-volumes /dev/sdb |
只有虚拟机实例能够访问块设备卷。但是,存储节点的底层OS负责管理卷关联的块设备。默认情况下,LVM卷扫描工具会扫描/dev/目录来寻找包含卷的块设备。如果某个OpenStack项目使用基于LVM的卷,扫描工具会扫描卷并缓存结果,这可能导致很多问题。因此,你必须重新配置LVM,让它仅仅扫描包含cinder-volumes卷组的设备:
1 2 3 4 |
devices { # a表示允许允许使用的卷,r表示拒绝使用的卷 # 拒绝所有其它的卷 filter = [ "a/sdb/", "r/.*/"] |
安装组件:
1 |
dnf -y install openstack-cinder targetcli python3-keystone |
修改配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
[DEFAULT] transport_url = rabbit://openstack:openstack@os.gmem.cc auth_strategy = keystone ; 此节点启用的存储后端 enabled_backends = lvm ; 配置镜像服务的API地址 glance_api_servers = http://os.gmem.cc:9292 ; 管理网络接口的IP地址 my_ip = 10.1.0.11 [database] connection = mysql+pymysql://cinder:cinder@os.gmem.cc/cinder [keystone_authtoken] www_authenticate_uri = http://os.gmem.cc:5000 auth_url = http://os.gmem.cc:5000 memcached_servers = os.gmem.cc:11211 auth_type = password project_domain_name = default user_domain_name = default project_name = service username = cinder password = cinder [oslo_concurrency] lock_path = /var/lib/cinder/tmp [lvm] volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver volume_group = cinder-volumes target_protocol = iscsi target_helper = lioadm |
启动服务:
1 2 |
systemctl enable openstack-cinder-volume.service target.service systemctl start openstack-cinder-volume.service target.service |
OpenStack Dashboard组件,即Horizon,此组件仅仅依赖于Identity。
安装软件:
1 |
dnf -y install openstack-dashboard |
修改配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
OPENSTACK_HOST = "os.gmem.cc" WEBROOT = '/dashboard/' # 允许哪些主机访问仪表盘 ALLOWED_HOSTS = ['os.gmem.cc'] # 配置基于Memcache的分布式会话存储 SESSION_ENGINE = 'django.contrib.sessions.backends.cache' CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': 'os.gmem.cc:11211', } } # 启用Identity API v3 OPENSTACK_KEYSTONE_URL = "http://%s/identity/v3" % OPENSTACK_HOST # 确保Domain支持 OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True # 配置API版本 OPENSTACK_API_VERSIONS = { "identity": 3, "image": 2, "volume": 3, } # 默认访问的Domain OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "Default" # 通过仪表盘创建的用户的默认角色 OPENSTACK_KEYSTONE_DEFAULT_ROLE = "user" # 配置网络 OPENSTACK_NEUTRON_NETWORK = { # 如果使用提供者网络,需要禁用router 'enable_router': False, 'enable_quotas': False, 'enable_distributed_router': False, 'enable_ha_router': False, 'enable_lb': False, 'enable_firewall': False, 'enable_vpn': False, 'enable_fip_topology_check': False, } TIME_ZONE = "Asia/Shanghai" |
修改配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
WSGIDaemonProcess dashboard WSGIProcessGroup dashboard WSGISocketPrefix run/wsgi WSGIApplicationGroup %{GLOBAL} WSGIScriptAlias /dashboard /usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi Alias /dashboard/static /usr/share/openstack-dashboard/static <Directory /usr/share/openstack-dashboard/openstack_dashboard/wsgi> Options All AllowOverride All Require all granted </Directory> <Directory /usr/share/openstack-dashboard/static> Options All AllowOverride All Require all granted </Directory> |
重启服务:
1 |
systemctl restart httpd.service memcached.service |
此后你应该可以通过:http://os.gmem.cc访问仪表盘。
修改horizon主配置文件:
1 2 3 4 5 |
# 添加以下配置 USE_SSL = True CSRF_COOKIE_SECURE = True SESSION_COOKIE_SECURE = True SESSION_COOKIE_HTTPONLY = True |
修改Dashboard的httpd配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
WSGISocketPrefix run/wsgi <VirtualHost *:443> ServerName os.gmem.cc SSLEngine On SSLCertificateFile /etc/httpd/ssl/os.gmem.cc.crt SSLCACertificateFile /etc/httpd/ssl/os.gmem.cc.crt SSLCertificateKeyFile /etc/httpd/ssl/os.gmem.cc.key SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown Header add Strict-Transport-Security "max-age=15768000" WSGIDaemonProcess dashboard WSGIProcessGroup dashboard WSGIApplicationGroup %{GLOBAL} WSGIScriptAlias /dashboard /usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi Alias /dashboard/static /usr/share/openstack-dashboard/static <Directory /usr/share/openstack-dashboard/openstack_dashboard/wsgi> Options All AllowOverride All Require all granted </Directory> <Directory /usr/share/openstack-dashboard/static> Options All AllowOverride All Require all granted </Directory> </VirtualHost> |
安装必要的httpd模块:
1 |
dnf -y install mod_ssl |
在启动实例之前,你需要创建必要的VNI。如果使用网络选项一,则虚拟机通过Provider(External)网络连接到PNI(基于bridging/switching)。
网络架构如下图:
使用下面的命令在OpenStack中创建一个名为provider的网络:
1 2 3 4 5 6 7 8 9 10 11 |
# share 表示允许所有project使用此虚拟网络 # external 表示网络是外部的,默认值internal openstack network create --share --external \ # 此虚拟网络所基于的物理网络 # 此名字对应的物理网络接口在linuxbridge_agent.ini中定义 # physical_interface_mappings = provider:eth0 --provider-physical-network provider \ # 此虚拟网络的物理实现机制(physical mechanism) --provider-network-type flat \ # 网络的名字 provider |
为上述网络创建一个子网:
1 2 3 4 5 6 7 |
openstack subnet create --network provider \ # 子网中,用于分配给虚拟机实例的IP地址范围,此IP地址范围由DHCP agent管理 --allocation-pool start=10.0.100.1,end=10.0.1.255 \ # DNS服务器地址 底层物理网络的网关地址 --dns-nameserver 10.0.0.1 --gateway 10.0.0.1 \ # 底层物理网络的CIDR --subnet-range 10.0.0.0/16 provider |
前面我们提到过两个网络选项,如果使用选项1,则参考上一小节的内容创建虚拟网络。如果使用选项2,则在创建上述provider网络之后,还需要参考本节内容。
网络架构如下:
使用选项2时,需要创建一个自服务(私有)的虚拟网络,并通过NAT连接到物理网络。此虚拟网络提供DHCP服务器,并且分配IP地址给实例。在这种私有网络中的实例可以直接访问外部网络(NAT),但是外部网络不能直接访问这些实例,除非给实例分配浮动IP。
修改环境变量,使用用户gmem来操作。
创建名为gmem的自服务网络:
1 |
openstack network create gmem-net |
非特权用户通常无法为上述命令指定额外的参数。OpenStack会依据下面的配置文件来自动选择参数:
1 2 3 4 5 |
[ml2] tenant_network_types = vxlan [ml2_type_vxlan] vni_ranges = 1:1000 |
创建子网:
1 2 3 4 5 |
openstack subnet create --network gmem-net \ # 子网的网关地址,不是物理网络上的网关地址 --dns-nameserver 10.1.0.1 --gateway 192.168.100.1 \ # 子网的CIDR --subnet-range 192.168.100.0/24 gmem-subnet |
自服务网络通过一个虚拟路由器,连接到提供者网络:
1 |
openstack router create gmem-router |
将上述子网添加为此虚拟路由器的一个接口(interface):
1 |
openstack router add subnet gmem-router gmem-subnet |
将在提供者网络上的生成一个“网关“,连接到路由器:
1 |
openstack router set gmem-router --external-gateway provider |
到控制节点上进行校验,确保虚拟网络正常工作:
1 2 3 4 5 6 7 8 9 10 11 |
# 检查网络命名空间,应该至少看到: # 一个qrouter开头的 # 二个qdhcp开头的 ip netns # 列出路由器的端口,确定提供者网络上的网关地址 openstack port list --router router # 确认可以从控制节点,或者物理网络上任何节点来访问上述网关地址 |
所谓Flavor就是虚拟机的规格,例如内存多大,CPU几个,磁盘几个,等等。最小的默认Flavor消耗512MB内存,这里我们创建一个仅消耗64MB内存的Flavor:
1 |
openstack flavor create --id 0 --vcpus 1 --ram 64 --disk 1 m1.nano |
大部分的云镜像支持基于PKI的身份验证,而不是密码。在启动实例之前,我们需要为计算服务创建密钥:
1 2 3 |
openstack keypair create --public-key /home/alex/Documents/puTTY/gmem.crt default openstack keypair list |
默认的安全组应用到所有的实例, 此安全组禁止对实例的所有远程访问。对于Linux镜像例如CirrOS,我们至少应该允许ICMP(ping)以及SSH:
1 2 3 |
openstack security group rule create --proto icmp default openstack security group rule create --proto tcp --dst-port 22 default |
列出可用的基础资源:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
openstack flavor list # +----+---------+-----+------+-----------+-------+-----------+ # | ID | Name | RAM | Disk | Ephemeral | VCPUs | Is Public | # +----+---------+-----+------+-----------+-------+-----------+ # | 0 | m1.nano | 64 | 1 | 0 | 1 | True | # +----+---------+-----+------+-----------+-------+-----------+ openstack image list # +--------------------------------------+--------------------+--------+ # | ID | Name | Status | # +--------------------------------------+--------------------+--------+ # | 5b337b93-96c6-4803-b0e2-bc0bce0afde9 | cirros-0.5.1-amd64 | active | # +--------------------------------------+--------------------+--------+ openstack network list # +--------------------------------------+----------+--------------------------------------+ # | ID | Name | Subnets | # +--------------------------------------+----------+--------------------------------------+ # | 500cd78a-a05c-4b93-b399-06b26cc108de | provider | 9be1305c-a641-40f0-bd1b-6617e96025e6 | # +--------------------------------------+----------+--------------------------------------+ openstack security group list # +--------------------------------------+---------+------------------------+----------------------------------+------+ # | ID | Name | Description | Project | Tags | # +--------------------------------------+---------+------------------------+----------------------------------+------+ # | f5b0e967-5903-4b6b-9b9d-8e39a07b52da | default | Default security group | e1c4a3403e1b46cd969e4d626b5cf799 | [] | # +--------------------------------------+---------+------------------------+----------------------------------+------+ |
1 2 3 |
openstack server create --flavor m1.nano --image cirros-0.5.1-amd64 \ --nic net-id=500cd78a-a05c-4b93-b399-06b26cc108de --security-group default \ --key-name default cirros-amd64-0 |
当虚拟机构建完毕后,其状态会从BUILD变为ACTIVE:
1 |
openstack server list |
CirrOS的默认用户密码是cirros / gocubsgo,确认可以登陆。
在虚拟机的宿主机上,可以看到OpenStack创建了一个网桥,连接了提供者物理网络和虚拟机(的tap设备):
1 2 3 4 |
brctl show # bridge name bridge id STP enabled interfaces # brq1305444e-cf 8000.100000000012 no eth0 # tapa87f2880-fc |
Keystone是OpenStack的Identity服务,它负责身份验证、授权,以及一系列其它服务。Keystone可以集成到外部的用户管理系统,例如LDAP。
Keystone通常是用户首先与之交互的服务,随后用户使用他的Identity来访问其它OpenStack服务。OpenStack组件也需要访问Keystone来验证用户声明的Identity是否合法。
用户或者服务,可以利用服务目录来得到其它服务(Openstack组件)的位置,服务目录(Service catalog)也是Keystone提供的服务之一。
每个服务可以提供1-N个端点,每个端点可以是admin/internal(可能仅限于OpenStack所在主机访问)/public(可能允许Internet访问)三种类型之一。在生产环境中,这些不同类型的端点可能出于安全方面的考虑,存放在不同的网络中,供不同类型的用户访问。
代表单个API消费者:
- 用户就是一个有身份验证信息的API消费实体
- 用户可以属于多个项目/角色
代表一组User的集合。
代表OpenStack中基本的所有权单元 —— OpenStack中各种计算资源都是归属于某个特定项目的。而Project则是归属于某个Domain的。
租户(Tenant)在OpenStack中,就是项目,其目的就是隔离计算资源。
是Project、User、Role、Group的高层次容器,后面三者仅仅属于唯一一个domain。Keystone默认提供一个名为Defulat的domain。
Keystone由三类组件构成。
中心化的HTTP服务器,对外提供鉴权的RESTful接口
集成在Server里面,用于访问存放在OpenStack外部(例如LDAP或MySQL数据库)的身份信息。
运行在使用Identity service的那些OpenStack组件中,负责拦截针对这些组件的请求,抽取用户凭证信息,发送到上述Server执行鉴权。
这些Modules基于Python Web Server Gateway Interface和OpenStack组件集成。
Token类型 | UUID | PKI | PKIZ | Fernet |
大小 | 32 Byte | KB 级别 | KB 级别 | 约 255 Byte |
支持本地认证 | 不支持 | 支持 | 支持 | 不支持 |
Keystone 负载 | 大 | 小 | 小 | 大 |
存储于数据库 | 是 | 是 | 是 | 否 |
携带信息 | 无 | user, catalog 等 | user, catalog 等 | user 等 |
涉及加密方式 | 无 | 非对称加密 | 非对称加密 | 对称加密(AES) |
是否压缩 | 否 | 否 | 是 | 否 |
版本支持 | D | G | J | K |
K版本之后,通常选择Fernet Token。
Nova,即OpenStack Compute组件,负责host和管理云主机,是IaaS系统的核心组成部分。可以管理的云主机类型包括虚拟机、物理机(依赖ironic),并对容器提供有限的支持。
Nova和Keystone交互进行身份验证。Placement负责计算资源的跟踪和选择(作为实例的宿主),Glance提供虚拟机镜像,这些组件配合就能让实例运行起来。
OpenStack自身不提供虚拟化软件,而是通过“驱动”和底层的Hypervisor进行交互。交互工作主要由Nova完成。
Nova由一系列分布式的组件构成,每种组件具有自己的职责。面向用户的是一个REST API。内部组件主要通过RPC消息传递机制通信。
API组件监听到请求后,通常会进行数据库读写操作,可选的,会将RPC消息发送给其它Nova组件,然后将REST响应发给客户端。RPC消息是通过 oslo.messaging 库完成的,这个库是基于消息队列的抽象。
大部分组件可以运行在多台宿主机上,并且其中具有一个manager负责监听RPC消息、执行一些周期性工作。一个主要的例外是nova-compute,此组件和它管理的Hypervisor(除了VMware或Ironic驱动)对应,每个Hypervisor对应一个nova-compute。
Nova具有一个逻辑的、中心化的、被所有组件共享的数据库。为了辅助OpenStack升级,对数据库的访问基于一个对象层,此对象层确保一个升级后的控制平面,仍然能和低版本的nova-compute进行交互。具体实现上,nova-compute通过中心化的nova-conductor间接的访问数据库,后者提供基于RPC的接口。
安装在控制节点上。提供OpenStack Compute API,负责确保一些策略,发起大部分编排活动(例如运行实例)。
安装在控制节点上。处理处理获取实例元数据的请求。
安装在计算节点上。Worker守护进程,负责调用Hypervisor API,在计算节点上创建、终结虚拟机实例。支持的Hypervisor API包括:
- XenAPI for XenServer/XCP
- libvirt for KVM or QEMU
- VMwareAPI for VMware
该组件的大概工作流程是:
- 从消息队列里接受Action
- 调用一系列的系统命令,启动虚拟机
- 在数据库中更新实例状态
从队列中取出虚拟机实例的请求,然后决定将其调度在哪台计算节点上。
协调nova-compute s服务和数据库之间的交互。避免nova-compute直接访问数据库。该模块支持水平扩容,避免将其部署在nova-compute运行的节点。
提供一个代理,用于通过VNC协议连接到运行中的实例。
提供一个代理,用于通过SPICE协议连接到运行中的实例,支持HTML5客户端。
这个服务目前已经独立出去,它负责跟踪资源库存、使用情况。
这是一个中心化的Hub,用于在不同组件之间传递消息。通常使用RabbitMQ。
存储云基础设施的构建时、运行时状态,包括:
- 可用的实例类型
- 使用着哦个的实例
- 可用的网络
- 项目
- ……
任何SQLAlchemy支持的RDBMS都可以。
为了支持Nova部署的水平扩展,Nova引入了分片机制,每个分片叫Cell。利用Cell:
- 可以在单个Region中将计算节点的数量扩容到成千上万。每个Cell具有自己的数据库、消息队列,这是可扩容的关键
- 实现故障隔离的特性(一个Cell故障,其它Cell还可以正常工作)
- 作为一种分组机制,可以将类似的硬件放在同一Cell中
Cell V1的特性:
- 捕获并中继消息给Cell
- 处理竞态条件
- 两级调度架构
Cell V1的缺点:
- 不支持安全组、主机聚合、可用区等特性
- 顶级调度功能很弱
当Nova API接收到针对实例的前请求后,实例的信息将从数据库读取,其中包含实例的宿主机名字。如果需要针对实例进行其它操作(通常都需要),那么宿主机名字将用来计算出消息队列的名字,RPC消息随后被写入消息队列,可以到达正确的计算节点。
引入Cell后,上述逻辑将变成:
- 查找实例的三元组:宿主机名称、数据库连接信息、消息队列连接信息
- 连接到数据库,获取实例记录
- 连接到消息队列,并根据宿主机名称,选额消息队列,发送RPC消息
引入Cell V2后,不存在没有Cell的部署架构。Cell V2的优势包括:
- 数据库、消息队列的分片,成为Nova的一等特性
- 不需要在顶级复制Cell数据库,Nova API需要自己的数据库,存放例如实例索引的信息
- 在gloabl和local数据元素之间划分好了界限。Flavor、Keypair之类的全局性质对象,仅仅需要存储在顶级。这样计算节点更加无状态化,不会被全局数据的修改所干扰
所有Nova部署中,都需要一个名为API的数据库,一个特殊的Cell数据库cell0,1-N个cell的数据库。高层次的跟踪信息存放在API数据库中,哪些从未调度成功的实例,存放在cell0。所有成功调度的/运行的实例,都放在其它cell数据库中。
你需要将API数据库的信息配置在nova.conf:
1 2 |
[api_database] connection = mysql+pymysql://nova:nova@os.gmem.cc/nova_api?charset=utf8 |
由于cell数据库数量不定,此外任何部署都至少有cell0和cell1(唯一的Cell使用),因此这些Cell的连接信息,是写在API数据库中(而不是静态编写在文件)的。
1 2 3 4 5 6 7 8 |
# 后续命令需要读写API数据库,因此首先执行api_db sync子命令来初始化schema su -s /bin/sh -c "nova-manage api_db sync" nova # 为cell0的数据库创建记录 nova-manage cell_v2 map_cell0 --database_connection \ mysql+pymysql://nova:nova@os.gmem.cc/nova_cell0 # 如果不指定--database_connection,就像样例环境那样,则自动使用[database]/connection字段 # 中的连接串,但是在结尾添加_cell0后缀 |
由于cell0中不会存在任何宿主机,不需要对它进行进一步配置。
现在,你需要创建第一个常规cell:
1 2 3 4 5 6 7 |
# 如果不指定 --database_connection、--transport-url,就像样例环境那样, # 则自动使用 [database]/connection 和 [DEFAULT]/transport_url su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova nova-manage cell_v2 create_cell --verbose --name cell1 \ --database_connection mysql+pymysql://nova:nova@os.gmem.cc/nova --transport-url rabbit://openstack:openstack@os.gmem.cc |
如果为cell1准备的数据库是空白的,你需要同步数据库schema:
1 |
su -s /bin/sh -c "nova-manage db sync" nova |
现在,cell1中没有任何宿主机,因此nova-scheduler不会把实例调度到此cell中。
使用下面的命令,可以扫描数据库中计算节点的记录,并将其添加到刚刚创建的cell中。执行命令之前,至少需要安装一个计算节点并添加到cell。
1 |
nova-manage cell_v2 discover_hosts |
上述命令会连接到所有cell数据库,扫描将自己注册到cell的宿主机,然后在API数据库中映射这些宿主机,这样nova-scheduler就可以进行调度了。
任何时候,你加入新的宿主机到cell,都需要调用此命令(或者启用自动发现)。
我们知道计算节点通过消息队列和控制平面通信,也不会直接访问数据库。实际上,计算节点属于哪个cell,就看它通过哪个消息队列连接。你只需要配置计算节点的nova.conf:
1 2 3 |
[DEFAULT] ; 设置为某个cell的--transport-url transport_url = rabbit://openstack:openstack@os.gmem.cc |
然后再启动nova-compute服务,最后验证、确保节点在下面命令的输出中:
1 |
nova service-list --binary nova-compute |
就将计算节点添加到cell中了。
要实现自动发现添加到cell的计算节点,并通过到API数据库,可以配置所有nova-scheduler节点的nova.conf:
1 2 3 |
[scheduler] ; 300秒执行一次发现 discover_hosts_in_cells_interval = 300 |
到目前为止(V版),还不支持跨Cell迁移实例。影响的操作包括resize/evacuate/migrate等。
如果Cell不可达,那么针对租户的用量统计信息可能不准确。
从T版开始,可以配置在Placement服务+API数据库上进行Quota统计,这样宕掉/性能很差的Cell不会导致用量统计不准确。
多Cell环境下,列出实例的结果可能没有排序、分页可能不正确。
从S版开始,元数据服务可以运行为两种模式之一:全局/PerCell。使用api.local_metadata_per_cell配置项
Nova将它启动的实例的配置信息呈现为元数据。cloud-init之类的助手会在虚拟机初始化时,利用元数据进行配置工作,例如设置虚拟机root密码。
通过元数据服务、或者config drive,元数据变的可(被实例使)用。你还可以通过nova api的user data特性来定制实例的元数据。
类别 | 说明 |
用户提供 |
创建实例的用户可以通过多种方式,将元数据传递给实例:
|
Nova提供 |
Nova自身会添加一些元数据,例如实例所在宿主机名称、实例所在AZ。 Nova提供OpenStack metadata API,以及EC2-compatible API。两者都是以日期来版本化的 |
部署者提供 |
对于创建实例的用户来说未知,由OpenStack的部署者提供。通过vendordata特性可以实现。用于实现在实例创建后,自动加入AD这样的网络管理类功能 |
控制节点上的Neutron元数据代理服务,负责代替虚拟机Nova metadata API。并自动设置正确的Instance ID、Tenant ID等请求头。
元数据服务为实例提供了一种获取自身元数据的REST API。实例可以通过169.254.169.254或者fe80::a9fe:a9fe访问此REST API,如此奇怪的地址是兼容Amazon EC2的考虑。在Openstack里面,这两个IP通过iptables映射到控制节点。
所有上述三类元数据,都可以通过此REST API访问:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# OpenStack metadata API curl http://169.254.169.254/openstack # EC2-compatible API curl http://169.254.169.254 # 都会显示若干目录(版本信息) # 2012-08-10 # 2013-04-04 # 2013-10-17 # 2015-10-15 # 2016-06-30 # 2016-10-06 # 2017-02-22 # 2018-08-27 # latest |
Config drive是一种特殊的drive,在实例boot时添加。实例可以挂载此drive,读取其中的文件,从而获取(通常应该从metadata service获取的)信息。
下面的命令示意了如何使用在创建实例时使用config drive:
1 2 3 4 5 6 |
# 使用config drive openstack server create --config-drive true --image my-image-name \ # 传递一个user data文件 --flavor 1 --key-name mykey --user-data ./my-user-data.txt \ # 传递两个元数据键值对 --property role=webservers --property essential=false MYINSTANCE |
如果客户机操作系统支持udev,则可以这样挂载config drive:
1 2 |
mkdir -p /mnt/config mount /dev/disk/by-label/config-2 /mnt/config |
否则,这样识别config drive对应的块设备:
1 2 |
blkid -t LABEL="config-2" -odevice # /dev/vdb |
config drive中的文件目录结构,和metadata service的URL结构对应:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
cd /mnt/config find . -maxdepth 2 # . # EC2兼容的元数据放在这里 # ./ec2 # ./ec2/2009-04-04 # ./ec2/latest # OpenStack元数据放在这里 # ./openstack # ./openstack/2012-08-10 # ./openstack/2013-04-04 # ./openstack/2013-10-17 # ./openstack/2015-10-15 # ./openstack/2016-06-30 # ./openstack/2016-10-06 # ./openstack/2017-02-22 # ./openstack/latest |
OpenStack元数据基于JSON格式分发:
- meta_data.json:提供Nova相关的信息
- network_data.json:提供从Neutron获取的,网络相关信息
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
// curl http://169.254.169.254/openstack/2018-08-27/meta_data.json { "random_seed": "yu5ZnkqF2CqnDZVAfZgarG...", "availability_zone": "nova", "keys": [ { "data": "ssh-rsa AAAAB3NzaC1y...== Generated by Nova\n", "type": "ssh", "name": "mykey" } ], "hostname": "test.novalocal", "launch_index": 0, "meta": { "priority": "low", "role": "webserver" }, "devices": [ { "type": "nic", "bus": "pci", "address": "0000:00:02.0", "mac": "00:11:22:33:44:55", "tags": ["trusted"] }, { "type": "disk", "bus": "ide", "address": "0:0", "serial": "disk-vol-2352423", "path": "/dev/sda", "tags": ["baz"] } ], "project_id": "f7ac731cc11f40efbc03a9f9e1d1d21f", "public_keys": { "mykey": "ssh-rsa AAAAB3NzaC1y...== Generated by Nova\n" }, "name": "test" } // curl http://169.254.169.254/openstack/2018-08-27/network_data.json { "links": [ { "ethernet_mac_address": "fa:16:3e:9c:bf:3d", "id": "tapcd9f6d46-4a", "mtu": null, "type": "bridge", "vif_id": "cd9f6d46-4a3a-43ab-a466-994af9db96fc" } ], "networks": [ { "id": "network0", "link": "tapcd9f6d46-4a", "network_id": "99e88329-f20d-4741-9593-25bf07847b16", "type": "ipv4_dhcp" } ], "services": [ { "address": "8.8.8.8", "type": "dns" } ] } |
兼容Amazon EC2 metadata service 2009-04-04版本。这意味着,为EC2设计的虚拟机镜像,可以和OpenStack一起工作。
EC2 API为每个元数据暴露了独立的URL:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# curl http://169.254.169.254/2009-04-04/meta-data/ ami-id ami-launch-index ami-manifest-path block-device-mapping/ hostname instance-action instance-id instance-type kernel-id local-hostname local-ipv4 placement/ public-hostname public-ipv4 public-keys/ ramdisk-id reservation-id security-groups # curl http://169.254.169.254/2009-04-04/meta-data/block-device-mapping/ ami # curl http://169.254.169.254/2009-04-04/meta-data/placement/ availability-zone # curl http://169.254.169.254/2009-04-04/meta-data/public-keys/ 0=mykey # curl http://169.254.169.254/2009-04-04/meta-data/public-keys/0/openssh-key ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDYVEprvtYJXVOBN0XNKVVRNCRX6BlnNbI+US\ LGais1sUWPwtSg7z9K9vhbYAPUZcq8c/s5S9dg5vTHbsiyPCIDOKyeHba4MUJq8Oh5b2i71/3B\ ISpyxTBH/uZDHdslW2a+SrPDCeuMMoss9NFhBdKtDkdG9zyi0ibmCP6yMdEX8Q== Generated\ by Nova |
就是一小段blob,OpenStack不知道它内容的意义。传递user data:
1 2 |
openstack server create --image ubuntu-cloudimage --flavor 1 \ --user-data mydata.file TEST |
在客户机里面访问user data:
1 2 3 4 |
# OpenStack http://169.254.169.254/openstack/{version}/user_data # EC2 http://169.254.169.254/{version}/user-data |
支持cloud-init的镜像,可以利用user data,定制实例的初始化过程。
这类数据可以通过metadata service或config drive读取。对于前者:
1 2 3 4 5 6 |
// curl http://169.254.169.254/openstack/2018-08-27/vendor_data2.json { "testing": { "value1": 1 } } |
cloud-init是一个在主要Linux发行版中都支持的包,用于在云环境(例如OpenStack)中初始化虚拟机实例。cloud-init在虚拟机第一次运行时执行。
cloud-init集成到系统启动的五个Stage,以发挥作用:
Stage | 说明 |
Generator |
基于Systemd启动时,此阶段中有一个Generator用于确认cloud-init.target十分需要包含在Boot Goals中。默认情况下此Generator会启用cloud-init,以下情形之一,则不启用:
|
Local |
此Stage运行一个Systemd服务cloud-init-local.service。该服务在 / 挂载为读写后立即执行,block尽可能多的Systemd启动单元,必须block网络 该Stage的意图包括:
|
Network |
此Stage运行一个Systemd服务cloud-init.service。该服务在Local Stage之后,所有网络启动后运行。包含的模块定义在/etc/cloud/cloud.cfg中 此Stage会处理所有user-data,所谓处理指:
此Stage会运行disk_setup、mounts模块,从而进行分区、格式化、配置挂载点(/etc/fstab)。这些模块不能运行的更早,韵味可能依赖于需要从网络才能得到的配置输入,例如用户提供的位于网络资源中的user-data |
Config |
此Stage运行一个Systemd服务cloud-config.service。包含的模块定义在/etc/cloud/cloud.cfg中 对于其他Boot Stage不产生影响的模块运行在此Stage |
Final |
此Stage运行一个Systemd服务cloud-final.service。它的运行时机相当于rc.local,也就是在启动的最后阶段。可以做的事情包括:
|
cloud-init需要判断实例是否第一次启动。在第一次启动时,会运行 per-instance的配置;在后续启动时,仅运行 per-boot的配置。
在运行的时候,cloud-init会将内部状态缓存起来,共后续boot读取。缓存存在,意味着两种情况之一:
- 实例不是第一次启动
- 文件系统被挂载给一个新实例,该实例是第一次启动。将一个OpenStack卷上传为镜像,然后从此镜像启动新实例,就会导致这种情况
默认情况下,cloud-init检查缓存中的实例ID,和运行时获取的实例ID,来判断是上述两种情况的哪一种。
使用命令 cloud-init clean可以清空缓存。
cloud-init的主配置文件位于 /etc/cloud/cloud.cfg, /etc/cloud/cloud.cfg.d目录中的所有其它文件都会被合并。CentOS 8云镜像的配置文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# 需要添加到系统中的用户,特殊值default特指system_info.default_user users: - default # 禁止root登陆 disable_root: 1 # 禁用密码登陆 ssh_pwauth: 0 mount_default_fields: [~, ~, 'auto', 'defaults,nofail,x-systemd.requires=cloud-init.service', '0', '2'] resize_rootfs_tmp: /dev ssh_deletekeys: 1 ssh_genkeytypes: ~ syslog_fix_perms: ~ disable_vmware_customization: false # 每个Stage都包含一系列的模块,可以启用/禁用 cloud_init_modules: - disk_setup - migrator - bootcmd - write-files - growpart - resizefs - set_hostname - update_hostname - update_etc_hosts - rsyslog - users-groups - ssh cloud_config_modules: - mounts - locale - set-passwords - rh_subscription - yum-add-repo - package-update-upgrade-install - timezone - puppet - chef - salt-minion - mcollective - disable-ec2-metadata - runcmd cloud_final_modules: - rightscale_userdata - scripts-per-once - scripts-per-boot - scripts-per-instance - scripts-user - ssh-authkey-fingerprints - keys-to-console - phone-home - final-message - power-state-change system_info: # 默认用户信息 default_user: name: centos lock_passwd: true gecos: Cloud User groups: [adm, systemd-journal] sudo: ["ALL=(ALL) NOPASSWD:ALL"] shell: /bin/bash distro: rhel paths: cloud_dir: /var/lib/cloud templates_dir: /etc/cloud/templates ssh_svcname: sshd # vim:syntax=yaml |
用户数据支持多种形式:
格式 | 说明 | ||||||||||||||||||||||||||||||||
Gzip压缩内容 | 任何user-data都可以压缩为gzip格式,cloud-init会解压它,然后再处理 | ||||||||||||||||||||||||||||||||
MIME Multi Part Archive | 使用此格式,用户可以指定多种类型的数据,例如同时指定一个user-data script和cloud-config。支持的类型包括:
使用make-mime子命令可以生成MIME multi-part文件:
|
||||||||||||||||||||||||||||||||
User-Data Script | 就是一段脚本,需要以 #!开头,包含在MIME Multi Part Archive中时使用Content-Type:text/x-shellscript | ||||||||||||||||||||||||||||||||
Include File |
文件包含一系列URL,每个URL一行,这些URL会被读取,从中获取Gzip压缩内容、MIME Multi Part Archive,或者普通文本 需要以 #include开头,包含在MIME Multi Part Archive中时使用Content-Type: text/x-include-url |
||||||||||||||||||||||||||||||||
Cloud Config Data |
这是最简单的通过user-data来实现实例定制的方式。就是提供一个YAML配置文件 需要以 #cloud-config开头,包含在MIME Multi Part Archive中时使用Content-Type:text/cloud-config 定制用户、组的例子:
写入到文件系统的例子:
添加YUM源:
添加APT源:
在首次启动时更新APT数据库:
执行YUM/APT Upgrade:
配置实例的受信任CA:
配置DNS:
在第一次启动时执行命令:
安装软件包:
调整挂载点:
cloud-init完毕后重启/关机:
配置实例的SSH Keys:
初始化磁盘:
自动增长分区大小:
|
||||||||||||||||||||||||||||||||
Upstart Job |
内容存放为/etc/init/下的一个文件,从而被Upstart调用 需要以 #upstart-job开头,包含在MIME Multi Part Archive中时使用Content-Type:text/upstart-job |
||||||||||||||||||||||||||||||||
Cloud Boothook |
存放在/var/lib/cloud并立即执行,没有任何机制保证钩子仅仅执行一次 需要以 #cloud-boothook开头,包含在MIME Multi Part Archive中时使用Content-Type:text/cloud-boothook |
||||||||||||||||||||||||||||||||
Part Handler |
一段代码,用于处理新的MIME类型,或者覆盖既有的MIME类型的处理器。以Python编写,包含函数:
示例:
需要以 #part-handler开头,包含在MIME Multi Part Archive中时使用Content-Type:text/part-handler |
所谓实例数据,是指cloud-init用来配置实例的所有数据的集合。数据来源包括:
- 云环境的元数据服务(metadata)
- 用户定制的,提供给实例的config-drive
- 镜像中的cloud-config seed files
- 提供文件/元数据服务提供的vendor-data
- 创建实例时提供的user-data
也就是说,上节的user-data是instance-data的一部分。
在OpenStack中,Flavor定义了实例的规格 —— 计算、内存、存储资源的硬件规格。Flavor也可以用来定义实例可以在哪些宿主机上启动。
命令行标记 | 说明 | ||
--vcpus | 虚拟CPU数量,必须 | ||
--ram | 内存/MB,必须 | ||
--disk |
根磁盘大小/GB,必须 从镜像创建虚拟机时,根磁盘是一个临时(ephemeral)磁盘,虚拟机的镜像会拷贝到该磁盘上。如果从持久化的卷来启动虚拟机,则不会使用这种磁盘 设置为0,其含义是,使用虚拟机镜像的大小作为临时磁盘大小。但是这种情况下会导致filter scheduler不能基于镜像尺寸来选择适当的宿主机。因此,你应该仅仅在从卷启动虚拟机、或者出于测试目的的时候,才将此参数设置为0 要强制必须从0根磁盘大小的Flavor来创建基于卷的虚拟机,设置策略规则:os_compute_api:servers:create:zero_disk_flavor |
||
--ephemeral |
额外的临时磁盘/GB,默认0 该参数为虚拟机提供额外的临时分去,虚拟机销毁后,此磁盘消失 |
||
--swap | 交换分区/MB,默认0 | ||
--public --private |
公共标记,默认True 指示该Flavor是不是可以被除了Flavor所在项目(租户)的其它租户使用 |
||
--property |
额外规格说明,可以指定多次,键值对。高级配置下,用作scheduler的提示信息
以quota:开头的属性,用于对Flavor进行配额限制,示例:
所有quota属性列表(前缀省略): |
允许使用的资源的配额可以针对项目(租户)或者用户进行设置。
配额 | 说明 |
cores | 每个项目总计允许分配的核心数 |
instances | 每个项目总计允许启动的实例数 |
key_pairs | 每个用户允许的密钥对数量 |
metadata_items | 每个实例允许的元数据数量 |
ram | 每个项目总计允许分配的内存MB |
server_groups | 每个项目允许的服务器组数量 |
server_group_members | 每个服务器组中成员的数量 |
使用下面的命令查看默认配额值:
1 |
openstack quota show --default |
要查看某个用户的配额,执行:
1 |
nova quota-show --user USER --tenant PROJECT |
主机聚合是一种对宿主机进行分区的机制,聚合中的主机常常具有类似的硬件/性能特征。一个主机可以属于多个聚合。
引入主机聚合最初是为了使用Xen资源池,但是现在作为一种机制,允许管理员将一系列键值对(属性)同时分配到多台主机。
主机聚合不直接对用户暴露,管理员可以将Flavor映射到主机聚合 —— 只需要为聚合设置匹配Flavor的额外规格说明的元数据,即可完成映射。
管理员也可以将一组主机划分为AZ,与主机聚合不同,AZ是面向用户的概念,而且主机仅能属于一个AZ。
要让Nova调度器支持主机聚合,需要配置:
1 2 |
[filter_scheduler] enabled_filters=...,AggregateInstanceExtraSpecsFilter |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# 在nova可用区中创建一个SSD磁盘的主机的聚合(后面假设聚合的ID为1) openstack aggregate create --zone nova fast-io # 为聚合设置元数据 openstack aggregate set --property ssd=true 1 # 添加主机到聚合 openstack aggregate add host 1 node1 openstack aggregate add host 1 node2 # 创建一个Flavor openstack flavor create --id 6 --ram 8192 --disk 80 --vcpus 4 ssd.large # 映射Flavor到聚合 openstack flavor set \ # 设置scope为aggregate_instance_extra_specs的额外规格, # 键值和聚合元数据一致 --property aggregate_instance_extra_specs:ssd=true ssd.large |
在Placement中,Aggregate表示相关的资源提供者(resource provider)的分组。在Placement中,Nova的计算节点就是资源提供者。因此,节点在Placement中也可以被加入到聚合。
使用下面的命令,可以查询计算节点的UUID,并将其加入到Placement聚合中:
1 2 3 4 5 6 7 8 9 10 |
openstack --os-compute-api-version=2.53 hypervisor list # +--------------------------------------+---------------------+-----------------+-----------------+-------+ # | ID | Hypervisor Hostname | Hypervisor Type | Host IP | State | # +--------------------------------------+---------------------+-----------------+-----------------+-------+ # | 815a5634-86fb-4e1e-8824-8a631fee3e06 | node1 | QEMU | 192.168.1.123 | up | # +--------------------------------------+---------------------+-----------------+-----------------+-------+ openstack --os-placement-api-version=1.2 resource provider aggregate set \ --aggregate df4c74f3-d2c4-4991-b461-f1a678e1d161 \ 815a5634-86fb-4e1e-8824-8a631fee3e06 |
从Nova 18.0.0开始,添加主机到Host Aggregate中后,会自动修改对应的Placement聚合。不需要手工操作。删除时类似。
为了使用Placement来进行租户隔离,必须存在和Host Aggregate在UUID+成员关系上匹配的Placement Aggregate。调度过滤器AggregateMultiTenancyIsolation会使用聚合元数据。
需要设置 scheduler.limit_tenants_to_placement_aggregate = True才能启用此特性。
配置示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# 创建主机聚合 openstack --os-compute-api-version=2.53 aggregate create myagg # +-------------------+--------------------------------------+ # | Field | Value | # +-------------------+--------------------------------------+ # | availability_zone | None | # | created_at | 2018-03-29T16:22:23.175884 | # | deleted | False | # | deleted_at | None | # | id | 4 | # | name | myagg | # | updated_at | None | # | uuid | 019e2189-31b3-49e1-aff2-b220ebd91c24 | # +-------------------+--------------------------------------+ # 添加节点到主机聚合 openstack --os-compute-api-version=2.53 aggregate add host myagg node1 # 获取租户ID openstack project list -f value | grep 'demo' 9691591f913949818a514f95286a6b90 demo # 设置此聚合仅仅给租户使用 openstack aggregate set --property filter_tenant_id=9691591f913949818a514f95286a6b90 myagg # 将主机加入到聚合 openstack --os-placement-api-version=1.2 resource provider aggregate set \ --aggregate 019e2189-31b3-49e1-aff2-b220ebd91c24 \ 815a5634-86fb-4e1e-8824-8a631fee3e06 |
1 |
nova aggregate-cache-images my-aggregate image1 image2 |
Nova组件nova-scheduler负责决定在哪台计算节点上创建虚拟机。 在调度的场景下,术语host表示运行了nova-compute服务的哪些节点。
调度器的基本配置项是:
1 2 3 4 5 6 |
[scheduler] driver = filter_scheduler [filter_scheduler] available_filters = nova.scheduler.filters.all_filters enabled_filters = AvailabilityZoneFilter, ComputeFilter, ComputeCapabilitiesFilter, ImagePropertiesFilter, ServerGroupAntiAffinityFilter, ServerGroupAffinityFilter |
默认的调度器驱动是 filter_scheduler,在默认配置下,该调度器选择满足以下所有条件的宿主机:
- AvailabilityZoneFilter:位于请求的AZ中
- ComputeFilter:能够服务请求
- ComputeCapabilitiesFilter:满足实例类型的extra_specs(来自Flavor)
- ImagePropertiesFilter:满足实例镜像属性中的架构、Hypervisor类型、虚拟机模式属性
- ServerGroupAntiAffinityFilter:满足服务器组的反亲和设置——和组中的其它虚拟机不再同一宿主机上
- ServerGroupAffinityFilter:满足服务器组亲和设置
当执行nova evacuate命令重建虚拟机时,调度器服务遵循管理员给出的目标宿主机,如果管理员没有指定目标宿主机,则由调度器来选择适当的宿主机。
从R版开始,调度器包含一个前置的过滤步骤,其目的时提升效率,减少候选的主机。
下面是一些常用的预过滤器:
镜像类型支持过滤器: [scheduler]/query_placement_for_image_type_support=True 过滤掉那些不支持用于启动虚拟机的镜像的格式的计算节点。例如,对于libvrit驱动,当使用Ceph作为临时存储后端时,不支持qcow2镜像格式。在混合使用基于Ceph、不使用Ceph作为存储后端的计算节点时,可以启用此过滤器 |
禁用状态节点过滤器:强制启用 从T版本开始,此过滤器会排除禁用状态的节点(类似于ComputeFilter)。具有trait COMPUTE_STATUS_DISABLED的(计算节点)资源提供者,将被排除,不作为调度候选 Trait由nova-compute服务管理,应该mirror位于os-services中的计算服务记录的disabled状态。例如,如果计算服务的状态是disabled,那么它关联的计算节点资源提供者对象应当具有COMPUTE_STATUS_DISABLED这一trait;当计算服务状态为enabled,对应资源提供者的此trait应该被移除 如果状态改变时计算服务宕了,那么trait将在它重启后同步。如果尝试给对应资源提供者添加/删除trait时出错,则update_available_resource这一定时任务负责重新同步。[DEFAULT]/update_resources_interval负责此同步操作的间隔 |
前面我们提到过,nova.scheduler.filter_scheduler.FilterScheduler是默认的调度器(驱动)。它使用过滤器、权重来选择宿主机。
配置项 [filter_scheduler]/available_filters 列出调度器可以使用的过滤器集合,此配置项可以指定多次:
1 2 3 4 5 |
[filter_scheduler] ; 所有自带过滤器 available_filters = nova.scheduler.filters.all_filters ; 加上这个自己编写的过滤器 available_filters = myfilter.MyFilter |
配置项 [filter_scheduler]/filter_scheduler.enabled_filters 列出当前nova-scheduler启用的过滤器。
过滤器 | 说明 | ||||
AggregateImagePropertiesIsolation |
从L版开始,Nova仅会传递标准元数据给此过滤器。如果需要使用所有元数据,考虑过滤器AggregateInstanceExtraSpecsFilter 该过滤器对 镜像元数据 和 聚合元数据 进行匹配:
|
||||
AggregateInstanceExtraSpecsFilter |
该过滤器对 实例类型(Flavor)的、Scope为aggregate_instance_extra_specs的extra_specs 和 聚合属性进行匹配 为了向后兼容,没有Scope的Specs也可以用来匹配,但是不推荐 —— 当同时使用ComputeCapabilitiesFilter时会出现冲突 使用此过滤器,可以实现将Flavor调度到特定的主机集合中 |
||||
AggregateMultiTenancyIsolation |
确保租户隔离(tenant-isolated)的主机聚合(即设置了filter_tenant_id的主机聚合)仅仅能被相关的租户(项目)所使用 filter_tenant_id可以用逗号分隔多个租户 如果某个主机属于设置了filter_tenant_id的聚合,那么某个不属于相应租户的用户发起创建虚拟机的请求时,虚拟机不会在此聚合的某个宿主机上创建 主机可以不属于任何设置了filter_tenant_id的聚合,通过此过滤器 |
||||
AggregateNumInstancesFilter |
用于限制宿主机上实例的最大数量 对于一个聚合,如果设置了max_instances_per_host,那么其中的宿主机上的实例不会超过特定数量 如果主机属于多个设置了max_instances_per_host的聚合,验证此主机实例数量是否到达上限时,使用最小的max_instances_per_host值 |
||||
AggregateTypeAffinityFilter |
用于实现实例类型(Flavor)亲和性 此过滤器pass(通过)没有设置instance_type的主机,或者所在聚合的元数据instance_type(逗号分隔)包含正在请求创建的虚拟机的instance_type的主机 |
||||
AllHostsFilter | 通过所有主机 | ||||
AvailabilityZoneFilter | 满足调度请求中关于可用区的需求 | ||||
ComputeCapabilitiesFilter |
对Flavor的extra_specs中的属性 和 compute capabilities进行匹配 如果Extra Spec中包含冒号,则:之前的看作命名空间,之后的看作需要匹配的key。如果命名空间不是capabilities,则忽略此Spec 为了向后兼容,没有Namespace的Specs也可以用来匹配,但是不推荐 —— 当同时使用AggregateInstanceExtraSpecsFilter时会出现冲突 某些虚拟化驱动支持报告CPU的trait给placement服务,这种情况下,应该在Flavor中使用trait,而不是使用此过滤器。因为trait提供了CPU特性的一致性命名,而且查询trait的效率更高 |
||||
ComputeFilter | 此过滤器pass(通过)所有启用的、可以工作的计算服务(节点) | ||||
DifferentHostFilter |
调度到其它宿主机,排除的宿主机由请求时给出的different_host来确定,该字段是一个实例的列表,排除的是这些实例所在的宿主机:
使用命令:
|
||||
ImagePropertiesFilter |
根据实例的镜像的属性来过滤宿主机,仅仅通过那些支持镜像属性的宿主机 属性包括:架构、Hypervisor类型/版本、虚拟机模式: hw_architecture,架构:i686, x86_64, arm, ppc64 ... 对于QEMU、KVM,Hypervisor类型都是qemu
|
||||
IsolatedHostsFilter |
允许定义一个隔离镜像集、隔离宿主机集,两者必须在一起 restrict_isolated_hosts_to_isolated_images 用于限制隔离主机仅仅运行隔离镜像。取值True意味着卷后备的虚拟机不能调度到隔离主机集;取值False则没有任何限制(对比镜像后备的虚拟机) 镜像集、宿主机集合必须配置在nova.conf:
|
||||
IoOpsFilter |
过滤掉具有太多并发IO实例的宿主机 max_io_ops_per_host指定 单个宿主机上IO敏感的实例的最大数量 |
||||
JsonFilter |
此过滤器默认没有启用,且没有广泛测试 允许用户为调度器提供一个JSON格式的提示。在提示中:
示例:
|
||||
PciPassthroughFilter | 仅仅通过匹配Flavor的extra_specs中设备请求的宿主机 | ||||
SameHostFilter |
调度到和指定实例(集)相同的宿主机(之一) 实例(集)由提示给出:
|
||||
ServerGroupAffinityFilter |
确保调度到指定的服务器组中,服务器组由提示给出
|
||||
ServerGroupAntiAffinityFilter |
确保不调度到指定的服务器组中,服务器组由提示给出 |
||||
SimpleCIDRAffinityFilter |
根据宿主机的IP地址CIDR进行过滤,指定两个提示: build_near_host_ip CIDR的第一个IP
|
经过过滤后,可能仍然有多个宿主机满足需求。那么,到底选择哪一个?这时需要基于权重来确定。
一个宿主机的最初权重由它拥有的硬件资源来确定,每当调度新的实例到它上面,宿主机的权重值就变小。
权重计算算法的参数,配置在nova.conf中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
[DEFAULT] ; 注意:主机聚合可以覆盖这里的权重因子设置 ; 内存权重因子 ram_weight_multiplier ; 磁盘权重因子 disk_weight_multiplier ; 处理器权重因子 cpu_weight_multiplier ; IO负载权重因子,负数表示倾向于选择轻负载的宿主机 io_ops_weight_multiplier ; 进行权重判断后,会返回N个最适合主机,然后在随机从中取一个作为最终宿主机 ; 该选项决定N的大小 scheduler_host_subset_size ; 默认权重值最大的获胜 scheduler_weight_classes = nova.scheduler.weights.all_weighers [filter_scheduler] ; 对于主机组进行软亲和时时候 soft_affinity_weight_multiplier ; 对于主机组进行软反亲和时时候 soft_anti_affinity_weight_multiplier ; 对于最近发生创建虚拟机失败的宿主机,设置权重因子 ; 设置为负数,则最近失败的主机更加少的机会被选择 build_failure_weight_multiplier ; 在跨Cell移动实例时,使用该权重因子 cross_cell_move_weight_multiplier |
从S版开始,nova-compute会基于计算驱动的capabilities报告为COMPUTE_开头的(资源提供者的)Trait(特性)。
通过配置Flavor,可以指定实例要求、禁止哪些Trait。例如,某个主机聚合支持multi-attach卷,你可以限制某个Flavor仅仅调度到这个主机聚合:
- 为Flavor设置extra_specs: trait:COMPUTE_VOLUME_MULTI_ATTACH=required
- 按照常规方式限制Flavor到主机聚合
1 2 3 |
openstack --os-compute-api-version=2.53 hypervisor list # 列出trait openstack --os-placement-api-version 1.6 resource provider trait list 8fa133f5-a41e-4ef6-a485-cb0d6e167860 |
关于基于计算驱动capabilities定义的Trait,需要注意:
- 计算服务拥有这些COMPUTE_开头的Trait的控制权,nova-compute服务启动后,或者update_available_resource定时任务执行后,会自动添加/擅长Traits
- 用户自定义的Trait,不会被删除。除非定义的Trait以COMPUTE_开头
- 如果用户通过命令: openstack resource provider trait delete 删除某个资源提供者的COMPUTE_*,计算服务会在重启时再次添加
在OpenStack中,可用区是一个用户可见的逻辑的云分区。在创建主机时,用户可以指定,创建到哪个可用区。
可用区没有在数据库中建模,而是定义为主机聚合的元数据。为主机聚合添加特定的元数据,即可将其中的主机加入到某个可用区。
需要注意主机聚合和AZ的不同:
- 宿主机可以属于多个主机聚合,但是只能属于一个AZ
- 默认情况下,主机是默认AZ的成员,即使它不属于任何主机聚合
其它OpenStack服务,例如网络、块存储服务,也有可用区的概念,但是实现方式各不相同。
默认AZ的名字,可以在nova.conf中配置:
1 2 |
[DEFAULT] default_availability_zone = nova |
该配置项指定计算服务(nova-compute组件)的默认可用区的名字。
可用区是在主机聚合上设置的:
1 2 3 4 5 6 7 8 |
# --os-compute-api-version=2.53 openstack aggregate create zircon openstack aggregate add host zircon centos-11 openstack aggregate add host zircon centos-12 openstack aggregate add host zircon centos-13 # 设置聚合的可用区 openstack aggregate set --property availability_zone=zircon zircon |
将主机聚合关联到可用区的操作,需要提前规划。聚合中任何主机上已经实例,则无法设置可用区。
导致实例所在宿主机改变的操作包括 evacuate, resize, cold migrate, live migrate 以及 unshelve。其中只有evacuate和live migrate可以绕过调度器,强制指定目标主机。
如果满足以下条件之一,迁移后的实例限定在特定的AZ中:
- 创建实例时,指定了availability_zone参数,即指明在特地AZ中创建实例
- 虽然没有指定availability_zone,但是API service配置了 default_schedule_zone
- 2.77版本之后,Unshelve实例时,指定了availability_zone
- cinder.cross_az_attach设置为False,default_schedule_zone也没有设置,但是实例使用了卷,这样会调度到卷所在的AZ
如果实例没有在特定AZ内创建,则它可以被自由的移动到其它AZ, AvailabilityZoneFilter不做任何事情。
需要注意,如果实例在某个AZ内创建的情况下,通过evacuate或者live migrate将其移动到另外一个AZ的主机上,是个危险的操作。因为假设后续你又resize实例,调度器会将其转移到原先的AZ。
Noava的配置项cinder.cross_az_attach,用于限制实例和它使用的卷在相同的AZ中。如果设置为False,则计算和存储资源会位于相同AZ,如果无法满足,则请求会失败:
- 创建实例时,将一个已存在的卷挂载给它,那么实例将创建到卷所在的AZ
- 创建实例时,需要创建一个新卷挂载给它,那么Nova将会在实例所在的AZ中创建卷
关于在Nova中使用、创建、管理卷,参考openstack server create。
Nova从Q版开始支持Cinder的多重挂载。前提条件:
- Compute API最小版本是2.6
- 底层的Hypervisor驱动必须支持将卷挂载到多个客户机。使用libvirt驱动时,libvirt必须大于3.10,qemu必须大于2.10
- 不支持swap一个正在使用的multiattach卷
OpenStack支持多种控制台来连接到客户机,包括VNC、SPICE、Serial、RDP、MKS(VMware vSphere)。推荐仅仅部署一种类型的控制台支持,此外需要注意某些Hypervisor不支持某些控制台类型。
为了连接到虚拟机控制台,计算节点的5900-5999端口必须开启。
不管使用哪种控制台,都需要部署console proxy服务。该服务负责:
- 提供用户所在的公共网络和虚拟机所在的私有网络之间的桥梁
- 中介Token验证
- 屏蔽Hypervisor相关的连接细节,给用户一致的体验
对于某些Hypervisor + Console驱动的组合,控制台代理是Hypervisor/其它外部服务提供的。其它的则由Nova提供控制台代理服务。Nova控制台代理的工作方式如下(以基于noVNC的VNC控制台为例):
- 用户访问OpenStack API,获取控制台访问URL,例如:http://ip:port/?path=%3Ftoken%3Dxyz
- 用户在浏览器打开控制台
- 浏览器连接到代理
- 代理校验用户的Token,映射Token到私有网络中的、实例的VNC服务器的地址:端口
- 计算节点在vnc.server_proxyclient_address中指定代理应该如何连接到本机的VNC服务器,代理通过此地址连接到VNC服务器
要启用基于noVNC的VNC控制台,OpenStack需要部署以下额外组件:
- 一个或多个 nova-novncproxy服务,以支持基于浏览器的noVNC客户端。在简单部署场景中,此服务运行在nova-api所在机器上,因为它是公共、私有网络之间的桥梁
VNC是很多Hypervisor和客户端支持的图形化控制台。noVNC支持通过浏览器访问VNC。
配置nova-novncproxy服务:
1 2 3 |
[vnc] novncproxy_host = 0.0.0.0 novncproxy_port = 6082 |
配置nova-compute服务:
1 2 3 4 5 |
[vnc] enabled = True novncproxy_base_url = http://os.gmem.cc:6082/vnc_auto.html server_listen = 127.0.0.1 server_proxyclient_address = 127.0.0.1 |
使用串口控制台(serial console)可以检查虚拟机的内核输出,查看其它虚拟消息。串口控制台在虚拟机的网络连接不可用时特别有效。
从J版开始,OpenStack支持可读写的串口控制台。你需要在计算节点上配置:
1 2 3 4 5 6 7 8 |
[serial_console] ; ... enabled = true base_url = ws://os.gmem.cc:6083/ ; 监听虚拟控制台请求的地址 listen = 0.0.0.0 ; 控制台代理连接到哪个网络接口,通常管理网 proxyclient_address = MANAGEMENT_INTERFACE_IP_ADDRESS |
使用下面的命令后的串口控制台的WS地址:
1 |
nova get-serial-proxy INSTANCE_NAME |
Nova支持注入密码到虚拟机的管理员用户,密码会打印在openstack server create命令的输出中。
默认情况下,仪表盘会显示管理员密码并允许修改。如果希望禁用此特性:
1 2 3 4 |
PENSTACK_HYPERVISOR_FEATURES = { ... 'can_set_password': False, } |
对于使用libvirt后端的Hypervisor(KVM/QEMU/LXC),管理员密码注入默认禁用,要启用需要修改:
1 2 |
[libvirt] inject_password=true |
1 2 3 4 5 6 |
[libvirt] ; 使用KVM以提升性能 virt_type = kvm ; 创建的实例的CPU模式,参考 ; https://blog.gmem.cc/libvirt-study-note#cpu-mode cpu_mode=host-passthrough |
默认情况下,很多placement相关的OpenStackt命令不可用,需要安装osc-placement插件。
默认情况下,使用的Placement API版本是1.0。要使用其它版本,需要指定 --os-placement-api-version命令行标记,或者设置环境变量:
1 |
export OS_PLACEMENT_API_VERSION=1.6 |
OpenStack Networking组件,即Neutron,允许你创建网络接口设备、将网络接口设备Attach到虚拟网络。Neutron基于插件化机制设计,用以支持不同的网络设备以及软件。
Neutron负责管理虚拟网络基础设施(Virtual Networking Infrastructure,VNI)的方方面面、以及物理网络基础设施(Physical Networking Infrastructure,PNI)的访问/接入层面。
Neutron支持防火墙、VPN等高级网络特性。
Neutron提供网络、子网、路由器的抽象,这些抽象模拟相应物理实体的特性。例如,网络包含子网,路由器负责再不同子网/网络之间进行封包路由。
任何给定的网络方案(set up),至少包含一个外部网络(External network)。与其它网络不同,外部网络不仅仅是虚拟网络,他是真实物理网络(可以访问OpenStack外部)的一种视图。外部网络上的IP地址,可以从OpenStack外部直接访问到。
除了外部网络之外,任何网络方案至少包含一个内部网络(Internal network),内部网络是虚拟(软件定义的)网络,直接将VM连接在一起。
为了从外部访问VM(或者反之),需要添加虚拟路由器。每个路由器包含一个网关,通向外部网络;包含1-N个接口,通往内部网络。和物理路由器类似,连接到同一个路由器的子网之间可以相互访问。VM可以通过路由器的网关访问外部网络。
当有什么连接到一个子网时,那个连接点(connection)就称为端口(port)。你将外部网络的IP地址分配到内部网络的(由于VM连接到子网而产生的)端口上,这样,外部实体就能直接访问VM。
Neutron支持安全组(security groups),安全组让管理员可以按组来定义防火墙规则。一个VM可以归属1-N个安全组,Neutron根据安全组中的规则,来阻止VM访问端口、端口范围。
一个典型的Netron部署,包含了多个服务(service)和代理(agent),这些组件可能运行在一个或多个节点上。
接受API请求,并路由给适当的OpenStack Networking plug-in进行处理。作为访问数据库的中心点。
Neutron使用插件化的架构,各种可拔插功能依赖于plugin和agent实现。
使用通用/厂商特定的技术,来提供网络分段(segmentation)和隔离(isolation),也就是划分出子网(network number相同的主机位于同一个子网,子网是个以太网)。
L2代理应当运行在任何需要网络连接、提供虚拟接口安全性的节点上,包括计算、网络节点。
OpenStack自带了Cisco 虚拟/物理交换机、NEC OpenFlow产品、Open vSwitch、Linux Bridging、VMware NSX产品的代理。
运行在网络节点上,提供东西向、南北向的路由能力,并提供FWaaS、VPNaaS之类的高级特性。
用于再Neutron服务器和各种代理之间进行消息交换,也用作某些特定插件存储网络状态的数据库。
主配置文件neutron.conf,neutron-server和各种Agent都会读取。该文件包含用于Neutron内部RPC的oslo.messaging配置,并且会包含一些和主机相关的信息。此配置文件还包括database、nova、keystone的凭证信息。
此外neutron-server可能会加载plugin特定的配置文件。而Agent则不会加载。原因是插件配置主要是全局范围的选项。
每个不同的Agent可能有自己的配置文件,他们应当在主配置之后加载。因此其中的配置项优先级更高。代理配置文件中,可能包含主机特定的配置,例如local_ip。
模块化L2(Modular Layer 2 ,ML2)插件是Neutron的L2框架,它允许你在一个部署中使用多种L2网络技术。ML2的扩展点是两种不同类型的驱动
网络类型驱动,定义了OpenStack网络的技术分类,例如VxLAN、flat。
每种实现技术都对应了一个ML2 Type驱动。这些驱动会维护任何需要的、和网络类型相关的状态。它会验证Provider网络上和网络类型有关的信息,并且负责在项目的网络中分配一个空闲的段。
网络机制驱动,定义了OpenStack网络的实现技术,例如flat网络可以利用Linux bridge或者OVS来实现。
Mechanism驱动会利用Type驱动所产生的信息,并且确保这些信息并应用。
Mechanism驱动能通过RPC利用L2代理,也能够直接和外部控制器/设备进行交互。
Mechanism驱动和Type驱动的搭配,不是任意的:
Mech\Type | Flat | VLAN | VxLAN | GRE |
Open vSwitch | Y | Y | Y | Y |
Linx Bridge | Y | Y | Y | N |
SRIOV | Y | Y | N | N |
MacVTap | Y | N | N | N |
L2 population | N | N | Y | Y |
在ML2的主配置文件/etc/neutron/plugins/ml2/ml2_conf.ini中配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
[ml2] ; 支持的Type驱动列表 type_drivers = flat,vlan,vxlan,gre ; flat相关配置 [ml2_type_flat] ; 可以从中创建flat网络的物理网络(physical_network)的名称 ; 设置为*则允许使用任何物理网络名 ; 设置为空则禁用flat网络 flat_networks = provider ; vlan相关配置 [ml2_type_vlan] ; 格式 <physical_network>:<vlan_min>:<vlan_max> 或者 <physical_network> ; 指定可用作VLAN provider以及租户网络的物理网络名称,以及可分配的VLAN Tag范围 network_vlan_ranges = provider:0:200 ; vxlan相关配置 [ml2_type_vxlan] ; 格式 <vni_min>:<vni_max>,<vni_min>:<vni_max>... 列出VxLAN VNI ID范围 vni_ranges = ; VxLAN的多播组,如果配置,所有广播流量发送到此组;如果不配置,禁用multicast VxLAN模式 vxlan_group = |
在ML2的主配置文件/etc/neutron/plugins/ml2/ml2_conf.ini中配置:
1 2 3 |
[ml2] ;支持的Mech驱动列表 mechanism_drivers = ovs,l2pop |
更多的配置查看相关Agent的配置文件。
该代理通过配置Linux Bridge来为OpenStack资源实现L2网络。配置文件路径 /etc/neutron/plugins/ml2/linuxbridge_agent.ini
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
[DEFAULT] ; 是否打开DEBUG级别的日志,默认INFO debug = False [agent] ; 每隔多少秒,Agent来轮询本地设备的变化情况 polling_interval = 2 ; 封装为外层IP报文时,设置的DSCP值。用于overlay网络。0-63之间的整数 dscp = ; 如果设置为True,则从内层封包取得DSCP,设置到外层封包上 dscp_inherit = False ; 使用的扩展列表 extensions = [linux_bridge] ; 格式:<physical_network>:<physical_interface>,<physical_network>:<physical_interface>... ; 将物理网络名称映射到Agent节点上的物理网络接口名。这样flat和VLAN网络才能利用这些网络 physical_interface_mappings = provider:eth0 ; 格式:<physical_network>:<physical_bridge> bridge_mappings [securitygroup] ; 此L2代理使用的安全组防火墙驱动 firewall_driver = ; 是否启用neutron security group API,如果不使用安全组,或者使用nova security group API,则禁用 enable_security_group = True ; 十分启用IPSet提升iptables的性能 enable_ipset = True ; 逗号分隔的,允许的ethertypes。0x开头的16进制形式 permitted_ethertypes = [vxlan] ; 此Agent是否支持VxLAN enable_vxlan = Tre ; VxLAN接口协议包的TTL ttl = ; VxLAN接口协议包的TOS,已经废弃,使用agent段的dscp选项代替 tos = ; VxLAN接口的多播组 ; 如果指定组地址的范围,必须使用CIDR格式 vxlan_group = 224.0.0.1 ; 本地的Overlay(Tunnel)网络端点的IP地址,使用一个IPv4/IPv6的、位于宿主机网络接口上的地址 local_ip = ; VxLAN包的UDP源地址范围 udp_srcport_min = udp_srcport_max = ; VxLAN的UDP目的地址 udp_dstport = ; 使用Local ARP responder,它提供本地响应,而非在overlay范围内进行ARP广播 ; Local ARP responder和allowed-address-pairs扩展存在兼容性问题 arp_responder = ; 描述组播地址和VLAN(VNI ID)之间的映射关系 ; <multicast address>:<vni_min>:<vni_max> 逗号分隔 multicast_ranges |
OpenStack支持对以下资源配置DNS:
资源 | DNS名 | DNS域 |
端口/Ports | 是 | 否 |
网络/Networks | 否 | 是 |
浮动IP | 是 | 是 |
要更改默认的域名后缀openstacklocal,需要修改neutron-server节点的:
1 2 3 4 |
[default] dns_domain = os.gmem.cc ; router插件需要启用,否则报错Extensions not found: ['auto-allocated-topology', 'dns-integration']. service_plugins = router |
1 2 3 4 |
[ml2] # dns即DNS Integration。是dns_domain_ports的子集 # dns_domain_ports,额外允许设置port的dns_domain属性 extension_drivers = port_security,dns |
重启服务:
1 |
systemctl restart neutron-server.service |
你可以为一个Port配置DNS名:
1 |
neutron port-create my-net --dns_name my-port |
当Port分配给实例时,实例的主机名+域名后缀,会自动成为Port的FQDN,例如centos8-amd64.os.gmem.cc
OpenStack DNS Service,即Designate,是一个支持多租户的OpenStack的DNSaaS服务。它提供集成了keystone身份验证的REST API,能够基于Nova/Neutron动作自动生成DNS记录。Designate支持多种DNS服务器,包括Bind9和PowerDNS 4
提供REST API接口。
编排Zones和RecordSet的创建、删除和更新。
编排周期性任务。
运行任务,例如Zone的创建/删除/更新,以及来自designate-producer的周期性任务。
一个小的DNS服务器,负责推送DNS Zone信息到面向客户的DNS服务器,也能够拉取Designate基础设施之外的DNS Zone信息。
某些DNS服务要求在本地执行命令,此代理负责对接到这些DNS服务。
为客户提供DNS服务,由designate-worker管理其记录。Bind9、Power DNS 4被支持的很好。
1 |
sudo apt install python3-designateclient |
安装openstack-designate以及相关依赖:
1 |
dnf install openstack-designate-* bind bind-utils -y |
1 2 3 |
CREATE DATABASE IF NOT EXISTS designate CHARACTER SET utf8 COLLATE utf8_general_ci; GRANT ALL PRIVILEGES ON designate.* TO 'designate'@'localhost' IDENTIFIED BY 'designate'; GRANT ALL PRIVILEGES ON designate.* TO 'designate'@'%' IDENTIFIED BY 'designate'; |
1 2 3 4 |
openstack user create --domain default --password designate designate openstack role add --project service --user designate admin openstack service create --name designate --description "DNS" dns openstack endpoint create --region china dns public http://openstack.gmem.cc:9001/ |
创建一个RNDC key:
1 2 3 |
rndc-confgen -a -k designate -c /etc/designate/rndc.key -r /dev/urandom chown named:named /etc/designate/rndc.key chmod 644 /etc/rndc.key |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
... include "/etc/designate/rndc.key"; options { ... allow-new-zones yes; request-ixfr no; listen-on port 53 { any; }; recursion no; allow-query { any; }; }; controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "designate"; }; }; |
改完重启服务:
1 2 |
systemctl enable named.service systemctl start named.service |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
[DEFAULT] transport_url = rabbit://openstack:openstack@openstack.gmem.cc [service:api] listen = 0.0.0.0:9001 auth_strategy = keystone enable_api_v2 = True enable_api_admin = True enable_host_header = True enabled_extensions_admin = quotas, reports [keystone_authtoken] auth_type = password username = designate password = designate project_name = service project_domain_name = Default user_domain_name = Default www_authenticate_uri = http://openstack.gmem.cc:5000/ auth_url = http://openstack.gmem.cc:5000/ memcached_servers = openstack.gmem.cc:11211 [storage:sqlalchemy] connection = mysql+pymysql://designate:designate@openstack.gmem.cc/designate |
1 |
su -s /bin/sh -c "designate-manage database sync" designate |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
- name: default # 池的名字,创建后不可改变。除非删除(连同关联的Zones)并重建 description: default attributes: {} # 该池负责管理的Zone的NS记录 # 记录应当在Designate之外创建, 指向控制节点的公共IP ns_records: - hostname: ns.openstack.gmem.cc. priority: 1 # 该池使用的DNS服务器列表,也就是Bind服务器的地址 nameservers: - host: 127.0.0.1 port: 53 # 该池的目标列表,对于Bind来说,每个BIND服务器对应一个条目 # designate会在每个Bind服务器上运行rndc命令 targets: - type: bind9 description: bind9 on openstack-1 # 列出designate-mdns服务地址,Bind服务器向其发送zone transfers (AXFRs)请求 # 应当是控制节点的IP masters: - host: 127.0.0.1 port: 5354 options: host: 127.0.0.1 port: 53 rndc_host: 127.0.0.1 rndc_port: 953 rndc_key_file: /etc/designate/rndc.key |
执行下面的命令创建池:
1 |
su -s /bin/sh -c "designate-manage pool update" designate |
1 2 3 4 5 |
systemctl start designate-central designate-api systemctl enable designate-central designate-api systemctl start designate-worker designate-producer designate-mdns systemctl enable designate-worker designate-producer designate-mdns |
查看DNS服务列表:
1 2 3 4 5 6 7 8 9 10 |
openstack dns service list +--------------------------------------+-------------+--------------+--------+-------+--------------+ | id | hostname | service_name | status | stats | capabilities | +--------------------------------------+-------------+--------------+--------+-------+--------------+ | a071880d-a2d4-468a-a452-da4e7856a63c | openstack-1 | api | UP | - | - | | e7b8a2dd-c92e-41fb-bd23-c342c76de154 | openstack-1 | central | UP | - | - | | 502c5b1f-1036-4a84-9b3e-14c7255b20eb | openstack-1 | mdns | UP | - | - | | a2f0d9ad-366b-4ec2-8b92-d2f0765f2333 | openstack-1 | producer | UP | - | - | | d64fa762-3598-4477-b7bc-a4394b326177 | openstack-1 | worker | UP | - | - | +--------------------------------------+-------------+--------------+--------+-------+--------------+ |
创建一个DNS Zone:
1 |
openstack zone create --email admin@gmem.cc os.gmem.cc. |
确认其状态到达ACTIVE:
1 2 3 4 5 6 |
openstack zone list +--------------------------------------+-------------+---------+------------+--------+--------+ | id | name | type | serial | status | action | +--------------------------------------+-------------+---------+------------+--------+--------+ | 2093169d-15d5-4e9c-8b94-a6569ffac7b8 | os.gmem.cc. | PRIMARY | 1618994404 | ACTIVE | NONE | +--------------------------------------+-------------+---------+------------+--------+--------+ |
创建一个记录集(RecordSet):
1 |
openstack recordset create --record '10.1.1.1' --type A os.gmem.cc. horizon |
Neutron支持将域名通过designate暴露给外部。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[default] # 决定了配置了dns_domain的port默认所在Zone dns_domain = os.gmem.cc. external_dns_driver = designate [designate] url = http://openstack.gmem.cc:9001/v2 admin_auth_url = http://openstack.gmem.cc:35357/v2.0 admin_username = neutron admin_password = neutron admin_tenant_name = service allow_reverse_dns_lookup = True ipv4_ptr_zone_prefix_size = 16 ipv6_ptr_zone_prefix_size = 116 |
1 |
extension_drivers=port_security,dns |
用例说明:用户创建在一个可被外部访问的网络上创建实例,并且希望从集群外部通过域名来访问实例。
参考步骤:
- 前提条件:
- 不支持使用 --external 创建的网络
- 支持FLAT, VLAN, GRE, VXLAN, GENEVE类型的网络
- 对于FLAT, VLAN, GRE, VXLAN, GENEVE,其segmentation ID必须位于分配给project networks的范围之外
- 给网络的dns_domain属性分配一个合法的值:
12# neutron net-update 5fdf474c-533a-403d-b7dd-cc7d7e1dfa23 --dns_domain os.gmem.cc.openstack network set --dns-domain os.gmem.cc. provider -
查看此Zone中的记录:
1234567openstack recordset list os.gmem.cc.+--------------------------------------+-------------+------+---------------------------------------------------------------------+--------+--------+| id | name | type | records | status | action |+--------------------------------------+-------------+------+---------------------------------------------------------------------+--------+--------+| 22422e08-0c17-4106-a222-35c3e535d37a | os.gmem.cc. | NS | ns.openstack.gmem.cc. | ACTIVE | NONE || e4683c9e-70c0-4d3b-83e1-bb5530059311 | os.gmem.cc. | SOA | ns.openstack.gmem.cc. admin.gmem.cc. 1618997152 3586 600 86400 3600 | ACTIVE | NONE |+--------------------------------------+-------------+------+---------------------------------------------------------------------+--------+--------+ -
创建一个端口,配置DNS名:
1234openstack port create --dns-name t3m1 --network provider \--fixed-ip subnet=provider,ip-address=10.2.0.111 --disable-port-security tcnp3-master-1# | dns_assignment | fqdn='t3m1.os.gmem.cc.', hostname='t3m1', ip_address='10.2.0.111' | - 再次查看Zone,应该发现名为t3m1.os.gmem.cc.的新A记录:
12openstack recordset list os.gmem.cc.# | f81bc3c2-2272-4f21-93d3-2c4fc9e6435d | t3m1.os.gmem.cc. | A | 10.2.0.111 | ACTIVE | NONE |
当把端口授予实例后,原先的A记录被替换,前缀改为实例的主机名。
OpenStack Block Storage service,即Cinder为VM提供块设备。块设备如何产生、如何被消费,取决于块设备驱动。如果使用多后端配置,则取决于多个驱动。Cinder具有多种驱动,包括NAS/SAN, NFS, iSCSI, Ceph,等等。
Block Storage API组件和Scheduler服务通常运行在控制节点上。取决于使用的驱动,Volume服务可能运行在控制节点、计算节点,或者独立的存储节点上。
Cinder和Nova交互,从而将卷提供给虚拟机实例。
接受API请求,路由给cinder-volume处理。
直接(或者通过消息队列)和后端存储服务交互、cinder-scheduler这样的组件交互。
cinder-volume会响应针对后端存储服务的读写请求,从而维持状态。它是通过驱动架构与后端交互的。
这是一个守护程序,负责选取一个最优化的、能够提供卷的节点,并由节点创建卷。
这是一个守护程序,负责备份任意类型的卷到某个Backup storage provider。它是通过驱动架构与后端交互的。
在上述进程之间交换信息。
1 2 3 |
[DEFAULT] backup_driver = cinder.backup.drivers.nfs.NFSBackupDriver backup_share = 10.0.0.1:/slow |
参考上文的样例环境。
需要注意的是,LVM后端可以映射为远程宿主机的磁盘。当卷从位于LVM后端上的快照上创建时,它必须和快照在一个存储节点上,这种情况下,远程映射可能是必须的,需要注意性能问题。不能假设LVM后端是本地磁盘。
添加到已启用后端列表:
1 2 3 4 5 6 7 8 |
[DEFAULT] enabled_backends = lvm,nfs [nfs] volume_driver = cinder.volume.drivers.nfs.NfsDriver nfs_shares_config = /etc/cinder/nfs_shares nfs_mount_point_base = /var/lib/cinder/mnt volume_backend_name = nfs |
配置NFS服务地址,以及使用的NFS导出目录的绝对路径:
1 |
10.0.0.1:/cinder |
并修改该配置文件的访问权限:
1 2 |
chown root:cinder /etc/cinder/nfsshares chmod 0640 /etc/cinder/nfsshares |
重新启动cinder-volume服务:
1 |
systemctl restart openstack-cinder-volume.service |
查看cinder服务列表:
1 2 3 |
cinder service-list | cinder-volume | openstack-2@nfs | nova | enabled | up | 2021-04-15T13:59:30.000000 |
创建对应的volume type:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
cinder type-create nfs cinder type-key nfs set volume_backend_name=nfs openstack volume type show nfs +--------------------+--------------------------------------+ | Field | Value | +--------------------+--------------------------------------+ | access_project_ids | None | | description | None | | id | c31ec381-c1f7-46c3-9119-bf699413f6b1 | | is_public | True | | name | nfs | | properties | volume_backend_name='nfs' | | qos_specs_id | None | +--------------------+--------------------------------------+ |
参考集成Ceph。
参考如下配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[DEFAULT] # 增加 后端key:后端类型 enabled_backends = rbd:rbd, file:file [glance_store] # 增加 default_backend=file # 注释掉 # stores = file,http,rbd # default_store = file filesystem_store_datadir = /var/lib/glance/images/ # 增加 [rbd] rbd_store_pool = images rbd_store_user = glance rbd_store_ceph_conf = /etc/ceph/ceph.conf rbd_store_chunk_size = 8 |
重启服务:
1 |
systemctl restart openstack-glance-api.service |
查看后端列表:
1 2 3 4 5 6 7 |
glance stores-info +----------+----------------------------------------------------+ | Property | Value | +----------+----------------------------------------------------+ | stores | [{"id": "rbd"}, {"id": "file", "default": "true"}] | +----------+----------------------------------------------------+ |
首先创建一个镜像记录:
1 |
glance image-create --disk-format raw --container-format bare --visibility public --name bionic-amd64 |
然后向此镜像记录上传镜像:
1 2 |
# 指定后端 镜像记录的ID glance image-upload --file bionic-server-cloudimg-amd64.img --store rbd d828f193-830f-4e1f-ad28-4fc607474368 |
通过Ceph命令可以看到,存储池中出现一个以镜像ID为名字的RBD镜像:
1 2 |
rbd -p images ls d828f193-830f-4e1f-ad28-4fc607474368 |
通过libvirt(底层是配置QEMU使用librbd),你可以将Ceph的RBD镜像挂载(Attach)给Openstack实例。
OpenStack有三部分可以用到Ceph存储:
- 镜像:Glance管理的虚拟机镜像(不可变的)可以存放在Ceph中。Openstack将其作为blob并下载使用
- 卷:虚拟机启动使用的卷,或者后续挂载的额外卷
- 客户机磁盘:虚拟机启动时使用的系统盘,默认情况下,此系统盘表现为Hypervisor的文件系统中的一个文件,通常位于/var/lib/nova/instances/<uuid>/。在Havana版本之前,唯一启动系统盘位于Ceph中的VM方法是,使用boot-from-volume特性。现在,则可以直接启动存储在Ceph中的虚拟机,而不需要使用Cinder。这样,在虚拟机热迁移过程中,可以方便的执行维护操作。另外一个好处是,如果Hypervisor宕机,你可以通过 nova evacuate几乎无缝的重新实例化VM,OpenStack会在系统盘对应的RBD镜像上加独占锁以防多个计算节点并发访问之
Glance 能够将镜像存储为一个 Ceph 块设备。通过 Cinder使用COW克隆镜像来启动虚拟机。Ceph不支持 QCOW2 格式的镜像,必须使用RAW格式的镜像。
1 2 3 4 5 6 |
ceph osd pool create volumes 32; rbd pool init volumes ceph osd pool create backups 32; rbd pool init backups ceph osd pool create images 32; rbd pool init images ceph osd pool create vms 32; rbd pool init vms for i in volumes backups images vms; do ceph osd pool application enable $i rbd; done |
需要在nova-compute, cinder-backup 和 cinder-volume节点上安装Ceph客户端软件:
1 |
dnf install -y ceph-common python-rbd |
glance-api节点只需要安装 python-rbd。
运行glance-api, cinder-volume, nova-compute, cinder-backup的节点,是Ceph客户端,因此首先把/etc/ceph/ceph.conf复制到这些节点。
然后,创建以下Ceph账户:
1 2 3 |
ceph auth get-or-create client.glance mon 'profile rbd' osd 'profile rbd pool=images' mgr 'profile rbd pool=images' ceph auth get-or-create client.cinder mon 'profile rbd' osd 'profile rbd pool=volumes, profile rbd pool=vms, profile rbd-read-only pool=images' mgr 'profile rbd pool=volumes, profile rbd pool=vms' ceph auth get-or-create client.cinder-backup mon 'profile rbd' osd 'profile rbd pool=backups' mgr 'profile rbd pool=backups' |
并且把Keyring分发到相应节点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# 镜像服务使用client-glance ceph auth get-or-create client.glance | ssh root@openstack-1 tee /etc/ceph/ceph.client.glance.keyring ssh root@openstack-1 chown glance:glance /etc/ceph/ceph.client.glance.keyring # 卷服务、计算节点使用client-cinder ceph auth get-or-create client.cinder | ssh root@openstack-2 tee /etc/ceph/ceph.client.cinder.keyring ssh root@openstack-2 chown cinder:cinder /etc/ceph/ceph.client.cinder.keyring ceph auth get-key client.cinder | ssh root@openstack-2 tee /tmp/client.cinder.key ceph auth get-or-create client.cinder | ssh root@openstack-3 tee /etc/ceph/ceph.client.cinder.keyring ssh root@openstack-3 chown cinder:cinder /etc/ceph/ceph.client.cinder.keyring ceph auth get-key client.cinder | ssh root@openstack-3 tee /tmp/client.cinder.key ceph auth get-or-create client.cinder | ssh root@openstack-4 tee /etc/ceph/ceph.client.cinder.keyring ssh root@openstack-4 chown cinder:cinder /etc/ceph/ceph.client.cinder.keyring ceph auth get-key client.cinder | ssh root@openstack-4 tee /tmp/client.cinder.key # 备份服务使用client.cinder-backup ceph auth get-or-create client.cinder-backup | ssh root@openstack-1 tee /etc/ceph/ceph.client.cinder-backup.keyring ssh root@openstack-1 chown cinder:cinder /etc/ceph/ceph.client.cinder-backup.keyring |
准备一个UUID,推荐所有节点使用同一UUID:
1 2 |
uuidgen b3a20e8b-a27a-4623-8ea1-39eb7e34da4c |
在每个节点上执行:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
cat > secret.xml <<EOF <secret ephemeral='no' private='no'> <uuid>b3a20e8b-a27a-4623-8ea1-39eb7e34da4c</uuid> <usage type='ceph'> <name>client.cinder secret</name> </usage> </secret> EOF virsh secret-define --file secret.xml virsh secret-set-value --secret b3a20e8b-a27a-4623-8ea1-39eb7e34da4c --base64 $(cat /tmp/client.cinder.key) rm -f secret.xml /tmp/client.cinder.key |
编辑配置文件:
1 2 3 4 5 6 7 8 |
[glance_store] stores = file,http,rbd default_store = file filesystem_store_datadir = /var/lib/glance/images/ rbd_store_pool = images rbd_store_user = glance rbd_store_ceph_conf = /etc/ceph/ceph.conf rbd_store_chunk_size = 8 |
注意,glance支持多个存储后端,上面的配置增加了一个rbd后端。
要启用copy-on-write的镜像克隆,增加配置:
1 2 |
[DEFAULT] show_image_direct_url = True |
为了防止glance在/var/lib/glance/image-cache/下缓存镜像,配置:
1 2 |
[paste_deploy] flavor = keystone |
修改备份节点的Cinder配置文件:
1 2 3 4 5 6 7 8 |
backup_driver = cinder.backup.drivers.ceph backup_ceph_conf = /etc/ceph/ceph.conf backup_ceph_user = cinder-backup backup_ceph_chunk_size = 134217728 backup_ceph_pool = backups backup_ceph_stripe_unit = 0 backup_ceph_stripe_count = 0 restore_discard_excess_bytes = true |
配置cinder.conf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[DEFAULT] # 增加一个ceph的后端 enabled_backends = lvm,nfs-fast,nfs-slow,ceph # 要支持多个Cinder后端,需要配置: glance_api_version = 2 # 后端配置 [ceph] volume_driver = cinder.volume.drivers.rbd.RBDDriver volume_backend_name = ceph 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 # 如果启用了cephx身份验证 rbd_user = cinder rbd_secret_uuid = b3a20e8b-a27a-4623-8ea1-39eb7e34da4c |
创建卷类型并关联到新建的后端:
1 2 |
cinder type-create ceph cinder type-key ceph set volume_backend_name=ceph |
到这一步,可以创建Ceph卷了,但是还不能挂载给虚拟机。
libvirt进程需要利用client.cinder的keyring来挂载Ceph卷(不管是作为普通块设备还是启动盘):
1 2 3 |
[libvirt] rbd_user = cinder rbd_secret_uuid = b3a20e8b-a27a-4623-8ea1-39eb7e34da4c |
为了支持直接从Ceph卷启动虚拟机,需要为Nova配置ephemeral后端。
建议在ceph.conf中启用RBD缓存(从Giant版本默认开启)。此外,可以开启client admin socket,以收集指标和辅助故障诊断:
1 2 3 4 5 6 |
[client] rbd cache = true rbd cache writethrough until flush = true admin socket = /var/run/ceph/guests/$cluster-$type.$id.$pid.$cctid.asok log file = /var/log/qemu/qemu-guest-$pid.log rbd concurrent management ops = 20 |
1 2 |
mkdir -p /var/run/ceph/guests/ /var/log/qemu/ chown qemu:libvirt /var/run/ceph/guests /var/log/qemu/ |
使用下面的命令可以将镜像转换为raw格式:
1 2 |
qemu-img convert -f {source-format} -O {output-format} {source-filename} {output-filename} qemu-img convert -f qcow2 -O raw precise-cloudimg.img precise-cloudimg.raw |
从raw格式的、存放在Ceph后端的镜像创建卷:
1 |
cinder create --image-id {id of image} --display-name {name of volume} {size of volume} |
当Glance和Cinder同时使用Ceph后端时,镜像使用copy-on-write方式克隆,因此新卷的很快。
如果通过OpenStack Dashboard操作,参考步骤:
- 新建一个实例
- 选择一个关联到copy-on-write克隆的镜像的卷。也就是存放在Ceph中的,创建自位于Ceph中的镜像的卷
- 选择从卷启动,并使用上一步的卷
所谓配额,是指限制某个项目(租户)或者类(class)能够使用的各种云资源的量。例如CPU核心个数、固定IP个数、实例个数、密钥对个数、内存量、存储量、备份存储量、备份个数、每个卷最大存储量、网络数、子网数,等等。
默认的admin项目的配额比较小,可以用 openstack quota set修改配额。要查看配额,可以:
1 2 3 4 5 |
# 显示项目的各种配额 openstack limits show --absolute --project admin # 显示计算配额 openstack quota list --compute --project admin |
每个Flavor都可以被分配额外的属性(Extra Specs),来限制它的CPU、IO、网络的速度。
CPU限速基于cgroups实现。
IO限流由QEMU处理(通过libvirt的blkdeviotune),尽管libvirt提供了基于cgroups的blkiotune特性,但是Nova并没有使用它。
流量塑形(Traffic shaping)也就是出入站带宽限制,基于tc实现。Libvirt以网络接口为级别进行流量塑形,如果它基于cgroups进行塑形,则客户机的所有网络接口被一起限制,因为cgroups运行在进程级别。
可以使用以下Extra Specs键:
键 | 说明 |
disk_write_bytes_sec | 限制字节数/秒,写 |
disk_read_bytes_sec | 限制字节数/秒,读 |
disk_read_iops_sec | 限制IOPS,读 |
disk_write_iops_sec | 限制IOPS,写 |
disk_total_bytes_sec | 限制字节数/秒,读写 |
disk_total_iops_sec | 限制IOPS,读写 |
配置示例:
1 2 3 4 5 6 7 8 |
# 通过nova-manage命令 nova-manage flavor set_key --name m1.small --key quota:disk_read_bytes_sec --value 10240000 # 通过nova命令,需要admin凭证 nova flavor-key m1.small set quota:disk_read_bytes_sec=10240000 # 通过openstack命令,property可以指定多个 openstack flavor set m1.small --property quota:disk_read_bytes_sec=10000 |
可以使用以下Extra Specs键:
键 | 说明 |
cpu_shares | 占用CPU时间的权重,不是绝对值。一个设置了2048的VM,会比1024的多用一倍的CPU时间 |
cpu_period | 单位微秒,限制在指定周期(period)内占用CPU带宽(时间)最大值(quota) |
cpu_quota |
可以使用以下Extra Specs键:
键 | 说明 |
vif_inbound_average |
inbound表示入站流量限制,outbound表示出站流量限制 average: 期望的平均带宽KB/s |
vif_outbound_average | |
vif_inbound_peak | |
vif_outbound_peak | |
vif_inbound_burst | |
vif_outbound_burst |
所谓QoS,是指能够确保一定的网络需求的能力,这些网络需求包括带宽、延迟、抖动、可靠性。
交换机、路由器之类的网络设备,能够给流量打标记,并以更高的优先级来处理这些流量,以满足应用提供者和终端用户之间的SLA(Service Level Agreement )。
在Neutron中,qos是一个高级的插件,它将QoS从OpenStaack网络代码的其他部分解耦出来,它从多个网络级别进行QoS控制,可以通过ml2扩展驱动的方式来使用。目前qos仅仅支持ml2(的SR-IOV, Open vSwitch, linuxbridge驱动)
在控制节点,配置Neutron:
1 |
service_plugins = router,metering,qos |
1 2 |
[ml2] extension_drivers = port_security,qos |
修改你所使用的网络代理的配置,配置文件位于 /etc/neutron/plugins/ml2/<agent_name>_agent.ini。例如:
1 2 |
[agent] extensions = qos |
在计算/网络节点,修改网络代理配置:
1 2 |
[agent] extensions = qos |
如果希望给浮动IP配置QoS,需要配置L3代理:
1 2 3 4 5 6 |
[agent] ; 如果需要支持路由器网关地址的QoS extensions = fip_qos,gateway_ip_qos ; 使用Open vSwitch时,由于rate limit对于OVS内部端口不工作,作为变通方法,添加配置 ovs_use_veth = True |
Differentiated Services(DS,DiffServ)是一种在IP网络中分类、管理网络流量并提供QoS的机制。DS在保障关键流量(例如VoIP、视频流)低延迟的同时,为非关键服务(例如Web流量)提供best-effort服务。
DS在8bit的IP头字段differentiated services(DS)字段(用于替换过时的IPv4 TOS字段)中,写入6bit的DSCP(Differentiated Services Code Point)。RFC 4594对各个DSCP值由规定,例如广播食品CS3的DSCP为24。
当使用VxLAN之类的Overlay网络时,DHCP标记仅仅应用在内层IP头上。在封装期间,DSCP标记不会自动拷贝到外层包头。为了自动在外层包头设置DSCP,需要配置网络代理:
1 2 3 |
[agent] dscp = 8 dscp_inherit = true |
OpenStack会将QoS规则映射为底层代理的配置。如果使用Linux Bridge作为网络代理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# 入站 tc qdisc show dev tap2e939f9e-9e # qdisc tbf 8002: root refcnt 2 rate 512Kbit burst 16Kb lat 50.0ms # 出站 tc filter show dev tap2e939f9e-9e parent ffff: # filter protocol all pref 49 basic chain 0 # filter protocol all pref 49 basic chain 0 handle 0x1 # police 0x1 rate 1024Kbit burst 32Kb mtu 64Kb action drop overhead 0b # ref 1 bind 1 # DSCP iptables -t mangle -nL neutron-linuxbri-qos-o2e939f Chain neutron-linuxbri-qos-o2e939f (1 references) target prot opt source destination DSCP all -- 0.0.0.0/0 0.0.0.0/0 DSCP set 0x10 |
使用默认的policy.json时,仅仅管理员能够创建QoS策略。 下面是个例子:
1 2 3 4 5 6 7 8 9 10 11 12 |
# 创建一个规则 openstack network qos policy create bw-limiter # 设置出站带宽限制 openstack network qos rule create --type bandwidth-limit --max-kbps 3000 --max-burst-kbits 2400 --egress bw-limiter # 创建一个DSCP标记规则 openstack network qos policy create dscp-marking # 设置DSCP值 openstack network qos rule create --type dscp-marking --dscp-mark 26 \ dscp-marking |
注意:对于OVS和Linux Bridge来说,QoS实现需要burst值才能确保正确的带宽限制行为。设置合理的burst值非常重要,如果仅设置bandwidth-limit,即使它的值是合理的,带宽也会被throttled。对于TCP流量来说,推荐burst为bandwidth-limit的80%,如果burst设置的过低,则实际获得的带宽可能小于预期。
为某个网络端口配置/解除QoS策略:
1 2 3 4 5 6 7 |
# 设置 openstack port set --qos-policy bw-limiter 88101e57-76fa-4d12-b0e0-4fc7634b874a # 解除 openstack port unset --qos-policy 88101e57-76fa-4d12-b0e0-4fc7634b874a # 创建端口时可以直接指定QoS策略 openstack port create --qos-policy bw-limiter --network private port1 |
你也可以将浮动IP、网络关联到QoS策略:
1 2 3 4 5 6 7 8 |
# 关联浮动IP到QoS策略 openstack floating ip create --qos-policy bw-limiter public openstack floating ip set --qos-policy bw-limiter d0ed7491-3eb7-4c4f-a0f0-df04f10a067c # 解除关联 openstack floating ip set --no-qos-policy d0ed7491-3eb7-4c4f-a0f0-df04f10a067c openstack floating ip unset --qos-policy d0ed7491-3eb7-4c4f-a0f0-df04f10a067c # 关联整个网络到QoS策略 openstack network set --qos-policy bw-limiter private |
关联到浮动IP的QoS策略,将在浮动IP挂载到某个端口的时候生效。
每个项目可以配置一个默认QoS策略:
1 |
openstack network qos policy create --default bw-limiter |
你可以在运行时动态修改QoS策略的规则,这些修改会传播到每个Attach到策略的端口:
1 2 3 |
# 修改规则 openstack network qos rule set --max-kbps 2000 --max-burst-kbits 1600 \ --ingress bw-limiter 92ceb52f-170f-49d0-9528-976e2fee2d6f |
要调整Nova日志级别,修改配置:
1 |
log_config_append=/etc/nova/logging.conf |
在/etc/nova/logging.conf中配置日志级别:
1 2 3 4 |
[logger_nova] level = INFO handlers = stderr qualname = nova |
此功能使用户能够将单个块存储卷挂载到多个服务器,以及从多个服务器访问单个块存储卷。此功能的用例包括 active-active 和 hot-standby 场景——有多台服务器需要访问卷上的数据,以在出现故障时快速恢复或能够处理系统中增加的负载。在 Queens 发行版中,有三个驱动程序支持 multi-attach :LVM、NetApp / SolidFire 和 Oracle ZFSSA
在 Nova 中,对 vGPU 的支持让云管理员能够定义 flavor 以请求 vGPU 的特定资源和分辨率。最终用户可以启动具有 vGPU 的虚拟机,这对于图像密集型工作负载以及人工智能和机器学习工作负载来说是一项重要的功能
Cyborg是用于管理硬件和软件加速资源(如 GPU,FPGA,CryptoCards 和 DPDK/SPDK)的架构,对NFV工作负载的电信公司而言,加速是一项必备的功能。通过Cyborg,运维人员可以列出、识别和发现加速器,将加速器连接到实例并将其分离、安装和卸载驱动器。它可以单独使用,或与 Nova 或 Ironic 结合使用
之前在 Nova 中可以实现虚拟机实例修复,现在 Ironic 中可以实现裸机实例修复。运维人员可以对错误配置的裸机节点进行故障排除,或从诸如丢失的SSH密钥等问题中恢复
OpenStack是在私有云中部署容器的首选平台,Queens版本扩展了微服务功能。Kuryr 增加了一个 CNI 守护进程来增加 Kubernetes 操作的可扩展性。为了支持高可用(HA),CNI 守护进程能够监控 Pod 事件,不需要为每个事件等待 Kubernetes API。即便控制器宕机了,也可以创建 Pod。
Zun 是一个新 的OpenStack 项目,它允许用户无需管理服务器或集群即可快速启动和运行容器。它通过与 Neutron,Cinder,Keystone 和其他核心 OpenStack 服务集成,无缝地将先进的企业网络、存储和身份验证功能添加到容器中
提供了一系列 Helm 图表和工具,用于在 Kubernetes之 上管理 OpenStack的生命周期,并将 OpenStack 作为独立服务运行
OCI 生成兼容 Open Container Initiative 的 OpenStack 服务镜像,可以放入像 OpenStack-Helm 这样的重量级部署工具,或者单独使用来交付像 Cinder 块存储这样的独立服务。 LOCI 提供了现有 OpenStack Kolla 项目的一种替代方案(为每个容器镜像提供一个更完整的打包方法)。LOCI 采取的方法更符合 Kubernetes 运行镜像的方式,其中容器本身非常小,管理位于容器外部
提供运行容器所需的裸机和网络功能:
- OpenStack Magnum,经过认证的Kubernetes安装程序,显著提升了Kubernetes集群的启动时间—无论节点数量多少,每个节点从10-12分钟降至5分钟
- 通过OpenStack云供应商,您现在可以在Manila、Cinder和Keystone服务的支持下启动完全集成的Kubernetes集群,从而充分利用其底层的OpenStack云平台
- Neutron,OpenStack网络服务,针对在组中创建端口的容器用例,更快速的创建批量端口
- Ironic,裸机配置服务,持续改进部署模板,以便于独立用户请求分配裸机节点并提交配置数据,而不需要预先配置驱动器
-
Neutron,网段范围管理,云管理员可通过新的扩展API动态管理网段范围,而不是采用之前编辑配置文件的方法。StarlingX和边缘用例将得益于此,更易于管理
-
对于网络密集型应用程序,拥有最小可用网络带宽至关重要。在Rocky周期中开始工作,提供基于最小带宽需求的调度,该功能已在Stein中交付。作为强化功能的一部分,Neutron将带宽视为一种资源,并与OpenStack Nova计算服务协作,将实例调度到满足其带宽需求的主机上
-
对API的改进增加了OpenStack体系结构和部署的灵活性,增加了对服务质量(QoS)策略规则aliases的支持,使调用者能够更高效地执行删除、显示和更新QoS规则等请求
-
Blazar,资源预留服务,引进了新的资源分配API,运营商可查询其云计算资源的保留状态
-
Placement是引入Stein版本的一个新项目,是从Nova项目中分离出来的。可定位候选资源供应商,简化了为工作负载迁移指定主机的任务。对于常见的调度操作,API性能提升了50%。Train版本中将删除Nova中的Placement服务,其后安装Nova需要使用单独的Placement服务
- 支持软件RAID:具有Ironic 裸机服务可保护服务免受磁盘故障的影响。欧洲核研究组织欧洲核子研究组织(CERN)领导了此功能的上游开发,并且已经将该功能在超过1000个节点上投入生产
- 基于硬件的加密:Nova 是OpenStack的计算功能, 其新框架支持对guest存储器进行基于硬件的加密,以保护用户免遭攻击者或流氓管理员在使用libvirt计算驱动程序时窥探其工作负载。此功能对于多租户环境和具有可公开访问的硬件的环境很有用
- 数据保护流程:Karbor 为检查,还原,计划和触发操作添加了事件通知。此功能允许用户使用位于根磁盘上的新添加的数据备份映像引导服务器
要求CentOS 8
完成了Nova Cyborg Interaction功能,使两者在某些方面进行紧密的联系,用于启动和管理具有GPU等加速器的实例
-
Nova API策略引入了具有scope_type功能的新默认角色
-
Ironic及其远程代理之间的交互身份验证得到了补充
-
Kolla 添加了对后端API服务的TLS加密的初始支持
-
Glance 优化了对Multiple Strores的操作,单次操作,后台同步
-
Keystone对创建应用程序凭据和信任关系的用户体验进行了极大改善
-
为volume-type设置最大和最小的Size
-
使用时间比较运算符过滤卷列表的能力
-
将卷上载到Image Service时,支持Glance multistore和镜像数据托管
-
添加了一些新的后端驱动程序,并且许多当前的驱动程序都增加了对更多功能的支持
-
随着Nova-Cyborg集成的完成,用户现在可以使用由Cyborg管理的加速器启动实例
-
实现了新的API,用以列出由Cyborg管理的设备,可以查看和管理加速器的列表
-
Cyborg通过在v2 API中采用microversions的模式,旨在将来版本中提供向后兼容的办法
-
Cyborg客户端现在基于OpenStack SDK,并支持大多数Version 2 API
-
通过增加更多的单元/功能测试并减少技术负担来提高总体质量
-
增强了Multiple Stores功能,用户现在可以向多个Stores导入单个镜像,在多个Stores中复制现有的imgae,并从单个Store中删除镜像
-
新导入了插件以解压镜像
-
再次为glance-store引入了S3 driver
-
支持范围内省的规则,该规则允许每个节点子集具有(并保留)规则,例如不同的硬件交付
-
支持硬件退役工作流程,以实现托管云中硬件退役的自动化
-
非管理员使用Ironic可以使用多租户概念和其他策略选项
-
Ironic及其远程代理之间的交互身份验证得到了补充,从而可以在不受信任的网络上进行部署
-
UEFI和设备选择现在可用于软件RAID
-
使用联合身份验证方法时,用于创建应用程序凭据和信任关系的用户体验已得到极大改善。角色分配来自映射的组成员身份的联盟用户将在令牌过期后将这些组成员身份保留为可配置的TTL,在此期间其应用程序凭证将保持有效
-
现在,可以通过在Keystone中直接创建联盟用户并将其链接到其身份提供者,而无需依赖于映射API,就可以为联盟用户指定具体的角色分配
-
当引导新的Keystone部署时,管理员角色现在默认设置为“ immutable”选项,这可以防止意外删除或修改它,除非有意删除了“ immutable”选项
-
Keystonemiddleware不再支持Identity v2.0 API,该身份在先前的发行周期中已从keystone中删除
-
恢复资源驱动程序的可配置性,因此,如果内置sql驱动程序不满足业务要求,现在可以创建自定义资源驱动程序
-
所有镜像,脚本和Ansible剧本都使用Python 3,并且对Python 2的支持也已删除
-
添加了对CentOS 8主机和镜像的支持
-
添加了对后端API服务的TLS加密的初始支持,从而提供了API流量的端到端加密。目前支持Keystone
-
增加了对开放虚拟网络(OVN)部署以及与Neutron集成的支持
-
增加了对部署Zun CNI(容器网络接口)组件的支持,从而使带有容器的Docker可以支持Zun capsules(pods)
-
添加了对Elasticsearch Curator的支持,以帮助管理集群日志数据
-
添加了将Mellanox网络设备与Neutron一起使用所必需的组件
-
简化了外部Ceph集成的配置,可以轻松地从Ceph-Ansible部署的Ceph集群过渡到在OpenStack中启用它
-
支持IPv6
-
DPDK支持嵌套设置以及其他各种与DPDK和SR-IOV相关功能的改进
-
与NetworkPolicy支持相关的多个修复程序
-
共享组已从试验性功能逐渐发展成熟。从API版本2.55开始,不再需要X-OpenStack-Manila-API-Experimental标头来创建/更新/删除共享组类型,组规范,组配额和共享组本身
-
兼容时,可以从跨存储池的快照创建共享。这项新功能可以通过分散先前局限于托管快照的后端的工作负载来更好地利用后端资源
-
引入了新的配额控制机制,以限制项目及其用户可创建的共享副本的数量和大小
-
现在可以按时间间隔查询异步用户消息
-
OVN驱动程序现在已合并到Neutron存储库中,并且是核心 Neutron ML2 drivers之一,例如linuxbridge或openvswitch。与openvswitch驱动程序相比,OVN驱动程序的优点包括具有分布式SNAT流量的DVR,分布式DHCP以及无需网络节点即可运行的可能性。当然其他ML2驱动程序仍然受到完全支持。当前默认代理还是openvswitch,但计划是使用OVN驱动程序成为将来的默认选择
-
添加了对无状态安全组的支持。用户现在可以将安全组集创建为无状态,这意味着conntrack将不会用于该组中的任何规则。一个端口只能使用无状态或有状态安全组。在某些用例中,无状态安全组将允许操作员选择优化的数据路径性能,而有状态安全组会在系统上施加额外的处理
-
已添加用于地址范围和子网池的基于角色的访问控制(RBAC)。地址范围和子通常由运营商定义并向用户公开。此更改使操作员可以在地址范围和子网池上使用更精细的访问控制
-
Neutron API中添加了对创建过程中标记资源的支持。用户现在可以设置资源标签,例如直接在POST请求中移植端口。这将大大提高kubernetes网络操作的性能。API调用的数量,例如Kuryr已发送给Neutron的邮件大大减少
-
Nova不再支持Python 2,Python 3.6和3.7则受支持
-
支持在Nova cells间进行冷迁移和重新调整虚拟机大小
-
支持precaching glance image到计算节点
-
支持在创建虚拟机时通过Cyborg来附加加速设备
-
进一步支持QOS最小的带宽功能(拓展了以下操作evacuate、live migrate、unshelve)
-
支持nova-manage placement auditCLI,以查找和清理孤立的资源分配
-
Nova API策略引入了具有scope_type功能的新默认角色。这些新更改提高了安全级别和可管理性。在处理具有“读取”和“写入”角色的系统和项目级别令牌的访问权限方面,新策略更加丰富
-
从卷启动的虚拟机能够使用Rescue操作,允许将稳定的磁盘设备连接到救援实例
-
计算节点支持多种虚拟GPU类型
-
移除os-consoles和os-networksREST APIs
-
移除nova-dhcpbridge、nova-console、nova-xvpvncproxy服务
Octavia提供负载均衡服务
-
Octavia现在支持在特定可用性区域中部署负载平衡器。这允许将负载平衡功能部署到边缘环境
-
Octavia amphora驱动程序已添加了一项技术预览功能,可以改善控制平面的弹性。如果控制平面主机在负载均衡器配置操作期间发生故障,备用控制器可以恢复进行中的配置并完成请求
-
用户现在可以指定侦听器和池可接受的TLS密码。这允许负载平衡器强制执行安全合规性要求
Placement 放置服务,通过使分配重试计数可配置,提高了常见的并发分配写入次数(例如繁忙的群集管理程序)情况下的鲁棒性
-
为Swift容器和对象添加了新的系统命名空间
-
使用新的名称空间添加了新的Swift对象版本API
-
添加了对使用新API的S3版本控制的支持
-
添加了使用SIGUSR1执行“无缝”重载的功能,其中WSGI服务器套接字从不停止接受连接
- 改进了对配置的默认卷类型的处理,并使用microversion 3.62添加了新的块存储API调用,可以为单个项目设置项目级别的默认卷类型
- 添加了一些新的后端驱动程序,同时当前的大部分驱动程序都添加了对更多功能的支持。例如,NFS驱动程序现在支持卷加密
- 使用流行的Zstandard压缩算法,增加了对cinder备份的支持
- 自Ussuri发行以来,用户可以使用由Cyborg管理的加速器启动实例,该发行版还支持两项操作Rebuild and Evacuate
- Cyborg支持新的加速器驱动程序(Intel QAT和Inspur FPGA),并达成协议,希望实施新驱动程序的供应商至少应提供完整的驱动程序报告结果
- 支持Program API,现在,用户可以在给定预加载的bitstream的情况下对FPGA进行编程
- 在此版本中,部分实施了针对cyborg的策略刷新(带有作用域的RBAC)(设备配置文件API),我们在基本策略和device_profile策略中实现了新的默认规则,并为所有策略添加了基本测试框架。对于向后兼容性,将旧规则保留为不推荐使用的规则,并使用与当前相同的默认值,以便现有部署将保持原样运行。实施所有功能后,我们将为用户提供两个周期的过渡期
- 增强了多个商店功能,管理员现在可以设置策略以允许用户复制其他租户拥有的镜像
- 概览允许配置多cinder存储
- 一目了然的RBD和Filesystem驱动程序现在支持稀疏镜像上传
- 增强了RBD驱动程序块上传镜像
- 部署步骤工作将基本部署操作分解为多个步骤,现在还可以包括部署时支持的RAID和BIOS接口的步骤
- 一个agent电源接口支持在没有基板管理控制器的情况下进行资源调配操作
- 现在可以将Ironic配置为进行HTTP Basic身份验证,而无需其他服务
- 添加了对Redfish虚拟介质的基于DHCP的部署的初始支持
- 添加了对Ubuntu Focal 20.04的支持
- 添加了对后端API服务的TLS加密的附加支持,从而提供了API流量的端到端加密
- 增加了对核心OpenStack服务的容器健康检查的支持
- 添加了对etcd的TLS加密的支持
- 改善了Ansible Playbook的性能和可伸缩性
- 增加了对将Neutron与Mellanox InfiniBand集成的支持
- 为Kayobe添加了对在neutron上部署自定义容器的支持
- Kuryr将不再使用注释在k8s api中存储关于OpenStack对象的数据。而是创建了一个相应的CRD,即KuryrPort、KuryrLoadBalancer和KuryrNetworkPolicy
- 增加了在嵌套设置中自动检测虚拟机桥接接口的支持
- 租户驱动的共享复制,数据保护,灾难恢复和高可用性的自助服务现已普遍可用并得到完全支持
- 共享服务器迁移现在作为一个实验性功能提供。共享服务器通过隔离网络路径中的共享文件系统来提供多租户保证。在这个版本中,云管理员能够将共享服务器移动到不同的后端或共享网络
- 现在可以通过IPv6使用元数据服务。用户现在可以在仅IPv6的网络中使用不带配置驱动器的元数据服务。
- flat已为分布式虚拟路由器(DVR)添加了对网络的支持。
- OVN后端增加了对浮动IP端口转发的支持。现在,在Neutron中使用OVN后端时,用户可以为浮动IP创建端口转发。
- 在OVN中增加了对路由器可用区域的支持。OVN驱动程序现在可以从路由器的Availability_zone_hints字段中读取,并使用给定的可用区域相应地调度路由器端口
- Nova支持在同一nova服务器中混合使用绑定和浮动CPU
- Nova支持通过提供程序配置文件来自定义计算节点的放置资源清单
- 即使使用Glance多存储 配置,Nova也支持 从Ceph RBD群集快速克隆Glance镜像
- Nova支持使用虚拟TPM设备创建服务器
- 用户现在可以指定侦听器和池接受的TLS版本。用户现在还可以设置其部署可接受的最低TLS版本
- Octavia现在使用新的侦听器应用程序层协议协商(ALPN)配置选项来支持TLS上的HTTP/2
- 现在可以将负载均衡器统计信息同时报告给多个统计信息驱动程序,并支持增量指标。这样可以更轻松地集成到外部度量系统中,例如时间序列数据库
- 用于amphora驱动程序的Octavia flavors现在支持将glance image标记指定为flavor的一部分。这允许用户定义Octavia flavor来引导备用的amphora镜像
- 负载平衡器池现在支持PROXY协议的版本2。使用TCP协议时,这允许将客户端信息传递到成员服务器。PROXYV2提高了使用PROXY协议与成员服务器建立新连接的性能,尤其是在侦听器使用IPv6的情况下
- 改进了读取纠错码数据时的第一字节延迟
- 当使用单独的复制网络运行时,后台守护程序和代理服务器之间的隔离度增加
- 我们开始看到生产集群从python2下运行Swift过渡到python3
Neutron元数据代理日志(/var/log/neutron/metadata-agent.log)报错:The remote metadata server responded with Forbidden. This response usually occurs when shared secrets do not match.
可能原因:元数据代理配置文件metadata_agent.ini中的metadata_proxy_shared_secret和nova.conf中配置的不一样。
报错示例:compressor.exceptions.OfflineGenerationError: You have offline compression enabled but key "xxx" is missing from offline manifest. You may need to run "python manage.py compress". Here is the original content
解决办法:
1 |
COMPRESS_OFFLINE = False |
然后重启httpd
禁用IPv6可以消除此错误:
1 |
net.ipv6.conf.all.disable_ipv6 = 1 |
linux-bridge从设计上禁用了IPv6,如果物理网卡上配置了IPv6地址,则neutron/root没有权限将IPv6地址从物理网卡移动到linux-bridge上。
尽管如此,linux-bridge仍然会将IPv6的L2帧转发,你仍然可以在客户机上使用IPv6。
使用provider网络时,底层网络中存在DHCP服务器时出现此情况。实例向底层网络中的DHCP请求了IP地址,而非DHCP Agent。
建议:使用底层网络,但是分配独立的网段。
需要修改镜像虚拟尺寸,首先检查一下镜像信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# 进入镜像存储目录 /var/lib/glance/images/ # 得到镜像ID openstack image list # | 379caead-7878-4d82-847d-502feea5b8ed | centos8-amd64-prepared | active | # 查看镜像信息 qemu-img info 379caead-7878-4d82-847d-502feea5b8ed # image: 379caead-7878-4d82-847d-502feea5b8ed # file format: qcow2 # virtual size: 128 GiB (137438953472 bytes) 虚拟尺寸 # disk size: 1.42 GiB # cluster_size: 65536 # Format specific information: # compat: 1.1 # compression type: zlib # lazy refcounts: false # refcount bits: 16 # corrupt: false # 挂载到虚拟文件系统 export LIBGUESTFS_BACKEND=direct virt-filesystems --long -h --all -a 379caead-7878-4d82-847d-502feea5b8ed # Name Type VFS Label MBR Size Parent # /dev/sda1 filesystem xfs - - 128G - # /dev/sda1 partition - - 83 128G /dev/sda # /dev/sda device - - - 128G # 检查实际用量 virt-df 379caead-7878-4d82-847d-502feea5b8ed # Filesystem 1K-blocks Used Available Use% # 379caead-7878-4d82-847d-502feea5b8ed:/dev/sda1 # 134206444 1678740 132527704 2% |
可以看到这是一个128G的XFS分区,由于XFS分区不支持Shrink,我们可以考虑将其备份,然后还原到一个较小的卷上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# 从上述镜像创建一个卷,附到/dev/vdb openstack volume create --size 130 --image centos8-amd64-prepared centos8-amd64 # 创建一个新的2GB的目标卷,附到/dev/vdc # 挂载 mount -t xfs /dev/vdb1 /tmp/vdb1 # mount: /tmp/vdb1: wrong fs type, bad option, bad superblock on /dev/vdb1, # missing codepage or helper program, or other error. # 上述报错的原因是 vda vdb的UUID重复 uuidgen xfs_admin -U 9e58a8e1-6962-4342-af59-ba10c53626cc /dev/vdb1 mount -t xfs /dev/vdb1 /tmp/vdb1 # 导出 xfsdump -l 0 -f vdb /dev/vdb1 # 导入 mkfs.xfs /dev/vdc1 mount /dev/vdc1 /tmp/vdc1 xfsrestore -f vdb /tmp/vdc1 |
把这个2G的卷保存为镜像即可。
镜像被外部程序修改,建议重新上传镜像。
上传卷为镜像时报此错误:Invalid volume: Volume 8d2747cf-b50e-4d36-a90a-33dd7b56cad4 status must be available
解决方案,配置Cinder:
1 |
enable_force_upload = true |
重启控制节点服务:
1 2 3 |
systemctl restart openstack-cinder-volume systemctl restart openstack-cinder-api systemctl restart openstack-cinder-scheduler |
从镜像创建卷失败,报如上错误。移除镜像的signature_verified属性即可解决:
1 |
openstack image unset --property signature_verified centos8-amd64-prepared |
openstack volume service list报告某些节点的cinder-volume处于down状态:
1 2 3 4 5 6 7 8 9 |
openstack volume service list # +------------------+---------------+------+---------+-------+----------------------------+ # | Binary | Host | Zone | Status | State | Updated At | # +------------------+---------------+------+---------+-------+----------------------------+ # | cinder-volume | centos-11@lvm | nova | enabled | down | 2021-01-14T10:44:12.000000 | # | cinder-volume | centos-13@lvm | nova | enabled | down | 2021-01-14T10:44:26.000000 | # | cinder-volume | centos-12@lvm | nova | enabled | down | 2021-01-14T10:44:23.000000 | # | cinder-scheduler | centos-10 | nova | enabled | up | 2021-01-16T10:14:23.000000 | # +------------------+---------------+------+---------+-------+----------------------------+ |
查看对应节点的/var/log/cinder/volume.log,出现上述报错。
原因:LVM卷组cinder-volumes没有初始化。
首先重置状态:
1 |
cinder snapshot-reset-state --state error 7f5154ca-9413-4071-b99f-ec60626a9efe |
然后登陆数据库删除记录:
1 2 3 |
use cinder; update snapshots set deleted=1,status='deleted',deleted_at=now(),updated_at=now() where deleted=0 and id='7f5154ca-9413-4071-b99f-ec60626a9efe'; |
报错内容:libvirt.libvirtError: internal error: Child process (tc filter add dev tapaf7dae14-ef parent ffff: protocol all u32 match u32 0 0 police rate 10485760kbps burst 10485760kb mtu 64kb drop flowid :1) unexpected exit status 1: Illegal "rate"
可能原因:限速的值太大了。
1 2 3 4 5 6 |
export OS_USERNAME=admin export OS_PASSWORD=111111 export OS_TENANT_NAME=admin export OS_AUTH_URL=http://192.168.101.250:35357/v3 export OS_USER_DOMAIN_NAME=Default export OS_PROJECT_DOMAIN_NAME=Default |
如果遇到报错:
Ignoring domain related config project_domain_name because identity API version is 2.0
Expecting to find domain in project. The server could not comply with the request since it is either malformed or otherwise incorrect. The client is assumed to be in error. (HTTP 400) (Request-ID: req-047e4968-2c06-4501-8635-0dd27093d5d8)
需要增加环境变量:
1 |
export OS_IDENTITY_API_VERSION=3 |
大佬牛逼