找回密码
 注册
查看: 3895|回复: 0

Openstack-Mitaka 高可用之 Pacemaker+corosync+pcs 高可用集群

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2018-10-19 16:05:14 | 显示全部楼层 |阅读模式
介绍及特点8 T+ Q9 l4 K) @0 ^' a
    Pacemaker:工作在资源分配层,提供资源管理器的功能
1 E% U# I/ u( Q5 C    Corosync:提供集群的信息层功能,传递心跳信息和集群事务信息, y; Y2 f: D( w, A9 s
    Pacemaker + Corosync 就可以实现高可用集群架构* A; H2 J% C+ m

' X# R4 r! ?* z! P: ^ 集群搭建* j6 r' [2 r. }3 {7 m7 d: E
以下三个节点都需要执行:% j5 a- t6 V& A$ @) i" w$ t$ X
; B7 h! A% S: p, |1 R/ Y
# yum install pcs -y
) A9 {* x' u& u7 `# systemctl start  pcsd ; systemctl enable pcsd
" J3 b' q3 c6 r# g# echo 'hacluster' | passwd --stdin hacluster- P' n' o: e6 P/ N5 z- ]1 U
# yum install haproxy  rsyslog -y3 K2 S" T! |& e1 e* w6 ]
# echo 'net.ipv4.ip_nonlocal_bind = 1' >> /etc/sysctl.conf        # 启动服务的时候,允许忽视VIP的存在
) \/ o( t# b+ o' i# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf        # 开启内核转发功能
, {. g# _. l2 g5 O9 L: [# sysctl -p
  H: W/ q" @/ D0 L% x: S* I3 o
& I8 i# r# g/ M' M在任意节点创建用于haproxy监控Mariadb的用户- c, q- q& i1 a: u6 x
MariaDB [(none)]> CREATE USER 'haproxy'@'%' ;& u9 g7 j; r6 M
配置haproxy用于负载均衡器
" ?* }& U( C0 G! _6 Y
: L5 L. d2 l: }[root@controller1 ~]# egrep -v "^#|^$" /etc/haproxy/haproxy.cfg$ g# x0 P8 `1 s6 q7 f
    log         127.0.0.1 local2- U; n! y, f- B5 ?2 \
    chroot      /var/lib/haproxy# b* w0 j( L* w" m& [
    pidfile     /var/run/haproxy.pid
; l/ d' d& R: \    maxconn     4000' _2 c2 _7 T9 l
    user        haproxy
! p4 L( q1 j- j! N" M- P    group       haproxy
$ p+ A1 t4 A/ I! Q+ E" F, P    daemon
: u! W0 n" [8 o( \. X    # turn on stats unix socket
- ]+ D& D$ c/ _! u6 V  ~& R    stats socket /var/lib/haproxy/stats6 C' @! y: x/ O2 l4 i8 D0 _4 u6 B
defaults
+ {3 [2 R1 A! p1 U1 r    mode                    http4 g! ^2 `# ]8 j. F$ {1 O
    log                     global* h1 [- L3 b8 p7 b% j  C
    option                  httplog1 y( h5 g( F4 b3 q
    option                  dontlognull! t9 ]3 T6 T% I% K, {. O  A2 ?
    option http-server-close8 S2 h# Q, b4 o5 b1 @; ~& m* Q
    option forwardfor       except 127.0.0.0/8
6 z) W# ^( ]& T1 A) u8 M    option                  redispatch
' g& q) Q8 d: q    retries                 3
/ ~9 z( B7 F1 b0 y; k, ~2 f    timeout http-request    10s. H' U9 s' x! S% a: Y/ R# V. ?9 Q" L  n' X
    timeout queue           1m
5 T5 v; r' P3 Y3 N, m$ G( Y    timeout connect         10s" m% m! E# s0 U- u: A. J6 Q
    timeout client          1m4 f0 c. w- `2 ]6 ~5 e8 ?4 f
    timeout server          1m
, n# q, u8 o" e6 W  M1 h/ g    timeout http-keep-alive 10s
) H, G8 y' t' b4 _# }6 G" S" G) Z    timeout check           10s% ~8 v% h1 _0 L% g) J
    maxconn                 4000- }! z) l2 b3 q, I
