OpenStack-Queens版双节点搭建-2020.4.5

OpenStack-Queens版双节点搭建-2020-4-5

本文档参考 官方安装指南 整理。

仅涉及基础组件安装,供学习参考。

目录

文章目录

环境准备

创建虚拟机

系统镜像:CentOS7.7.1908-Minimal 下载地址

VMware创建两台虚拟机controller、compute,配置如下

controllercompute
内存>=4G>=2G
处理器>=2Core>=2Core
硬盘>=20G>=20G
CD/DVDCentOS7.2.1511CentOS7.2.1511
网卡1(nat模式,禁用DHCP)192.168.200.10(稍后设置)192.168.200.20(稍后设置)
网卡2(仅主机,禁用DHCP)192.168.210.10(稍后设置)192.168.210.20(稍后设置)
虚拟化不必开启开启

CentOS的安装过程略,一些小tips:

关于“虚拟网络编辑器”:网关默认192.168.200.2,可以修改。这里改为192.168.200.1。

使网卡名为ethX:安装系统时install CentOS 7处按Tab键,
留个空格添加net.ifnames=0 biosdevname=0,然后回车,启动安装程序。
在这里插入图片描述

关于分区/home可以不要,分配给根分区/

密码:为便于记忆,后面所有密码均为六个零000000
compute可以由controller克隆

配置网络

192.168.200.0作为管理网络/外部网络/部署网络
192.168.210.0作为隧道网络

controller节点

vi /etc/sysconfig/network-scripts/ifcfg-eth0

按i进入编辑模式,修改为以下

DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.200.10
NETMASK=255.255.255.0
GATEWAY=192.168.200.1
DNS1=8.8.8.8
按:wq保存退出
vi /etc/sysconfig/network-scripts/ifcfg-eth1

按i进入编辑模式,修改为以下

DEVICE=eth1
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.210.10
NETMASK=255.255.255.0

按:wq保存退出
重启网络

systemctl restart network

compute节点

同理,注意地址eth0为192.168.200.20,eth1为192.168.210.20

vi /etc/sysconfig/network-scripts/ifcfg-eth0

按i进入编辑模式,修改为以下

DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.200.20
NETMASK=255.255.255.0
GATEWAY=192.168.200.1
DNS1=8.8.8.8
按:wq保存退出
vi /etc/sysconfig/network-scripts/ifcfg-eth1

按i进入编辑模式,修改为以下

DEVICE=eth1
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.210.20
NETMASK=255.255.255.0

按:wq保存退出
重启网络

systemctl restart network

使用终端软件(SecureCRT、Xshell等)连接

配置物理机网卡vmnet8 /vmnet1,
win10:打开“网络和Internet设置”->“以太网”->“更改适配器选项”->右击网卡->“属性”->“Internet协议版本4”->“属性”->“使用下面的IP地址”
vmnet8 IP地址:192.168.200.254 掩码255.255.255.0
vmnet1 IP地址:192.168.210.1 掩码255.255.255.0
终端软件输入IP,用户名和密码连接

修改主机名、hosts

controller节点

[root@localhost ~]# hostnamectl set-hostname controller
再按CTRL+D重新登陆
[root@controller ~]# vi /etc/hosts
添加
192.168.200.10 controller
192.168.200.20 compute

compute节点

[root@localhost ~]# hostnamectl set-hostname compute
[root@compute ~]# vi /etc/hosts
添加
192.168.200.10 controller
192.168.200.20 compute

关闭防火墙、SELinux

systemctl  stop firewalld.service
systemctl  disable  firewalld.service
sed -i 's/SELINUX=.*/SELINUX=permissive/g' /etc/selinux/config
setenforce 0

安装NTP服务

controller节点

[root@controller ~]# yum install chrony -y
[root@controller ~]# vi /etc/chrony.conf
注释掉
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
添加
server ntp.aliyun.com iburst #使用阿里ntp
allow 192.168.200.0/24 #允许网段其他节点同步时间
[root@controller ~]# systemctl enable chronyd.service
[root@controller ~]# systemctl start chronyd.service
[root@controller ~]# chronyc sources

compute节点

[root@compute ~]# yum install chrony -y
[root@compute ~]# vi /etc/chrony.conf
注释掉
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
添加
server controller iburst #同步controller节点
注释掉(如果有这句的话)
#pool 2.debian.pool.ntp.org offline iburst
[root@compute ~]# systemctl enable chronyd.service
[root@compute ~]# systemctl start chronyd.service
[root@compute ~]# chronyc sources

安装OpenStack软件包

所有节点

方法一 方便但速度慢
# yum install centos-release-openstack-queens
方法二 使用国内阿里的源
# mkdir /etc/yum.repos.d/bak
# mv /etc/yum.repos.d/* /etc/yum.repos.d/bak
# curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
# vi /etc/yum.repos.d/openstack.repo
[centos-openstack-queens]
name=CentOS-7 - OpenStack queens
baseurl=https://mirrors.aliyun.com/centos/7/cloud/x86_64/openstack-queens/
gpgcheck=0
enabled=1
[centos-qemu-ev]
name=CentOS-$releasever - QEMU EV
baseurl=https://mirrors.aliyun.com/centos/7/virt/x86_64/kvm-common/
gpgcheck=1
enabled=1

在所有节点上升级软件包:

# yum upgrade -y

如果升级过程包括新内核(kernel),需要重启
安装OpenStack客户端:

# yum install python-openstackclient -y

安装 openstack-selinux软件包以自动管理OpenStack服务的安全策略:

# yum install openstack-selinux -y

