0%

ssh连接空闲一段时间后出现:

1
packet_write_wait: Connection to UNKNOWN port 65535: Broken pipe

这是连接超时,需要设置一个保持心跳的参数,客户端是ServerAliveInterval,服务器端是ClientAliveInterval,参数值单位为second,还可以在.ssh/config中为每用户、每连接设置此参数

客户端:
/etc/ssh/ssh_config文件

1
2
Host *
ServerAliveInterval 45

References:
[1]How to prevent “Write Failed: broken pipe” on SSH connection?
[2]当SSH遇到“Write failed: Broken pipe”

tomcat9 on debian buster没有catalina.out日志文件,修改/usr/share/tomcat9/bin/catalina.sh文件,大约380多行处

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
elif [ "$1" = "run" ]; then

shift
#行添加开始
if [ -z "$CATALINA_OUT_CMD" ] ; then
touch "$CATALINA_OUT"
catalina_out_command=">> \"$CATALINA_OUT\" 2>&1"
else
catalina_out_command="| $CATALINA_OUT_CMD"
fi
#行添加结束
if [ "$1" = "-security" ] ; then
if [ $have_tty -eq 1 ]; then
echo "Using Security Manager"
fi
shift
eval exec "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
-classpath "\"$CLASSPATH\"" \
-Djava.security.manager \
-Djava.security.policy=="\"$CATALINA_BASE/policy/catalina.policy\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
#行尾添加$catalina_out_command
org.apache.catalina.startup.Bootstrap "$@" start $catalina_out_command
else
eval exec "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
-classpath "\"$CLASSPATH\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
#行尾添加$catalina_out_command
org.apache.catalina.startup.Bootstrap "$@" start $catalina_out_command
fi

最后重新启动tomcat9服务就可以。

ceph官方仓库尚未提供debian 10 buster版本的ceph nautilus,而debian官方仓库里也只有ceph 12版本,可以使用三方仓库在debian buster上安装ceph nautilus

proxmox仓库

1
2
3
$ echo 'deb \[arch=amd64\] http://download.proxmox.com/debian/ceph-nautilus buster main' sudo tee /etc/apt/sources.list.d/proxmox-ceph.list
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7BF2812E8A6E88E0
$ sudo apt update && sudo apt install ceph

croit.io仓库

1
2
3
$ curl https://mirror.croit.io/keys/release.asc sudo apt-key add -
$ echo 'deb https://mirror.croit.io/debian-nautilus/ buster main' sudo tee /etc/apt/sources.list.d/croit-ceph.list
$ sudo apt update && sudo apt install ceph

Updated(2020/02/01): 现在可以使用buster-backports仓库来安装ceph nautilus

ceph集群安装的第一步是monitor自举

一、monitor bootstrapping
1、添加配置文件/etc/ceph/ceph.conf
这里集群的名字使用默认的ceph,ceph.conf文件名中的基本名ceph也是集群名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
\[global\]
# 使用uuidgen生成,debian请安装uuid-runtime包
fsid = 0238426D-78D6-48CD-AF64-B6A8407996C6
# 使用主机名,可以用hostname -s命令获取
mon initial members = node8
# ip地址,支持messenger v1和v2
mon_host = 192.168.3.8
#mon_host = v2:192.168.3.8:3300/0,v1:192.168.3.8:6789/0
# public network可以指定逗号分割的多个子网
public network = 192.168.3.0/24
# 使用cephx认证
auth cluster required = cephx
auth service required = cephx
auth client required = cephx
osd journal size = 1024
# 副本策略,副本数量
osd pool default size = 3
# 降级状态最小副本数量,低于此数量会失败
osd pool default min size = 2
# 默认placement group数量
osd pool default pg num = 333
# 默认placement groups for placement数量
osd pool default pgp num = 333
osd crush chooseleaf type = 1

2、创建集群keyring,生成monitor密钥

1
$ ceph-authtool --create-keyring /tmp/ceph.mon.keyring --gen-key -n mon. --cap mon 'allow *'

3、创建管理keyring,生成client.admin用户并加入keyring

1
$ sudo ceph-authtool --create-keyring /etc/ceph/ceph.client.admin.keyring --gen-key -n client.admin --cap mon 'allow *' --cap osd 'allow *' --cap mds 'allow *' --cap mgr 'allow *'