listen galera_cluster( @& j' Q  U% ^2 |& S5 }3 O
    mode tcp            , n& V8 u$ H! E: H. r+ i
    bind 192.168.0.10:33069 o3 w& M# P8 o9 k- R
    balance source
3 E- ]( Q9 l6 q# L7 N5 O; k2 m    option mysql-check user haproxy
2 Q* j8 S) T9 y5 o! i    server controller1 192.168.0.11:3306 check inter 2000 rise 3 fall 3 backup
6 t4 p1 Y: f( z% L    server controller2 192.168.0.12:3306 check inter 2000 rise 3 fall 3 9 c' k# f& d# h% j: w
    server controller3 192.168.0.13:3306 check inter 2000 rise 3 fall 3 backup
; q) d2 e' `+ C. \8 P- p0 J, a% q- |
listen memcache_cluster
! R0 B, C0 c' H3 V    mode tcp
+ i2 |% t2 f, ~& n0 t8 f9 K    bind 192.168.0.10:11211
6 G8 a+ ]% |3 N  ^3 J. b& h8 x6 n1 Y    balance source- h3 g0 J% u' G2 x4 k' p) Q/ j
    option tcplog3 [/ }5 h2 W) O
    server controller1 192.168.0.11:11211 check inter 2000 rise 3 fall 3 ' Q' Y* X# p# J
    server controller2 192.168.0.12:11211 check inter 2000 rise 3 fall 33 x# V- H9 e" b
    server controller3 192.168.0.13:11211 check inter 2000 rise 3 fall 3, n* {: M7 h3 A( q
3 g6 [( V1 `' B# ~
) i3 g) d, e- j! n2 R. Y
注意:
0 w/ S1 d2 Q! v% _" u  ?* @    (1)确保haproxy配置无误,建议首先修改ip和端口启动测试是否成功。: y: B5 L2 [2 `3 a
    (2)Mariadb-Galera和rabbitmq默认监听到 0.0.0.0 修改调整监听到本地 192.168.0.x
0 c/ j! d# C# ]' h( w    (3)将haproxy正确的配置拷贝到其他节点,无需手动启动haproxy服务9 B0 e7 a4 D" w9 j
为haproxy配置日志(所有controller节点执行):
4 B  ?6 O+ ]. g) }7 \/ z: P
% \  `8 O5 \9 G: H, ~- Y  v! k# vim /etc/rsyslog.conf+ w: v, N* W9 B# w

: p$ Q7 M, _- M; Z0 ~6 Z' X$ModLoad imudp! u& n$ i- l$ n+ p% S( ?# X% w8 A
$UDPServerRun 514
' f% F5 x5 C( B' S7 [  Q  M, j  f7 m* P& J1 z
local2.*                                                /var/log/haproxy/haproxy.log
" p: c+ w$ @% Z% n( a! p. F; g8 }: K' h) {
7 O0 l+ }) B+ v6 Y
# mkdir -pv /var/log/haproxy/
9 J" R' \8 j% smkdir: created directory ‘/var/log/haproxy/’
5 h# I0 n. W3 x% X! d! F4 K- I) E4 n' N/ ~
# systemctl restart rsyslog
  q& Y/ l1 @/ g( {( k7 c$ E# H- L3 s5 a5 P+ \; _1 E& R+ a
启动haproxy进行验证操作:/ |4 a1 c* u2 I9 m
( ~' ?% D6 p, Z0 x' b% a1 r% K( R
# systemctl start haproxy
; Q# D5 _; c! x* y* @+ T9 d[root@controller1 ~]# netstat -ntplu | grep ha6 e: L) {6 c" d: X
tcp        0      0 192.168.0.10:3306       0.0.0.0:*               LISTEN      15467/haproxy      
" S  I% Y1 M, ?& Stcp        0      0 192.168.0.10:11211      0.0.0.0:*               LISTEN      15467/haproxy      
2 t7 F' d. m% a. hudp        0      0 0.0.0.0:43268           0.0.0.0:*                           15466/haproxy
2 J0 o+ u! g5 m
# u# T8 r+ J7 A" S验证成功,关闭haproxy
5 s( D7 m* T1 S7 d, z, H# systemctl stop haproxy
7 t8 w/ H+ u  v
/ X" v$ |# V* T0 M. P' t' n 6 Y# `& ]8 T# \8 D( A
在controller1节点上执行:  u/ y( }" Q; i( Q# A/ S- v% Z1 d
[root@controller1 ~]# pcs cluster auth controller1 controller2 controller3 -u hacluster -p hacluster --force
, x0 h% _$ t) m2 Ccontroller3: Authorized
0 V2 x6 u- N4 o4 Z! acontroller2: Authorized) I. ^6 u" g6 ]
controller1: Authorized
5 y# L4 D3 ?5 e" G创建集群:
1 s9 k% c, w4 C5 Z6 B4 U
$ n( G: K, {9 E, f; g[root@controller1 ~]# pcs cluster setup --name openstack-cluster controller1 controller2 controller3  --force' j( f6 A+ ?( `  [& z
Destroying cluster on nodes: controller1, controller2, controller3...
9 G' n- T8 P1 _7 {0 F: ]3 Dcontroller3: Stopping Cluster (pacemaker)...
, Y! m  t" L% r! H9 O! P2 `controller2: Stopping Cluster (pacemaker)...
4 P6 {2 z4 X8 W: l3 n& E" ^controller1: Stopping Cluster (pacemaker)...
, Y0 d' i" S, s) C8 Gcontroller3: Successfully destroyed cluster+ N3 V2 p$ d2 I; ^( F1 O7 ?
controller1: Successfully destroyed cluster
$ p  J9 b6 }0 c7 ^% e5 tcontroller2: Successfully destroyed cluster
- K4 {* ]) q6 }% q" |9 e
% V" m; m  s& X: Q5 zSending 'pacemaker_remote authkey' to 'controller1', 'controller2', 'controller3'. Q- U8 l8 B, ~6 V, {8 B( Z2 W& c
controller3: successful distribution of the file 'pacemaker_remote authkey'4 J) d: E9 T& n0 U4 d3 Q
controller1: successful distribution of the file 'pacemaker_remote authkey'8 K: t" Z& G! s$ i8 t: E
controller2: successful distribution of the file 'pacemaker_remote authkey'1 |! @$ H, C5 t8 M/ F; C
Sending cluster config files to the nodes...
6 l2 x/ D5 [% l" j# Xcontroller1: Succeeded
* ^1 }  p" K( w) D7 _) Gcontroller2: Succeeded
0 c8 ~0 M8 z4 C% \/ V+ Zcontroller3: Succeeded
3 {( @0 W/ v4 U; s0 a! Y; a' e8 G  q" T
Synchronizing pcsd certificates on nodes controller1, controller2, controller3...' O* r' n" i  `5 P
controller3: Success, ?6 X, H7 N$ s0 h; j1 n; c" i8 P
controller2: Success
4 I2 O* c& I7 g! B% k" Hcontroller1: Success
- f' V# p" @8 P0 r  VRestarting pcsd on the nodes in order to reload the certificates...
5 E4 m+ [8 V/ ?# I: Y2 [8 ?& a4 Scontroller3: Success! K7 A( g1 x5 o; z% m
controller2: Success% T! I' t% i) i. Y1 j6 u' X
controller1: Success
/ K4 @) A' d- {; I* A" Y! X% j, ?; P; P
启动集群的所有节点:
7 G( s( c! |7 i$ q: w. W& o8 p& W3 m6 j5 o2 j) }6 i
[root@controller1 ~]# pcs cluster start --all
" R* B& m+ D" G5 Bcontroller2: Starting Cluster...1 y6 {) ?  L6 X6 u7 G* k
controller1: Starting Cluster...% l1 U2 S- b! Q* ]% F0 t
controller3: Starting Cluster...
1 C0 E4 V$ v: _7 Z[root@controller1 ~]# pcs cluster enable --all' t# c; g2 ~- m. ^* U( i
controller1: Cluster Enabled
* `! `- }: Z! A4 ?$ ^' u7 y/ pcontroller2: Cluster Enabled
+ R4 {- u$ T2 C9 c& X: ~controller3: Cluster Enabled
- y+ o9 t% x* r! d
& K. u6 d1 B' H4 u查看集群信息:
. f: Z' f: P- k" F
8 ]" t8 L# `; l7 B" A% @# M$ p[root@controller1 ~]# pcs status
! v& A" `- H/ S. M( `Cluster name: openstack-cluster
5 x1 k' `& T  r6 EWARNING: no stonith devices and stonith-enabled is not false4 Q, x6 K- I3 |3 [
Stack: corosync
* B9 s# S8 {' YCurrent DC: controller3 (version 1.1.16-12.el7_4.4-94ff4df) - partition with quorum
# ?7 r4 H9 q8 H7 w/ P6 B( {Last updated: Thu Nov 30 19:30:43 20173 M" Z* z$ ?8 m! h: ?! B' r
Last change: Thu Nov 30 19:30:17 2017 by hacluster via crmd on controller3
6 x5 e* _+ T9 k
( L* A, z$ E& ~/ P5 y: y3 nodes configured
. h/ D# M: W$ F# P0 resources configured
9 z9 I7 r. l( y
) j2 B# g: U2 t+ e  x( y: qOnline: [ controller1 controller2 controller3 ]
5 w8 f4 s# W) K. w& [9 n6 D5 B) N! z' {& T! F
No resources
3 O; O" N6 G- U( i3 s/ H0 }  m' w1 X

+ \4 w+ R# U! VDaemon Status:, ]# i3 R0 M/ o, h3 j
  corosync: active/enabled9 u/ F& {  J' l6 O
  pacemaker: active/enabled2 M" P- b3 o. n# U; g4 U& b0 E
  pcsd: active/enabled7 A1 X1 V9 S; j0 f" a( F! u) y3 P
[root@controller1 ~]# pcs cluster status
& q9 e6 U1 m. M# |. CCluster Status:
- d7 }. j4 ?! ~3 N Stack: corosync
0 l+ A* b/ s5 g/ ^" G% h Current DC: controller3 (version 1.1.16-12.el7_4.4-94ff4df) - partition with quorum
: @* _( P- ]" X4 m Last updated: Thu Nov 30 19:30:52 20179 H% B5 y. M3 `8 N* H, z  s
Last change: Thu Nov 30 19:30:17 2017 by hacluster via crmd on controller3  ?  O1 X, N' Z+ t5 h7 c$ t" y$ S
3 nodes configured
$ b0 V$ f, e8 W" G4 A; z: ?$ j 0 resources configured
3 [0 H* M1 P# K+ t+ W" H
$ z) r" h$ Z4 \: v  C  m' y2 _PCSD Status:
  l, x; C% c7 t$ a: O  controller2: Online$ T# e2 P/ j7 I9 {8 q2 b
  controller3: Online% \0 `6 m1 S! h' l2 Z4 \
  controller1: Online
' N- l- R6 b" N6 S/ b7 n5 N$ U4 W  j% [& ?7 h% c
三个节点都在线
7 g+ i9 ?1 m' Y默认的表决规则建议集群中的节点个数为奇数且不低于3。当集群只有2个节点,其中1个节点崩坏,由于不符合默认的表决规则, 集群资源不发生转移,集群整体仍不可用。no-quorum-policy="ignore"可以解决此双节点的问题,但不要用于生产环境。换句话说,生 产环境还是至少要3节点。
# J2 {  Y: W9 W3 cpe-warn-series-max、pe-input-series-max、pe-error-series-max代表日志深度。, J/ y* v7 V9 Z: |  b' p$ v
cluster-recheck-interval是节点重新检查的频率。! A1 e- w9 k* W% z, V: U3 D% b' M
[root@controller1 ~]#  pcs property set pe-warn-series-max=1000 pe-input-series-max=1000 pe-error-series-max=1000 cluster-recheck-interval=5min
+ D9 @7 p! Y- Z( ?5 ^4 Z1 C8 L: p4 H禁用stonith:0 O. _$ [# {4 J8 C8 S: @
stonith是一种能够接受指令断电的物理设备,环境无此设备,如果不关闭该选项,执行pcs命令总是含其报错信息。+ t5 _- h# V( l( ?* d# l
[root@controller1 ~]# pcs property set stonith-enabled=false. _" S1 }% W) G0 p; V
二个节点时,忽略节点quorum功能:
& W2 \  a( T  Q' X5 ]# _[root@controller1 ~]# pcs property set no-quorum-policy=ignore
9 g- Z  u! x$ r- z验证集群配置信息4 @. m4 O. x: U. r2 o, d
[root@controller1 ~]# crm_verify -L -V1 n: c' u; b. _& y" t5 j2 X
为集群配置虚拟 ip
5 l8 r8 t; x: f6 g( l6 }[root@controller1 ~]# pcs resource create ClusterIP ocf:heartbeat:IPaddr2 \
& p. Q( n. k) j. Y ip="192.168.0.10" cidr_netmask=32 nic=eno16777736 op monitor interval=30s
; f5 Z5 _9 y# o0 W% y1 g9 ]- b到此,Pacemaker+corosync 是为 haproxy服务的,添加haproxy资源到pacemaker集群
( _( A( s2 Y' U, S5 E. }/ _- u3 F( F[root@controller1 ~]# pcs resource create lb-haproxy systemd:haproxy --clone
- ?: C2 U; ?. G: }说明:创建克隆资源,克隆的资源会在全部节点启动。这里haproxy会在三个节点自动启动。
: }) c- I; ^1 \8 U5 o* Q+ i/ F& c查看Pacemaker资源情况
# D2 t3 r& |8 e8 R+ W- l4 b[root@controller1 ~]# pcs resource % A( X: S8 R; c2 x7 o
ClusterIP    (ocf::heartbeat:IPaddr2):    Started controller1        # 心跳的资源绑定在第三个节点的- ~" \- R6 i# ?- E/ q1 y3 `
Clone Set: lb-haproxy-clone [lb-haproxy]        # haproxy克隆资源! }; q% `2 h; S
     Started: [ controller1 controller2 controller3 ], o! ]" i; o9 [* E( ^