如果我们没有进行关闭selinux,openstack-selinux就会自动帮我们设置

安装数据库

controller节点

安装软件包

# yum install mariadb mariadb-server python2-PyMySQL -y

新建配置

# vi /etc/my.cnf.d/openstack.cnf

添加内容,bind-address 设置为controller节点的管理IP地址

[mysqld]
bind-address = 192.168.200.10
default-storage-engine = innodb
innodb_file_per_table = on
max_connections = 4096
collation-server = utf8_general_ci
character-set-server = utf8

启动数据库服务,并将其配置为在系统引导时启动:

# systemctl enable mariadb.service
# systemctl start mariadb.service

通过运行mysql_secure_installation 脚本来保护数据库服务。
为数据库root设置密码

# mysql_secure_installation
Enter current password for root (enter for none): #第一次进入,root无密码,留空
Set root password? [Y/n] y#设置root密码
New password: 
Re-enter new password: #再次输入确认
Password updated successfully!
Remove anonymous users? [Y/n] y#移除匿名用户
Disallow root login remotely? [Y/n] n#禁止root用户远程登陆,否
Remove test database and access to it? [Y/n] y#移除测试数据库
Reload privilege tables now? [Y/n] y#重载权限表

消息队列

安装软件包:

# yum install rabbitmq-server -y

启动消息队列服务,并将其配置为在系统引导时启动:

# systemctl enable rabbitmq-server.service
# systemctl start rabbitmq-server.service

添加openstack用户:

# rabbitmqctl add_user openstack 000000
替换000000为合适的密码。

允许用户配置,写入和读取访问权限 openstack:

# rabbitmqctl set_permissions openstack ".*" ".*" ".*"

缓存服务

安装软件包:

yum install memcached python-memcached -y

编辑/etc/sysconfig/memcached配置服务使用控制器节点的管理IP地址。这是为了允许其他节点通过管理网络进行访问。
更改OPTIONS="-l 127.0.0.1,::1"

OPTIONS="-l 127.0.0.1,::1,controller" 

启动Memcached服务,并将其配置为在系统启动时启动:

# systemctl enable memcached.service
# systemctl start memcached.service

Etcd服务

安装软件包

yum install etcd -y

编辑/etc/etcd/etcd.conf文件,以控制节点管理IP地址设置相关选项,以使其他节点通过管理网络进行访问

#[Member]
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://192.168.200.10:2380"
ETCD_LISTEN_CLIENT_URLS="http://192.168.200.10:2379"
ETCD_NAME="controller"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.200.10:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.200.10:2379"
ETCD_INITIAL_CLUSTER="controller=http://192.168.200.10:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-01"
ETCD_INITIAL_CLUSTER_STATE="new"

启用并启动etcd服务:

# systemctl enable etcd
# systemctl start etcd

安装OpenStack服务

认证服务keystone

在安装和配置身份服务之前,必须创建数据库。

使用数据库访问客户端以root用户身份连接到数据库服务器:

mysql -uroot -p000000

创建keystone数据库,授予对keystone数据库的适当访问权限

MariaDB [(none)]> CREATE DATABASE keystone;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY '000000';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY '000000';
替换`000000`为合适的密码。
MariaDB [(none)]> \q

安装和配置keystone

...表示应保留的潜在默认配置选项。
安装软件

# yum install openstack-keystone httpd mod_wsgi -y

编辑/etc/keystone/keystone.conf文件并完成以下操作:
配置数据库访问:

[database]
# ...
connection = mysql+pymysql://keystone:000000@controller/keystone
替换`000000`为您为数据库选择的密码。

配置Fernet令牌提供者:

[token]
# ...
provider = fernet

填充keystone数据库:

 su -s /bin/sh -c "keystone-manage db_sync" keystone

初始化Fernet密钥存储库:

keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
keystone-manage credential_setup --keystone-user keystone --keystone-group keystone

引导身份服务:
注:在Queens发行之前,keystone需要在两个单独的端口上运行,以适应Identity v2 API,后者通常在端口35357上运行单独的仅管理员服务。

keystone-manage bootstrap --bootstrap-password 000000 \
--bootstrap-admin-url http://controller:5000/v3/ \
--bootstrap-internal-url http://controller:5000/v3/ \
--bootstrap-public-url http://controller:5000/v3/ \
--bootstrap-region-id RegionOne

000000替换为合适的管理员密码

配置Apache HTTP服务器

编辑/etc/httpd/conf/httpd.conf文件

ServerName controller

创建/usr/share/keystone/wsgi-keystone.conf文件链接:

ln -s /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/

启动Apache HTTP服务,并将其配置为在系统启动时启动:

systemctl enable httpd.service
systemctl start httpd.service

配置管理帐户

export OS_USERNAME=admin
export OS_PASSWORD=000000
export OS_PROJECT_NAME=admin
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_DOMAIN_NAME=Default
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3

替换000000为命令keystone-manage bootstrap中使用的密码 。

创建域,项目,用户和角色

创建域(已存在,不用创建)

openstack domain create --description "An Example Domain" example

创建项目
service项目,其中包含添加到环境中的每个服务的唯一用户

openstack project create --domain default --description "Service Project" service

常规的项目和用户。例如

  • 创建demo项目:
openstack project create --domain default --description "Demo Project" demo
  • 创建demo用户:
 openstack user create --domain default --password-prompt demo
 #需要为demo设置密码
  • 创建user角色:
  openstack role create user
  • user角色添加到demo项目和用户:
openstack role add --project demo --user demo user
  • demo创建一个用户脚本demo-openrc.sh
