Linux 在运行的过程中会产生很多日志文件,一般存放在 /var/log
目录下,而其中 journal
目录中存放的是 journald
daemon 程序生成的日志,其中包括了所有 kernel, initrd, services 等等产生的日志。这些日志在系统发生状况排查问题的时候非常有用。
jounrnald
daemon 程序会收集系统运行的日志并存储到二进制文件中。为了查看这些二进制文件通常会使用到 journalctl
命令。但是默认情况下这些日志文件会占用磁盘空间的 10%,而大部分情况下这些日志文件是不需要查看的。所以可以配置减小一些 journal 日志的占用。
默认的日志文件保存在 /var/log/journal
下,可以使用 du
查看。不过我个人推荐使用可视化的 gdu
来 查看 。
du -sh /var/log/journal
查看占用磁盘空间可以使用 journalctl
命令查看日志占用:
sudo journalctl --disk-usage
如果要去清理 journal 日志,可以先执行 rotate
命令:
journalctl --rotate && \
systemctl restart systemd-journald
删除两天前的日志:
journalctl --vacuum-time=2days
删除两个礼拜前的日志:
journalctl --vacuum-time=2weeks
或者删除超出文件大小的日志:
journalctl --vacuum-size=20M
journalctl --disk-usage
# OR
du -sh /run/log/journal
journalctl --verify
ls -l /run/log/journal/*
systemctl status systemd-journald
修改配置文件:
sudo vi /etc/systemd/journald.conf
修改其中的两项:
SystemMaxUse=100M
RuntimeMaxUse=100M
SystemMaxUse 设置 /var/log/journal
RuntimeMaxUse 设置 /run/log/journal
然后使设置生效:
sudo systemctl daemon-reload
问题
Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.
原因是:
the disk usage of the log files for journald
journal 日志空间达到了上限
数据是最重要的,本着系统可以挂,但是数据不能丢的原则,这里就整理一下在 Proxmox VE 系统中,直接备份虚拟机,和恢复虚拟机的过程。
设置 Storage,允许保存 VZDump backup 文件:
在执行备份之前,需要通过上面的设置设定一个允许备份的 Storage,然后之后的备份文件会存放到该 Storage 中。备份文件以文件形式存储。在大部分的情况下,可以使用 NFS 服务器作为存储备份。
Proxmox VE 备份服务提供了三种不同的备份模式,在备份菜单中可以看到:
对于备份的文件,Proxmox VE 提供了多种压缩算法,lzo, gzip, zstd。
目前来说,Zstandard(zstd) 是三种算法中最快的,多线程也是 zstd 优于 lzo 和 gzip 的地方。但 lzo 和 gzip 通常来说更加常用。可以安装 pigz 来无缝替换 gzip 以提供更好的性能。
使用了不同的压缩算法的备份文件的扩展名如下:
file extension | algorithms |
---|---|
.zst | Zstandard(zstd) compression |
.gz or .tgz | gzip compression |
.lzo | .zo compression |
备份可以通过 GUI 或者 命令行工具来进行。
首先关闭虚拟机
通过命令行备份:
cd /var/lib/vz/dump
vzdump 101
说明:
/var/lib/vz/dump
目录中备份 101 号虚拟机通过 UI 界面备份数据:
在备份虚拟机时有些时候不想要备份虚拟机中的特定目录,比如说缓存目录,这样可以加快备份的速度,以及减小备份文件的体积。
在 Datacenter -> Backup 中建立备份任务之后,会在系统中新建一个 cron,在 /etc/pve/vzdump.cron
文件中:
PATH="/usr/sbin:/usr/bin:/sbin:/bin"
15 2 * * 6 root vzdump 100 101 102 --mailnotification always --compress zstd --mode snapshot --quiet 1 --storage local --exclude-path /mnt/ --exclude-path '/dev/disk/by-id/ata-HGST*'
可以看到,实际使用了 vzdump
命令,直接在后面添加 --exclude-path
并加上不需要备份的目录即可。
更多的用法可以参考 vzdump
命令的使用。
配置了备份之后查看日志可以看到:
INFO: Backup started at 2021-10-23 16:59:05
INFO: status = running
INFO: VM Name: ubuntu20.04
INFO: include disk 'scsi0' 'local:101/vm-101-disk-0.qcow2' 64G
INFO: include disk 'scsi1' '/dev/disk/by-id/ata-HGST_HUS726020ALA610_K5HWJ6NG' 1953514584K
INFO: include disk 'scsi2' '/dev/disk/by-id/ata-HGST_HUS726020ALA610_K5J0ZUWA' 1953514584K
INFO: include disk 'scsi3' '/dev/disk/by-id/ata-HGST_HUS726020ALA610_K5HW9RJG' 1953514584K
INFO: backup mode: snapshot
INFO: ionice priority: 7
INFO: creating vzdump archive '/var/lib/vz/dump/vzdump-qemu-101-2021_10_23-16_59_05.vma.zst'
我的虚拟机挂载了三块硬盘,而备份的时候会包括这三块 2T 的硬盘,这是没有必要的,可以通过如下的方法跳过备份挂载而硬盘。
在虚拟机的设置中,点击 Hard Disk,在 Advance 高级选项中可以将 Backup 取消选中,然后保存,在备份的时候就不会保存该设备了。
随着虚拟机备份文件的增多,可以占用的本地文件会越来越多,所以定时清理必不可少。
在 Datacenter -> Storage 在备份的 Storage 中双击进行设置,在 Backup Retention 中可以去掉勾选 Keep all backups
然后进行设置。
crontab -e
然后编辑:
10 2 * * * find /var/lib/vz/dump/ -mtime +14 -delete
我们使用 qmrestore
命令从备份中还原 KVM VM 101。
pct restore 600 /mnt/backup/vzdump-lxc-777.tar
qmrestore vzdump-qemu-019-2018_10_14-15_13_31.vma 101
要从GUI还原VM,请执行以下步骤。
之前简单的了解过一下 Ansible,但没怎么具体使用起来,这两天因为要管理的机器多了起来,所以又把 Ansible 学了起来。这篇文章就主要了解一下 Ansible Roles 的使用。
之前的文章简单的知道在 Ansible 中可以使用 playbook 来组织一系列的任务。但如果要复用这些任务,并且更加模块化的花,那就离不开 Ansible Roles。
之前的文章中也说过可以使用 playbook 来管理一系列的任务,但随着使用 playbook 就不可以免的膨胀,可能会出现上百行的 playbook,那为了复用和结构化地组织 playbook, Ansible 在 1.2 版本引入了 Roles 的概念。
Ansible 中的 Roles 是 Ansible 的另一个重要的概念,通过 Roles 可以通过文件结构自动加载相关的 vars, files, tasks, handlers, 或者其他 Ansible 组件。这样说可能比较抽象,可以理解成通过在文件系统上的文件分类,可以自动让 Ansible Roles 去加载相关的内容。一旦通过 Roles 组织了内容就可以非常简单地复用和分享给其他人。
Ansible Role 定义了一个目录结构,包括了8大类标准的结构,一个 Role 必须包含至少其中一个文件夹,其他没有使用的文件夹可以省略:
# playbooks
site.yml
webservers.yml
fooservers.yml
roles/
common/
tasks/
handlers/
library/
files/
templates/
vars/
defaults/
meta/
webservers/
tasks/
defaults/
meta/
默认情况下 Ansible 会自动寻找每一个目录下的 main.yml
文件(main.yaml
或者 main
)。
tasks/main.yml
,role 需要执行的主要任务handlers/main.yml
,可能会被使用的 handlers,可以由该 role 使用,也可以被 role 之外的其他任务使用library/my_module.py
modulesdefaults/main.yml
默认变量vars/main.yml
role 的其他变量files/main.yml
files that the role deploys,role 需要使用的文件templates/main.yml
templates that the role deploysmeta/main.yml
metadata,角色依赖默认情况下 Ansible 会在下面两个位置寻找 Roles:
roles
中/etc/ansible/roles
中也可以通过 roles_path 的方式指定 Role 的位置。更多可以参考 Configuring Ansible。
在 ansible.cfg
中定义:
roles_path = /etc/ansible/roles:/usr/share/ansible/roles
或者也可以直接指定具体的 path:
---
- hosts: webservers
roles:
- role: '/path/to/my/roles/common'
可以通过三种方式使用 Roles:
roles
选项,最常用的方式include_role
,可以动态使用import_role
,静态使用在 playbook 中,可以这样使用role:
- hosts: webserver
roles:
- common
- webserver
可以传递参数:
---
- hosts: webservers
roles:
- common
- role: foo_app_instance
vars:
dir: '/opt/a'
app_port: 5000
tags: typeA
- role: foo_app_instance
vars:
dir: '/opt/b'
app_port: 5001
tags: typeB
也可以向 roles 传递参数,例如:
- hosts: webserver
roles:
- common
- { role: foo_app_instance, dir:'/opt/a',port:5000}
- { role: foo_app_instance, dir:'/opt/b',port:5001}
甚至也可以条件式地使用roles,例如:
- hosts:webserver
roles:
- { role: some_role, when: "ansible_so_family == 'RedHat" }
include_role
会按照定义的顺序执行,如果之前有定义其他的任务,会先执行其他任务。
---
- hosts: webservers
tasks:
- name: Print a message
ansible.builtin.debug:
msg: "this task runs before the example role"
- name: Include the example role
include_role:
name: example
- name: Print a message
ansible.builtin.debug:
msg: "this task runs after the example role"
行为和上面的一样。
---
- hosts: webservers
tasks:
- name: Print a message
ansible.builtin.debug:
msg: "before we run our role"
- name: Import the example role
import_role:
name: example
- name: Print a message
ansible.builtin.debug:
msg: "after we ran our role"
可以使用 ansible-galaxy role init role_name
来创建 role,这个命令会创建一个目录结构。
使用 ansible-galaxy 创建的 role 会有一些初始化的设定,在 meta/main.yml 中可以看到基础的 galaxy_info
配置,包括了作者信息,协议等等。
ansible-galaxy list # 列出已经安装的galaxy
ansible-galaxy install geerlingguy.redis # 安装一个galaxy role
ansible-galaxy remove geerlingguy.redis # 删除一个galaxy role
CPU 窃取(CPU steal)指的是一个虚拟 CPU 核心必须等待物理 CPU 的时间百分比。通常 CPU 窃取发生在共享主机上,简短地来说就说当共享主机去处理一个请求时发生延迟。这种情况通常会发生在资源争夺的时候,当处理 CPU 密集型任务时。
在共享主机、或云主机中,虚拟机管理程序会安装在物理硬件和虚拟机化化境之间,然后将 CPU 时间、内存等等资源分配给虚拟机。
当进程准备好由虚拟 CPU 执行时,等待管理程序分配物理 CPU,而如果管理程序将此 CPU 已经分配给了另一个虚拟机时,就会发生等待。
CPU 窃取时间长的原因:
当检测到共享主机性能无故受到影响时,怀疑可能出现 CPU steal。最好的排查方法就是使用 iostat
命令。
iostat 1 10
for x in `seq 1 1 30`; do ps -eo state,pid,cmd | grep "^D"; echo "-"; sleep 2; done
top -bn 1 | head -15
拆分开每一行命令:
iostat 1 10
每隔 1s 执行一次 iostat 命令,执行 10 次。
结果可能是这样的:
avg-cpu: %user %nice %system %iowait %steal %idle
5.29 2.12 12.17 46.03 0.53 33.86
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
dm-0 1.00 4.00 0.00 0.00 4 0 0
dm-1 19.00 760.00 6144.00 0.00 760 6144 0
loop0 0.00 0.00 0.00 0.00 0 0 0
loop1 0.00 0.00 0.00 0.00 0 0 0
loop2 0.00 0.00 0.00 0.00 0 0 0
loop3 0.00 0.00 0.00 0.00 0 0 0
loop4 0.00 0.00 0.00 0.00 0 0 0
loop5 0.00 0.00 0.00 0.00 0 0 0
loop6 0.00 0.00 0.00 0.00 0 0 0
loop7 0.00 0.00 0.00 0.00 0 0 0
loop8 0.00 0.00 0.00 0.00 0 0 0
loop9 0.00 0.00 0.00 0.00 0 0 0
xvda 34.00 1412.00 0.00 0.00 1412 0 0
xvdb 30.00 1124.00 0.00 0.00 1124 0 0
xvdc 161.00 964.00 5440.00 0.00 964 5440 0
从结果上来看,上面的结果只有一点儿的 CPU steal,来看看一个存在 CPU steal 的结果。
avg-cpu: %user %nice %system %iowait %steal %idle
0.39 0.00 12.74 0.00 37.84 49.03
注意到 %steal
值,这么高的值则表示正在发生 CPU steal。一般来说这个值低于 15% 算是比较正常,如果一直比较偏高则需要 open a ticket 给虚拟机提供商请求调查了。
for x in `seq 1 1 30`; do ps -eo state,pid,cmd | grep "^D"; echo "-"; sleep 2; done
这一行命令则是检查状态在 D 状态的进程,D 状态意味着进程在 uninterruptible sleep,这一行命令每隔 1s 执行一次,执行 30 次。
正常的结果应该是只输出 -
行。而如果输出的结果中包含 D 状态的进程:
# for x in `seq 1 1 30`; do ps -eo state,pid,cmd | grep "^D"; echo "-"; sleep 2; done
-
D 2169 [jbd2/sda-8]
-
D 2169 [jbd2/sda-8]
-
D 2169 [jbd2/sda-8]
这意味着特定的进程在 uninterruptible sleep。调查该特定的进程,查看是否因为其他的,比如 IO 等待而造成系统卡顿。
D 状态进程通常在等待 IO,但这也常常意味着会发生 CPU steal,所有的系统资源都会被绑定到 D 状态的进程上,导致系统无法处理其他任务。
D 状态的进程无法被通常的方法 kill,因此一个完整的系统重启才可能清除掉此类进程。另一个方法就是等待 IO ,直到进程自己解决问题。但缺点也是在整个等待 IO 的过程中会持续造成系统问题。
top -bn 1 | head -15
top
命令是用来监控系统进程资源使用情况的命令,上面的命令则是打印资源使用最多的 15 个进程。
注意:超出 100% 使用率的进程不是问题,一个 8 CPU 核心的虚拟机可能会有 800% 的 CPU 使用率
在查看 top
的结果时,如果 top
命令结果中有占用 CPU 异常的进程,可以进行相关的处理。
另外一个查看的命令是 mpstat
mpstat -P ALL 1 10
每隔 1s 时间打印一次,在结果中可以查看 %steal
的数值。
在 sysstat 包中的 sar
命令也可以查看 steal 情况。
之前的一篇文章简单的通过内网穿透,异地组网的概念介绍过 ZeroTier,过去几年里面几台设备也一直陆陆续续地在使用着,虽然中间也短暂切换成 frp,也尝试过 [[Tailscale]],但 ZeroTier 一直是候选方案中排名在前的。
ZeroTier 官方默认免费的方案可以支持最多 50 台设备的连接,我陆陆续续也用不超过 20 台。所以使用官方提供的基本服务是丝毫没有任何问题的。但就是本着折腾的态度,也是学习一下 ZeroTier network controller 相关的内容,记录一下如何自建 ZeroTier network controller。
ZeroTier 是一个虚拟组网工具,他可以让设备和设备之间通过互联网的帮助,就像是在局域网(LAN)之间通信一样。通过 安装 ZeroTier One 客户端,并加入一个 16 位数字的 ZeroTier 网络就能实现。
ZeroTier 网络是通过 ZeroTier network controller 来完成配置的。用户既可以使用 ZeroTier 官方 提供的 network controller,也可以使用自己搭建的独立网络控制器(standalone network controller)。
如何设置自己独立的网络控制器就是这篇文章的重点。
ztncui 是一个开源的 ZeroTier 网络控制中心的用户界面。
代码地址:https://github.com/key-networks/ztncui
ZeroTier 的网络 Controller 是一个控制节点,该节点会通过 roots (根节点)来发现彼此。可以和 DNS 根服务器类比。
ZeroTier 的 Network ID 由两部分组成:节点 ID + 其他字符。
每一个 ZeroTier 节点(Nodes)会通过 Network ID 的前10位来发现 network controller,然后通过 networking controller 来发现局域网中的其他节点。
然后每一个节点可以通过 zerotier-cli peers
来查看匹配网络中的节点。
如果 network controller 离线了,那些已经建立连接的节点会保持连线,但是无法再往网络中添加新的节点。
上文提及的 ztncui 就是一个开源的 ZeroTier 网络控制器界面,通过他可以快速搭建自己的 ZeroTier 网络控制器,这里我们使用 Docker 镜像快速搭建。如果需要手工搭建,可以直接参考官网。
本文使用的镜像是:
这里直接贴出 docker-compose.yml
文件:
version: '3.3'
services:
ztncui:
container_name: ztncui
image: keynetworks/ztncui
restart: always
volumes:
- ~/ztncui/ztncui:/opt/key-networks/ztncui/etc
- ~/ztncui/zt1:/var/lib/zerotier-one
environment:
- NODE_ENV=${NODE_ENV}
- HTTP_PORT=${HTTP_PORT}
- HTTP_ALL_INTERFACES=yes
- ZTNCUI_PASSWD=${ZTNCUI_PASSWORD}
- MYADDR=${MYADDR}
ports:
- '3443:3443'
- '3180:3180'
说明:
HTTP_PORT
:后台端口ZTNCUI_PASSWD
:后台默认密码MYADDR
: VPS 的网络地址,公网IP地址然后在同级目录新建文件 .env
:
# more https://github.com/key-networks/ztncui-aio
NODE_ENV=production
HTTP_PORT=3443
ZTNCUI_PASSWD=
MYADDR=your.ip
后续更新会在 dockerfile。
然后使用 docker-compose up -d
启动。
启动之后可以访问 IP:3443
可以访问管理后台。
自建 ZeroTier network controller 可以提升节点建立连接的稳定性,同时也解除了官网的设备连接数限制。
但 network controller 自身并不能提升节点和节点之间的连接速度。
一旦使用了自建的 ZeroTier 网络,便需要一定精力去维护 network controller 的稳定性。
并且如果 network controller 挂掉可能无法再新增加节点。不过新增节点的操作也不是高频操作,对我个人使用而言问题不大。
除了 ztncui 这一个用户界面,还有一些在逐渐发展的,可以根据自己需要挑选:
[[2018-06-14-zerotier | 使用 Zerotier 组建虚拟局域网实现内网穿透]] |
过去的这一年里,不断的有人在我耳边说起一个词「内卷」,但是我让说这个词的人解释一下自己所说的这个词的含义,却没有人能够用一句话解释清楚这个词。所以在我的笔记中就一直留着这一个词条,让我不断的去思考「内卷」一词的含义。一般来说,我在没有弄明白某一个概念之前,不会在日常生活中反复的去使用。但周围反复在用的人实在太多了,所以整理一下过去我听到的,以及看到的。
我周围的人通常在这几个场景中会用到「内卷」这个词:
但究竟什么是内卷,如果是恶性竞争,那么我们为什么要发明一个词来表达重复的含义?
那接下来我们就从最原本的含义来探究一下「内卷」。
内卷对应的英文单词是 involution
。involution 在 American Heritage English 上的解释:
英文单词 involution 有内卷,退化的含义。
在哲学领域,内卷化一词最早被提及是 18 世纪德国哲学家 [[康德]] 的《批判力批判》,康德将 involution 和 Entwicklung(演化)进行了区分。
他在《批判力批判》中将「内卷化」定义成与「演化」相对的概念,「演化」形容事物从无到有、从低级到高级的发展过程,而「内卷化」则指的是事物在原有的基础之上,不断向内发展,不断复杂化的过程,这个过程中,并没有新事物诞生。1
美国人类学家 Goldennweiser(Alexander Aleksandrovich Goldenweiser) 将内卷化定义成在某一个状态下,无法稳定,也无法转变为新的状态,只能不断内部运动,变得复杂的文化模式。2
美国人类学家 Clifford Geertz ,在《农业内卷化——印度尼西亚的生态变化过程》(Agricultural Involution: The Processes of Ecological Change in Indonesia)中,借用 Goldenweiser 内卷化的概念研究爪哇岛的水稻农业,提出了 agricultural involution(农业化内卷)的概念。他认为水稻种植造成了社会复杂性,但没有促成技术或政治的变革,这个过程被他称为「内卷化」,Geertz 的使用,使得「内卷化」一词在人类学家和社会学家之间广为流传。
Geertz 在书中提到,1830 年以后爪哇受到了两方面的限制:
面对土地短缺采用了共同分担贫穷的模式,引起工业变革的失败3。
而在国内对「内卷」一词的引用则是在黄宗智的《长江三角洲小农家庭与乡村发展》中,作者把内卷化这一概念用于中国经济发展与社会变迁的研究,他把通过在有限的土地上投入大量的劳动力来获得总产量增长的方式,即边际效益递减的方式,将一种没有发展的增长称为「内卷化」。
但是在「内卷化」一词进入公众领域之后,其含义发生了巨大变化,在网络上,随着传播,内卷一词的语义发生了偏差。人们往往用其来指代恶性竞争、过度竞争,底层淘汰等现象。
总结上面的这些定义,尽管在哲学、社会学等等不同领域中,不同学者都对内卷化展开了研究,但是对内卷化都有各自不同的定义,这些定义不尽相同,目前也没有一个统一的定义。
但是能看到一些统一性的地方:
对于社会整体而言,内卷是一个停滞不前,无法转变的状态,虽然看着再不断发展,但是无法产生新的事物。而对于社会中的个体而言,内卷则使得个体投入更多,但却收获相同的结果,在边际效应上退化,对个体而言不管如何努力、改变都无法促进变革。
在这里我无法再进一步探究内卷的原因,我也无法得知为什么整个社会会掉进这样的陷阱,我知道只有当市场上的人能够充分的去发明新的事物,能够自由的表达自己的观点,即使这个事物的发明可能带来灾难,即使这个观点可能是错误的,但只有这样的自由,才能不让社会陷入一潭死水,只有自由的讨论才能使得真理在辩论中脱颖而出。在信息公开透明、可以自由交流的社会中,信息的流动会弥补信息的不对称,从而使得社会中的个体能够根据自己所获得的信息做出决策,从而提高生产效率,从而发展出新的理论。就像[[密尔]]在[[论自由]]一书中所说,迫使意见不能被表达这是对整个人类的掠夺。
在我们日常生活中所讨论的内卷一词早已超出了其原本的含义,甚至在某一些地方的使用是错误的,只掩盖了原来的一些问题。很多人所说的「内卷」,其实并不是「内卷」。
就像之前看到的豆瓣短文:
有人将职场学历要求越来越高视为内卷。事实上,这并不是内卷。例如一个工程师、银行经理的招聘要求从本科到硕士,从硕士到名校硕士,这其实是社会对岗位人才的要求越来越高,而不是内卷。 一个单位加班越来越严重,只要加班是有效的,这也不叫内卷,这属于劳动剥削。 将资本、风投偏爱低技术含量产业(例如共享单车、社区团购、滴滴这种的),而非原研药、精密机床、机器人这些高技术产业视为内卷。其实这也不是内卷。热钱真正偏爱的,是收益周期短的服务行业,“共享经济”、滴滴、美团、拼多多、游戏产业……这些看上去是互联网科技产业,其实它们是互联网加持的服务业,它们提供的是交通、配送、游戏娱乐、餐饮、购物等等服务。资本热钱真正偏爱的收益周期短、好讲故事的服务业。而这些生活服务产业又都是大众化服务,所以我们经常会在媒体宣传上、身边生活中看到这些服务产品(例如共享单车、美团骑手、游戏广告等),于是就会形成了资本只喜欢这种产业的错觉。实际上,高技术产业——造精密机床、造飞机、造机器人……这些技术产业都有它们自己的体系,只是它们离我们的生活较远,我们不太了解而已。所以这也算不上内卷。这属于是风投资本倾向于收益周期短、曝光率较高的服务业。如果真要靠投资共享单车那点钱去研究飞机、造芯片,那国家怎么可能发展呢?高科技企业自有其发展的政策、金融、市场体系。 将所有的加班都视为「内卷」这实际上掩盖了劳动法保障不健全的问题。假如劳动法保障够刚性,当暗示加班成为一种人人鄙视的违法行为时,加班生态是绝对可以好转的。而乱用内卷概念,则会把责任归于员工身上,反而忽略了法律制度、企业的问题,这就掩盖了真实的问题所在。
正确的使用「内卷」一词,才能让我们有针对性的解决问题,而不是像现在这样任其随意被滥用,从而掩盖真正能够被解决的问题。
康德.判断力批判·第 2 版[M].北京:人民出版社,2002. ↩
McGee, R. Jon; Warms, Richard L. Critical Contributions to Anthropology. Theory in Social and Cultural Anthropology: An Encyclopedia. SAGE Publications. 2013-08-28. ISBN 9781506314617 ↩
Cohen, Jeffrey H.; Dannhaeuser, Norbert. Involution and modernisation. Economic Development: An Anthropological Approach. Rowman Altamira. 2002-04-23. ISBN 9780759116696 ↩
前两天在新机器上使用我的 dotfiles 配置的时候,本来会自动安装 zinit,并进行一些初始化配置,但突然发现卡在了 zinit 配置拉取的过程中,还以为 GitHub 权限配置的问题,但仔细看了一下发现作者把整个仓库,以及个人页面都给删除了。 https://github.com/zdharma/zinit
这个仓库显示 404,我还以为产生了错觉,因为刚刚从 Google 点击跳转过来,Google 的结果还在,但自己一搜就发现原来真的是作者本人把仓库删除了。
所以也没有办法,除了我本地的一份缓存,最近一次提交还是 6 月份,所以只能搜索一下看看还有没有人有最新的备份,然后就看到了 GitHub 上之前贡献者新建的社区维护的仓库。把我 dotfiles 中的地址替换成该仓库目前暂时没有遇到任何问题。
另外要注意如果用到了如下的插件也要响应地替换:
zdharma/zinit -> zdharma-continuum/zinit
zdharma/fast-syntax-highlighting -> zdharma-continuum/fast-syntax-highlighting
zdharma/history-search-multi-word -> zdharma-continuum/history-search-multi-word
我个人也备份了一份代码 https://github.com/einverne/zinit 有兴趣可以看看。
不过我个人还是建议切换到社区维护的版本上。
我不对作者的行为做任何评价,因为我并不清楚发生了什么,但是无疑这种删库的行为已经伤害了曾经的使用者,以及曾经贡献过代码的开发者。代码容易恢复,当作者仓库的 wiki 内容已经只能从 Google Cache 中恢复了,这无疑会对使用者造成一些困扰。
从这件事情延伸到生活中,以及这两天刚刚发生的 [[Notability]] 买断制更改为订阅模式造成的恶劣舆论影响,让我不经去思考,在如今这样的严重依赖数字化的生活中保持安定。在过去的经历中,已经让我渐渐地养成习惯,尽量去使用[[自由软件]](能够获取源码),尽量去使用跨平台能导出可使用数据的软件(比如 Obsidian 即使再用不了,我还可以用任何编辑器去编辑我的笔记),如果有离线可用的,绝不用在线服务(Obsidian 相较于 Notion,Notion 开始就不在我的备选方案)。虽然已经这样的做法已经渐渐地让我不会再受到服务关闭的影响,但于此同时我需要考虑的东西就变得多了,数据安全问题,数据备份的问题,这只是涉及数字资产。
但生活中比数字资产重要多的东西也非常多,要做好任何重要的东西可能丢失的备份策略,如果丢失身份证呢,如果在旅行的过程中丢失了护照呢,或者手机失窃了呢? 去备份任何你生活需要依赖的东西,不要将手机和身份证放到一起,不要将银行卡和任何证件放到一起,去备份你生活中产生的任何个人的数据。
很早之前在 QNAP 上就已经安装过老版本的 Gogs,一路升级到 0.11.91 之后很久没有更新,看了一下用的镜像还是 2020 年 2 月份的,看到 Gogs 也已经迭代了好几个版本,正好这一次做迁移,把 Gogs 从 QNAP 迁移到 VPS 上,随便想着也升级一下 Gogs 的版本。
因为之前使用 Docker 安装的,所以迁移的步骤也比较简单,两个部分数据,一部分是 MySQL 数据库,mysqldump 迁移导入即可,另一部分是写的磁盘持久化部分,tar
打包,scp 或 rsync 传输也比较快。
Gogs 升级到 0.12.x 的时候官方有一些配置发生了变化,我的所有配置文件都在 ~/gogs
文件夹下,所以我需要修改:
vi ~/gogs/gogs/conf/app.ini
然后修改其中的配置。官方的 0.12.0 的 changelog 已经写的非常清楚了,将这些修改都更改了。
❯ cat ~/gogs/gogs/conf/app.ini
BRAND_NAME = Gogs
RUN_USER = git
RUN_MODE = dev
[database]
TYPE = mysql
HOST = db_host:3306
NAME = gogs
USER = gogs
PASSWORD = BTxax
SSL_MODE = disable
PATH = data/gogs.db
[repository]
ROOT = /data/git/gogs-repositories
[server]
DOMAIN = git.example.com
HTTP_PORT = 3000
EXTERNAL_URL = https://git.example.com
DISABLE_SSH = false
SSH_PORT = 10022
START_SSH_SERVER = false
OFFLINE_MODE = false
[mailer]
ENABLED = false
[service]
REQUIRE_EMAIL_CONFIRMATION = false
ENABLE_NOTIFY_MAIL = false
DISABLE_REGISTRATION = false
ENABLE_CAPTCHA = true
REQUIRE_SIGNIN_VIEW = false
[picture]
DISABLE_GRAVATAR = false
ENABLE_FEDERATED_AVATAR = false
[session]
PROVIDER = file
[log]
MODE = file
LEVEL = Info
ROOT_PATH = /app/gogs/log
[security]
INSTALL_LOCK = true
SECRET_KEY = Mj
可以大致参考我的,但不是每一个选项都要一致,最好自行查看每个选项的含义。
cp app.ini app.ini.bak
sed -i \
-e 's/APP_NAME/BRAND_NAME/g' \
-e 's/ROOT_URL/EXTERNAL_URL/g' \
-e 's/LANDING_PAGE/LANDING_URL/g' \
-e 's/DB_TYPE/TYPE/g' \
-e 's/PASSWD/PASSWORD/g' \
-e 's/REVERSE_PROXY_AUTHENTICATION_USER/REVERSE_PROXY_AUTHENTICATION_HEADER/g' \
-e 's/\[mailer\]/\[email\]/g' \
-e 's/\[service\]/\[auth\]/g' \
-e 's/ACTIVE_CODE_LIVE_MINUTES/ACTIVATE_CODE_LIVES/g' \
-e 's/RESET_PASSWD_CODE_LIVE_MINUTES/RESET_PASSWORD_CODE_LIVES/g' \
-e 's/ENABLE_CAPTCHA/ENABLE_REGISTRATION_CAPTCHA/g' \
-e 's/ENABLE_NOTIFY_MAIL/ENABLE_EMAIL_NOTIFICATION/g' \
-e 's/GC_INTERVAL_TIME/GC_INTERVAL/g' \
-e 's/SESSION_LIFE_TIME/MAX_LIFE_TIME/g' \
app.ini
使用命令 sed 替换。1
然后在新的 VPS 上使用 docker-compose:
version: "3"
services:
gogs:
image: gogs/gogs:0.12.3
container_name: gogs
restart: always
volumes:
- ~/gogs:/data
ports:
- "10022:22"
environment:
VIRTUAL_HOST: git.example.com
VIRTUAL_PORT: 3000
LETSENCRYPT_HOST: git.example.com
LETSENCRYPT_EMAIL: admin@example.info
networks:
default:
external:
name: nginx-proxy
因为我使用 Nginx Proxy 做反向代理,如果需要可以去除掉。
然后直接 docker-compose up -d
启动即可。
这个时候我遇到一些问题。查看日志
less ~/gogs/gogs/log/gogs.log
2021/10/30 07:35:18 [ INFO] Gogs 0.12.3
2021/10/30 07:35:18 [FATAL] [...o/gogs/internal/route/install.go:75 GlobalInit()] Failed to initialize ORM engine: auto migrate "LFSObject": Error 1071: Specified key was too long; max key length is 767 bytes
会发现报错,这个错误 GitHub issue 上面也有人报错,之前因为迁移,没有来得及查看,后来仔细查看 Gogs 其他日志:
less ~/gogs/gogs/log/gorm.log
发现 gorm 日志中在创建 lfs_object
表的时候发生了错误。
2021/10/30 07:33:49 [log] [gogs.io/gogs/internal/db/db.go:166] Error 1071: Specified key was too long; max key length is 767 bytes
2021/10/30 07:33:49 [sql] [gogs.io/gogs/internal/db/db.go:166] [823.087µs] CREATE TABLE `lfs_object` (`repo_id` bigint,`oid` varchar(255),`size` bigint NOT NULL,`storage` varchar(255) NOT NULL,`created_at` DATETIME NOT NULL , PRIMARY KEY (`repo_id`,`oid`)) ENGINE=InnoDB [] (0 rows affected)
结合之前在 changelog 中看到的,升级到 0.12.x 之后 Gogs 会自动创建这张表,而创建失败了自然就无法启动报 502 错误了。
看这个错误 Error 1071,一看就是 MySQL 的错误。
Error 1071: Specified key was too long; max key length is 767 bytes
我的机器上使用的是 MariaDB,然后 gogs 数据库默认使用的是 utf8mb4_general_ci
collation,默认情况下索引长度会有问题,所以将数据库的默认 collation 改成 utf8_general_ci
即可。
登录 phpmyadmin 选中数据库 gogs,然后在 Operations 最下面可以看到 Collation 设置,直接修改保存即可。
ALTER DATABASE <database_name> CHARACTER SET utf8 COLLATE utf8_general_ci;
在 Ubuntu 18.04 网络配置中,某一次升级之后就发现网络配置中心里面少了有线网络配置。
为了恢复有线网络配置,需要手动修改 NetworkManager 的配置文件。
首先查看 interfaces 文件中内容。
❯ sudo cat /etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback
确保该配置文件正确。
然后修改 NetworkManager.conf 文件
sudo vi /etc/NetworkManager/NetworkManager.conf
将文件中的 :
managed=false
修改为
managed=true
然后修改 10-globally-managed-devices.conf
配置文件,添加有线设备:
sudo vi /usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf
修改为:
[keyfile]
unmanaged-devices=*,except:type:ethernet,except:type:wifi,except:type:wwan
注意其中的 except: type: ethernet
这一部分。
最后重启 NetworkManager
sudo service network-manager restart
最后就能够在网络配置中心中手动配置有线网络连接。
之前购买的 So you Start(OVH 旗下品牌) 的独服,配置有 4 块 2T 的硬盘,但是 So you Start 后台默认的 RAID 级别是 RAID1,这样使得可用的空间只有 8T 中的 2T,25% 的使用率,虽然硬盘安全性级别比较高(允许多块硬盘损坏的情况下依然不丢数据),但是空间可用率太低了,所以折中一下可以使用 RAID-10(允许一块硬盘损坏而不丢失数据),这里就记录一下如何把 So you Start 的独服从 RAID-1 级别在线调整成 RAID-10。正常情况下 OVH 旗下的主机品牌,包括 OHV,So you Start, Kimsufi 都可以适用本教程,其他独服的操作也类似。
主要分成后面几个步骤(具体的操作步骤和演示可以参考后文):
mdadm /dev/md1 --fail /dev/sdc1
mdadm /dev/md1 --remove /dev/sdc1
wipefs -a /dev/sdc1
mdadm --grow /dev/md1 --raid-devices=2
first think about a partitioning scheme. usually there is no need to absolutely put everything on a single large partition. proxmox for instance puts disk images and whatnot into /var/lib/vz which then is an ideal mount point for a split partition.
首先在 So you Start 后台管理面板中使用 Reinstall 重新安装系统。
/
然后留一定空间给 swap
。比如我的机器是 32G 的,可以给 16G swap,然后剩余的空间都划给 /
。如果熟悉 Linux 的分区,并且想要自己定义剩下的空间给 RAID-x,或 ZFS,或 LVM,可以划分一个比如 2G 给 /boot
分区,然后划分240G 给 /
然后 16G 给 swap
,之后可以把 /
从 RAID1 调整为 RAID10安装完成进入系统:
debian@pve:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 10 (buster)
Release: 10
Codename: buster
重新调整 RAID 级别。需要特别感谢 LET 上面的 Falzo 根据他所提供的详细步骤我才完成了 RAID1 到 RAID10 的在线调整。
大致的步骤需要先将 RAID1 调整为 RAID0,然后在调整为 RAID10.
首先来查看一下默认的 RAID 信息:
root@pve:~# cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md2 : active raid1 sda2[0] sdc2[1] sdd2[3] sdb2[2]
511868928 blocks super 1.2 [4/4] [UUUU]
bitmap: 2/4 pages [8KB], 65536KB chunk
unused devices: <none>
可以看到有一个 md2 RAID,使用了 raid1,有四个分区分别是 sda2, sdc2, sdd2, sdb2 组合而成。
查看硬盘信息(模糊掉敏感的一些标识信息):
root@pve:~# fdisk -l
Disk /dev/sdb: 1.8 TiB, 2000398934016 bytes, 3907029168 sectors
Disk model: HGST HUS7-----AL
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: B411C4C1-EA13-42F1-86D8-DC-------115
Device Start End Sectors Size Type
/dev/sdb1 2048 1048575 1046528 511M EFI System
/dev/sdb2 1048576 1025048575 1024000000 488.3G Linux RAID
/dev/sdb3 1025048576 1058603007 33554432 16G Linux filesystem
Disk /dev/sdc: 1.8 TiB, 2000398934016 bytes, 3907029168 sectors
Disk model: HGST HUS7-----AL
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: DA108B72-B409-4F9E-8FF1-0D---------8
Device Start End Sectors Size Type
/dev/sdc1 2048 1048575 1046528 511M EFI System
/dev/sdc2 1048576 1025048575 1024000000 488.3G Linux RAID
/dev/sdc3 1025048576 1058603007 33554432 16G Linux filesystem
Disk /dev/sdd: 1.8 TiB, 2000398934016 bytes, 3907029168 sectors
Disk model: HGST HUS-----0AL
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: DC27A340-79CB-437E-952F-97A-------A8
Device Start End Sectors Size Type
/dev/sdd1 2048 1048575 1046528 511M EFI System
/dev/sdd2 1048576 1025048575 1024000000 488.3G Linux RAID
/dev/sdd3 1025048576 1058603007 33554432 16G Linux filesystem
Disk /dev/sda: 1.8 TiB, 2000398934016 bytes, 3907029168 sectors
Disk model: HGST HU------0AL
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 76C633FE-ACC3-40FA-A111-2C--------C8
Device Start End Sectors Size Type
/dev/sda1 2048 1048575 1046528 511M EFI System
/dev/sda2 1048576 1025048575 1024000000 488.3G Linux RAID
/dev/sda3 1025048576 1058603007 33554432 16G Linux filesystem
/dev/sda4 3907025072 3907029134 4063 2M Linux filesystem
Disk /dev/md2: 488.2 GiB, 524153782272 bytes, 1023737856 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
然后可以通过 mdadm 命令 reshape RAID1,这一步可以直接在线执行,完全不需要 [[IPMI]] 等等额外的工具。
在线将 RAID1 转变成 RAID10 的步骤可以参考这篇文章 作者写的非常清楚。[[Converting RAID1 to RAID10 online]]
具体的步骤可以查看如下:
root@pve:~# cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md2 : active raid1 sda2[0] sdc2[1] sdd2[3] sdb2[2]
511868928 blocks super 1.2 [4/4] [UUUU]
bitmap: 2/4 pages [8KB], 65536KB chunk
unused devices: <none>
root@pve:~# mdadm /dev/md2 --fail /dev/sdc2
mdadm: set /dev/sdc2 faulty in /dev/md2
root@pve:~# mdadm /dev/md2 --remove /dev/sdc2
mdadm: hot removed /dev/sdc2 from /dev/md2
root@pve:~# wipefs -a /dev/sdc2
/dev/sdc2: 4 bytes were erased at offset 0x00001000 (linux_raid_member): fc 4e 2b a9
root@pve:~# mdadm /dev/md2 --fail /dev/sdd2
mdadm: set /dev/sdd2 faulty in /dev/md2
root@pve:~# mdadm /dev/md2 --remove /dev/sdd2
mdadm: hot removed /dev/sdd2 from /dev/md2
root@pve:~# wipefs -a /dev/sdd2
/dev/sdd2: 4 bytes were erased at offset 0x00001000 (linux_raid_member): fc 4e 2b a9
root@pve:~# mdadm --grow /dev/md2 --raid-devices=2
raid_disks for /dev/md2 set to 2
root@pve:~# cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md2 : active raid1 sda2[0] sdb2[2]
511868928 blocks super 1.2 [2/2] [UU]
bitmap: 3/4 pages [12KB], 65536KB chunk
unused devices: <none>
root@pve:~# mdadm --detail /dev/md2
/dev/md2:
Version : 1.2
Creation Time : Thu Oct 21 12:58:06 2021
Raid Level : raid1
Array Size : 511868928 (488.16 GiB 524.15 GB)
Used Dev Size : 511868928 (488.16 GiB 524.15 GB)
Raid Devices : 2
Total Devices : 2
Persistence : Superblock is persistent
Intent Bitmap : Internal
Update Time : Thu Oct 21 13:33:45 2021
State : clean
Active Devices : 2
Working Devices : 2
Failed Devices : 0
Spare Devices : 0
Consistency Policy : bitmap
Name : md2
UUID : 0686b64f:07957a70:4e937aa2:23716f6e
Events : 158
Number Major Minor RaidDevice State
0 8 2 0 active sync /dev/sda2
2 8 18 1 active sync /dev/sdb2
root@pve:~# sudo mdadm --grow /dev/md2 --level=0 --backup-file=/home/backup-md2
mdadm: level of /dev/md2 changed to raid0
root@pve:~# cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md2 : active raid0 sdb2[2]
511868928 blocks super 1.2 64k chunks
unused devices: <none>
root@pve:~# mdadm --misc --detail /dev/md2
/dev/md2:
Version : 1.2
Creation Time : Thu Oct 21 12:58:06 2021
Raid Level : raid0
Array Size : 511868928 (488.16 GiB 524.15 GB)
Raid Devices : 1
Total Devices : 1
Persistence : Superblock is persistent
Update Time : Thu Oct 21 13:40:10 2021
State : clean
Active Devices : 1
Working Devices : 1
Failed Devices : 0
Spare Devices : 0
Chunk Size : 64K
Consistency Policy : none
Name : md2
UUID : 0686b64f:07957a70:4e937aa2:23716f6e
Events : 163
Number Major Minor RaidDevice State
2 8 18 0 active sync /dev/sdb2
root@pve:~# mdadm --grow /dev/md2 --level=10 --backup-file=/home/backup-md2 --raid-devices=4 --add /dev/sda2 /dev/sdc2 /dev/sdd2
mdadm: level of /dev/md2 changed to raid10
mdadm: added /dev/sda2
mdadm: added /dev/sdc2
mdadm: added /dev/sdd2
raid_disks for /dev/md2 set to 5
root@pve:~# cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md2 : active raid10 sdd2[5] sdc2[4](S) sda2[3](S) sdb2[2]
511868928 blocks super 1.2 2 near-copies [2/1] [U_]
[>....................] recovery = 0.5% (2835392/511868928) finish=50.8min speed=166787K/sec
unused devices: <none>
root@pve:~# mdadm --misc --detail /dev/md2
/dev/md2:
Version : 1.2
Creation Time : Thu Oct 21 12:58:06 2021
Raid Level : raid10
Array Size : 511868928 (488.16 GiB 524.15 GB)
Used Dev Size : 511868928 (488.16 GiB 524.15 GB)
Raid Devices : 2
Total Devices : 4
Persistence : Superblock is persistent
Update Time : Thu Oct 21 13:42:49 2021
State : active, degraded, recovering
Active Devices : 1
Working Devices : 4
Failed Devices : 0
Spare Devices : 3
Layout : near=2
Chunk Size : 64K
Consistency Policy : resync
Rebuild Status : 1% complete
Name : md2
UUID : 0686b64f:07957a70:4e937aa2:23716f6e
Events : 221
Number Major Minor RaidDevice State
2 8 18 0 active sync set-A /dev/sdb2
5 8 50 1 spare rebuilding /dev/sdd2
3 8 2 - spare /dev/sda2
4 8 34 - spare /dev/sdc2
root@pve:~# mdadm --misc --detail /dev/md2
/dev/md2:
Version : 1.2
Creation Time : Thu Oct 21 12:58:06 2021
Raid Level : raid10
Array Size : 511868928 (488.16 GiB 524.15 GB)
Used Dev Size : 511868928 (488.16 GiB 524.15 GB)
Raid Devices : 2
Total Devices : 4
Persistence : Superblock is persistent
Update Time : Thu Oct 21 13:47:58 2021
State : active, degraded, recovering
Active Devices : 1
Working Devices : 4
Failed Devices : 0
Spare Devices : 3
Layout : near=2
Chunk Size : 64K
Consistency Policy : resync
Rebuild Status : 11% complete
Name : md2
UUID : 0686b64f:07957a70:4e937aa2:23716f6e
Events : 554
Number Major Minor RaidDevice State
2 8 18 0 active sync set-A /dev/sdb2
5 8 50 1 spare rebuilding /dev/sdd2
3 8 2 - spare /dev/sda2
4 8 34 - spare /dev/sdc2
root@pve:~# mdadm --misc --detail /dev/md2
/dev/md2:
Version : 1.2
Creation Time : Thu Oct 21 12:58:06 2021
Raid Level : raid10
Array Size : 511868928 (488.16 GiB 524.15 GB)
Used Dev Size : 511868928 (488.16 GiB 524.15 GB)
Raid Devices : 2
Total Devices : 4
Persistence : Superblock is persistent
Update Time : Thu Oct 21 13:48:29 2021
State : clean, degraded, recovering
Active Devices : 1
Working Devices : 4
Failed Devices : 0
Spare Devices : 3
Layout : near=2
Chunk Size : 64K
Consistency Policy : resync
Rebuild Status : 12% complete
Name : md2
UUID : 0686b64f:07957a70:4e937aa2:23716f6e
Events : 588
Number Major Minor RaidDevice State
2 8 18 0 active sync set-A /dev/sdb2
5 8 50 1 spare rebuilding /dev/sdd2
3 8 2 - spare /dev/sda2
4 8 34 - spare /dev/sdc2
root@pve:~# mdadm --grow /dev/md2 --raid-devices=4
root@pve:~# cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md2 : active raid10 sdd2[5] sdc2[4] sda2[3] sdb2[2]
511868928 blocks super 1.2 64K chunks 2 near-copies [4/3] [U_UU]
[>....................] reshape = 0.2% (1387520/511868928) finish=67.4min speed=126138K/sec
unused devices: <none>
root@pve:~# mdadm --misc --detail /dev/md2
/dev/md2:
Version : 1.2
Creation Time : Thu Oct 21 12:58:06 2021
Raid Level : raid10
Array Size : 511868928 (488.16 GiB 524.15 GB)
Used Dev Size : 511868928 (488.16 GiB 524.15 GB)
Raid Devices : 4
Total Devices : 4
Persistence : Superblock is persistent
Update Time : Thu Oct 21 13:50:47 2021
State : clean, degraded, reshaping
Active Devices : 3
Working Devices : 4
Failed Devices : 0
Spare Devices : 1
Layout : near=2
Chunk Size : 64K
Consistency Policy : resync
Reshape Status : 1% complete
Delta Devices : 2, (2->4)
Name : md2
UUID : 0686b64f:07957a70:4e937aa2:23716f6e
Events : 725
Number Major Minor RaidDevice State
2 8 18 0 active sync set-A /dev/sdb2
5 8 50 1 spare rebuilding /dev/sdd2
4 8 34 2 active sync set-A /dev/sdc2
3 8 2 3 active sync set-B /dev/sda2
root@pve:~# mdadm --misc --detail /dev/md2
/dev/md2:
Version : 1.2
Creation Time : Thu Oct 21 12:58:06 2021
Raid Level : raid10
Array Size : 511868928 (488.16 GiB 524.15 GB)
Used Dev Size : 511868928 (488.16 GiB 524.15 GB)
Raid Devices : 4
Total Devices : 4
Persistence : Superblock is persistent
Update Time : Thu Oct 21 13:51:59 2021
State : active, degraded, reshaping
Active Devices : 3
Working Devices : 4
Failed Devices : 0
Spare Devices : 1
Layout : near=2
Chunk Size : 64K
Consistency Policy : resync
Reshape Status : 3% complete
Delta Devices : 2, (2->4)
Name : md2
UUID : 0686b64f:07957a70:4e937aa2:23716f6e
Events : 769
Number Major Minor RaidDevice State
2 8 18 0 active sync set-A /dev/sdb2
5 8 50 1 spare rebuilding /dev/sdd2
4 8 34 2 active sync set-A /dev/sdc2
3 8 2 3 active sync set-B /dev/sda2
root@pve:~# cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md2 : active raid10 sdd2[5] sdc2[4] sda2[3] sdb2[2]
511868928 blocks super 1.2 64K chunks 2 near-copies [4/3] [U_UU]
[====>................] reshape = 21.8% (111798784/511868928) finish=59.6min speed=111736K/sec
unused devices: <none>
root@pve:~# mdadm --misc --detail /dev/md2
/dev/md2:
Version : 1.2
Creation Time : Thu Oct 21 12:58:06 2021
Raid Level : raid10
Array Size : 511868928 (488.16 GiB 524.15 GB)
Used Dev Size : 511868928 (488.16 GiB 524.15 GB)
Raid Devices : 4
Total Devices : 4
Persistence : Superblock is persistent
Update Time : Thu Oct 21 14:05:44 2021
State : active, degraded, reshaping
Active Devices : 3
Working Devices : 4
Failed Devices : 0
Spare Devices : 1
Layout : near=2
Chunk Size : 64K
Consistency Policy : resync
Reshape Status : 22% complete
Delta Devices : 2, (2->4)
Name : md2
UUID : 0686b64f:07957a70:4e937aa2:23716f6e
Events : 1345
Number Major Minor RaidDevice State
2 8 18 0 active sync set-A /dev/sdb2
5 8 50 1 spare rebuilding /dev/sdd2
4 8 34 2 active sync set-A /dev/sdc2
3 8 2 3 active sync set-B /dev/sda2
root@pve:~# df -h
Filesystem Size Used Avail Use% Mounted on
udev 16G 0 16G 0% /dev
tmpfs 3.2G 8.9M 3.2G 1% /run
/dev/md2 481G 1.5G 455G 1% /
tmpfs 16G 0 16G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 16G 0 16G 0% /sys/fs/cgroup
/dev/sdd1 511M 3.3M 508M 1% /boot/efi
tmpfs 3.2G 0 3.2G 0% /run/user/1000
root@pve:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 1.8T 0 disk
├─sda1 8:1 0 511M 0 part
├─sda2 8:2 0 488.3G 0 part
│ └─md2 9:2 0 488.2G 0 raid10 /
├─sda3 8:3 0 16G 0 part [SWAP]
└─sda4 8:4 0 2M 0 part
sdb 8:16 0 1.8T 0 disk
├─sdb1 8:17 0 511M 0 part
├─sdb2 8:18 0 488.3G 0 part
│ └─md2 9:2 0 488.2G 0 raid10 /
└─sdb3 8:19 0 16G 0 part [SWAP]
sdc 8:32 0 1.8T 0 disk
├─sdc1 8:33 0 511M 0 part
├─sdc2 8:34 0 488.3G 0 part
│ └─md2 9:2 0 488.2G 0 raid10 /
└─sdc3 8:35 0 16G 0 part [SWAP]
sdd 8:48 0 1.8T 0 disk
├─sdd1 8:49 0 511M 0 part /boot/efi
├─sdd2 8:50 0 488.3G 0 part
│ └─md2 9:2 0 488.2G 0 raid10 /
└─sdd3 8:51 0 16G 0 part [SWAP]
root@pve:~# cat /proc/mdstat
Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
md2 : active raid10 sdd2[5] sdc2[4] sda2[3] sdb2[2]
511868928 blocks super 1.2 64K chunks 2 near-copies [4/3] [U_UU]
[======>..............] reshape = 32.9% (168472448/511868928) finish=49.0min speed=116718K/sec
unused devices: <none>
等待很长一段时间之后 RAID10 完成:
root@pve:~# mdadm --misc --detail /dev/md2
/dev/md2:
Version : 1.2
Creation Time : Thu Oct 21 12:58:06 2021
Raid Level : raid10
Array Size : 1023737856 (976.31 GiB 1048.31 GB)
Used Dev Size : 511868928 (488.16 GiB 524.15 GB)
Raid Devices : 4
Total Devices : 4
Persistence : Superblock is persistent
Update Time : Fri Oct 22 01:39:27 2021
State : clean
Active Devices : 4
Working Devices : 4
Failed Devices : 0
Spare Devices : 0
Layout : near=2
Chunk Size : 64K
Consistency Policy : resync
Name : md2
UUID : 0686b64f:07957a70:4e937aa2:23716f6e
Events : 6536
Number Major Minor RaidDevice State
2 8 18 0 active sync set-A /dev/sdb2
5 8 50 1 active sync set-B /dev/sdd2
4 8 34 2 active sync set-A /dev/sdc2
3 8 2 3 active sync set-B /dev/sda2
完成 RAID10 的调整之后,如果磁盘还有剩余的空间,可以再分区,之后使用 ZFS,raidz 可以自己选择。
然后可以更具官方的教程,直接在 Debian 的基础之上安装 Proxmox VE。之后需要移除掉 cloud-init 否则网络配置会产生问题。