注意:这里一定要进行资源绑定,否则每个节点都会启动haproxy,造成访问混乱
/ p2 R2 _% y, r, i8 p' f2 c将这两个资源绑定到同一个节点上, x  n% _: Y. h* g: N3 d6 V4 s
[root@controller1 ~]# pcs constraint colocation add lb-haproxy-clone ClusterIP INFINITY
+ E/ w) R, c& _! v绑定成功
) y) ]# O' Z4 H3 Q# I( S# A[root@controller1 ~]# pcs resource
. [+ j% l' [: p ClusterIP    (ocf::heartbeat:IPaddr2):    Started controller3' |/ I9 s  r9 T/ H2 R$ `2 D
Clone Set: lb-haproxy-clone [lb-haproxy]
8 U+ f) [' l3 Y: o" ^0 x# b5 |& E     Started: [ controller1]
" ?( A) W+ N  e# U6 r* W! q3 v     Stopped: [ controller2 controller3 ]( [! n# v2 i6 s5 k7 P
配置资源的启动顺序,先启动vip,然后haproxy再启动,因为haproxy是监听到vip
* V- R' \  H! G[root@controller1 ~]# pcs constraint order ClusterIP then lb-haproxy-clone
" W4 c% U. f1 }- Z  S0 B4 p% w手动指定资源到某个默认节点,因为两个资源绑定关系,移动一个资源,另一个资源自动转移。* j' a4 A) A- N$ l

; z6 s1 q8 ?/ [  [[root@controller1 ~]# pcs constraint location ClusterIP prefers controller1* @0 x0 g0 I# t; P& q' K
[root@controller1 ~]# pcs resource
7 X3 v' ?, Z8 ?+ X ClusterIP    (ocf::heartbeat:IPaddr2):    Started controller1, q; I; S9 i3 }2 d7 d
Clone Set: lb-haproxy-clone [lb-haproxy]
$ c) a& E0 m9 @3 R7 @5 d     Started: [ controller1 ]
+ [$ M! `0 F. K" }* h: t; T     Stopped: [ controller2 controller3 ]
2 Q# ^# f' d% d; }  q: C( |" D+ U1 N( L[root@controller1 ~]# pcs resource defaults resource-stickiness=100        # 设置资源粘性,防止自动切回造成集群不稳定
! s  Q* B& k+ |* l现在vip已经绑定到controller1节点  j$ m1 |  Z" y: H  o
[root@controller1 ~]# ip a | grep global
+ Y& d/ D8 n9 S' {8 u% `    inet 192.168.0.11/24 brd 192.168.0.255 scope global eno16777736* u/ ^1 j0 T+ V. q: ?4 a8 d
    inet 192.168.0.10/32 brd 192.168.0.255 scope global eno167777360 {8 ^5 O0 |% x3 d
    inet 192.168.118.11/24 brd 192.168.118.255 scope global eno33554992- h' ]: r& ]0 z1 C

! G, o7 K0 C  V尝试通过vip连接数据库
+ ]7 G" u1 d0 S" e2 G, cController1:
% C0 Y5 \# n. \6 }: V7 n+ P+ ]5 O
9 P* x" n2 V$ x3 n[root@controller1 haproxy]# mysql -ugalera -pgalera -h 192.168.0.10
% Q" I( Z7 s' T% l6 U) g& V  B6 D$ c" }) [  g6 H: ~- n
" q0 l4 v0 B' S* m
Controller2:6 s3 N6 T& }; z' d, k# H# S
. F: A& D# O$ R4 s, I
 