export OS_USERNAME=demo
export OS_PASSWORD=000000
export OS_PROJECT_NAME=demo
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_DOMAIN_NAME=Default
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3

验证

取消临时变量

unset OS_AUTH_URL OS_PASSWORD
  1. admin用户身份请求身份验证令牌:
openstack --os-auth-url http://controller:35357/v3 \
--os-project-domain-name Default --os-user-domain-name Default \
--os-project-name admin --os-username admin token issue

输入admin用户密码。

  1. demo用户身份请求身份验证令牌:
openstack --os-auth-url http://controller:5000/v3 \
  --os-project-domain-name Default --os-user-domain-name Default \
  --os-project-name demo --os-username demo token issue

输入demo用户密码

创建OpenStack客户端环境脚本

为了提高客户端操作的效率,OpenStack支持简单的客户端环境脚本,也称为OpenRC文件。这些脚本通常包含所有客户端的通用选项,但也支持唯一选项。
创建脚本admin-openrc.sh

export OS_PROJECT_DOMAIN_NAME=Default
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_NAME=admin
export OS_USERNAME=admin
export OS_PASSWORD=000000
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2

创建脚本demo-openrc.sh

export OS_PROJECT_DOMAIN_NAME=Default
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_NAME=demo
export OS_USERNAME=demo
export OS_PASSWORD=000000
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2

使用脚本
. admin-openrc.shsource admin-openrc.sh
openstack token issue可以成功获取token

镜像服务glance

创建 glance 数据库:

MariaDB [(none)]> CREATE DATABASE glance;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' IDENTIFIED BY '000000';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' IDENTIFIED BY '000000';
MariaDB [(none)]> \q

000000替换为合适的密码

获取admin用户的环境变量

. admin-openrc.sh

创建glance用户:

openstack user create --domain default --password-prompt glance
#设置密码`000000`或其它

把admin角色添加到glance用户和项目中

openstack role add --project service --user glance admin

创建glance服务实体:

openstack service create --name glance --description "OpenStack Image" image

创建镜像服务API端点

openstack endpoint create --region RegionOne image public http://controller:9292
openstack endpoint create --region RegionOne image internal http://controller:9292
openstack endpoint create --region RegionOne image admin http://controller:9292

安装和配置组件

安装软件包:

yum install openstack-glance -y

编辑/etc/glance/glance-api.conf
[glance_store]部分, 配置本地文件系统存储和映像文件的位置

[database]
# ...
connection = mysql+pymysql://glance:000000@controller/glance
#替换000000为glance数据库的密码

[keystone_authtoken][paste_deploy] 部分配置keystone访问

[keystone_authtoken]
# ...
auth_uri = http://controller:5000
auth_url = http://controller:5000
memcached_servers = controller:11211
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = glance
password = 000000
#替换000000为glance在身份服务中的密码
[paste_deploy]
# ...
flavor = keystone

注释或删除此[keystone_authtoken]部分中的其他选项 。

在 [glance_store]部分, 配置本地文件系统存储和镜像文件的位置:

[glance_store]
# ...
stores = file,http
default_store = file
filesystem_store_datadir = /var/lib/glance/images/

编辑/etc/glance/glance-registry.conf
[glance_store]部分, 配置本地文件系统存储和映像文件的位置

[database]
# ...
connection = mysql+pymysql://glance:000000@controller/glance
#替换000000为glance数据库的密码

[keystone_authtoken][paste_deploy] 部分配置keystone访问

[keystone_authtoken]
# ...
auth_uri = http://controller:5000
auth_url = http://controller:5000
memcached_servers = controller:11211
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = glance
password = 000000
#替换000000为glance在身份服务中的密码
[paste_deploy]
# ...
flavor = keystone

注释或删除此[keystone_authtoken]部分中的其他选项 。

填充镜像服务数据库:

su -s /bin/sh -c "glance-manage db_sync" glance

启动镜像服务,并将其配置为在系统引导时启动

systemctl enable openstack-glance-api.service openstack-glance-registry.service
systemctl start openstack-glance-api.service openstack-glance-registry.service

计算服务nova

以下操作全部在controller节点

创建数据库

nova_api, nova, nova_cell0,placement

MariaDB [(none)]> CREATE DATABASE nova_api;
MariaDB [(none)]> CREATE DATABASE nova;
MariaDB [(none)]> CREATE DATABASE nova_cell0;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost' IDENTIFIED BY '000000';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%' IDENTIFIED BY '000000';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' IDENTIFIED BY '000000';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' IDENTIFIED BY '000000';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'localhost' IDENTIFIED BY '000000';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'%' IDENTIFIED BY '000000';

获取admin用户的环境变量

. admin-openrc.sh

创建服务凭证

创建nova用户:

# openstack user create --domain default --password-prompt nova
为nova设置密码

为nova用户添加admin角色:

# openstack role add --project service --user nova admin

创建服务实体

# openstack service create --name nova --description "OpenStack Compute" compute

创建compute API 服务端点

openstack endpoint create --region RegionOne compute public http://controller:8774/v2.1
openstack endpoint create --region RegionOne compute internal http://controller:8774/v2.1
openstack endpoint create --region RegionOne compute admin http://controller:8774/v2.1

疑问?官网并未说需要为placement创建数据库,但是一些教程上有

MariaDB [(none)]> CREATE DATABASE placement;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'localhost' IDENTIFIED BY '000000';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'%' IDENTIFIED BY '000000';

创建placement用户

# openstack user create --domain default --password-prompt placement

添加到admin角色

# openstack role add --project service --user placement admin