4、创建bootstrap-osd keyring,生成client.bootstrap-osd用户并加入keyring

1
$ sudo ceph-authtool --create-keyring /var/lib/ceph/bootstrap-osd/ceph.keyring --gen-key -n client.bootstrap-osd --cap mon 'profile bootstrap-osd' --cap mgr 'allow r'

5、将生成的key添加到ceph.mon.keyring

1
2
$ sudo ceph-authtool /tmp/ceph.mon.keyring --import-keyring /etc/ceph/ceph.client.admin.keyring
$ sudo ceph-authtool /tmp/ceph.mon.keyring --import-keyring /var/lib/ceph/bootstrap-osd/ceph.keyring

6、生成monitor map

1
$ monmaptool --create --add node8 192.168.3.8 --fsid 0238426D-78D6-48CD-AF64-B6A8407996C6 /tmp/monmap

注意此处指定的节点名称、ip地址和fsid要与/etc/ceph/ceph.conf中指定的一致,ip地址还可以使用新的格式指定v2:192.168.3.8:3300/0,v1:192.168.3.8:6789/0

map文件是二进制格式的,可以这样查看生成的map内容

1
2
3
4
5
6
7
8
$ monmaptool --print /tmp/monmap
monmaptool: monmap file /tmp/monmap
epoch 0
fsid 0238426d-78d6-48cd-af64-b6a8407996c6
last_changed 2019-10-28 20:24:58.156493
created 2019-10-28 20:24:58.156493
min_mon_release 0 (unknown)
0: v1:192.168.3.8:6789/0 mon.node8

7、创建monitor数据目录

1
sudo -u ceph mkdir /var/lib/ceph/mon/ceph-node8

目录名字格式为{cluster-name}-{hostname}

8、修改ceph.mon.keyring访问权限

1
$ chmod o+r /tmp/ceph.mon.keyring

不然会因为ceph用户无法读取/tmp/ceph.mon.keyring而抛出如下错误:

1
2
2019-10-28 19:43:54.149 7eff2ff1f440 -1 mon.node8@-1(???) e0 unable to find a keyring file on /tmp/ceph.mon.keyring: (13) Permission denied
2019-10-28 19:43:54.149 7eff2ff1f440 -1 ceph-mon: error creating monfs: (2) No such file or directory

9、初始化monitor数据结构

1
sudo -u ceph ceph-mon --mkfs -i node8 --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring

10、启动ceph monitor

1
2
3
4
//$ sudo ln -sf /lib/systemd/system/ceph-mon@.service /etc/systemd/system/multi-user.target.wants/ceph-mon@node8.service
//$ sudo systemctl daemon-reload
$ sudo systemctl enable ceph-mon@node8.service
$ sudo systemctl start ceph-mon@node8.service

生成monitor实例自启动systemd服务文件并开启服务

11、查看集群状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ sudo ceph -s
cluster:
id: 0238426d-78d6-48cd-af64-b6a8407996c6
health: HEALTH_WARN
1 monitors have not enabled msgr2

services:
mon: 1 daemons, quorum node8 (age 12m)
mgr: no daemons active
osd: 0 osds: 0 up, 0 in

data:
pools: 0 pools, 0 pgs
objects: 0 objects, 0 B
usage: 0 B used, 0 B / 0 B avail
pgs:

12、启用messenger v2协议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ sudo ceph mon enable-msgr2
$ sudo ceph -s
cluster:
id: 0238426d-78d6-48cd-af64-b6a8407996c6
health: HEALTH_OK

services:
mon: 1 daemons, quorum node8 (age 67m)
mgr: no daemons active
osd: 0 osds: 0 up, 0 in

data:
pools: 0 pools, 0 pgs
objects: 0 objects, 0 B
usage: 0 B used, 0 B / 0 B avail
pgs:

集群健康状态成为HEALTH_OK
dump集群配置

1
2
3
4
5
6
7
8
$ sudo ceph mon dump
dumped monmap epoch 2
epoch 2
fsid 0238426d-78d6-48cd-af64-b6a8407996c6
last_changed 2019-10-28 20:15:02.687549
created 2019-10-28 19:51:04.486571
min_mon_release 14 (nautilus)
0: \[v2:192.168.3.8:3300/0,v1:192.168.3.8:6789/0\] mon.node8