* i. G8 K6 @' b高可用配置成功。  T& J  R7 y& A' k! a5 a$ W( o

/ {& \& F& J9 u/ E  i( Q+ j测试高可用是否正常2 D# t0 O! X* p9 \! c" E) D/ o2 o' ^
在controller1节点上直接执行 poweroff -f$ C) V- `( I& r" v) ?- s1 E2 C
[root@controller1 ~]# poweroff -f! t7 m+ P. x# w, C" l
vip很快就转移到controller2节点上3 r- O4 K5 q  I3 R0 K

! Y+ b3 c' D" q- w再次尝试访问数据库
: W: ]4 }5 A; R% o; H% o; O3 z
( ^) ]( P! y- w% G& x
: Z& Q( ?# M4 ?1 s1 k( U( I 无任何问题,测试成功。
" D. R( d* J3 A; |- I! }查看集群信息:
! k; c( T2 q4 ?0 J$ X
1 Y# U+ B& j# w$ r8 I[root@controller2 ~]# pcs status " ^2 a/ N% B1 s  x0 B
Cluster name: openstack-cluster
* h6 W( L) Q2 s3 s& {+ y  JStack: corosync% v" x, X, H; z0 D. L
Current DC: controller3 (version 1.1.16-12.el7_4.4-94ff4df) - partition with quorum& j5 q# n& z$ h6 Z" T
Last updated: Thu Nov 30 23:57:28 2017  H1 P2 K+ J% d) w) W
Last change: Thu Nov 30 23:54:11 2017 by root via crm_attribute on controller1& Q1 v" C9 K; a8 Z* n' d5 M6 o

1 }& O8 c9 R9 O$ D0 e2 o" C3 nodes configured
! W6 L: z, o* @% V" R4 resources configured
* \/ C7 h* ]# a2 U. J
" r7 L+ m+ ]5 |  WOnline: [ controller2 controller3 ]6 \3 s& }3 `% E0 t8 K
OFFLINE: [ controller1 ]            # controller1 已经下线1 V# P- T, j9 T( e1 g
5 [: M0 T% a+ Q6 u% l! l
Full list of resources:7 K1 j6 q  T7 |5 G1 ^7 I5 z( d- t
0 F8 ?& o) ]0 [* k9 \: X
ClusterIP    (ocf::heartbeat:IPaddr2):    Started controller2+ E  d% g: M/ @# K- ^! e3 b' w
Clone Set: lb-haproxy-clone [lb-haproxy]
: H, `, [( z* Q. A7 g2 y" e     Started: [ controller2 ]2 |, ~3 z) r& K9 r( y
     Stopped: [ controller1 controller3 ]1 g: p# Q  ?0 W& f" M7 ]  E/ G2 [
: r, N. P5 e; ?% k+ a& z! B$ Q
Daemon Status:
& Y4 G: b5 V9 o  |1 N" V1 m7 S  corosync: active/enabled1 |4 u" u! E% F. g0 N# B4 w
  pacemaker: active/enabled
+ J8 ?7 f4 ^; k( A( R2 u  pcsd: active/enabled
您需要登录后才可以回帖 登录 | 注册

本版积分规则

返回首页|Archiver|手机版|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )

GMT+8, 2026-6-12 02:47 , Processed in 0.020035 second(s), 22 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表