创建Placement API服务实体

# openstack service create --name placement --description "Placement API" placement

创建Placement API服务端点

openstack endpoint create --region RegionOne placement public http://controller:8778
openstack endpoint create --region RegionOne placement internal http://controller:8778
openstack endpoint create --region RegionOne placement admin http://controller:8778

安装和配置软件

# yum install openstack-nova-api openstack-nova-conductor \
  openstack-nova-console openstack-nova-novncproxy \
  openstack-nova-scheduler openstack-nova-placement-api -y

编辑/etc/nova/nova.conf文件

[DEFAULT]部分中,启用计算和元数据API:

[DEFAULT]
# ...
enabled_apis = osapi_compute,metadata

[api_database][database]部分中,配置数据库访问权限:

[api_database]
# ...
connection = mysql+pymysql://nova:000000@controller/nova_api

[database]
# ...
connection = mysql+pymysql://nova:000000@controller/nova

替换000000为nova数据库的密码。

  • 在该[DEFAULT]部分中,配置RabbitMQ消息队列访问:
[DEFAULT]
# ...
transport_url = rabbit://openstack:000000@controller

替换000000为您在RabbitMQ中为openstack 帐户选择的密码。

  • [api][keystone_authtoken]部分中,配置身份服务访问:
[api]
# ...
auth_strategy = keystone

[keystone_authtoken]
# ...
auth_url = http://controller:5000/v3
memcached_servers = controller:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = nova
password = 000000

替换000000nova用户的密码。

注释或删除此[keystone_authtoken] 部分中的任何其他选项。

在该[DEFAULT]部分中,配置my_ip选项以使用控制器节点的管理接口IP地址:

[DEFAULT]
# ...
my_ip = 192.168.200.10

在本[DEFAULT]节中,启用对网络服务的支持:

[DEFAULT]
# ...
use_neutron = True
firewall_driver = nova.virt.firewall.NoopFirewallDriver

在该[vnc]部分中,将VNC代理配置为使用控制器节点的管理接口IP地址:

[vnc]
enabled = true
# ...
server_listen = $my_ip
server_proxyclient_address = $my_ip

在该[glance]部分中,配置镜像服务API的位置:

[glance]
# ...
api_servers = http://controller:9292

在该[oslo_concurrency]部分中,配置锁路径:

[oslo_concurrency]
# ...
lock_path = /var/lib/nova/tmp

在该[placement]部分中,配置Placement API:

[placement]
# ...
os_region_name = RegionOne
project_domain_name = Default
project_name = service
auth_type = password
user_domain_name = Default
auth_url = http://controller:5000/v3
username = placement
password = 000000

替换000000placement用户的密码 。注释掉该[placement]部分中的所有其他选项。

由于一个软件bug,您必须通过将以下配置添加到来启用对Placement API的访问 /etc/httpd/conf.d/00-nova-placement-api.conf

<Directory /usr/bin>
     <IfVersion >= 2.4>
         Require all granted
      </IfVersion>
    <IfVersion < 2.4>
       Order allow,deny
      Allow from all
    </IfVersion>
</Directory>

重新启动httpd服务:

  systemctl restart httpd

填充nova-api数据库:

su -s /bin/sh -c "nova-manage api_db sync" nova

注册cell0数据库:

   su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova

创建cell1

   su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova

填充nova数据库:

su -s /bin/sh -c "nova-manage db sync" nova

验证nova cell0和cell1是否正确注册:

   # nova-manage cell_v2 list_cells
    + ------- + ----------------------------------- --- + 
   | Name| UUID | 
   + ------- + -------------------------------------- + 
      | cell1 | 109e1d4b-536a-40d0-83c6-5f121b82b650 | 
      | cell0 | 00000000-0000-0000-0000-000000000000 | 
   + ------- + -------------------------------------- +

启动Compute服务并将其配置为在系统启动时启动:

systemctl enable openstack-nova-api.service openstack-nova-consoleauth.service openstack-nova-scheduler.service openstack-nova-conductor.service openstack-nova-novncproxy.service
systemctl start openstack-nova-api.service openstack-nova-consoleauth.service openstack-nova-scheduler.service openstack-nova-conductor.service openstack-nova-novncproxy.service

以下操作全部在compute节点

安装和配置的部件

安装软件包:

# yum install openstack-nova-compute

漫长等待之后报错

Header V4 RSA/SHA1 Signature, key ID XXXX: NOKEY

Public key for qemu-kvm-ev-2.12.0-33.1.el7_7.4.x86_64.rpm is not installed

百度之后,说需要导入rpm的签名信息

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

还是没有用
最后解决

# yum install openstack-nova-compute --nogpgcheck -y

编辑/etc/nova/nova.conf文件并完成以下操作:

在此[DEFAULT]部分中,仅启用计算和元数据API:

[DEFAULT]
# ...
enabled_apis = osapi_compute,metadata

在该[DEFAULT]部分中,配置RabbitMQ消息队列访问:

[DEFAULT]
# ...
transport_url = rabbit://openstack:000000@controller

替换000000为在RabbitMQopenstack 帐户的密码。

[api][keystone_authtoken]部分中,配置身份服务访问:

[api]
# ...
auth_strategy = keystone

[keystone_authtoken]
# ...
auth_url = http://controller:5000/v3
memcached_servers = controller:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = nova
password = 000000

替换000000为您000000在身份服务中为用户选择的密码。

注释或删除此[keystone_authtoken] 部分中的任何其他选项。

在该[DEFAULT]部分中,配置my_ip选项:

[DEFAULT]
# ...
my_ip = 192.168.200.20

替换MANAGEMENT_INTERFACE_IP_ADDRESS为计算节点上管理网络接口的IP地址,对于示例体系结构中的第一个节点,通常为10.0.0.31 。

在本[DEFAULT]节中,启用对网络服务的支持:

[DEFAULT]
# ...
use_neutron = True
firewall_driver = nova.virt.firewall.NoopFirewallDriver

注意

默认情况下,Compute使用内部防火墙服务。由于联网包含防火墙服务,因此必须使用nova.virt.firewall.NoopFirewallDriver防火墙驱动程序禁用计算防火墙服务。

在该[vnc]部分中,启用和配置远程控制台访问:

[vnc]
# ...
enabled = True
server_listen = 0.0.0.0
server_proxyclient_address = $my_ip
novncproxy_base_url = http://192.168.200.10:6080/vnc_auto.html

服务器组件侦听所有IP地址,代理组件仅侦听计算节点的管理接口IP地址。

novncproxy_base_url使用Web浏览器访问此计算节点上的实例的远程控制台的位置。

如果用于访问远程控制台的Web浏览器驻留在无法解析controller主机名的主机上,则必须替换为控制节点的管理接口IP地址。

在该[glance]部分中,配置图像服务API的位置:

[glance]
# ...
api_servers = http://controller:9292

在该[oslo_concurrency]部分中,配置锁定路径:

[oslo_concurrency]
# ...
lock_path = /var/lib/nova/tmp

在该[placement]部分中,配置Placement API:

[placement]
# ...
os_region_name = RegionOne
project_domain_name = Default
project_name = service
auth_type = password
user_domain_name = Default
auth_url = http://controller:5000/v3
username = placement
password = 000000

替换000000为keystone中placement用户的密码 。注释掉该[placement]部分中的所有其他选项。

最终确定安装

确定您的计算节点是否支持虚拟机的硬件加速:

egrep -c '(vmx|svm)' /proc/cpuinfo

如果此命令返回值,则您的计算节点支持硬件加速,通常不需要其他配置。one or greater

如果此命令返回值0,则您的计算节点不支持硬件加速,并且您必须配置libvirt为使用QEMU而不是KVM。

编辑文件中的[libvirt]部分,/etc/nova/nova.conf如下所示:

[libvirt]
# ...
virt_type = qemu

启动Compute服务及其相关性,并将其配置为在系统启动时自动启动:

systemctl enable libvirtd.service openstack-nova-compute.service
systemctl start libvirtd.service openstack-nova-compute.service

将计算节点添加到单元数据库中

controller节点上:
获取管理员凭据以启用仅管理员的CLI命令,然后确认数据库中有计算主机:

. admin-openrc
openstack compute service list --service nova-compute
[root@controller ~]# openstack compute service list --service nova-compute
+----+--------------+---------+------+---------+-------+----------------------------+
| ID | Binary       | Host    | Zone | Status  | State | Updated At                 |
+----+--------------+---------+------+---------+-------+----------------------------+
|  6 | nova-compute | compute | nova | enabled | up    | 2020-04-04T13:20:44.000000 |
+----+--------------+---------+------+---------+-------+----------------------------+

发现计算主机:

su -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova

注意
添加新的计算节点时,必须在控制器节点上运行nova-manage cell_v2 discover_hosts注册这些新的计算节点。另外,您可以在/etc/nova/nova.conf中设置适当的间隔 :

[scheduler]
discover_hosts_in_cells_interval = 300

验证

controller节点

. admin-openrc

列出服务组件以验证每个进程的成功启动和注册:

openstack compute service list
+----+------------------+------------+----------+---------+-------+----------------------------+
| ID | Binary           | Host       | Zone     | Status  | State | Updated At                 |
+----+------------------+------------+----------+---------+-------+----------------------------+
|  3 | nova-conductor   | controller | internal | enabled | up    | 2020-04-04T13:21:44.000000 |
|  4 | nova-consoleauth | controller | internal | enabled | up    | 2020-04-04T13:21:44.000000 |
|  5 | nova-scheduler   | controller | internal | enabled | up    | 2020-04-04T13:21:45.000000 |
|  6 | nova-compute     | compute    | nova     | enabled | up    | 2020-04-04T13:21:44.000000 |
+----+------------------+------------+----------+---------+-------+----------------------------+

注意

此输出应指示在控制器节点上启用的三个服务组件和在计算节点上启用的一个服务组件。

列出身份服务中的API端点以验证与身份服务的连接性:

以下端点列表可能会有所不同,具体取决于OpenStack组件的安装。

openstack endpoint list

在镜像服务中列出镜像以验证与镜像服务的连接性:

openstack image list

检查cells和placement API是否正常运行:

nova-status upgrade check

网络服务neutron

在controller节点

创建数据库

MariaDB [(none)]>CREATE DATABASE neutron;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY '000000';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY '000000';

创建neutron用户

. admin-openrc
openstack user create --domain default --password-prompt neutron
#为neutron用户设置密码

将用户加入admin角色

openstack role add --project service --user neutron admin

创建服务实体

openstack service create --name neutron \
--description "OpenStack Networking" network

创建访问端点

openstack endpoint create --region RegionOne \
network public http://controller:9696
openstack endpoint create --region RegionOne \
network internal http://controller:9696
openstack endpoint create --region RegionOne \
network admin http://controller:9696

开始配置:自服务网络Self-service networks

安装软件包

yum install openstack-neutron openstack-neutron-ml2 openstack-neutron-linuxbridge ebtables -y

配置服务器组件