二、添加其他monitor

一个monitor可以运行ceph集群,但是在生产环境推荐至少要运行三个monitor实例或以上,而且数量最好是奇数,这是因为容错时需要大多数实例达成一致的原因。monitor可以与OSD实例运行在一台物理机器上,但推荐是分开部署。

以下操作皆是在将要添加的monitor机器上执行

1、拷贝初始monitor配置文件

将集群第一个monitor的配置文件目录/etc/ceph整个拷贝到新monitor相同路径,注意保持文件属性不变。之后,新monitor节点虽然尚未初始化,但已经可以访问ceph集群。

2、创建目录

1
$ sudo -u ceph mkdir /var/lib/ceph/mon/ceph-node6

3、获取monitor keyring

1
2
$ sudo ceph auth get mon. -o /tmp/ceph.mon.keyring
exported keyring for mon.

注意检查/tmp/ceph.mon.keyring文件的访问权限,确保ceph用户可以读取。

4、获取集群monitor map

1
2
$ sudo ceph mon getmap -o /tmp/ceph.mon.map
got monmap epoch 2

5、初始化新monitor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ sudo -u ceph ceph-mon --mkfs -i node6 --monmap /tmp/ceph.mon.map --keyring /tmp/ceph.mon.keyring
$ sudo systemctl enable ceph-mon@node6.service
$ sudo systemctl start ceph-mon@node6.service
$ sudo ceph -s
cluster:
id: 0238426d-78d6-48cd-af64-b6a8407996c6
health: HEALTH_OK

services:
mon: 2 daemons, quorum node8,node6 (age 0.16939s)
mgr: no daemons active
osd: 0 osds: 0 up, 0 in

data:
pools: 0 pools, 0 pgs
objects: 0 objects, 0 B
usage: 0 B used, 0 B / 0 B avail
pgs:

可以看到集群已经有了两个monitor
查看集群monitor状态信息

1
2
$ sudo ceph mon stat
e3: 2 mons at {node6=\[v2:192.168.3.6:3300/0,v1:192.168.3.6:6789/0\],node8=\[v2:192.168.3.8:3300/0,v1:192.168.3.8:6789/0\]}, election epoch 26, leader 0 node8, quorum 0,1 node8,node6

添加其他新monitor重复以上步骤。

References:
[1]Ceph Docs
[2]Debian stable and Ceph are great
[3]MANUAL DEPLOYMENT
[4]ceph nautilus版本手动安装
[5]CEPH-MGR ADMINISTRATOR’S GUIDE
[6]NETWORK CONFIGURATION REFERENCE
[7]ADDING/REMOVING MONITORS

PostgreSQL 11 on Debian buster使用带有复制槽的流复制实现高可用只读热备库

主库端操作

1、主库参数配置
配置文件/etc/postgresql/11/main/postgresql.conf

1
2
3
4
# wal_level = replica #默认配置即可
# max_wal_senders = 10 #默认配置即可
wal_keep_segments = 100 #虽然使用复制槽,但仍然防御性设置此参数,防止建立备库的过程中需要的wal log被循环覆盖
# max_replication_slots = 10 # 默认配置即可

2、主库复制用户认证配置

使用超级用户postgres或者新建一个具有replication权限的用户作为备库连接到主库进行复制的用户
创建用于复制的用户repl_usr

1
2
postgres=# create role repl_usr with login replication password 'repl_passwd';
CREATE ROLE

修改/etc/postgresql/11/main/pg_hba.conf文件

1
host replication repl_usr 0.0.0.0/0 md5

postgres用户默认没有启用密码,只能本地peer方式访问,如果需要远程使用此用户,需要先启用密码访问。

3、创建复制槽
名字设定为repl_slot_1

1
2
3
4
5
6
7
8
9
10
postgres=# SELECT * FROM pg_create_physical_replication_slot('repl_slot_1');
slot_name lsn
-------------+-----
repl_slot_1
(1 row)
postgres=# SELECT slot_name, slot_type, active FROM pg_replication_slots;
slot_name slot_type active
-------------+-----------+--------
repl_slot_1 physical f
(1 row)

