|
|
在正式部署之前,需要对每个节点做如下配置和检查:
3 P0 N; W: Z$ {" e7 C1 S# i0 z+ S* ]5 V% w
配置 |openEuler 24.03 LTS SP1 官方 yum 源,需要启用 EPOL 软件仓以支持 OpenStack
9 E& I$ z) H z8 U! n6 V7 \& z1 ^
; A I( w- S2 {- r. Nyum update
: C) d4 N# e Y8 e; e3 S( |yum install openstack-release-antelope
- n; m5 O: z3 c; i# e' A, _( cyum clean all && yum makecache4 v+ j% ~; z/ n
注意:如果你的环境的YUM源没有启用EPOL,需要同时配置EPOL,确保EPOL已配置,如下所示。' Y! t* S6 O4 L# b3 }6 |
( @- n. Y0 {7 s& q% x
vi /etc/yum.repos.d/openEuler.repo; h2 I+ r% o; _! E" ~
/ [" V0 @9 \4 l* U' l, Z[EPOL]( w4 {6 Y4 V9 M( r
name=EPOL5 n0 \; G b: d8 o; g$ C
baseurl=http://repo.openeuler.org/openEuler-24.03-LTS-SP1/EPOL/main/$basearch/7 W4 P3 w+ s, A9 v
enabled=1( ~9 q3 p! b: [- P' J A2 z u! R
gpgcheck=1
p" w9 H$ {! ngpgkey=http://repo.openeuler.org/openEuler-24.03-LTS-SP1/OS/$basearch/RPM-GPG-KEY-openEuler8 j% O$ p* p3 s" l# {; c5 e5 i% e1 i
; ~, L) W- o6 b+ U {5 Z5 `' ? k1 \0 s' ~" D( ?. z3 w5 Z
修改主机名以及映射
9 S3 f1 h1 {! n2 L: Q$ s& u8 c3 I' F, v4 e+ z3 \. Q
每个节点分别修改主机名,以controller为例:4 A% A$ X+ A2 \' G5 r I2 s
: K. ~) w3 v( \+ ahostnamectl set-hostname controller
' F* v+ z! {+ t3 w' H4 k, y- h" ~' A9 U8 s
vi /etc/hostname
; {+ a# R) n& T) @内容修改为controller1 o0 y& Z! U8 k
然后修改每个节点的/etc/hosts文件,新增如下内容:6 O/ Y! ~5 p, ^
# ]2 z+ ~7 @' Y) I. Q. \192.168.16.2 controller
7 f( [# b! B! |/ V$ ~3 K192.168.16.3 compute1
! X9 n% {$ ?+ B& D5 H4 a, K$ u192.168.16.4 compute2
2 G4 R7 C5 p$ b时钟同步¶
, W ~/ T: `# ]7 |) ?集群环境时刻要求每个节点的时间一致,一般由时钟同步软件保证。本文使用chrony软件。步骤如下:6 j6 W* E) K {4 C: \# G* w
; a# |. n) D G: yController节点:
) w# D) C6 x2 z4 W b" w' ]( T" V2 D
安装服务& d0 i+ t: S' C% q
dnf install chrony
) F% h" s; t5 A" h( u修改/etc/chrony.conf配置文件,新增一行
2 A9 T1 b5 Q( p* r9 Y9 k4 ]# 表示允许哪些IP从本节点同步时钟
. M- d, _/ i3 b5 k R/ B3 ]allow 192.168.16.0/24# m; [' Y* Z V
重启服务
3 O) I' H% Q% p0 H# p G; Wsystemctl restart chronyd) e L2 o: c- k3 A7 l: |
其他节点, ^/ c' d. x! {$ R7 X+ |
. u' t: a/ X% J9 T5 u
安装服务
+ t4 R/ F$ Z/ m! g8 b% l0 O, K$ c/ u8 N/ L. Z) |, O9 F1 s
dnf install chrony4 l4 s. k9 r( t2 c1 _! I' c% Q
修改/etc/chrony.conf配置文件,新增一行
6 v" y& X/ p2 W5 w; B/ u3 x9 }
# NTP_SERVER是controller IP,表示从这个机器获取时间,这里我们填192.168.16.2,或者在`/etc/hosts`里配置好的controller名字即可。) m! [* }/ J; V
server controller iburst
" |- W1 @( G' o2 j. [同时,要把pool pool.ntp.org iburst这一行注释掉,表示不从公网同步时钟。& T4 l% \- f0 m {, N+ P
& g/ [, L0 Y# r$ F, M4 a. F
重启服务
; m$ k, C G7 |% d+ t: w+ g; C4 ^/ V" Z# z5 C0 k) Q: G
systemctl restart chronyd
- z; B2 I. S0 d. k5 M配置完成后,检查一下结果,在其他非controller节点执行chronyc sources,返回结果类似如下内容,表示成功从controller同步时钟。
9 c0 ?/ m' ~8 I8 V9 e
, O v3 `# g. R" _MS Name/IP address Stratum Poll Reach LastRx Last sample- O* w p! W, C) V$ _' P, x
===============================================================================
3 B9 n# z9 g( ?! B^* 192.168.16.2 4 6 7 0 -1406ns[ +55us] +/- 16ms
8 Q! C: B' [! H4 _. D1 G安装数据库¶+ [% l4 T7 s* _0 [+ P
数据库安装在控制节点,这里推荐使用mariadb。
i/ O% e+ U( D) u2 ^& D; w, r8 z
7 t8 c: O' l6 \( y; v7 B安装软件包& x) n. g- Q7 t3 l/ G% b" l
, _/ U8 K8 U2 }( `% o- g
dnf install mysql-config mariadb mariadb-server python3-PyMySQL
# {) w8 A$ B% N7 [" T" }2 f新增配置文件/etc/my.cnf.d/openstack.cnf,内容如下
0 C) u% a/ O3 ?; G( v) ?: e
$ Z; K: ?: O: ?[mysqld]
' S! T {4 d1 S) q7 S# ~bind-address = 192.168.16.2
$ ~8 v; z# `3 A; Cdefault-storage-engine = innodb
2 [6 \0 Q# D7 s, E: tinnodb_file_per_table = on
2 S7 J) ~' `( i7 Vmax_connections = 4096# j) S7 y3 J- e2 n
collation-server = utf8_general_ci1 P5 `7 M8 r* Q( w- k! G
character-set-server = utf8# @- Y) d! j1 P7 D' _+ f# `
启动服务器+ N8 ~. e" u1 O# f; J
! \# g6 ?5 x/ p! B8 |" u" G! A
systemctl start mariadb4 a. \5 B( i& S! m3 X( }
初始化数据库,根据提示进行即可
. m4 U; E [' } U, }) y% \. p9 \; o- b0 ~: j+ Y
mysql_secure_installation8 {* k4 b# H n0 A/ f
示例如下:
% J$ M% v- i5 r- ^
+ G8 v+ Y0 K1 yNOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB g, Q I( f( f& J. m/ ^1 E
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
0 v8 X k5 a8 V7 G' _1 P1 H4 T1 W7 K
; Y3 w6 E% T, y ~In order to log into MariaDB to secure it, we'll need the current% V9 u0 L% x7 g6 I. x
password for the root user. If you've just installed MariaDB, and9 L0 f" e Z* n; h* _ Y, O( M, y9 f3 A
haven't set the root password yet, you should just press enter here.
' q \/ B! f; c6 S3 ?% a! D
4 E/ E$ q) K7 G9 m0 FEnter current password for root (enter for none): , B8 g. M; s2 |$ k3 `& m3 i
! q a4 B) L# ~
#这里输入密码,由于我们是初始化DB,直接回车就行 [3 d" b) N4 N8 | h6 G, h( U
1 Y1 x7 N. E4 E2 F. e OOK, successfully used password, moving on...
: i5 l0 ?, c( k; ?; }" g- u; d4 m% ]. \* }* _, x! _+ [+ N
Setting the root password or using the unix_socket ensures that nobody
, m) J8 @8 v i) n/ |can log into the MariaDB root user without the proper authorisation.
) K& B0 M' }6 b, G8 V; C) W7 J* y. r; |
You already have your root account protected, so you can safely answer 'n'.( R/ M. r/ t- `% c
+ |5 X# e/ C. g# 这里根据提示输入N& \( g# v# \8 T. `- H9 w
* T* ^. n6 }" F
Switch to unix_socket authentication [Y/n] N
6 a5 `6 C' p$ O, V6 _1 B9 k; x0 G& u- k* `; K
Enabled successfully!: J$ R4 z2 p/ [
Reloading privilege tables..
) W2 T" D/ s0 x! ^0 \ E6 h; I... Success!
1 i3 w7 {1 H: A+ [4 D* S6 |+ P- {6 S% J; A
! K1 h9 K$ a* j& d, j' p9 n
You already have your root account protected, so you can safely answer 'n'.# G) ?* V1 Z& t: v7 [8 n6 C0 j
" C0 L5 b. x+ k6 @( ]* d1 f# 输入Y,修改密码
4 M# ]6 E. `0 @ B6 U. o( _4 O' Q; z* O# k$ ?; i
Change the root password? [Y/n] Y
; S$ j* {$ X( N
% R0 Y) m, U) U! ?) ]! c6 w1 LNew password:
& K5 E- Q9 J9 dRe-enter new password: 0 e) X5 L2 Z+ |8 S
Password updated successfully!
4 L% @$ h2 X: I) \9 f8 JReloading privilege tables..# w1 z0 {0 f; o
... Success!
( `/ X. w0 v/ T# q$ B! k4 G( I8 B$ D9 X6 b2 F1 O& {
' B0 _- _, t; e' Y; w n% sBy default, a MariaDB installation has an anonymous user, allowing anyone0 j5 _( d: j$ P5 P- w, Z6 @' f
to log into MariaDB without having to have a user account created for1 X% F8 r. p' v; i1 D8 x' d
them. This is intended only for testing, and to make the installation
7 a/ Z9 a3 f3 ]0 Zgo a bit smoother. You should remove them before moving into a7 G! {( E4 h: l8 ]; j G1 i
production environment.
' S1 f/ O3 o& N+ _( E% r4 y, i: N# o/ S) J
# 输入Y,删除匿名用户
* [3 f. S: M; @5 J+ H$ J
0 e) W) e% G: e2 B1 K- ERemove anonymous users? [Y/n] Y5 s7 J+ ~4 r1 Y1 W! J* P8 X
... Success!
) V' l+ M/ e& y# ?/ t% p9 {' z! K! x/ V* a+ ~
Normally, root should only be allowed to connect from 'localhost'. This$ \9 C' T+ b' f6 b# Q
ensures that someone cannot guess at the root password from the network.
5 J; n% e/ d. _2 G4 U. g6 h7 `3 x( S" b6 i; L
# 输入Y,关闭root远程登录权限- R4 G/ b n9 V. S: E0 T) P2 C
8 s- q7 b: S- a/ oDisallow root login remotely? [Y/n] Y
( o# \6 e% s: {8 J- J) I8 {... Success!
2 }5 z0 ^, H, Z# h
9 o8 d8 J1 j+ i4 t) n9 pBy default, MariaDB comes with a database named 'test' that anyone can
8 U7 M* T) A# p- |& d/ Z# oaccess. This is also intended only for testing, and should be removed
2 ]. O) I1 ^* v6 b cbefore moving into a production environment., U$ \6 q# a$ t+ _( a" \
) m: u1 d! x2 W& [3 U7 y$ }
# 输入Y,删除test数据库
9 [) Z% t7 Q3 X' o9 h% H/ J: T5 k* y- o
Remove test database and access to it? [Y/n] Y
. ^, @: W* M" A- Dropping test database...
8 A6 u& ], t/ h# e... Success!( H3 g9 c7 f/ G, Z7 w
- Removing privileges on test database...& j- C/ M$ n/ V- J# U% d, Y
... Success!1 ], i/ _3 {$ t6 x! C5 B1 m
* {/ j# o, F9 O1 `. h# |2 W$ mReloading the privilege tables will ensure that all changes made so far
( j8 A% N' O1 l7 B" k& vwill take effect immediately.
% u- j3 c% v! t. A7 o+ M; ]
+ L; X2 [2 b$ W1 O# 输入Y,重载配置
% C9 t) }0 d$ z3 l9 C3 C8 {3 }# a! r4 B; S$ Z
Reload privilege tables now? [Y/n] Y& ~8 Z) x& x: P- s: U" Y; P' o6 S, x
... Success!8 x" b' e) R: S& J" ^( Y2 k. G
2 }+ b: e: P/ e1 U; D
Cleaning up...
* h% q# a$ t. n3 {' V6 s0 ?, C
0 ^! @: N N" OAll done! If you've completed all of the above steps, your MariaDB
* \' r, O9 v# }$ iinstallation should now be secure./ V+ S E/ w+ X5 T7 N9 J A
验证,根据第四步设置的密码,检查是否能登录mariadb: g" N! U0 l; B- y5 [
7 W+ Q# C+ O6 x! Y5 c4 f/ ]mysql -uroot -p
# D$ w4 [- `# {即可直接登录数据库 c, k' H. }+ r. f
r2 A! V. a3 d9 e z" f n, ^
安装消息队列¶
) v/ E- Z f7 P消息队列安装在控制节点,这里推荐使用rabbitmq。
5 Z: p% M& t& W; f, j- i
8 u I6 a6 Q1 g" O" [安装软件包# A( T; V/ a a6 [$ A
dnf install rabbitmq-server% @7 @2 i% @' R- i A
启动服务
/ X+ [, F6 d7 r& Q: [/ ~+ W" Csystemctl start rabbitmq-server. E W" B; n' F; Q* m
配置openstack用户,RABBIT_PASS是openstack服务登录消息队里的密码,需要和后面各个服务的配置保持一致。% {. I! O; }# G/ b. F, W
rabbitmqctl add_user openstack RABBIT_PASS6 z# I+ q3 j5 B& E
rabbitmqctl set_permissions openstack ".*" ".*" ".*"" L4 w2 o( E3 j/ r
安装缓存服务¶
, V, E! D; e& u- w8 u: z( q消息队列安装在控制节点,这里推荐使用Memcached。2 J2 L8 o- y& B8 h
3 D$ _% G( E; n! o
安装软件包5 p+ U. Y* v' S
dnf install memcached python3-memcached
4 v. @) `' v6 i' h修改配置文件/etc/sysconfig/memcached
! v1 r+ e' W: [0 Q7 mOPTIONS="-l 0.0.0.0,::1,controller"' V8 N0 ]) X1 A: ]4 p
启动服务% {# w0 i3 w, Q% f4 S d' @2 v
systemctl start memcached
: k# a2 N) J2 R* m r6 L部署服务¶
, B9 o! k+ Y F4 a& u& u% [, JKeystone¶
9 Z+ h, ?8 [# ^8 d7 y, XKeystone是OpenStack提供的鉴权服务,是整个OpenStack的入口,提供了租户隔离、用户认证、服务发现等功能,必须安装。
2 V& I' r2 h e) A& Y, N
) {5 N# X$ d3 _+ t& j2 M创建 keystone 数据库并授权
9 N1 a% q& ?! \ H- e$ d. f4 d2 R9 ~# c f/ G
mysql -u root -p. L6 b. ^; A" r$ `3 v
' d. P Z* {( C/ E' A
MariaDB [(none)]> CREATE DATABASE keystone;
& E3 J+ I0 H RMariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' \
9 C# q6 H$ ]' N9 e- r0 oIDENTIFIED BY 'KEYSTONE_DBPASS';' y2 C' j3 h9 o' }: N# _2 \; M! ^
MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' \: B2 [6 e' t2 b _
IDENTIFIED BY 'KEYSTONE_DBPASS';8 U* [# W7 I3 q) m: c1 P+ P
MariaDB [(none)]> exit
) ?1 b+ g% c7 w. d- z注意
7 A" s) C1 y4 C7 Z& S& F6 D* S& u+ f5 P
替换 KEYSTONE_DBPASS,为 Keystone 数据库设置的密码 (一般可用opessl 或者uuidgen方式生产复杂密码)
9 v& k' w5 t7 V' z E& u$ ^1 n0 N/ H+ y" Z% Z+ K+ }, X
安装软件包) N& s" N# m. A
' d, Y$ }4 s8 L" ^' K' S9 d0 zdnf install openstack-keystone httpd mod_wsgi
/ g. c5 C$ A9 j& N+ T2 g' O( H配置keystone相关配置. O2 I' z+ m s4 Z7 y
6 y6 j8 `1 Q- @8 f$ ^) k/ o
vim /etc/keystone/keystone.conf
' |' N2 c! J- j* l6 w9 G. \8 g T/ x
[database]
/ l7 F# I* p& Q% Wconnection = mysql+pymysql://keystone:KEYSTONE_DBPASS@controller/keystone: k& n q6 x# y" Q1 M6 t W9 O
8 N9 _$ @" q. P: s: b9 `7 O2 \
[token]
0 `" G$ M- S) v+ A7 Q' yprovider = fernet
' {* I c3 n. W4 M) t; @% b" g5 ?' K$ h/ y! A: o
5 Y4 N E3 E! x4 D T3 J解释4 e( i9 ~6 _6 C' u! p" m
! i0 \4 u% a8 H( b+ t9 m% ?[database]5 Y/ T' z0 o! I; r
部分,配置数据库入口
- a* Y, i$ P# g# G# J8 p
4 h. e) U L4 u& X5 ^3 z[token]
" R `! }# w$ Z5 I6 g部分,配置token provider0 V; k+ J" {' T* L
; K) @& L/ V- T: J
1 k! Z5 _$ B4 R5 _. c: u$ ^同步keystone数据库
/ k) X/ _! [" Z+ a
2 `4 G) k& o- `+ R- Qsu -s /bin/sh -c "keystone-manage db_sync" keystone
" A( G$ W7 g& c, F {( B; k2 F- |0 a: j$ s* z6 k
初始化Fernet密钥仓库" F q' u7 L" o
, e" P2 X7 d) O' `- dkeystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
) P0 ]. G0 o- b5 F) T6 ?keystone-manage credential_setup --keystone-user keystone --keystone-group keystone3 a# c; }# Z* x1 O. U) [
1 R# H' L& \ w$ y
启动服务: K! K8 X/ \- O# `/ r
这两种方式都可以:" z1 x; H- v# I! c; Z- f
keystone-manage bootstrap --bootstrap-password ADMIN_PASS --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
: u8 A3 E1 F" J
" h; Y( v l: F0 [# mkeystone-manage bootstrap --bootstrap-password ADMIN_PASS --bootstrap-admin-url http://controller:5000 --bootstrap-internal-url http://controller:5000 --bootstrap-public-url http://controller:5000 --bootstrap-region-id RegionOne
. A+ ~/ i/ F& t' a0 `注意
0 D7 I* z/ f! r9 n' d! [& A% k) y2 K( r: n, `/ p, Q( L
替换 ADMIN_PASS,为 admin 用户设置密码
( ^$ [; O8 F; [$ K
6 ?( Z, d" T+ X0 r6 _) N2 F" [配置Apache HTTP server( I. i% t5 D& D' c% c
2 z) j0 V( |* ~% a+ f+ h
打开httpd.conf并配置" `9 t {) L/ {/ H0 d6 F
- S0 v' P0 W2 b l" Q. T, J
#需要修改的配置文件路径/ f/ }0 h2 x6 ?. E: U4 I. P1 p1 ?
vim /etc/httpd/conf/httpd.conf
4 Y! K0 _8 M; r0 |0 c5 A6 z) G6 ~) b" Z- W
#修改以下项,如果没有则新添加, Z. I# {, Q' B/ ~& _% S
ServerName controller9 {* }+ \+ |# i. G- W5 R, c$ O; o
创建软链接
3 F0 H7 B+ N) ?4 X! U# M& J9 A# @9 e4 ]3 [0 Q
ln -s /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/
3 e( |- W# ~6 G% z& X解释 O) i7 a2 k% Y6 ?2 _- ^0 [
: A Q Q5 r3 ]配置 ServerName 项引用控制节点+ P, J o# f: ^* o/ F4 D
% h* l2 |, X! `) S \. k7 h- z- `
注意 如果 ServerName 项不存在则需要创建
$ z6 Z" N! f9 Y' V( p$ \. k
) u j9 _ L9 z9 z1 A启动Apache HTTP服务4 O9 @5 v: L' S8 D
3 c {. F. A' e5 A5 _! ?6 n6 rsystemctl enable httpd.service
# Q, A, H1 I2 T: N! H% b7 fsystemctl start httpd.service
; H+ ]/ s0 a! `. R1 N创建环境变量配置, k2 H% ] _# M, g
3 d. j* r, t6 v6 T5 Ucat << EOF >> .admin-openrc/ t- C$ b) u9 w$ J
export OS_PROJECT_DOMAIN_NAME=Default; W5 q2 W7 E0 c2 y6 ^
export OS_USER_DOMAIN_NAME=Default
7 ^6 l& s x; O7 k. Jexport OS_PROJECT_NAME=admin
" W. G) y- @9 t/ [7 Xexport OS_USERNAME=admin6 V' e( X0 |' z" x
export OS_PASSWORD=ADMIN_PASS4 j0 I2 [7 V: i" a
export OS_AUTH_URL=http://controller:5000/v3 P8 ]( C7 E' k7 b, d& G" p$ ?
export OS_IDENTITY_API_VERSION=33 U" `1 ?/ }* [9 S( t9 E V6 c
export OS_IMAGE_API_VERSION=2
: ~& I: P5 I/ c: p9 _EOF! p9 R) x4 W/ G2 U
2 g" K$ `8 j/ e9 O- g) d& S
注意
0 r; ~! }1 X# A+ u& ~% V5 c# I# F% S6 w
替换 ADMIN_PASS 为 admin 用户的密码
) D0 k4 J! f q) ]- S* G! J8 x; E, Z
依次创建domain, projects, users, roles% Z$ C7 k, b3 Y/ U
h* p/ k' z4 E4 j2 X! J" N" X( p
3 o. w ~$ o# U3 X. J: r需要先安装python3-openstackclient. ^/ ~4 N) i- ?2 P
1 x' K+ R' F; [- w2 H& S7 G/ p
dnf install python3-openstackclient: P/ h: f. u9 ?8 S( Q! Q+ x
3 O+ ` I6 V2 Z1 ?1 Z/ x
导入环境变量
. K5 v5 F+ e5 r7 z/ z
b3 {- H p: Q9 Usource ~/.admin-openrc
3 F3 O- o$ q( I创建project service,其中 domain default 在 keystone-manage bootstrap 时已创建0 C* P( ?7 s- W T
+ Q& J- t& ~# |8 G; `( sopenstack domain create --description "An Example Domain" example4 W5 Z, } p) i' M
: {5 E: K; {2 _, V5 G8 K; U2 }* jopenstack project create --domain default --description "Service Project" service6 H: r2 c& u' N7 L( @2 m' x3 f( s# t
5 e$ C' n& B3 y! `7 Q创建(non-admin)project myproject,user myuser 和 role myrole,为 myproject 和 myuser 添加角色myrole* m' Y$ i2 ^+ b8 F
( n; u. m- Z0 C4 s3 {
openstack project create --domain default --description "Demo Project" demo
1 M/ {( @6 x9 O9 ]3 N( Y/ D& J$ D7 V/ U( j/ Y, W) R; V+ u9 p% V
openstack user create --domain default --password-prompt demo
$ c) v& W2 x; b; e$ }1 }openstack role create demo3 L4 M( K4 e: K+ ^5 e( ]+ ^3 q
openstack role add --project admin --user demo demo
5 G& g& q& D0 @. |验证; L' @; P: i2 C7 j! I# T! \2 i
) u3 C7 \& r0 R8 p& J; c取消临时环境变量OS_AUTH_URL和OS_PASSWORD: b% N! c$ L9 j
* @. \; a; Q2 J) u. ~2 F
source .admin-openrc t- s9 ?& I ]$ p& `. R
unset OS_AUTH_URL OS_PASSWORD* E" U4 K! u' z) j, I2 k r
为admin用户请求token:
4 B* ?& ~% d6 f7 i+ P
4 x K; }- R" u+ ^" j5 {openstack --os-auth-url http://controller:5000/v3 --os-project-domain-name Default --os-user-domain-name Default --os-project-name admin --os-username admin token issue8 Q v- |) ^: O6 [/ @& g) O* g
' @5 s; l8 k) S! Z W2 y
为myuser用户请求token:
/ u* G1 a( L8 ]: B2 X, R/ h4 d" k4 i# w, {: ]- Q. U$ @. {0 V& g
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
9 _. P, z0 A! v) c) C& t; I! G/ b
* D+ V- g$ e6 u# c8 e% J安装Glance¶4 _0 ?- m2 R8 ?4 f" ^+ J
Glance是OpenStack提供的镜像服务,负责虚拟机、裸机镜像的上传与下载,必须安装。
3 s1 a L$ I5 F m" M& x& b! M6 J1 M' J6 d; _4 ~0 H! `3 P# o- S
Controller节点:
* }! s+ E G9 z8 a+ U0 M" Z4 C& F8 y! b+ @( [# I7 U7 q
创建 glance 数据库并授权
& }4 n% u6 `9 l8 E
# r7 A. g) t! ^9 D9 B' V6 U: Zmysql -u root -p
( L y( I- p8 [, N, ^3 A; F6 b/ i8 H; {0 F0 S4 a8 I1 w
MariaDB [(none)]> CREATE DATABASE glance;
7 w/ g- e0 k* e* p! b- hMariaDB [(none)]> GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' \
0 N& ]8 A, g& FIDENTIFIED BY 'GLANCE_DBPASS';* M3 b9 t9 Q8 T
MariaDB [(none)]> GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' \
$ t- P l, P. ?, cIDENTIFIED BY 'GLANCE_DBPASS';
9 J1 e- i: k3 L9 L, K5 G4 I0 JMariaDB [(none)]> exit$ C: i+ u0 ]+ H0 g2 l' E9 m9 t6 x& H
注意: `7 P0 B# Z0 }" O; |1 w
7 C3 w7 L" B) O1 U& l4 H; t3 _
替换 GLANCE_DBPASS,为 glance 数据库设置密码9 |8 m. S0 B/ r& N8 L- l, k9 d
7 g6 |3 V% x3 E C0 j9 N9 H
初始化 glance 资源对象
- ?# h9 o+ I$ v
2 P ` g3 c1 Q" b5 l8 m' m导入环境变量
- N% V, T' C8 U* A: ^+ M4 e+ y$ E& a
source ~/.admin-openrc
/ K6 X7 A( U0 x创建用户时,命令行会提示输入密码,请输入自定义的密码,下文涉及到GLANCE_PASS的地方替换成该密码即可。
; p5 X3 Z" X$ A' y x( `( B6 c- g" y4 I8 e3 l- a
openstack user create --domain default --password-prompt glance+ l( J+ \1 p8 l
User Password:7 l! T' B) V* Y& r% D6 ?
Repeat User Password:; @7 I4 O. u! {! E, G
添加glance用户到service project并指定admin角色:1 G. t- D# w+ H' W: R
4 n+ `7 i, Y; R5 x' D# q7 N: _
openstack role add --project service --user glance admin
( E! c L0 j4 `5 [( J创建glance服务实体:
' j: f4 d9 K) l) E/ Q7 H* {. \
* _1 e' I* F- J! m9 x0 Gopenstack service create --name glance --description "OpenStack Image" image) J4 U: l; a8 \ k+ e i, e
创建glance API服务:
8 U- h9 n# S7 c, q" A/ k: h/ k8 o# E
% a r1 _- ?, L2 @. R5 W+ yopenstack endpoint create --region RegionOne image public http://controller:9292
! d, E& I# L2 ]! C2 v- M5 Eopenstack endpoint create --region RegionOne image internal http://controller:9292# j7 ?# o- T% i9 r
openstack endpoint create --region RegionOne image admin http://controller:9292
- P0 C1 H. ^: _1 y' ]+ S安装软件包
( O' O4 E& q) C3 Y- l/ @% W' P y
9 Z @, U i% `dnf install openstack-glance
: P! q( v; x8 _修改 glance 配置文件# Z( y7 |7 x# t( M5 `0 M+ ^
7 L$ J: y0 R/ U* d% hvim /etc/glance/glance-api.conf2 t ?& `+ U; F0 p2 M9 M
0 ]! x/ r! F' m. z9 Y! K[database]
; Q! U; @' ^1 f5 w# o" b+ Gconnection = mysql+pymysql://glance:GLANCE_DBPASS@controller/glance! s6 \: Z( ^' r1 e8 b
0 i- \5 c( I* K1 y, K7 X
[keystone_authtoken]6 I+ `3 K- n( N$ v
www_authenticate_uri = http://controller:5000
- Y, Z/ i* t, g; N; \ ~auth_url = http://controller:5000
2 e! M2 j- M* z& M+ S; Smemcached_servers = controller:11211: m6 R& b% F; L, R E2 D6 N k
auth_type = password
1 i- c- M7 Q. }; G+ \6 bproject_domain_name = Default& ?- }+ \# L1 r4 r# y
user_domain_name = Default
) S/ q+ j2 I5 A) k2 ?" hproject_name = service; r1 G3 F; r, w. T
username = glance& S A' o z3 u! I' s' ~% \
password = GLANCE_PASS( B8 m `+ \9 H/ u' A% x( W) ]# I
9 B+ l5 \$ _1 c4 }: N* u8 J
[paste_deploy]
$ q7 A* Y; q: f* E# vflavor = keystone: u* B5 p3 o* P6 l( m
e4 q$ e" s( m$ Y[glance_store]' u1 H" Q, Y( c; t
stores = file,http# k0 S! J2 H6 w0 V) r
default_store = file
, @3 X/ M5 K' w8 G1 Sfilesystem_store_datadir = /var/lib/glance/images/! q5 A! [) _5 ~1 g7 J6 W6 G8 K" e
解释:
8 q: x+ q3 d6 v, t) E
7 |1 r) }5 Q5 A3 h8 o[database]部分,配置数据库入口
+ K. m6 f) n7 E9 l0 J. D; S
+ o& o W" K& \% ]) J6 w! V[keystone_authtoken] [paste_deploy]部分,配置身份认证服务入口1 T6 d7 s4 [9 }$ F: I
1 y; F* L3 P& L& t
[glance_store]部分,配置本地文件系统存储和镜像文件的位置) W4 ?# b- w8 ~! Z' u- Q
8 _& ~3 S e1 j7 e8 [ J同步数据库
2 M% V5 B* T+ p% J/ R+ T1 c
7 k* E: C1 l2 o* W: x6 C1 Bsu -s /bin/sh -c "glance-manage db_sync" glance
2 I" }8 |4 y6 E0 [' ]启动服务:+ q: v G* e. G; u' w5 v
; ?" l( z' L3 K/ psystemctl enable openstack-glance-api.service
% ^+ i, M, K' |: O4 g4 Ksystemctl start openstack-glance-api.service
1 }6 O1 D, Y( ` \/ K( x8 K( H: L验证
' ?7 w& e1 u/ ]5 \/ g- O' X
) g& ?) ]9 e% D导入环境变量
; f# B& g8 {+ y& Y8 O) ]5 T. I4 | ~
sorce .admin-openrcu! l% M0 { I1 u, U$ W0 I
下载镜像
9 _$ u- t/ Z2 {: z a; j8 _
! a/ N) L9 C% x) j5 R# {x86镜像下载:* Q3 m1 L/ z+ Y4 D
wget http://download.cirros-cloud.net ... 5.2-x86_64-disk.img" r5 r* o# g( w" H3 J$ q/ G
* g; `' `. R' [" I9 k P/ Yarm镜像下载:5 {5 P' \$ W1 c! |- F4 }' j) X
wget http://download.cirros-cloud.net ... .2-aarch64-disk.img
6 y+ c5 [( u T# o% B注意8 w7 w9 i/ H& J- \" C9 B
5 k: o: r. O- n; k如果您使用的环境是鲲鹏架构,请下载aarch64版本的镜像;已对镜像cirros-0.5.2-aarch64-disk.img进行测试。
4 x! X' \" y7 B- p; [
" {# a) z/ z5 A9 J向Image服务上传镜像:7 T' H3 S- q) c1 f# P8 d8 { ^
" w4 |+ X7 H, R' \: _
openstack image create --disk-format qcow2 --container-format bare --file cirros-0.5.2-x86_64-disk.img --public cirros+ B, g, v& ], _! k
确认镜像上传并验证属性:
+ F& Q% T% ~6 l& Q+ ?1 y) v# w! J" U0 s
openstack image list
]; a. \/ u. g$ W" d
* A6 y# T2 o9 y, ?2 J8 L
1 _/ ~+ x' N) y7 g% P% K0 Q- ePlacement¶2 y' d* f4 u" D% F% P
Placement是OpenStack提供的资源调度组件,一般不面向用户,由Nova等组件调用,安装在控制节点。
2 P* E* I5 [! [2 d3 a6 L" g) _; Q' N/ B8 K4 E# J
安装、配置Placement服务前,需要先创建相应的数据库、服务凭证和API endpoints。
/ b; s, h& k) C7 X: y
6 I0 b( m3 V; x( P* R创建数据库3 K+ X* J2 p5 ?/ d4 |
% M" m$ ^9 A1 @使用root用户访问数据库服务:
% u: T0 t: o8 c# x5 e* E8 D) V/ Q! T# y
mysql -u root -p
, i. d# f8 ]- n, ~/ T8 j' s% F创建placement数据库:% b! }; V; k, ]* e) l. w/ ~! F# u
1 B# \4 V1 t( n- a1 t7 [: _
MariaDB [(none)]> CREATE DATABASE placement;: I9 W% I$ `" N
授权数据库访问:. n. i9 a/ e+ a6 P' h
; A5 K: ?7 l* v- h* SMariaDB [(none)]> GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'localhost' \
$ P9 V& F5 D- r! R, l* ] IDENTIFIED BY 'PLACEMENT_DBPASS';& S Y/ w/ T5 t: m& I
MariaDB [(none)]> GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'%' \+ k9 B# q1 m0 U& g
IDENTIFIED BY 'PLACEMENT_DBPASS';2 K9 a; y1 K7 b( A
替换PLACEMENT_DBPASS为placement数据库访问密码。
( m6 w5 Z* Z, Z) B! Z. r7 s8 g) g
5 r9 y8 L4 m( j退出数据库访问客户端:0 L. E7 C r4 L* v8 {: R, t
7 b+ G: l0 r% u$ p3 l
exit( H4 Q1 c: N+ |! i- C, r/ P
配置用户和Endpoints2 w3 t( ^' _0 Q; Y: W8 x
7 K" x; P9 y4 L% u9 i! L% C$ N
source admin凭证,以获取admin命令行权限:4 ?9 {' N! u) U+ s
) G$ W; e/ O2 m( Q' csource ~/.admin-openrc
* a: @) N2 B2 [9 `& k$ I; I创建placement用户并设置用户密码:" N' b3 _& `( @, z E
* u3 X, V. M+ a
openstack user create --domain default --password-prompt placement o3 c. R4 w+ h! u. {4 F
! j T% b \3 q# |
User Password:
* }, ]7 Q* [0 u1 l$ K) mRepeat User Password:
) R% b% E9 \5 r% T( l! i. ]添加placement用户到service project并指定admin角色:4 b% W; v% E4 ^; S8 t
' P4 D& v9 Y5 p( m* U, N$ B
openstack role add --project service --user placement admin* @6 _+ J" Q3 r6 R8 A3 b
创建placement服务实体:
; G& T; o* H/ I+ _" n- G- @" s9 ~! ^( i' I) J
openstack service create --name placement --description "Placement API" placement! c' O# L- a) w' Q+ Y) O. |& {$ L
创建Placement API服务endpoints:2 g2 t5 T9 R: _& A) X& T/ j
) U( \0 X2 K3 i; `
openstack endpoint create --region RegionOne placement public http://controller:8778
% Y. a5 ~* U6 q; ^4 D; Q# v( \openstack endpoint create --region RegionOne placement internal http://controller:8778
- x9 n! q9 Q, }' f9 iopenstack endpoint create --region RegionOne placement admin http://controller:8778
( Y; z, {5 P/ G' H" E7 ]安装及配置组件$ Y5 G" _ ]) K( P5 Y. g
0 M: k4 N5 N y* m4 S5 K安装软件包:
8 Y1 B) y2 y- n8 b' g1 m: K) ?9 u& K" p% U% K
dnf install openstack-placement-api- T1 G. f8 r* I. u. k3 K' r6 z
编辑/etc/placement/placement.conf配置文件,完成如下操作:4 m! r. C/ _# I$ h- K9 y
1 Y( X7 \0 ?1 `, M: F1 Z U在[placement_database]部分,配置数据库入口:4 ?6 [* {9 L% S7 h- B
1 P/ b3 Y5 U+ f5 w6 m! j" y[placement_database]6 {: B4 T* \4 Y
connection = mysql+pymysql://placement:PLACEMENT_DBPASS@controller/placement9 ?5 _6 M6 |0 L
替换PLACEMENT_DBPASS为placement数据库的密码。
# }* ~- c/ d5 i8 `6 c R: |' V% v( i$ S, A& Q% n
在[api]和[keystone_authtoken]部分,配置身份认证服务入口:0 v/ }, l' e- u- K- K8 l r
1 a. p# V0 Z. I& s. \[api]' p7 h; I, ]. @; X+ i! P
auth_strategy = keystone4 h- K1 @8 {7 G& u- ]+ c9 c/ g
3 M7 h. `2 \/ J7 g* h6 B, }+ P[keystone_authtoken]
0 ?( E: b, f! ?$ Z$ s/ R! pauth_url = http://controller:5000/v3
2 y# y6 m1 t" r0 w$ N5 Cmemcached_servers = controller:11211% N! [/ E- O4 g# h2 ?% }- J6 [
auth_type = password
# J. B9 v6 u7 L' E/ r: H! |' eproject_domain_name = Default; W. a) C9 z i2 R
user_domain_name = Default
' q! W% {0 |0 e% `project_name = service
* \0 p8 W* _6 M& x6 t) _* x4 Rusername = placement0 r8 |4 R) B! R
password = PLACEMENT_PASS; [1 T" Q: P& {5 D
替换PLACEMENT_PASS为placement用户的密码。
! T/ W+ u. W! t) S3 }, r. q" A, t3 Y, D; V. g R$ x
数据库同步,填充Placement数据库:0 ~; P! L. \& x, ^- z3 V3 W. O5 P
: y" u* X8 D& _ \) S5 A, W- j
su -s /bin/sh -c "placement-manage db sync" placement
) \4 \( ^0 p8 B' F" W启动服务. ]4 p8 M' t6 @$ X4 ~
3 u$ a' q6 \) e3 F4 c6 o
重启httpd服务:
- M9 P6 s; N- @" E
. `, q. J% O3 m; ` X3 V, ssystemctl restart httpd; Z2 Y& K- j! m! t! x
验证
' C7 J- x/ j' \) c3 G
7 [( n# s$ \* N: m7 I% gsource admin凭证,以获取admin命令行权限
) ` a9 a0 N$ L4 A {" O# j
( H+ V, R! ?8 M0 q5 Jsource .admin-openrc( R7 \ E& ~, N$ l7 f7 A
执行状态检查:
; G% f0 h0 S! u! T" y5 J- x" w9 z8 h) ~9 D, V/ |4 L; u
placement-status upgrade check
x/ x3 r+ H# ^# ~" r( b+----------------------------------------------------------------------+- s6 i; X4 ?8 }+ O0 s! o
| Upgrade Check Results |
) Z; j9 |/ ]6 A0 }3 i4 K1 N+----------------------------------------------------------------------+6 y3 y% @# z4 Z( u* T! @
| Check: Missing Root Provider IDs |: t/ l7 j A2 t$ L/ z+ N
| Result: Success |
1 j/ T- V5 K7 s% j; k- a" O+ H| Details: None |
6 ~& g: n" o% I& {, b7 d9 n C+----------------------------------------------------------------------+4 m4 i/ k0 F) Y7 W* Q0 m
| Check: Incomplete Consumers |
$ y5 `# N J3 y2 S| Result: Success |
3 }- f- s0 M1 l9 }) B, L0 J" I| Details: None |- G- d0 z. m& I! f
+----------------------------------------------------------------------+
4 |0 q+ N5 e3 U0 v2 b+ P/ @& j| Check: Policy File JSON to YAML Migration |( p6 T( s/ R* K# z1 J0 G
| Result: Failure |, h- J4 r) e6 |; ^
| Details: Your policy file is JSON-formatted which is deprecated. You |
; n2 d/ C8 |- s! R" M/ I* Z9 L* r0 W; n$ z| need to switch to YAML-formatted file. Use the |
0 }% j. X9 E# z4 \; q5 j| ``oslopolicy-convert-json-to-yaml`` tool to convert the |, z: q* d9 ^2 |6 e
| existing JSON-formatted files to YAML in a backwards- |1 ^. Q/ c) a @. v
| compatible manner: https://docs.openstack.org/oslo.policy/ |( z8 Y; v, ]5 t) n5 [/ D
| latest/cli/oslopolicy-convert-json-to-yaml.html. |
/ Z4 V- x0 W' m+----------------------------------------------------------------------+5 R3 f2 `0 n2 l/ l6 R% ~
这里可以看到Policy File JSON to YAML Migration的结果为Failure。这是因为在Placement中,JSON格式的policy文件从Wallaby版本开始已处于deprecated状态。可以参考提示,使用oslopolicy-convert-json-to-yaml工具 将现有的JSON格式policy文件转化为YAML格式。; i& p) R o1 {
I; n1 `; Y: r5 Z; Boslopolicy-convert-json-to-yaml --namespace placement \# s9 j. t9 L1 V/ {
--policy-file /etc/placement/policy.json \2 Z+ Q$ M D P+ G5 K+ U
--output-file /etc/placement/policy.yaml
4 O' v* k+ N) J% l2 Z* [' m) _6 U$ emv /etc/placement/policy.json{,.bak}5 I/ y+ A. j1 H# h- X8 c
0 C" n1 D0 c3 d注:当前环境中此问题可忽略,不影响运行。3 [: w2 T4 _/ F0 X
* s- p5 P. t _# z: t! z' R. _
+ H2 M1 h' P4 h
" d% w w) h! M5 |Nova¶' m, ]/ W6 ]1 Z
Nova是OpenStack的计算服务,负责虚拟机的创建、发放等功能。
7 c) E* K t- @+ q" L" U0 k/ L+ I
) T9 g) I+ p4 aController节点# n" x- X6 y2 B0 c) y4 m, H: O4 ]
# }; d7 [8 c' K) b5 N: x
在控制节点执行以下操作。3 w0 t# v' t4 j8 ^4 E
5 Z# X% Z9 i; [1 B, @创建数据库
# J& \. {# w' ]0 G& B
- L8 h+ ~5 @4 W, ~/ z使用root用户访问数据库服务:! E( ~4 d- F/ H9 f8 [. k; s
; j1 j w% E9 ~0 \3 qmysql -u root -p( _# h. j) \& B0 Z) u
创建nova_api、nova和nova_cell0数据库:
: p4 `3 d1 Q1 V) C/ [- t+ k4 v
- B1 x1 i; K- O, kMariaDB [(none)]> CREATE DATABASE nova_api;
3 t' R+ l, G% s' T1 {MariaDB [(none)]> CREATE DATABASE nova;# I0 J) [# J# t+ v: n
MariaDB [(none)]> CREATE DATABASE nova_cell0;
- \, N$ p, I, z% G( F u! W授权数据库访问:
* K) O7 T/ R' F5 T' ^; O* E" Z
( y5 E3 k7 q" h' {9 G! u- sMariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost' IDENTIFIED BY 'NOVA_DBPASS';* H+ ]1 C' K4 i+ j+ a: V% ]
MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%' IDENTIFIED BY 'NOVA_DBPASS';
1 ^6 w6 t4 D1 Y
6 D0 [) `7 o# \0 J ^/ A4 s' m. oMariaDB [(none)]> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' IDENTIFIED BY 'NOVA_DBPASS';. o" q+ P& A: ]4 P: N
MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' IDENTIFIED BY 'NOVA_DBPASS';
5 G# u/ z8 U' s$ I* P! m4 B
; z* }' m C: kMariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'localhost' IDENTIFIED BY 'NOVA_DBPASS';
0 ]' z: |; g$ p/ G) ZMariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'%' IDENTIFIED BY 'NOVA_DBPASS';
5 i2 z: f2 b- |4 l
, H2 V" A5 O w2 R: C+ d* y. s替换NOVA_DBPASS为nova相关数据库访问密码。
% o3 j, D }" g- q' C2 I
0 p( G2 _/ \: ^, [& b退出数据库访问客户端:4 W8 e1 W, P: T3 n. J# m# H! C
( W& I# I+ E3 G( j" C3 p- _exit
- U4 h: p; [3 M" i4 F配置用户和Endpoints# ?+ C- [# J; i8 e
$ J/ f9 @3 D0 F/ L
source admin凭证,以获取admin命令行权限:
" o5 `% y' t. h' J1 y3 B
4 f; o3 o5 _0 C8 E( A9 ?source ~/.admin-openrc! j& O g0 g' T, y* V" b- @
创建nova用户并设置用户密码:" A, Q: |+ l3 j1 S! K* W
, M2 B/ j/ R: r( r' ?6 }, h
openstack user create --domain default --password-prompt nova
/ V: g9 y$ v4 O# t! M, P
% L8 C* x- N% c4 b+ U% L$ G0 zUser Password:
, B: ^& Y! f8 d, s* CRepeat User Password: z8 |5 [' P; x) C; t3 u9 a" W/ ~# m
添加nova用户到service project并指定admin角色:
- a7 `! F! z1 b8 j+ A7 C% @) t8 b4 `6 l0 `0 Y! z* A! Z
openstack role add --project service --user nova admin
+ a f; P2 y3 z0 m* Y创建nova服务实体:1 b0 h1 b1 {& M) c0 T
% P8 _& x" @0 V5 T+ J- Oopenstack service create --name nova --description "OpenStack Compute" compute
, j# s: l: Y- ~8 K9 m( v3 m创建Nova API服务endpoints:
! m1 N3 s6 m8 l7 ]4 v, j
1 [% H& H F! _$ [# \# hopenstack endpoint create --region RegionOne compute public http://controller:8774/v2.18 j. E' x8 B: ~# s
openstack endpoint create --region RegionOne compute internal http://controller:8774/v2.1
$ K! n5 y6 Y! b4 T. xopenstack endpoint create --region RegionOne compute admin http://controller:8774/v2.1- W( |8 |4 @0 J
! e( V9 s, A* Z3 k0 R安装及配置组件
9 s9 F% U4 a: Z( G* o
+ A- q/ ?5 ]1 N5 s' U# y' z安装软件包:
6 \. h+ g' {$ V6 ~) v7 `! o9 a# M. o" K; J+ J: I- ~
dnf install openstack-nova-api openstack-nova-conductor openstack-nova-novncproxy openstack-nova-scheduler
" y, F% N9 _* L编辑/etc/nova/nova.conf配置文件,完成如下操作:! m8 R+ q- G; w! u/ L6 X& I, q" c
/ S* j2 u0 {/ @
在[default]部分,启用计算和元数据的API,配置RabbitMQ消息队列入口,使用controller节点管理IP配置my_ip,显式定义log_dir:
( i" q- U% F. a/ G# M6 y$ v) j- W2 X6 l* N8 ^2 a' z$ K1 g
[DEFAULT]# u, i: _& a& Q( [' X
enabled_apis = osapi_compute,metadata8 h2 |$ b6 J4 l+ }; {8 e* ?
transport_url = rabbit://openstack:RABBIT_PASS@controller:5672/
& X Z( o; a2 H9 H! n6 D; E+ \my_ip = 192.168.16.2
+ a$ c; O$ |3 }5 N P2 ~8 X" n( klog_dir = /var/log/nova5 R5 G" N1 t, }% _! `
state_path = /var/lib/nova
$ b9 Y2 A) d6 m# K2 [
- X1 j4 e' e. o# u2 ^' R8 v4 b( K替换RABBIT_PASS为RabbitMQ中openstack账户的密码。
+ P; a' r& ]( Y `3 J
, T- O5 A+ [8 B" O5 r在[api_database]和[database]部分,配置数据库入口:
2 `, ~1 ^+ r' s* z9 f+ D n$ z ~; r1 T, M. D6 U, L
[api_database]
% h& T. O7 ]( I+ l$ oconnection = mysql+pymysql://nova:NOVA_DBPASS@controller/nova_api `6 P5 J8 b0 H- j
6 _3 H0 o) z5 L; v
[database]
, L7 A F% q; jconnection = mysql+pymysql://nova:NOVA_DBPASS@controller/nova. [* ^6 z0 Z! r7 m8 n1 \' g
替换NOVA_DBPASS为nova相关数据库的密码。
. Q1 V/ N# K$ h+ A
9 O. Z! d& Z0 P) n4 {' K( D$ r在[api]和[keystone_authtoken]部分,配置身份认证服务入口:$ r+ X1 S" R3 T z f1 m: K* {
7 C! W6 d! N5 L! M( Q' H j7 l
[api]7 y" k8 J# o7 N* b Y7 u" t. b
auth_strategy = keystone
?8 x- [3 m: N, H. R/ s* @/ A; z1 R- n
[keystone_authtoken]- n6 {+ z1 s% ^, T$ J, z
auth_url = http://controller:5000/v3' Z5 J! ]! Z8 l6 U6 V; |' v) _- X
memcached_servers = controller:11211
9 G/ Y9 A; T& A% Sauth_type = password
' H& o( u9 _9 w# V+ Gproject_domain_name = Default; ]1 X, x9 U9 U' l" c8 Z
user_domain_name = Default" Q5 z( r& s5 Y
project_name = service
7 l3 o0 V% ~5 z7 E9 ?: \username = nova
+ c0 h9 w8 M' q, l, e) b7 Mpassword = NOVA_PASS
/ U, C, k8 t0 F. o- X: J* t4 t& K替换NOVA_PASS为nova用户的密码。3 Y8 z* b' n. ]: I% y
" I2 }8 O7 X' F9 }7 p/ K; {
在[vnc]部分,启用并配置远程控制台入口:
; g# v# N: t! b- l2 [, J: y/ V& q4 S6 P& l
[vnc]5 t, C& m x8 A9 H2 E% Q j
enabled = true
/ ?2 V$ `+ q2 T+ e9 dserver_listen = $my_ip controller
' L" [# w% \# r9 Y- H) T% o( }server_proxyclient_address = $my_ip controller9 d5 W" Y/ L V
1 W4 p; A) L H5 _0 M7 P' ~# @
在[glance]部分,配置镜像服务API的地址:
0 ^' Q' K! G9 o |% y5 n- g1 g7 j5 C$ \) Z8 r
[glance]) G' T+ k1 w& |$ |2 X3 Y1 I
api_servers = http://controller:92923 ]4 H8 n. T* k' y3 r. ^4 S, c9 g
# C1 G2 G4 ?, h3 ]在[oslo_concurrency]部分,配置lock path:
2 z8 M% T% R* r6 k. r+ m1 A) |. @6 C
1 }% A E+ N9 j& L[oslo_concurrency]8 a+ z1 ]! n; h/ o R! X
lock_path = /var/lib/nova/tmp
9 Y8 d3 h% R% x- J7 E5 T1 |+ e[placement]部分,配置placement服务的入口:5 u1 ~' h0 k* w& E& z& ]5 n( k
& x' L/ ?( w) Z# k/ n2 d/ O% s
[placement]
2 Y K' g2 O) O; u2 vregion_name = RegionOne
L9 ]# X, x# Cproject_domain_name = Default& Y& b+ o8 @7 O5 j" P4 _
project_name = service
2 L, }7 h: J! s& sauth_type = password; i/ y/ b1 S' D
user_domain_name = Default8 M1 K7 M" M h! v6 q8 s2 o% _
auth_url = http://controller:5000/v37 e, `9 y$ E* V: r# O$ s
username = placement
6 \& W' ]6 `$ g1 ]password = PLACEMENT_PASS
9 z, f# @) C) S% p替换PLACEMENT_PASS为placement用户的密码。7 H6 X# R) c/ B8 k
0 O$ B+ X. |0 H4 h" O数据库同步:
/ p7 p% i+ F( O) g
1 C7 q$ E/ T: S7 f- t4 s" E s4 e- G同步nova-api数据库:
8 b1 b1 E/ U4 h I0 J+ D0 R8 y t! I
su -s /bin/sh -c "nova-manage api_db sync" nova
! j. ^# z: v" P0 V8 k# N注册cell0数据库:
1 C) ]* l* k5 M4 P( ]) X4 v7 Y# h. n1 C( K* v0 N3 Z
su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova3 G b# ~5 y+ H$ E9 h$ A1 M7 N
创建cell1 cell:$ \, `1 c9 v, ?$ i, c9 n( B
( ^% K a5 G" T3 q2 ksu -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova
& _1 L' h I0 Q( [7 }/ r同步nova数据库:
2 N) n, T; U$ u$ a2 B
* z0 n8 M$ P5 tsu -s /bin/sh -c "nova-manage db sync" nova
; t# g) N# a; y% V5 y验证cell0和cell1注册正确:
% p# j ?1 x4 P# A) @
2 f7 ^$ {* P2 u6 x) l" y& Ysu -s /bin/sh -c "nova-manage cell_v2 list_cells" nova1 ]( {( ^4 p G
启动服务9 A: y: _- [3 ?
* c9 L' s1 p5 o( J0 R: O; t% o
systemctl enable openstack-nova-api.service openstack-nova-scheduler.service openstack-nova-conductor.service openstack-nova-novncproxy.service+ I( X) m3 Q1 t
% X+ q% S# S4 G* zsystemctl start openstack-nova-api.service openstack-nova-scheduler.service openstack-nova-conductor.service openstack-nova-novncproxy.service
2 A2 \5 {( `7 I9 d) I7 h) {" y9 K$ _! V" i" E; G( B
Compute节点4 e7 B! o8 B( S* l4 N
/ x- @$ h: q" f4 G; r
在计算节点执行以下操作。+ n' A+ q3 q; a7 K; R. N
% f& t% }# q4 ]# r安装软件包
9 K+ G& Z) H, m. g5 o+ c$ r
% M0 o; n, M: o+ n5 ]/ xdnf install openstack-nova-compute: B! z& s) O3 \
编辑/etc/nova/nova.conf配置文件
7 O K$ A2 P0 f: {7 Y+ ?
6 x: d. D( q/ z0 _+ H# B4 d在[default]部分,启用计算和元数据的API,配置RabbitMQ消息队列入口,使用Compute节点管理IP配置my_ip,显式定义compute_driver、instances_path、log_dir:
: F& l( G% \: e( e/ @; v8 u9 @' ?! E8 f: \4 ~7 l; ^ i
[DEFAULT]2 s) H6 o0 W8 C$ O2 m( D2 L
enabled_apis = osapi_compute,metadata7 H( O$ P, V$ y: I
transport_url = rabbit://openstack:RABBIT_PASS@controller:5672/6 z% m0 O9 D! ^/ G6 Y2 N
my_ip = 192.168.0.3; u, `& @" C( Z" o! Y: W
compute_driver = libvirt.LibvirtDriver, D8 m4 x0 J" k- N' e
instances_path = /var/lib/nova/instances
7 }+ L! K! I! |4 T. l1 p9 jlog_dir = /var/log/nova
. d8 |9 U( i" O0 l$ T$ L替换RABBIT_PASS为RabbitMQ中openstack账户的密码。* R) B, u) V7 F4 O. X& `9 y ~1 L9 N1 j
5 j4 P' J. Q! [
在[api]和[keystone_authtoken]部分,配置身份认证服务入口:
0 q2 I' L7 h4 ~' c7 W7 u9 H2 }+ l" K% U* U! ^" g
[api]& p( f4 a' I7 c+ S( f
auth_strategy = keystone
3 Y. e# J/ ?+ B* j4 \
3 H q) L1 ~! Y( s* q8 z" X[keystone_authtoken]
4 \1 N' Q+ q: v0 Fauth_url = http://controller:5000/v38 ~& L0 ]. b. ] U, t- R4 n
memcached_servers = controller:112117 `1 ~4 i9 n/ o8 a, j* H/ J1 g# X
auth_type = password
1 y I7 Z! |+ i$ O) z& Rproject_domain_name = Default
2 h6 Q/ @( o/ R3 guser_domain_name = Default
# J! j, T9 p9 `' U" d; A* I* Qproject_name = service7 l O4 @# y4 l- m
username = nova; B4 ]$ L e, n' m
password = NOVA_PASS
5 C8 h" B' O: J$ Q, ^替换NOVA_PASS为nova用户的密码。
5 n: ~/ R, I. F7 k
! L- @* Y0 |1 F5 Q- }1 T在[vnc]部分,启用并配置远程控制台入口:
7 x* l4 n1 a; H$ s2 |5 w" q. d$ Z1 t/ W
[vnc]
2 h: q0 E0 B/ N* Zenabled = true
- H* R3 x$ `) x+ ~! \. Y) g, o+ Oserver_listen = $my_ip
7 h7 d2 T) E9 h2 @server_proxyclient_address = $my_ip
" s. ~3 @9 @8 O. d) O& _novncproxy_base_url = http://controller:6080/vnc_auto.html
2 n, d* G5 h+ S$ o9 i! ^! G2 ?在[glance]部分,配置镜像服务API的地址:
. J/ s3 ]; K: D8 k; b; e7 h* a. E9 e
[glance]$ i1 g- [2 ~ V
api_servers = http://controller:92923 @9 D8 E. W5 G0 p
在[oslo_concurrency]部分,配置lock path:
0 G+ w2 b! {4 X$ l& r6 r: V1 P3 _& x/ R+ }6 }
[oslo_concurrency]$ i( ?. m8 e7 Z
lock_path = /var/lib/nova/tmp
5 \) d0 |) o1 s& p! j( n; u[placement]部分,配置placement服务的入口:
5 Y& K- H( M, ?2 e; y" E0 Q' t2 ?; L" t5 _2 {$ p
[placement]
! I! q3 B0 q1 U$ `) O O/ o9 Xregion_name = RegionOne
& m( r6 a( W6 g+ [2 D4 {8 Sproject_domain_name = Default* R# l0 R8 j G8 ?3 O
project_name = service
& f1 E* l$ e, x9 Y0 n! rauth_type = password7 }- X. h7 ` H
user_domain_name = Default
! M \7 n' [3 y3 K/ j2 Gauth_url = http://controller:5000/v36 r/ k; y7 j; m6 y
username = placement Z, t* m( r; `: X3 \' k/ v
password = PLACEMENT_PASS* N% G. }7 |0 Q+ l/ `6 Y$ M# D
替换PLACEMENT_PASS为placement用户的密码。
1 ]7 w* V) ^" {1 p( y/ @6 J4 a2 I. T$ o, n
确认计算节点是否支持虚拟机硬件加速(x86_64)
- q6 G D8 U: Y, c. Q
% u! O& f' j# |* X8 J处理器为x86_64架构时,可通过运行如下命令确认是否支持硬件加速:
2 \+ `: s( v8 N0 c5 J
0 k4 U+ s( W! f( Cegrep -c '(vmx|svm)' /proc/cpuinfo
; r( V2 {& R5 {0 r5 f# v2 b k' Y' ]如果返回值为0则不支持硬件加速,需要配置libvirt使用QEMU而不是默认的KVM。编辑/etc/nova/nova.conf的[libvirt]部分:$ r- c' l& Y8 W- S- f, h* c6 t
" ^* \% b1 Q5 G4 a6 f[libvirt]
' V- t% w7 u- @! H, q6 Y7 ~virt_type = qemu) i5 m0 [* r. b4 \
如果返回值为1或更大的值,则支持硬件加速,不需要进行额外的配置。
$ v+ |/ V- h+ @7 L- K
% ?9 V6 |$ n8 z, w. T$ V. |6 I$ l确认计算节点是否支持虚拟机硬件加速(arm64)
6 r# t, F9 g$ q6 [
) F2 M! n: I8 r' I8 m处理器为arm64架构时,可通过运行如下命令确认是否支持硬件加速:
) x3 `1 G1 R% x! _4 j6 `8 \8 m: f
virt-host-validate$ m# a0 w1 k; y e, _
# 该命令由libvirt提供,此时libvirt应已作为openstack-nova-compute依赖被安装,环境中已有此命令 s$ |3 O: p' e3 s. l4 h4 u
显示FAIL时,表示不支持硬件加速,需要配置libvirt使用QEMU而不是默认的KVM。 U$ L- N! u, k6 k
$ V1 w6 p; v( B' a' P+ U# ?
QEMU: Checking if device /dev/kvm exists: FAIL (Check that CPU and firmware supports virtualization and kvm module is loaded)" h& ^/ z8 d& k$ n6 w
编辑/etc/nova/nova.conf的[libvirt]部分:# n- M7 i2 ?: j
9 S! [% ^( H0 J' }. ?/ q3 |
[libvirt]! A! [+ F* W$ ?. k5 G' `' y B
virt_type = qemu
2 F, E) g* s: ?, l显示PASS时,表示支持硬件加速,不需要进行额外的配置。
: t- U+ a# ^# B8 G9 @+ q
: i& d- y; V0 s3 Y" m$ aQEMU: Checking if device /dev/kvm exists: PASS
6 `9 h+ J0 ]% E配置qemu(仅arm64), R$ z/ k4 i1 d$ D+ ~1 O. u0 a
% b3 S8 k9 x: @! s仅当处理器为arm64架构时需要执行此操作。
1 u$ v2 {& H6 ^
. g, ]# @- G+ t0 y& Y( U" n编辑/etc/libvirt/qemu.conf:
4 `& ]0 F; I# [! I* |9 F n( _
- R8 E4 a$ w1 Anvram = ["/usr/share/AAVMF/AAVMF_CODE.fd: \
( K( p6 p* N& ^3 j /usr/share/AAVMF/AAVMF_VARS.fd", \
: O9 t' g: V* M1 F5 m/ }0 i "/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw: \) u2 I2 ^: C) M
/usr/share/edk2/aarch64/vars-template-pflash.raw"]4 v {( n V7 t. }
编辑/etc/qemu/firmware/edk2-aarch64.json
0 D5 z& U2 k) X7 s" V" c8 w' p# R. ?! Z6 X$ H! r; B( L# J _
{
( s6 u7 K4 I7 A. N# b" P, | "description": "UEFI firmware for ARM64 virtual machines",
2 [" D" b3 o6 R6 Y9 I9 J "interface-types": [
% m$ R" B6 d G8 E5 K) o "uefi"
2 |: V- n2 p, {) x$ a" f; F ],
" d1 s2 _3 X4 C- r6 S- | "mapping": {: V0 q8 F2 I5 W8 c
"device": "flash",
$ |1 Y& F, }2 E) B o- A "executable": { S& c/ G: z5 V" O2 U/ r; O
"filename": "/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw",# Z9 K3 K1 M( a4 J
"format": "raw"% o8 s0 A3 r" E% s$ }
},! O! [- |9 V L# [
"nvram-template": {
" X) v9 T1 a5 H/ b/ h. E "filename": "/usr/share/edk2/aarch64/vars-template-pflash.raw",, d$ E8 @4 k& ?- ]9 {
"format": "raw"
8 x; q) R* J) X. a" U. H9 y }
/ d( K% S8 M' b0 X3 z },: a1 J9 `# a+ n8 U+ C
"targets": [6 S/ }# o! ? S/ Y* l c( a$ U) @
{2 l1 ~+ T' K0 ?: T
"architecture": "aarch64",
. I. X8 c( }/ V# |3 [/ x/ H "machines": [
) x, j4 N$ o$ m "virt-*"
9 R; u F& s/ p# s4 I7 O5 [ ]+ q ?3 O" r$ Q
}
2 R4 W b/ x$ C2 @ ],; {9 ~0 u; O) [4 D
"features": [
/ U, ?6 F0 Q$ k0 y
' l; e$ d2 L/ i0 Q; f ],7 H1 \' K# S) B: q8 s
"tags": [# V: ]# `/ c# K: F* G
7 r- G5 J- j% ? }+ E/ D3 C
]& i4 t+ x, h+ h; T9 x( ^
}
" c- Q- ~ g# F0 a s启动服务' g: x, a, t' v, c
: Z" y1 z) ], G& j! `- {
systemctl enable libvirtd.service openstack-nova-compute.service
3 ~, V( ?' ]: ?( @6 }* Tsystemctl start libvirtd.service openstack-nova-compute.service. |# V3 x0 V' C) D- v7 n
Controller节点
P8 d- e* P0 T
/ r4 {8 x6 X% R2 z6 `3 P7 Z% a在控制节点执行以下操作。
! d, \% y5 P+ {5 [, j7 _ C. [0 k
添加计算节点到openstack集群
, i R9 F/ R& Y+ ?0 {- S T9 }# c$ Q3 q! Q9 @
source admin凭证,以获取admin命令行权限:
) j1 b2 [5 |; v* E# W/ d# M' l5 s; f; `
source ~/.admin-openrc
( \$ I J( m: S; D/ N确认nova-compute服务已识别到数据库中:
' k1 `% c* g- F u, a" N
/ l* h0 U" g1 sopenstack compute service list --service nova-compute6 M8 a% x/ X% l/ @& [6 k
发现计算节点,将计算节点添加到cell数据库:: W! ~7 t) C5 U. Q
7 N5 d( |* B' zsu -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova: t: Q: d, D. f0 c. r' F
结果如下:# r, O% R: h* M! P% j) Y
Modules with known eventlet monkey patching issues were imported prior to eventlet monkey patching: urllib3. This warning can usually be ignored if the caller is only importing and not executing nova code.
, f4 S/ S& O7 G: E0 l EFound 2 cell mappings.
9 K- ^+ o1 Z( u' KSkipping cell0 since it does not contain hosts. J7 i$ ]0 j- B; F
Getting computes from cell 'cell1': 6dae034e-b2d9-4a6c-b6f0-60ada6a6ddc2% K& k( W0 M: m6 I8 u
Checking host mapping for compute host 'compute': 6286a86f-09d7-4786-9137-1185654c9e2e
6 N1 U; c( D! C r: nCreating host mapping for compute host 'compute': 6286a86f-09d7-4786-9137-1185654c9e2e) m! H% V9 B- u( a
Found 1 unmapped computes in cell: 6dae034e-b2d9-4a6c-b6f0-60ada6a6ddc2
& y" f# f {- k% q8 _2 c! s验证2 a) Z. S* X3 }7 \- S
8 N' K4 d, m" S y, R: X# l! O
列出服务组件,验证每个流程都成功启动和注册:
+ b0 V8 E4 M( l, w1 u1 Kopenstack compute service list# Q' ? S* J$ h
列出身份服务中的API端点,验证与身份服务的连接:
( i; O& @# x+ zopenstack catalog list. z! H2 ^" b9 `8 T
列出镜像服务中的镜像,验证与镜像服务的连接:
, h6 K* f3 E5 A8 N9 sopenstack image list
. ^ Z ]7 z3 V0 Y* ~检查cells是否运作成功,以及其他必要条件是否已具备。
& T5 M, n* L* ]' O9 znova-status upgrade check
+ b6 {* Z6 r) e/ u; DNeutron¶
3 r1 Y6 q4 x' K* [( b2 XNeutron是OpenStack的网络服务,提供虚拟交换机、IP路由、DHCP等功能。
7 e& |: w: B/ S
$ @' G' Q8 ^8 G, hController节点: d0 a7 W, {. L# C8 @" Q
# I$ @5 I. Z9 _
创建数据库、服务凭证和 API 服务端点
[$ P6 T9 d3 B
0 S& \4 r) u8 n5 b) w: o# p& {创建数据库:
1 i: G& x' j2 \6 I# v0 I# k- `# Q2 Z( M
mysql -u root -p
1 G' ^, J N5 d% u* l
# A7 q. {* u3 r3 ~1 fMariaDB [(none)]> CREATE DATABASE neutron;1 Q; E8 j- x& @
MariaDB [(none)]> GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY 'NEUTRON_DBPASS';
' Z4 Y2 s& i3 ~MariaDB [(none)]> GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY 'NEUTRON_DBPASS';
7 B/ \8 ]' \# [3 x; [( iMariaDB [(none)]> exit;+ t% U% {3 L8 P" h) X
创建用户和服务,并记住创建neutron用户时输入的密码,用于配置NEUTRON_PASS:
2 k/ N) T$ }1 G( F E$ w, }' [$ m& Q- t; ^0 _
source ~/.admin-openrc$ S I$ B a8 F
openstack user create --domain default --password-prompt neutron: b9 ~/ l* B' w$ `* p3 l$ E, W2 C
openstack role add --project service --user neutron admin& H" ? T) k, y0 q: @/ d/ D4 e+ z
openstack service create --name neutron --description "OpenStack Networking" network. s3 n" i- L1 ^8 k9 E
部署 Neutron API 服务:
$ [3 c+ X% i( R% z$ G% {# {! |' r3 Y8 ]- _7 Q! k" T1 L$ s# A: e
openstack endpoint create --region RegionOne network public http://controller:96963 O: ]+ y# K4 P7 p
openstack endpoint create --region RegionOne network internal http://controller:9696
; R* V. \* \4 x8 fopenstack endpoint create --region RegionOne network admin http://controller:9696
! M, ^, {$ t5 a7 m/ ^. e安装软件包
( X t0 y3 V1 K, l `. O7 Y/ Y8 y& `4 d4 E7 G7 v( v
dnf install -y openstack-neutron openstack-neutron-linuxbridge ebtables ipset openstack-neutron-ml2/ C1 M" ?3 }+ K4 H/ s3 t U
3. 配置Neutron1 s/ |( K* j. ~3 J
修改/etc/neutron/neutron.conf$ @) G) S% Q# ^4 n. Z6 F- L$ m
( p2 p" V; ^0 g9 f5 C- j[database]9 K/ E8 a3 B" A1 t0 z
connection = mysql+pymysql://neutron:NEUTRON_DBPASS@controller/neutron
. [( A8 w ]; o3 q4 }
# x$ _$ X3 A& @& x! x K[DEFAULT]
5 F: ?4 k8 d$ fcore_plugin = ml2
5 N' m8 G2 L( a, i0 [. M, m- aservice_plugins = router
1 p# T# U/ G1 {% C4 L& R8 d0 Uallow_overlapping_ips = true
& L4 n' B. {; R, Etransport_url = rabbit://openstack:RABBIT_PASS@controller
: b: a, Y$ P& \auth_strategy = keystone
: K" Y9 \7 X% |) J0 X3 C! E: L) Jnotify_nova_on_port_status_changes = true8 H9 m5 q: Y8 B8 j b
notify_nova_on_port_data_changes = true. r/ V5 y5 v- @
4 ?% q) m: Y, j
[keystone_authtoken]
0 B5 {) S N" q4 g" vwww_authenticate_uri = http://controller:5000
! `. U, d* @. u: Jauth_url = http://controller:50002 O4 H. c( L; n+ g- ?% F
memcached_servers = controller:11211
3 C% ?, \+ I1 t1 `- iauth_type = password) l G! F, e/ ]( `" q" @
project_domain_name = Default
- H; y6 C( h) o! s7 n/ Guser_domain_name = Default& ]! i; j; d3 B" |& `
project_name = service
( O0 R: J0 w9 ?1 P+ Jusername = neutron! g: _3 _* R8 ~; y: e
password = NEUTRON_PASS
) v* f/ R2 w$ D, Z& D
- ^/ B8 @$ k- z1 R* S[nova]! E! b& d) ?6 G* E
auth_url = http://controller:5000) k2 G! U! g0 H8 n) ~
auth_type = password
' D( H/ D- L% t: z/ l/ z9 a1 {project_domain_name = Default7 { [! u& e" @
user_domain_name = Default
' ?& o* B. s# l+ {region_name = RegionOne) u4 \1 L* x0 _
project_name = service+ Z# P4 O2 N; N, }+ t3 f! H5 c, l
username = nova- {. O/ |2 v+ P2 T9 e. _$ s
password = NOVA_PASS
, U4 _: P/ E0 Y& D" c, E6 H# C7 P. b9 O2 [, A5 @
[oslo_concurrency]. k% S" E' z: |8 x9 M" S( v. l C* K7 Z
lock_path = /var/lib/neutron/tmp
! b* w( J `# G% E
' @- P6 a* l( M4 B7 B B; B[experimental]+ K7 C/ W% y# r
linuxbridge = true
! n( V( ?/ K$ Y6 S& f9 R配置ML2,ML2具体配置可以根据用户需求自行修改,本文使用的是provider network + linuxbridge**
6 {3 [, B1 @2 r$ r0 J! d5 J* j( W- R
; Q" [ ~/ u; X( h/ F修改/etc/neutron/plugins/ml2/ml2_conf.ini
2 `7 P& W' _) m# q# w. `4 ]& S0 N+ G& o) C8 Y1 Z+ R6 G4 g
[ml2]7 h o! d9 [0 ^9 D3 E% m1 k6 G
type_drivers = flat,vlan,vxlan3 i5 q1 B' S. k( K- r
tenant_network_types = vxlan' m+ T- i( m1 A: Z8 g
mechanism_drivers = linuxbridge,l2population
+ |# w2 F2 P0 Oextension_drivers = port_security
3 ~ f2 c+ O F1 Z' f/ c( D+ a* |* g. A. `- s$ f
[ml2_type_flat]/ R* y: @4 K4 L6 n. N6 A
flat_networks = provider
8 k$ _& j& e6 {- ] S) R3 h* `% h
, z* e" ` I* R- v/ ~[ml2_type_vxlan]3 ]" b, l1 o4 f: X" o2 a
vni_ranges = 1:1000
# Q* I8 g F/ U3 V) I+ D7 ^+ r0 {
7 s2 n; S3 D; J$ J0 M9 h( \ O[securitygroup]
3 P2 o* b- H: K' Uenable_ipset = true
2 Z3 L- O8 N' B# |修改/etc/neutron/plugins/ml2/linuxbridge_agent.ini- z6 _0 d$ z! v* a% d
; O& P/ |( M* C8 i) u* ?0 Z[linux_bridge]! N% d/ k4 {* \/ _- X
physical_interface_mappings = provider:PROVIDER_INTERFACE_NAME
7 D9 [; v, d! C5 m$ E& |9 p" J/ l# p5 a! [6 A( q
[vxlan]
E# k3 r/ ~/ d: \( a3 V* henable_vxlan = true' @2 |! W, d/ H
local_ip = OVERLAY_INTERFACE_IP_ADDRESS `1 i; n- |/ Z, O. N; |9 w
l2_population = true
6 Q1 z$ D4 z# z6 ^) u% N; |! P7 n9 o8 G7 z8 {, K: a
[securitygroup]1 @3 r2 ?! |5 r, K J8 k. M. F; O
enable_security_group = true+ j1 Y$ M% x0 F) B0 a
firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver
0 i( ?; q4 G9 ~4 p0 m配置Layer-3代理3 N( a9 a$ n$ H1 d$ F0 ^
. P2 [& A5 H& H4 n% g2 O7 X& j
修改/etc/neutron/l3_agent.ini' T- V# _& N% h1 l
* [' ^/ C% n2 n: w, g
[DEFAULT]
4 Y" a. N9 f) H9 Q) w0 N Binterface_driver = linuxbridge
+ z: g% ?* ]; m y: K( R8 L! \2 K配置DHCP代理 修改/etc/neutron/dhcp_agent.ini
$ q, i3 \- R) C5 I* h7 k
% \% d0 z! G7 ?& O5 _+ R8 @7 R/ T+ z[DEFAULT]) e& A( e# S. `) J. `+ z$ W
interface_driver = linuxbridge, c' Z4 J- j) B2 j6 l# J ]
dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq6 O0 v4 o% \ ], c! h7 K0 w
enable_isolated_metadata = true
( f% e8 t# M! U; A* L$ S; B配置metadata代理) I& S8 u1 t$ k0 h1 t& [& e: v
3 o" a. y2 l) @4 b5 [1 X, ^修改/etc/neutron/metadata_agent.ini
6 W( D$ ~4 c2 S' R; b% j2 N: r" M' s- Q
3 @6 P, }6 r' M& V[DEFAULT]' `! v6 O$ L Y& Y
nova_metadata_host = controller8 j7 k2 i. X% V2 E
metadata_proxy_shared_secret = METADATA_SECRET
' U) b% {; W. e配置nova服务使用neutron,修改/etc/nova/nova.conf
) S, O9 V5 c5 H" k- H5 k[neutron]
3 w! M% o3 j* g- N' {auth_url = http://controller:5000
8 r+ g3 g* v( f( o, n2 M: zauth_type = password
: a+ @8 F+ }/ V: Qproject_domain_name = default% n5 l$ c' \6 {) R Z& Y
user_domain_name = default
6 Q3 Z+ V! U$ H+ O$ M2 A# Vregion_name = RegionOne9 C# u) I2 ` S2 [
project_name = service+ u" k$ }1 F# p/ H& ]: Q: m
username = neutron8 }4 J7 s8 h, x; b2 z8 n
password = NEUTRON_PASS- ^3 E, T. N2 b
service_metadata_proxy = true
. V( c9 l( Z' b0 Jmetadata_proxy_shared_secret = METADATA_SECRET
- h/ V T' z) z7 V1 \+ \创建/etc/neutron/plugin.ini的符号链接
! l8 P/ \0 D, w$ v0 t
$ E% h G6 a: n4 O6 K8 mln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini# m+ Y! B0 y z) {
同步数据库
1 ~( ?$ V; c; ]8 U8 M& C5 _+ k9 e- [- `5 U; R$ o0 I9 {
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" neutron9 [ n) \/ m8 r7 ^
重启nova api服务
* j8 i, [0 y8 H9 i: Xsystemctl restart openstack-nova-api( o: |/ \% O% T% T, ?9 {
启动网络服务' H, v( m7 p9 n9 B5 ]
: a8 }; ?& r1 K
systemctl enable neutron-server.service neutron-linuxbridge-agent.service \" F) h$ m$ H- [$ P9 e" ~! o
neutron-dhcp-agent.service neutron-metadata-agent.service neutron-l3-agent.service
+ O" C7 G3 S# }& a' H7 _* Y; ~+ {systemctl start neutron-server.service neutron-linuxbridge-agent.service \
l$ i" m) E( t. l4 e( O, cneutron-dhcp-agent.service neutron-metadata-agent.service neutron-l3-agent.service
H: v7 t0 M" \$ w% aCompute节点
' k0 I7 I) l( N9 W( v+ i* I Z( N. b% A4 r5 P P
安装软件包
- q2 S6 e$ @( h3 I& Y' H: j3 D7 l( Xdnf install openstack-neutron-linuxbridge ebtables ipset -y! {- k: \# W) D* u$ Z, z8 j
配置Neutron
+ @9 W4 @% f% f2 |( b( t$ P. x) J1 n- d0 e
修改/etc/neutron/neutron.conf- U' U: q8 B, N
; |; E% Z. L# d& m
[DEFAULT]' q z* w8 O+ M# t" ^! e9 _
transport_url = rabbit://openstack:RABBIT_PASS@controller
$ K; z. n ]) I1 j$ g. Jauth_strategy = keystone# @2 M0 x6 }6 ]: G
$ u" N" k, u- f" o; x: l
[keystone_authtoken]
2 O" c- g# \9 z: l* N c4 Fwww_authenticate_uri = http://controller:5000$ Z$ G9 J2 n x7 J8 w8 b% Q8 O
auth_url = http://controller:5000
9 p% S& n$ o% cmemcached_servers = controller:11211
) [) F# H0 E4 y4 Z/ C1 Yauth_type = password' L) w0 j8 T8 d, h
project_domain_name = Default
2 a) P* e2 P+ v- ?' Uuser_domain_name = Default
) M& w9 z2 ~6 ~1 Q# D$ lproject_name = service& k% U; I1 o1 n; m" D
username = neutron" J+ Z9 b8 u, W" M( I
password = NEUTRON_PASS3 b9 I& Q0 T" b- @4 v, p* J
3 [# h' |; ^; \& V% N[oslo_concurrency]6 U5 x& H( W- f# s) J
lock_path = /var/lib/neutron/tmp, u+ W3 a3 }4 N( I" E% x3 Q
修改/etc/neutron/plugins/ml2/linuxbridge_agent.ini
3 }' V% e' ~2 L" K! q( \
# L1 G0 ?& J8 M" _' @0 j3 s8 N[linux_bridge]
. F5 H' Q3 }8 G9 [/ gphysical_interface_mappings = provider:PROVIDER_INTERFACE_NAME
5 b$ i, M) B8 S: y9 ?$ D8 b; N$ c1 I& ?& o: v+ R0 \5 r
[vxlan]
; O+ q6 U. F9 N( O' Penable_vxlan = true
! q+ A* i1 H% h% f6 X" glocal_ip = OVERLAY_INTERFACE_IP_ADDRESS
; D4 L) M+ X2 }8 [l2_population = true
4 x' m+ d3 j# J# w4 b- y% F3 ]# A" C5 {) d
[securitygroup]
5 t. p: X" g7 v4 `enable_security_group = true
' h9 Q7 B% E2 r0 j0 D: C0 Tfirewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver
& w$ f! Q, f% @* y# I配置nova compute服务使用neutron,修改/etc/nova/nova.conf
$ w t8 d' @3 m$ y. |6 I- ]1 V
, p2 e6 ^& F: l5 q; s* d( E, \[neutron]
7 N5 w4 G. S8 C; F. I9 mauth_url = http://controller:5000: R/ V( c; L' a# ]5 {) M
auth_type = password
; Z! {# K& R) q3 P8 W- Nproject_domain_name = default6 x3 q) Q8 u( Z( X- Y9 O0 q$ ^
user_domain_name = default, r& r7 S$ _( q; y! i
region_name = RegionOne
8 b% m$ h5 @- K3 f2 gproject_name = service
# r, d4 S, s5 D0 A, o4 Qusername = neutron( ^/ [- X; `8 D1 R( c
password = NEUTRON_PASS) l# E. f4 U0 Y( [ E- s$ |* x1 c
重启nova-compute服务1 L* m( R9 B( a
systemctl restart openstack-nova-compute.service
: ]6 ^8 @$ L7 s! R! \启动Neutron linuxbridge agent服务
3 e% q. U( G7 J: M+ I- r- Usystemctl enable neutron-linuxbridge-agent
, G( i! j5 x" _. p: A4 usystemctl start neutron-linuxbridge-agent
# M: E, _8 Z$ y; x1 c( c9 [Cinder¶2 X2 K( e/ X9 a" M! L' A# G
Cinder是OpenStack的存储服务,提供块设备的创建、发放、备份等功能。
' d: ^+ [, v; l/ m/ X: J0 s5 k/ _4 j) [4 @+ U
Controller节点:
|$ W# s7 d* g# }5 q$ s* I( u( D% T- X U( k5 }. c" T
初始化数据库' J- `5 h$ C1 K S# [" d6 W
0 y0 K2 I& Q: m/ o/ r5 p; h4 a$ I; _
CINDER_DBPASS是用户自定义的cinder数据库密码。
, c% c9 v, z1 ~) x' h7 D9 e! s2 \9 E4 c/ G# C' a- _
mysql -u root -p% M2 H3 S6 w$ Z9 d+ O
; Y2 Y+ g$ C5 U% N+ @MariaDB [(none)]> CREATE DATABASE cinder;+ [# P2 |& p' R; d, U+ i. _8 n
MariaDB [(none)]> GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' IDENTIFIED BY 'CINDER_DBPASS';
' ^% A; U9 x. H: pMariaDB [(none)]> GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' IDENTIFIED BY 'CINDER_DBPASS';
+ Y/ m9 Z j Z; \) ]MariaDB [(none)]> exit
( o3 H! r+ Q g: J# l9 R: J初始化Keystone资源对象
/ C2 I8 j- o6 V; U% v/ W
3 h7 H* _" [- g2 R1 y$ j# r- v! Bsource ~/.admin-openrc! ~' f" n# B8 ]0 X* k
7 p5 D; W/ L- K# R. |#创建用户时,命令行会提示输入密码,请输入自定义的密码,下文涉及到`CINDER_PASS`的地方替换成该密码即可。
/ F" ]; o. G" t- ~; y% q7 Popenstack user create --domain default --password-prompt cinder
" j+ T! P# v; x6 I/ G0 L& b, a8 ]( e y1 i. I i0 @4 d
openstack role add --project service --user cinder admin. M- X" n/ I4 h' d; E/ }. I, P' h
openstack service create --name cinderv3 --description "OpenStack Block Storage" volumev32 u& s5 v+ d6 S$ H
Y T. Y% ]* C& sopenstack endpoint create --region RegionOne volumev3 public http://controller:8776/v3/%\(project_id\)s
3 N7 l8 g+ ~6 V' hopenstack endpoint create --region RegionOne volumev3 internal http://controller:8776/v3/%\(project_id\)s
. R: m0 D1 r7 x* q' popenstack endpoint create --region RegionOne volumev3 admin http://controller:8776/v3/%\(project_id\)s1 v/ _8 S, O3 x8 P4 [" Y
3. 安装软件包- C1 v, K8 ^5 q4 G& i. M% p& k5 S
dnf install openstack-cinder-api openstack-cinder-scheduler
, A+ t7 w$ L4 Y3 ~5 c修改cinder配置文件/etc/cinder/cinder.conf
! N$ a; H* r1 t8 h- X% d" ^3 G6 R$ w5 q9 w
[DEFAULT]
, L! p- u' e4 H+ H& f! o h. rtransport_url = rabbit://openstack:RABBIT_PASS@controller
; u9 g% L6 C& l9 Y5 }9 I/ @$ Xauth_strategy = keystone8 \# ?+ Q6 h0 T0 [! O* z
my_ip = 192.168.16.2
3 m" M- I8 S- s. ^; h& `1 T1 u! N) C! t9 |3 D5 ^8 ~
[database]$ |$ E/ f# s0 ]
connection = mysql+pymysql://cinder:CINDER_DBPASS@controller/cinder
& c. Y+ S6 z0 n# e$ X
& k m: H( f1 Q[keystone_authtoken]
& D% m3 ?- b* B3 ^* Twww_authenticate_uri = http://controller:5000
) `& Z# \- s. {- A9 x8 }auth_url = http://controller:50008 M" o% d) K: ~& `! c. c5 m1 V
memcached_servers = controller:11211
* X, X" ~% r7 Kauth_type = password8 K F* K8 ^, j j, m6 F0 S
project_domain_name = Default3 S7 c5 d g' m B& ?* w2 q
user_domain_name = Default
A% ^3 `9 y2 R+ sproject_name = service3 D, \1 }7 N4 [; x Y, U
username = cinder
s5 |5 _1 @4 T6 Z$ e0 Q$ @# Rpassword = CINDER_PASS
) a9 D9 g; ?7 H0 n! |# z
2 a) g- r& D* _[oslo_concurrency]0 U5 q8 C& H* G! b' M! G
lock_path = /var/lib/cinder/tmp: X0 R6 n+ a+ ]7 e+ T# h0 |8 I
数据库同步4 S! r& {+ L6 }1 Q- O; G+ x
* Z0 V2 F- e. h8 esu -s /bin/sh -c "cinder-manage db sync" cinder
* m8 R- ?+ M4 h# Z修改nova配置/etc/nova/nova.conf$ G ~- B4 N+ d8 C" h3 N0 V# S
9 l$ H+ H& ~( O3 _[cinder]
. A3 R0 k( ^4 M) ]0 \! Ros_region_name = RegionOne, s W+ {' J/ b' n7 x/ J* O+ m
启动服务
$ B5 ~& n8 v! V1 N- L5 o( q
: @) @" _8 v* b1 f/ esystemctl restart openstack-nova-api1 y% m; t6 t. }! `! u
systemctl start openstack-cinder-api openstack-cinder-scheduler
' O: r+ o N, F4 N' H4 |3 s0 zStorage节点:! G5 T5 \1 J2 `
7 S! H* r2 I" ?2 i6 b) QStorage节点要提前准备至少一块硬盘,作为cinder的存储后端,下文默认storage节点已经存在一块未使用的硬盘,设备名称为/dev/sdb,用户在配置过程中,请按照真实环境信息进行名称替换。
" ^% ]. h7 X3 }* }% d0 ]) V# `# ]% Z. r0 j- G, U Z! d8 ]
Cinder支持很多类型的后端存储,本指导使用最简单的lvm为参考,如果您想使用如ceph等其他后端,请自行配置。
8 Y7 B9 Q- k; ?' m: J) Z# c
6 U( d, E0 O) H% n安装软件包) `3 i, O1 h& D$ E: k) ]
; Q6 K* ?0 k% d, Q! \0 u; Z) tdnf install lvm2 device-mapper-persistent-data scsi-target-utils rpcbind nfs-utils openstack-cinder-volume openstack-cinder-backup
1 Z4 {3 z! T" X3 [5 h( S! K5 R配置lvm卷组$ g3 r8 `1 c# Q" u
6 k% l5 p9 H' Ppvcreate /dev/sdb
Z% q& p! d2 L- x. M) m' ]vgcreate cinder-volumes /dev/sdb
) F4 U: O: y+ Y* t, C9 l修改cinder配置/etc/cinder/cinder.conf
, l. Y* @7 u! m* L; ?. R# @
" k1 h; q, i. T. k+ s3 x[DEFAULT]
3 ?8 ?( i/ V- w, q) G9 Utransport_url = rabbit://openstack:RABBIT_PASS@controller2 ^# T' F, h* Y6 Z2 |! R/ C
auth_strategy = keystone+ t! G8 Q8 {; R) J
my_ip = 192.168.16.4. ?8 _1 j" V3 h9 k* l0 ^: ~" p2 l
enabled_backends = lvm5 ?. M, P! Q; I" w. U" X! _; n: Q# V
glance_api_servers = http://controller:9292- S4 t2 }7 J) V5 `+ ]9 m6 r5 D
" p9 v# w# B; P }" L) T! U
[keystone_authtoken], V# @. o: r# M4 F# N* q1 q8 l
www_authenticate_uri = http://controller:5000
' F/ O1 p, Z/ A [" o( D9 cauth_url = http://controller:5000" m8 O* |) e" j d
memcached_servers = controller:11211
% @, e- C: d1 L; M7 ^! E5 D4 xauth_type = password+ Q# ]% @$ e% d( ]3 P% n; d
project_domain_name = default2 G, q" J3 F0 {" y; i
user_domain_name = default
$ C, a$ k9 o5 L4 n9 d t! R& aproject_name = service
8 e5 k8 l& P! y( Ousername = cinder
& u& ]1 f0 g' [9 ]) Y( g2 ^password = CINDER_PASS
, h4 j( z9 O3 D4 A' V4 I; z( {- @0 p4 A0 S4 ?' _/ g
[database]
- D: M Z4 ^) ], v, U; C6 sconnection = mysql+pymysql://cinder:CINDER_DBPASS@controller/cinder
& j0 @/ p/ ?% k9 S @, U5 C( q
4 Y; i5 l' A+ P' ?& q[lvm]+ v5 e- m" I9 _3 x5 _2 ^9 Z- `9 Z
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver8 ~6 r: g: P+ a3 E3 I
volume_group = cinder-volumes9 e, J' j! p% q
target_protocol = iscsi; T% F2 ^8 Y* [) B4 H, B
target_helper = lioadm& a+ ^2 E2 x' L2 _! H4 L- @# P* E
- u# {8 g: T* B3 P; I) W7 m( g[oslo_concurrency]
1 K8 k" |! p2 P) a+ Y+ qlock_path = /var/lib/cinder/tmp, @0 L9 V: Q) b! n9 f
配置cinder backup (可选)+ q$ X/ C5 _% {: d7 X. {# @
0 v& A8 o$ x. n4 o' X% @* P/ B! ecinder-backup是可选的备份服务,cinder同样支持很多种备份后端,本文使用swift存储,如果您想使用如NFS等后端,请自行配置,例如可以参考OpenStack官方文档对NFS的配置说明。$ c5 S! K6 h8 Y7 f! j+ S/ o" q! s# d
6 C$ E; q2 j. u修改/etc/cinder/cinder.conf,在[DEFAULT]中新增
% I" R+ I9 e' F9 s6 m z. |9 n9 K
4 z" C4 ?5 _) |+ H( v0 C* D/ S* s[DEFAULT]
) N2 X- X( {0 {backup_driver = cinder.backup.drivers.swift.SwiftBackupDriver
/ U- D; i/ x1 C6 ~* Y% e9 B, ibackup_swift_url = SWIFT_URL
6 {( o! `5 R3 K2 K, \这里的SWIFT_URL是指环境中swift服务的URL,在部署完swift服务后,执行openstack catalog show object-store命令获取。
# t9 O& h& u' j1 e, C6 s% ]. y
: g W: ?: ^3 L启动服务; q' f: d3 ~% @5 ?% @
& Y$ R8 K6 I$ V3 ^: wsystemctl start openstack-cinder-volume target+ P' o+ d: H9 |; y, y5 R
systemctl start openstack-cinder-backup (可选)
5 @. I k2 R* ^5 z1 }6 U至此,Cinder服务的部署已全部完成,可以在controller通过以下命令进行简单的验证
1 G9 A" f8 l7 `6 x z8 B
% Q/ C0 ]4 @$ F8 y8 z6 csource ~/.admin-openrc; J- S# z8 S% p" U) |+ x
openstack storage service list
! O) q* {* j" H# X+ b+ o9 Iopenstack volume list% e! T, [5 |) P& Q5 J& m* E
Horizon¶- q( i/ e- o3 ]. d1 s
Horizon是OpenStack提供的前端页面,可以让用户通过网页鼠标的操作来控制OpenStack集群,而不用繁琐的CLI命令行。Horizon一般部署在控制节点。
' L' B3 c8 Y1 O% } y; B1 E
! ^2 {% X$ }5 `& F ^安装软件包
1 s% ]; H4 | L* a& R& H% G- k" @* U! a2 w7 G
dnf install openstack-dashboard" h1 u; b7 X- Y! M
修改配置文件/etc/openstack-dashboard/local_settings ]" B0 g7 `% s- g) g
' r9 s7 ^1 G/ v9 }OPENSTACK_HOST = "controller"
% g2 F \6 g" JALLOWED_HOSTS = ['*', ]( }1 @) q8 K. g9 }6 E7 y
OPENSTACK_KEYSTONE_URL = "http://controller:5000/v3"* K" S" Z) x$ V' C4 t1 y
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' i6 O, L: e+ r R; n% n k
CACHES = {" r+ o$ ?0 i8 |
'default': {: D9 L% W* F; M; x7 d9 Y" W5 D6 D
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
( r- @3 a; ~0 Q( f 'LOCATION': 'controller:11211',
! e- b6 E9 t6 a& P8 b9 u }2 b! Q* Q9 L1 }/ Q( V k- F
}
8 f' s! b- i% b$ `6 B9 ^OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True
8 I4 x F% {: R# m! [* E+ U; ]) vOPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "Default"' e' F* A0 B1 J/ f, K5 ~3 t4 Y
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "member", Y8 Y4 Q3 y u6 Q- z) l: ~
WEBROOT = '/dashboard'; k D; l# o% o! o" Q! V
POLICY_FILES_PATH = "/etc/openstack-dashboard"
5 C% {8 W7 N/ `5 z; B" B6 ~, r, M. g
- M. y& ?# b4 Z2 _OPENSTACK_API_VERSIONS = {: D K9 E, u$ l K3 X! C/ }
"identity": 3,
# V6 J9 i" s1 M' o "image": 2,, r8 N4 J- f3 y$ s* P2 X
"volume": 3,% M. Q1 X6 C9 M0 M9 T
}
4 B- a' h- t/ E/ m. H( I5 }2 N0 K重启服务
( P1 ~3 |/ o3 l* q5 F1 u& s3 u3 x7 p! x7 G |, i( P
systemctl restart httpd6 k* ^" E0 T! d& Y) [
至此,horizon服务的部署已全部完成,打开浏览器,输入http://192.168.16.2/dashboard,打开horizon登录页面。! W: w/ g( j. [
; }0 T5 v( b7 }& ?7 q: m
|
|