编辑/etc/neutron/neutron.conf文件并完成以下操作:

[database]部分中,配置数据库访问:

[database]
# ...
connection = mysql+pymysql://neutron:000000@controller/neutron

替换000000为neutron数据库的密码。

[DEFAULT]部分中,启用ML2插件,路由器服务和重叠的IP地址:

[DEFAULT]
# ...
core_plugin = ml2
service_plugins = router
allow_overlapping_ips = true

[DEFAULT]部分中,配置RabbitMQ 消息队列访问:

[DEFAULT]
# ...
transport_url = rabbit://openstack:000000@controller

替换000000为您openstack在RabbitMQ中为帐户选择的密码 。

[DEFAULT][keystone_authtoken]部分中,配置身份服务访问:

[DEFAULT]
# ...
auth_strategy = keystone

[keystone_authtoken]
# ...
auth_uri = http://controller:5000
auth_url = http://controller:35357
memcached_servers = controller:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = 000000

替换000000为您neutron 在keystone中的密码。

注释掉或删除此[keystone_authtoken]部分中的任何其他选项 。

[DEFAULT][nova]部分中,将网络配置为通知Compute网络拓扑更改:

[DEFAULT]
# ...
notify_nova_on_port_status_changes = true
notify_nova_on_port_data_changes = true

[nova]
# ...
auth_url = http://controller:35357
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = nova
password = 000000

替换000000为您nova 在身份服务中为用户选择的密码。

-在[oslo_concurrency]部分中,配置锁定路径:

  [oslo_concurrency]
  # ...
  lock_path = /var/lib/neutron/tmp

配置ml2插件

ML2插件使用Linux桥接器机制为实例构建第2层(桥接和交换)虚拟网络基础结构。

编辑/etc/neutron/plugins/ml2/ml2_conf.ini文件并完成以下操作:

[ml2]中,启用flat,VLAN和VXLAN网络:

[ml2]
# ...
type_drivers = flat,vlan,vxlan

[ml2]中,启用VXLAN自助服务网络:

[ml2] 
#... 
tenant_network_types  =  vxlan

[ml2]中,启用Linux桥接器和第2层填充机制:

[ml2]
# ...
mechanism_drivers = linuxbridge,l2population

配置ML2插件后,删除该type_drivers选项中的值 可能会导致数据库不一致。

Linux网桥代理仅支持VXLAN覆盖网络。

[ml2]中,启用端口安全扩展驱动程序:

[ml2]
# ...
extension_drivers = port_security

[ml2_type_flat]中,将提供者虚拟网络配置为平面网络:

[ml2_type_flat]
# ...
flat_networks = provider

[ml2_type_vxlan]中,为自助服务网络配置VXLAN网络标识符范围:

[ml2_type_vxlan]
# ...
vni_ranges = 1:1000

[securitygroup]中,启用ipset以提高安全组规则的效率:

[securitygroup]
# ...
enable_ipset = true

配置Linux网桥代理

Linux网桥代理为实例构建第2层(桥接和交换)虚拟网络基础结构并处理安全组。

编辑/etc/neutron/plugins/ml2/linuxbridge_agent.ini文件并完成以下操作:

[linux_bridge]中,将提供者虚拟网络映射到提供者物理网络接口:

[linux_bridge] 
physical_interface_mappings  =  provider:eth0

替换eth0为基础提供商物理网络接口的名称。

[vxlan]中,启用VXLAN覆盖网络,配置处理覆盖网络的物理网络接口的IP地址,并启用第2层填充:

[vxlan]
enable_vxlan = true
local_ip = 192.168.210.10
l2_population = true

替换192.168.210.10为处理覆盖网络的基础物理网络接口的IP地址。示例体系结构使用管理接口将流量隧道传输到其他节点。因此,请替换为控制器节点的管理IP地址。

在该[securitygroup]部分中,启用安全组并配置Linux网桥iptables防火墙驱动程序:

[securitygroup]
# ...
enable_security_group = true
firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver

通过验证以下所有sysctl值设置为1,确保Linux操作系统内核支持网桥过滤器:

net.bridge.bridge-nf-call-iptables 
net.bridge.bridge-nf-call-ip6tables
echo "net.bridge.bridge-nf-call-iptables=1" >> /etc/sysctl.conf 
echo "net.bridge.bridge-nf-call-ip6tables=1" >> /etc/sysctl.conf

要启用网络桥接器支持,通常br_netfilter需要加载内核模块。

modprobe br_netfilter

配置l3

第3层(L3)代理为自服务网络提供路由和NAT服务。

编辑/etc/neutron/l3_agent.ini文件并完成以下操作:

在该[DEFAULT]部分中,配置Linux网桥接口驱动程序和外部网桥:

[DEFAULT]
# ...
interface_driver = linuxbridge

配置DHCP代理

DHCP代理为虚拟网络提供DHCP服务。

编辑/etc/neutron/dhcp_agent.ini文件并完成以下操作:

[DEFAULT]中,配置Linux桥接口驱动程序Dnsmasq DHCP驱动程序,并启用元数据隔离,以便提供商网络上的实例可以通过网络访问元数据:

[DEFAULT]
# ...
interface_driver = linuxbridge
dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq
enable_isolated_metadata = true

配置元数据代理

元数据代理提供配置信息,例如实例的凭据。

编辑/etc/neutron/metadata_agent.ini文件并完成以下操作:

在该[DEFAULT]部分中,配置元数据主机和共享密码:

[DEFAULT]
# ...
nova_metadata_host = controller
metadata_proxy_shared_secret = 000000