备库端操作

1、使用基础备份恢复数据库作为备库

a. 停止备库

1
$ sudo systemctl stop postgresql

b. 删除备库现有集群数据
将备库postgresql集群数据目录下的所有文件删除,删除debian默认安装postgresql集群数据:

1
# rm -rf /var/lib/postgresql/11/main/*

c. 恢复基础备份

1
$ sudo -u postgres tar zxvf baseback20191019.tgz -C /var/lib/postgresql/11/main/

一定要注意恢复的数据文件的属主是运行PostgreSQL服务的系统用户,debian系统上为postgres,还应该保持原来的权限。
这里使用的基础备份包含了备份完成时所有需要的WAL日志,所以可以不配置restore_command进行日志恢复,而且wal_keep_segments设置了较大的数值,基础备份之后生成的WAL日志可以通过流复制从master获取。

2、参数配置
配置文件/etc/postgresql/11/main/postgresql.conf

1
2
3
4
5
6
7
# hot_standby = on #默认配置
```
配置文件/var/lib/postgresql/11/main/recovery.conf
```js
standby_mode = 'on'
primary_conninfo = 'host=192.168.3.6 port=5432 user=repl_usr password=repl_passwd'
primary_slot_name = 'repl_slot_1'

3、启动备库

1
$ sudo systemctl start postgresql.service

检查复制状态

1、主库端
检查复制槽状态

1
2
3
4
5
postgres=# SELECT slot_name, slot_type, active FROM pg_replication_slots;
slot_name slot_type active
-------------+-----------+--------
repl_slot_1 physical t
(1 row)

可以看到复制槽repl_slot_1已经处于活动状态。

当前WAL日志的位置:

1
2
3
4
5
postgres=# select pg_current_wal_lsn();
pg_current_wal_lsn
--------------------
0/D000140
(1 row)

复制状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
postgres=# \\x
Expanded display is on.
postgres=# select * from pg_stat_replication;
-\[ RECORD 1 \]----+------------------------------
pid 1567
usesysid 16386
usename repl_usr
application_name walreceiver
client_addr 192.168.3.7
client_hostname
client_port 58492
backend_start 2019-10-20 17:36:05.768654+08
backend_xmin
state streaming
sent_lsn 0/D000140
write_lsn 0/D000140
flush_lsn 0/D000140
replay_lsn 0/D000140
write_lag
flush_lag
replay_lag
sync_priority 0
sync_state async

2、备库端
最后一个收到的WAL日志

1
2
3
4
5
postgres=# select pg_last_wal_receive_lsn();
pg_last_wal_receive_lsn
-------------------------
0/D000140
(1 row)

References:
[1]Chapter 26. High Availability, Load Balancing, and Replication
[2]26.5. Hot Standby
[3]Failover
[4]PostgreSQL Switchover vs. Failover
[5]PostgreSQL主备切换
[6]PostgreSQL 流复制的主备切换

主配置路径/etc/postgresql/11/main/postgresql.conf
连续归档备份主要涉及三个参数

参数配置

wal_level
默认值为replica,支持WAL归档,replication以及hot standby,所以此参数保持默认值即可。

archive_mode
归档模式,默认为off,关闭状态,还有两个选项值on和always。on表示打开归档模式,always表示在日志恢复和replication状态下,仍然会将恢复的日志继续进行归档,所以一般设置为on就可以了。

archive_command
归档命令,指定一个shell命令字符串来保存WAL文档,其中%p代表归档文件路径,%f代表归档文件的名字,不包含路径。归档命令返回0表示归档成功,非0表示归档失败,服务器会保留未归档的WAL日志文档,直到重新归档成功,或者服务器耗尽存储空间,进入panic关闭状态。
不要将WAL归档日志存储在本机,可以挂载NFS或其他远程文件系统来存储日志,也可以使用scp拷贝到远程服务器,总之archive_command十分灵活。
下面的命令写入挂载在本地/mnt/wals目录的远程NFS文件系统