替换000000为元数据代理的密码。

配置nova使用网络服务

编辑/etc/nova/nova.conf文件

在该[neutron]部分中,配置访问参数,启用元数据代理,并配置密码:

[neutron]
# ...
url = http://controller:9696
auth_url = http://controller:35357
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = neutron
password = 000000
service_metadata_proxy = true
metadata_proxy_shared_secret = 000000

替换第一个000000neutron 在keystone中的密码。
替换第二个000000为元数据代理的密码。

最终安装

网络服务初始化脚本需要/etc/neutron/plugin.ini指向ML2插件配置文件的符号链接 /etc/neutron/plugins/ml2/ml2_conf.ini。如果此符号链接不存在,请使用以下命令创建它:

# ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini

填充数据库:

# 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

重新启动Compute API服务:

systemctl restart openstack-nova-api.service

启动网络服务,并将其配置为在系统引导时启动。

# 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

对于自服务网络,还需要启用并启动第3层服务:

# systemctl enable neutron-l3-agent.service
# systemctl start neutron-l3-agent.service

compute节点

安装软件

yum install -y openstack-neutron-linuxbridge ebtables ipset

配置公共组件

网络公共组件配置包括身份验证,消息队列和插件。

编辑/etc/neutron/neutron.conf文件并完成以下操作:

在本[database]节中,注释掉所有connection选项,因为计算节点不会直接访问数据库。

在该[DEFAULT]部分中,配置RabbitMQ 消息队列访问:

[DEFAULT]
# ...
transport_url = rabbit://openstack:000000@controller

替换000000openstack 在RabbitMQ中的密码。

[DEFAULT][keystone_authtoken]部分中,配置身份服务访问:

[DEFAULT]
# ...
auth_strategy = keystone

[keystone_authtoken]
# ...
auth_uri = http://controller:5000
auth_url = http://controller:35357
memcached_servers = controller:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = 000000

替换000000neutron 在keystone中。

注释掉或删除此[keystone_authtoken]部分中的任何其他选项 。

在该[oslo_concurrency]部分中,配置锁定路径:

[oslo_concurrency]
# ...
lock_path = /var/lib/neutron/tmp

开始配置:自服务网络

配置Linux网桥代理

Linux网桥代理为实例构建第2层(桥接和交换)虚拟网络基础结构并处理安全组。

编辑/etc/neutron/plugins/ml2/linuxbridge_agent.ini文件并完成以下操作:

[linux_bridge]节中,将提供者虚拟网络映射到提供者物理网络接口:

[linux_bridge]
physical_interface_mappings =eth0

替换eth0为基础提供商物理网络接口的名称。

[vxlan]节中,启用VXLAN覆盖网络,配置处理覆盖网络的物理网络接口的IP地址,并启用第2层填充:

[vxlan]
enable_vxlan = true
local_ip = 192.168.210.20
l2_population = true

替换192.168.210.20为处理覆盖网络的基础物理网络接口的IP地址。
[securitygroup]部分中,启用安全组并配置Linux网桥iptables防火墙驱动程序:

[securitygroup]
# ...
enable_security_group = true
firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver

通过验证以下所有sysctl值设置为1,确保Linux操作系统内核支持网桥过滤器:

net.bridge.bridge-nf-call-iptables 
net.bridge.bridge-nf-call-ip6tables
echo "net.bridge.bridge-nf-call-iptables=1" >> /etc/sysctl.conf 
echo "net.bridge.bridge-nf-call-ip6tables=1" >> /etc/sysctl.conf

要启用网络桥接器支持,通常br_netfilter需要加载内核模块。

modprobe br_netfilter

配置nova以使用网络服务

编辑/etc/nova/nova.conf文件并完成以下操作:

在该[neutron]部分中,配置访问参数:

[neutron]
# ...
url = http://controller:9696
auth_url = http://controller:35357
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = neutron
password = 000000

替换000000neutron 在身份服务中的密码。

最终安装

重新启动计算服务:

systemctl restart openstack-nova-compute.service

启动Linux网桥代理,并将其配置为在系统引导时启动:

systemctl enable neutron-linuxbridge-agent.service
systemctl start neutron-linuxbridge-agent.service

界面管理horizon

controller节点

安装软件包

yum install openstack-dashboard -y

编辑 /etc/openstack-dashboard/local_settings 文件并完成以下操作:

配置dashboard以在controller节点上使用OpenStack服务 :

OPENSTACK_HOST = "controller"

允许主机访问dashboard:

ALLOWED_HOSTS = ['one.example.com', 'two.example.com']

注意

ALLOWED_HOSTS也可以是[’*’]以接受所有主机。这可能对开发工作有用,但可能不安全,因此不应在生产中使用。有关 更多信息,请参见 https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts。

配置memcached会话存储服务:

SESSION_ENGINE = 'django.contrib.sessions.backends.cache'

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

注释掉任何其他会话存储配置。

启用身份API版本3:

OPENSTACK_KEYSTONE_URL = "http://%s:5000/v3" % OPENSTACK_HOST

启用对域的支持:

OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True

配置API版本:

OPENSTACK_API_VERSIONS  =  { 
    “ identity” : 3 ,
    “ image” : 2 ,
    “ volume” : 2 ,
}

配置Default为通过dashboard创建的用户的默认域:

OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "Default"

配置user为通过dashboard创建的用户的默认角色:

OPENSTACK_KEYSTONE_DEFAULT_ROLE = "user"

(可选)配置时区:

TIME_ZONE = "UTC"

替换UTC为适当的时区标识符。参见时区列表