1
2
3
4
5
6
7
8
9
10
archive_command='test ! -f /mnt/wals/%f && cp %p /mnt/wals/%f'
```

要注意archive_command是以运行postgresql数据库的postgres用户来执行的,要注意权限问题,所以/mnt/wals目录postgres用户要有写入权限。

wal_keep_segments
指定在pg_wal目录下保留的wal日志数量。如果replication使用log ship方式可以防止standby跟不上primary产生wal log的速度导致standby需要的日志被循环覆盖而失效。如果流复制replication时使用复制槽则不会存在这个问题,只要wal log没有被standby apply则primay永远不会删除这些wal log,此参数是没有影响的。还有就是pg_basebackup时如果同时备份需要的wal log则,需要设置此参数以防止需要备份的wal log被循环覆盖。
这是设置为100
```js
wal_keep_segments = 100

修改wal_level、archive_mode、wal_keep_segments需要重新启动postgresql才能生效。

查看归档设置是否生效:

1
2
3
4
5
6
7
8
9
10
11
12
$ sudo -u postgres psql
psql (11.5 (Debian 11.5-1+deb10u1))
Type "help" for help.

postgres=# select name, setting from pg_catalog.pg_settings where name like 'archive%' or name = 'wal_level';
name setting
-----------------+----------------------------------------------
archive_command test ! -f /mnt/wals/%f && cp %p /mnt/wals/%f
archive_mode on
archive_timeout 0
wal_level replica
(4 rows)

手动切换WAL日志测试归档是否成功:

1
2
3
4
5
6
7
8
9
10
11
postgres=# select pg_current_wal_lsn();
pg_current_wal_lsn
--------------------
0/1659450
(1 row)

postgres=# select pg_switch_wal();
pg_switch_wal
---------------
0/1659468
(1 row)

查看/mnt/wals目录下是否有了新归档的WAL日志文件

基础备份

开启归档后,应该立即进行一次基础备份,基础备份加上WAL日志可以完整的恢复整个数据库集群。
这里使用pg_basebackup在本地服务器进行基础备份,使用postgresql用户进行操作,要注意输出文件写入权限问题

1
$ sudo -u postgres sh -c 'pg_basebackup -l 20191019 -RPv -Ft -D - | gzip -c > baseback20191019.tgz'

出现错误提示:

1
2
pg_basebackup: cannot stream write-ahead logs in tar mode to stdout
Try "pg_basebackup --help" for more information.

这是因为pg_basebackup有一个参数-X --wal-method默认设置为s,但此方法与tar格式写入stdout不兼容,可见postgresql源代码

1
2
3
4
5
6
7
if (format == 't' && includewal == STREAM_WAL && strcmp(basedir, "-") == 0)
{
pg_log_error("cannot stream write-ahead logs in tar mode to stdout");
fprintf(stderr, _("Try \\"%s --help\\" for more information.\\n"),
progname);
exit(1);
}

-X --wal-method参数可以使pg_basebackup直接包含恢复需要的WAL日志文档,形成一个完整的直接用于恢复的备份,不需要再单独拷贝归档日志文件。但是要注意,wal_keep_segments参数要设置的大一些,防止在备份期间生成的归档日志被循环覆盖,这样基本备份会失败。每个WAL日志有16MB大小,wal_keep_segments设置数乘以16MB就是服务器保存这些wal log需要使用的额外存储空间。
当然-X --wal-method参数也可以设置为n,这样恢复时需手动管理自基础备份以来的生成的WAL日志。

在postgres用户的主目录/var/lib/postgresql或postgres可以写的其他目录下执行基础备份完整的命令:

1
2
3
4
5
6
7
sudo -u postgres sh -c 'pg_basebackup -l 20191019 -RPv -Ft --wal-method=f -D - | gzip -c > baseback20191019.tgz'
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/6000028 on timeline 1
40157/40157 kB (100%), 1/1 tablespace
pg_basebackup: write-ahead log end point: 0/60000F8
pg_basebackup: base backup completed

pg_basebackup备份时会生成一个.backup文件标识出保证此次备份完整性所需要的最后一个WAL日志,使用此次基础备份恢复系统时,不再需要之前的WAL日志。生成的备份文档内也有一个文件叫做backup_label,与此文件内容相同。
此文件的内容类似如下:

1
2
3
4
5
6
7
8
9
10
START WAL LOCATION: 0/6000028 (file 000000010000000000000006)
STOP WAL LOCATION: 0/60000F8 (file 000000010000000000000006)
CHECKPOINT LOCATION: 0/6000060
BACKUP METHOD: streamed
BACKUP FROM: master
START TIME: 2019-10-19 20:20:44 CST
LABEL: 20191019
START TIMELINE: 1
STOP TIME: 2019-10-19 20:20:45 CST
STOP TIMELINE: 1

也可以远程使用pg_basebackup制作基础备份,pg_basebackup使用复制协议,因此需要配置pg_hba.conf文件以允许replication连接

1
host replication all 192.168.0.0/24 

还需要设置postgresql.conf文件中的max_wal_senders参数以允许至少一个session连接来进行备份,postgresql 11默认设置为10,够用了。

References:
[1]25.3. Continuous Archiving and Point-in-Time Recovery (PITR)
[2]19.5. Write Ahead Log
[3]19.6. Replication
[4]pg_basebackup
[5]9.26. System Administration Functions

dmesg有提示:

1
ip_local_port_range: prefer different parity for start/end values

查询本地端口范围

1
2
$ cat /proc/sys/net/ipv4/ip_local_port_range
1024 65000

起始与结束端口都是偶数,打开/etc/sysctl.conf添加:

1
net.ipv4.ip_local_port_range = 1024 65535

开始端口与结束端口奇偶不同就可以了。

kvm上的debian虚拟客户机,升级操作系统到buster之后,重启内核启动缓慢:

1
2
3
\[ 3.126166\] ppdev: user-space parallel port driver
\[ 138.280959\] random: crng init done
\[ 138.280968\] random: 7 urandom warning(s) missed due to ratelimiting

随机数产生存在问题,以下方法解决

1
2
3
sudo apt-get install haveged
sudo systemctl enable haveged
sudo systemctl start haveged

References:
[1]Debian Testing takes a long time to load. Crng init done [closed]
[2]random: 7 urandom warning(s) missed due to ratelimiting

这里以lxd使用的zfs存储后端为例来扩展zpool

先看一下lxd默认存储池default的信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ lxc storage show default
config:
size: 10GB
source: /var/snap/lxd/common/lxd/disks/default.img
zfs.pool_name: default
description: ""
name: default
driver: zfs
used_by:
- /1.0/profiles/default
status: Created
locations:
- none

从zfs端看default zpool

1
2
3
$ zpool list default
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
default 9G 372K 9.00G - - 0% 0% 1.00x ONLINE -

只有10G大小,现在扩展到100G

停止所有正在运行的容器,使用truncate将存储文件尺寸增大90G:

1
$ sudo truncate -c -s +90G /var/snap/lxd/common/lxd/disks/default.img

查看zpool的自动扩展属性:

1
2
3
$ zpool get autoexpand default
NAME PROPERTY VALUE SOURCE
default autoexpand off default

是关闭的,将其打开

1
$ sudo zpool set autoexpand=on default

查看default存储池的设备名称

1
2
3
4
5
6
7
8
9
10
11
$ zpool status -vg default
pool: default
state: ONLINE
scan: none requested
config:

NAME STATE READ WRITE CKSUM
default ONLINE 0 0 0
15286821055422665849 ONLINE 0 0 0

errors: No known data errors

扩展default池到最大可用容量

1
$ sudo zpool online -e default 15286821055422665849

查看default池

1
2
3
$ zpool list default
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
default 99G 399K 99.0G - - 0% 0% 1.00x ONLINE -

可以看到容量已经扩展到了100G

关闭zpool的自动扩展

1
$ sudo zpool set autoexpand=off default

lxd端查看:

1
2
3
4
5
6
7
8
9
10
$ lxc storage info default
info:
description: ""
driver: zfs
name: default
space used: 340.99kB
total space: 102.98GB
used by:
profiles:
- default

lxd官方文档给的方案,参见[3]:

1
2
3
4
sudo truncate -s +5G /var/lib/lxd/disks/<POOL>.img
sudo zpool set autoexpand=on lxd
sudo zpool online -e lxd /var/lib/lxd/disks/<POOL>.img
sudo zpool set autoexpand=off lxd

References:
[1]How to resize ZFS used in LXD
[2]GROWING ZFS POOL
[3]Storage configuration