可设置为

UTC 国际标准时间

Asia/Shanghai 上海东八区。北京时间

When support for time zones is enabled, Django stores datetime information inUTC in the database, uses time-zone-aware datetime objects internally, andtranslates them to the end user’s time zone in templates and forms.

翻译一下:当使用时区时,Django存储在数据库中的所有日期时间信息都以UTC时区为准,在后台使用有时区的datetime,前台用户使用时,在网页上转换成用户所在的时区。

编辑/etc/httpd/conf.d/openstack-dashboard.conf如果未包含,则添加以下行 。

WSGIApplicationGroup %{GLOBAL}

重新启动Web服务器和会话存储服务:

systemctl restart httpd.service memcached.service

测试
登陆http://192.168.200.10/dashboard
Demain:default
user:admin
password:000000
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jH15zp8t-1586091449372)(C:\Users\kdl\AppData\Roaming\Typora\typora-user-images\image-20200405145923704.png)]

使用测试镜像创建一个实例

controller上操作。可以用命令行也可以用dashboard。

创建网络

创建外网

创建提供者网络,名称extnet:

. admin-openrc.sh
openstack network create --share --external \
  --provider-physical-network provider \
  --provider-network-type flat extnet
openstack network list

在外部网络上创建一个子网,名称extnet-subnet

openstack subnet create --network extnet \
  --allocation-pool start=192.168.200.100,end=192.168.200.200 \
  --dns-nameserver 8.8.8.8 --gateway 192.168.200.1 \
  --subnet-range 192.168.200.0/24 extnet-subnet
openstack subnet list

创建租户网络

创建自服务网络,名称intnet1

. demo-openrc.sh
openstack network create intnet1
openstack network list

在租户网络创建子网,名称intnet1-subnet1

openstack subnet create --network intnet1 \
  --dns-nameserver 8.8.8.8 --gateway 172.16.1.1 \
  --subnet-range 172.16.1.0/24 intnet1-subnet1
openstack subnet list

登录到dashboard,项目-网络-网络拓扑,可以看到创建的两个网络

image-20200405154302553

需要创建路由将两个网络连接起来

创建路由

创建路由

. demo-openrc.sh
openstack router create router1

租户网络添加到路由器
将自助服务网络子网添加为路由器上的接口:

neutron router-interface-add router1 intnet1-subnet1

路由器连接到外部网络
在路由器上的提供商网络上设置网关:

neutron router-gateway-set router1 extnet

查看路由上的端口

neutron router-port-list router1

拓扑

image-20200405161448104

配置默认安全组放行所有进出流量

项目-网络-安全组-default-管理规则

全选删除

所有

创建镜像

下载测试镜像cirros

将cirros-0.3.4-x86_64-disk.img使用终端工具上传到虚拟机
再上传到glance

openstack image create "cirros" --disk-format qcow2 --container-format bare --public < cirros-0.3.4-x86_64-disk.img

创建实例类型

创建名为 flavor1、ID 为 1234、内存为 512MB、硬盘为 1GB、虚拟内核数量为 1 的云主机类型;

. admin-openrc.h
nova flavor-create flavor1 1234 512 1 1

创建实例

创建实例,名称kdl1

openstack network list 
#找租户网络intnet1的id,我的是2786647d-f670-4d30-8965-868c990eb4ad
openstack server create --flavor flavor1 --image cirros \
--nic net-id=2786647d-f670-4d30-8965-868c990eb4ad kdl1

创建成功

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-My848sl1-1586091449373)(C:\Users\kdl\AppData\Roaming\Typora\typora-user-images\image-20200405175411423.png)]

绑定浮动IP,并连接终端

绑定浮动IP
点击“绑定浮动IP”
分配浮动IP
分配浮动IP
关联
关联成功
打开终端软件,使用浮动ip连接
用户名cirros
密码cubswin:)
在这里插入图片描述

踩过的坑

1.安装软件包报错Header V4 RSA/SHA1 Signature, key ID XXXX: NOKEY。Public key for xxx.rpm is not installed

# yum install openstack-nova-compute -y

漫长等待之后报错

Header V4 RSA/SHA1 Signature, key ID XXXX: NOKEY

Public key for qemu-kvm-ev-2.12.0-33.1.el7_7.4.x86_64.rpm is not installed

百度之后,说需要导入rpm的签名信息

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

还是没有用
最后解决

# yum install openstack-nova-compute --nogpgcheck -y

2.进入dashboard查看拓扑,看不到建好的网络或者路由

原因:极有可能是创建时使用的用户(admin还是demo)和登陆时的用户不一样所致

3.创建新虚拟机报错 :Host is not mapped to any cell

原因:未发现计算节点所致
解决:在控制节点执行

# nova-manage cell_v2 discover_hosts --verbose

4.进入vnc的web界面,发现网络错误连接不了

原因:看一下网址发现是http://controller:6080/xxxxx,解析不了controller
解决:修改/etc/nova/nova.conf

[vnc]
novncproxy_base_url  http://192.168.200.10:6080/vnc_auto.html

5.实例开机卡在”booting from hard disk“

百度一下,发现配置成virt_type=kvm的问题。但是明明egrep -c '(vmx|svm)' /proc/cpuinfo返回值不是0呀?

[root@compute ~]# egrep -c '(vmx|svm)' /proc/cpuinfo              
2

解决办法:编辑/etc/nova/nova.conf修改

[libvirt]
#cpu_mode = none #网上回答有这句,实测不写也行
virt_type = qemu

重启nova服务

systemctl restart openstack-nova-compute.service
  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值