问题现象:

Windows 11 + WSL2 + Ubuntu分发, 主机上启动VPN. WSL2内使用docker运行容器. curl http站点没问题, curl https站点显示 Connected to... 并且header已发送, 但是收不到响应.

推测是MTU导致的. 因为curl http的响应是301, body很小, header也很小, 但是curl https要返回的内容可能比较多所以丢包了.

分别在wsl2下安装tcpdump并监听ethdocker0接口, 在windows下安装wireshark并监听VPN网卡(tun模式).

在docker内发起http请求, 可以看到docker0接口正常, eth接口正常, wireshark能看到请求和响应.

在docker内发起https请求, 可以看到docker0接口有请求报文, eth接口只有握手报文, wireshark能看到请求报文.

通过 ip a 命令查看接口, 可以发现WSL2内eth接口mtu为1370, docker0的mtu为1500. 推测MTU不匹配且没开启PMTU导致丢包.

解决方法是配置docker使其mtu变为1370, 方法如下:

1
sudo vim /usr/lib/systemd/system/docker.service

在配置文件中, 将ExecStart=...这一行改为:

1
2
3
...
ExecStart=/usr/bin/dockerd --mtu 1370 -H fd:// --containerd=/run/containerd/containerd.sock
...

然后重新启动docker服务:

1
sudo systemctl daemon-reload && sudo systemctl restart docker

再访问https就正常了.

Win11这个右键之后还要【显示更多选项】实在是让人费解. 参考以下方法恢复至原来的右键菜单行为:

Win+X, A 打开终端 (powershell也可以)

1
2
3
reg.exe add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" /f /ve
taskkill /F /IM explorer.exe
explorer.exe

其中第二步和第三步也可以通过任务管理器来重启【Windows资源管理器】

参考

Restore old Right-click Context menu in Windows 11

注意:请务必做好数据备份,本文的前提是对Proxmox中的VM操作, 利用了PVE的备份和还原能力.

  1. 创建一个一样大小的硬盘并挂载到VM.

  2. 选择一个live系统,这里我们选择 Ubuntu Desktop 24.04.1 LTS

  3. 将live盘设置为启动盘,启动系统,选择 Try Ubuntu 进入 live 环境

  4. 由于我原来的LVM系统盘有三个分区 1M, 1G的/boot, 199G的lvm数据分区,所以需要先拷贝系统,再把boot部分的补上, 具体操作如下:

1
2
3
4
5
6
7
8
...
sda 8:0 0 200G 0 disk
|- sda1 8:1 0 1M 0 part
|- sda2 8:2 0 1G 0 part
|- sda3 8:3 0 199G 0 part
|- ubuntu--vg-ubuntu--lv 252:0 0 199G 0 lvm
sdb 8:16 0 200G 0 disk
...

切换至root用户 sudo su 由于是live系统不需要输入密码

创建几个mount点:

1
2
3
mkdir /mnt/src
mkdir /mnt/srcboot
mkdir /mnt/dst

初始化新磁盘(这里 /dev/sda是原来的磁盘, /dev/sdb 是新的磁盘)

1
2
3
4
5
6
7
8
9
gdisk /dev/sdb
输入 p 查看分区, 当前应该没有分区
输入 n 新建分区
分区类型选择 p (primary)
起始位置 2048 终止位置 4095 HexCode设置为 EF02 (BIOS boot partition)
输入 n 新建分区
分区类型选择 p (primary)
起始位置 4096 终止位置, HexCode保持默认 (8300, Linux filesystem)
输入 w 将改动写入到磁盘

如果原来的磁盘不是GPT格式可以尝试如下命令:

1
2
3
4
5
6
7
fdisk /dev/sdb
输入 p 查看分区, 当前应该没有分区
输入 n 新建分区
分区类型选择 p (primary)
起始位置, 大小 等等全部选择默认
新建完成分区后输入 a 将分区标记为引导分区
输入 w 将改动写入到磁盘

在新的磁盘上创建文件系统

1
2
mkfs -t ext4 /dev/sdb2
注意如果没有创建 BIOS boot 分区, 应该使用 /dev/sdb1

挂载磁盘

1
2
3
mount -o ro /dev/sda2 /mnt/srcboot
mount -o ro /dev/mapping/ubuntu--vg-ubuntu--lv /mnt/src
mount /dev/sdb1 /mnt/dst

安装pv工具以便查看复制进度

1
apt update && apt install pv

开始拷贝数据

1
2
tar -C /mnt/src --preserve-permissions --xattrs --xattrs-include=*.* --numeric-owner -c . | pv | tar -xf - -C /mnt/dst --preserve-permissions --xattrs --xattrs-include=*.* --numeric-owner
tar -C /mnt/srcboot --preserve-permissions --xattrs --xattrs-include=*.* --numeric-owner -c . | pv | tar -xf - -C /mnt/dst/boot --preserve-permissions --xattrs --xattrs-include=*.* --numeric-owner

其中 --perserve-permission 是为了保留权限, 对于 root 用户来说是默认的, 但是为了保险起见还是加上

--xattrs, --xattrs-include=*.* 启用额外属性支持, 并拷贝全部属性. 这样类似/usr/bin/ping等文件的 capability 也会被保存下来.

--numeric-owner 要求 tar 使用数字UID/GID 而不是用户名

给新磁盘文件系统下挂载分区

1
2
cd /mnt/dst
for i in /dev /dev/pts /proc /sys /run; do mount --bind $i .$i; done

修改 /etc/fstab,保证里面 /dev/disk/by-uuid/ 对应的磁盘和新磁盘一致. 通过 lsblk -o NAME,uuid 来查看磁盘的uuid

1
nano /mnt/dstetc/fstab

切换rootfs,安装grub. 再运行 update-grub 更新 grub 配置

1
2
3
4
cd /mnt/dst
chroot .
grub-install /dev/sdb
update-grub

退出 chroot, 关闭系统 shutdown now

  1. 弹出 live CD 和原来的磁盘 (在PVE中对应remove和detach)

  2. 重新启动新的系统,可能会遇到几个问题:

grub 菜单展示了 Ubuntu 但是回车进去报错 you need to load kernel first
这种情况应该是因为当前grub标签 (hd0,gpt2) 跟现实不匹配导致的. (也可能是前面忘记执行了update-grub)
在选择页面按下 c 进入 grub shell

1
2
3
4
5
6
7
8
9
ls -l 确认当前磁盘列表和磁盘的UUID
set prefix=(hd0,gpt2)/boot/grub 注意如果不是GPT格式应该用(hd0,msdos1)
set root=(hd0,gpt2)
insmod normal

insmod linux
linux /boot/vmlinuz root=UUID={磁盘的UUID}
initrd /boot/initrd.img
boot

此时应该就会进入系统了

  1. 如果前面忘了改 /etc/fstab 此时进入新系统后会卡在两个任务上:
1
2
Reached target ....
[ ***] Job dev-disk-by\x2duuid-.....device/start running (9s / 1min 30s)

这个没什么好办法,会卡两次,等三分钟就好了。进入系统后记得把 /etc/fstab 改了,运行 sudo grub-install && sudo update-grub 然后再重启应该就没问题了.

参考

Live-cloning a running Linux installation to a new machine

grub error: you need to load kernel first

How do I list my devices in GRUB?

[SOLVED] Creating a BIOS boot partition using gdisk

GPT fdisk - ArchWiki

How to Install Grub Bootloader in Linux

VMware workstation似乎有个bug, 当添加新的SCSI磁盘时VM内不会显示新的 /dev/ 块设备, 例如:

1
2
3
4
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 50G 0 disk
├─sda1 8:1 0 1M 0 part
└─sda2 8:2 0 50G 0 part /

此时通过VMware控制台添加一个200G的磁盘, 再运行 lsblk 并不会有任何变化.

需要执行以下脚本”刷新”:

1
2
3
for h in $(ls /sys/class/scsi_host); do
echo '- - -' > /sys/class/scsi_host/$h/scan
done

再运行 lsblk 就可以看到磁盘了:

1
2
3
4
5
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 50G 0 disk
├─sda1 8:1 0 1M 0 part
└─sda2 8:2 0 50G 0 part /
sdb 8:16 0 200G 0 disk

参考

[SOLVED] Virtual Hard Disk is added, but not showing using lsblk -d command

开发机从 Ubuntu Server 20.04.6 升级到 Ubuntu Server 24.04.1 LTS 版本, 没遇到什么大问题. 但是发现 podman 变成了 [installed,local] 版本, 没有被自动升级. 但是看了一下容器,镜像,Volume还在.

  1. 卸载当前版本

我之前用的是kubic社区的podman源, 需要先卸载 sudo apt remove podman 再删除掉apt能识别出来不再需要的依赖: sudo apt autoremove

此时如果直接安装新版本 podman 可能会有问题, 提示 /etc/containers/containers.conf 被包 containers-common 使用.

可以尝试: sudo apt remove containers-common buildah crun. 卸载前通过 sudo apt list --installed | grep installed,local 确认是否为本地版本.

还是不行的话就只能手动逐个卸载了:

1
2
3
sudo dpkg --remove crun
sudo dpkg --remove podman
sudo dpkg --remove containers-common

总之需要保证之前的版本都卸载掉. 不需要(也不要)运行 purge. 会丢失数据.

  1. 安装新版本

sudo apt install podman golang-github-containernetworking-plugin-dnsname

其中 golang-github-containernetworking-plugin-dnsname 这个不清楚为什么在 Ubuntu 24.04 源里名字这么奇怪, 根据文档来看应该是 podman-plugins 或者 podman-dnsname 才对. Podman 4.x 版本删除了 dnsname 这个插件, 导致通过 compose 拉起的容器组之间不能直接通过 service 名字做寻址.

这个名字是通过 sudo apt search dnsname 找到的.

如果不安装这个包, 可能会看到类似下面的错误:

1
WARN[0000] Error validating CNI config file /home/kiritow/.config/cni/net.d/wgop-net-wg0.conflist: [failed to find plugin "dnsname" in path [/usr/local/libexec/cni /usr/libexec/cni /usr/local/lib/cni /usr/lib/cni /opt/cni/bin]]

装完之后在 /usr/lib/cni 下应该会看到 dnsname 插件.

  1. 安装Docker-Compose

由于Docker Compose V2已经从pip包升级合并到docker命令了, 因此我们需要使用docker官网提供的docker-compose独立安装包: Install Compose standalone

注意: 之前提到的 Ubuntu 22.04 里面 containernetworking-plugins 的问题似乎已经解决了, 现在安装 podman 会正确的安装这个依赖包. 参考之前的文章

参考

containers/dnsname: name resolution for containers 这个插件现在已经archive了.

下面的参考没太大价值, 更多感觉还是要看 dnsname 这个插件的文档: Using the dnsname plugin with Podman

Podman network dns option not working with the DNS plugin enabled #20911

Impossible to override container’s DNS with network #17499

Small issues (and fixes) when moving to Ubuntu 23.04

Podman dnsname install issues

  1. 关闭swap

sudo vim /etc/fstab 把带有 /swap.img 的一行注释掉, 然后重启 sudo reboot

不想重启的话可以适用这条命令关闭swap sudo swapoff -a

  1. 准备容器运行环境
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 安装Containerd
curl -vL https://github.com/containerd/containerd/releases/download/v1.6.33/containerd-1.6.33-linux-amd64.tar.gz -O
sudo tar -xzvf containerd-1.6.33-linux-amd64.tar.gz -C /usr/local
wget https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
sudo mv containerd.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now containerd

# 安装 runc
curl -vL https://github.com/opencontainers/runc/releases/download/v1.1.13/runc.amd64 -O
sudo install -m755 runc.amd64 /usr/local/sbin/runc

# 安装 CNI
sudo mkdir -p /opt/cni/bin
curl -vL https://github.com/containernetworking/plugins/releases/download/v1.5.1/cni-plugins-linux-amd64-v1.5.1.tgz -O
sudo tar -xzvf cni-plugins-linux-amd64-v1.5.1.tgz -C /opt/cni/bin/

在root下执行 sudo su

1
2
mkdir /etc/containerd/
containerd config default > /etc/containerd/config.toml

编辑配置文件 vim /etc/containerd/config.toml

修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
BinaryName = ""
CriuImagePath = ""
CriuPath = ""
CriuWorkPath = ""
IoGid = 0
IoUid = 0
NoNewKeyring = false
NoPivotRoot = false
Root = ""
ShimCgroup = ""
SystemdCgroup = false # <--- 这里的false改为true
...

保存后重启服务 sudo systemctl restart containerd

  1. 配置网络 sudo vim /etc/sysctl.d/k8s.conf
1
net.ipv4.ip_forward=1

使其生效: sudo sysctl --system

  1. 安装kubeadm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

sudo apt-get update
# apt-transport-https may be a dummy package; if so, you can skip that package
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

# If the directory `/etc/apt/keyrings` does not exist, it should be created before the curl command, read the note below.
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
  1. 启动kubelet
1
sudo systemctl enable --now kubelet
  1. kubeadm创建集群 (可能需要一段时间)

这里的 --pod-network-cidr需要跟下面的flannel配置一样, flannel默认是 10.244.0.0/16

1
sudo kubeadm init --pod-network-cidr=10.77.0.0/16

看到这个就是创建成功了

1
2
3
Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

如果需要将其他节点加入到集群内但是忘记复制了安装之后的命令, 可以创建一个新的 bootstrap token, 有效期为1天. 会打印出用于加入集群的命令.

1
kubeadm token create --print-join-command
  1. 复制 kubectl 用到的配置
1
2
3
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
  1. 安装 Flannel
1
2
3
wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
sed -i s_10.244.0.0/16_10.77.0.0/16_g kube-flannel.yml
kubectl apply -f kube-flannel.yml

查看状态 kubectl get nodes

1
2
NAME        STATUS   ROLES           AGE     VERSION
lsp-k8s-1 Ready control-plane 5m17s v1.30.3

注意 Flannel 在新版Ubuntu Server (24.04)上可能会安装失败, log报错如下:

1
Failed to check br_netfilter: stat /proc/sys/net/bridge/bridge-nf-call-iptables: no such file or directory

参考以下方案解决:

1
modprobe br_netfilter

安装 Istio (可选)

1
2
3
4
curl -L https://istio.io/downloadIstio | sh -

istioctl x precheck
istioctl install

整合脚本

整合脚本是我在写完前面内容之后一段时间才整理出来的, 因为一直忙活GKE所以忘了整本地的集群. 这里面的版本可能跟前文的不太一样.

这个脚本需要在所有节点上运行. 创建集群, 加入集群命令不一样就不放到这里了.

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
37
38
39
40
41
42
43
#!/bin/bash
set -euxo pipefail
sudo swapoff -a

curl -vL https://github.com/containerd/containerd/releases/download/v1.7.24/containerd-1.7.24-linux-amd64.tar.gz -O
sudo tar -xzvf containerd-1.7.24-linux-amd64.tar.gz -C /usr/local
wget https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
sudo mv containerd.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now containerd

curl -vL https://github.com/opencontainers/runc/releases/download/v1.2.2/runc.amd64 -O
sudo install -m755 runc.amd64 /usr/local/sbin/runc

sudo mkdir -p /opt/cni/bin
curl -vL https://github.com/containernetworking/plugins/releases/download/v1.6.0/cni-plugins-linux-amd64-v1.6.0.tgz -O
sudo tar -xzvf cni-plugins-linux-amd64-v1.6.0.tgz -C /opt/cni/bin/

sudo mkdir -p /etc/containerd/
sudo containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i s/SystemdCgroup\ =\ false/SystemdCgroup\ =\ true/g /etc/containerd/config.toml

sudo systemctl restart containerd

echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/k8s.conf
sudo sysctl --system

sudo apt-get update
# apt-transport-https may be a dummy package; if so, you can skip that package
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

# If the directory `/etc/apt/keyrings` does not exist, it should be created before the curl command, read the note below.
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

sudo systemctl enable --now kubelet

注意, PVE环境下如果图省事用Clone VM创建更多节点, 需要使用这样一个脚本来确保Clone出来的机器能够正常使用. 需要在上面的脚本之前执行并重启. 参考 Proxmox如何完整的复制一个VM

1
2
3
4
5
6
7
8
set -xe
sudo vim /etc/hostname
sudo vim /etc/hosts
echo -n | sudo tee /etc/machine-id
sudo rm /var/lib/dbus/machine-id
sudo ln -s /etc/machine-id /var/lib/dbus/machine-id
sudo rm -rf /etc/ssh/ssh_host*
sudo dpkg-reconfigure openssh-server

参考

Creating a cluster with kubeadm

Fix sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables.

Ava Max - Salt (Lyrics) oh, oh oh oh oh oh↑ I’m all out of salt, I’m not gonna cry

Kelly Clarkson - Stronger (What Doesn’t Kill You) [Official Video]

突然的自我 伍佰AndChinaBlue ♫「等不完守候,如果仅有此生 又何用待从头」♫ 動態歌詞Lyrics Music ♫ White_Lyric

谭咏麟 - 卡拉永远Ok『不想归去挂念你 对影只得我自己』【動態歌詞Lyrics】

Press Play Walk Away - S3RL & Synthwulf Laptop DJ

【Future Bass】MYUKKE. - YUMEND

Will Sparks - Untouchable (feat. Aimee Dalton) [Official Music Video]

Blasterjaxx & Marnik - Heart Starts to Beat (Official Music Video)

《苹果香》狼戈 (哈族民歌) Apple Scent - Langge 六星街里还传来, 巴扬琴声吗

往期优秀作品推荐

2024年6月

最近在阿里轻量云买了一些机器, 同样都是1C/0.5G, Ubuntu 20.04 的机器运行非常正常, Ubuntu 22.04 的机器却隔一段时间就没有响应了. 具体表现为能ping通, 但是ssh登录会超时失败, 宿主机监控CPU/磁盘IO大涨. 登录VNC能看到类似这样的提示:

1
2
3
4
5
6
7
8
9
[44211.553196] Out of memory: Killed process 95466(apt-check) ... shmem-rss:0KB, UID:0 pgtables:300KB dom_score_adj:0
[44213.738115] systemd[1]: Failed to start Refresh fwupd metadata and update motd.
[63358.618014] Out of memory: Killed process 123118(apt-check) total-vm:190376KB ... UID:0 pgtables:364kB oom_score_adj:0
[63359.212458] systemd[1] : Failed to start Dailyapt download activities.
[74055.581349] Out of memory: Killed process 126756 (apt-check) total-vm:190376kB, ... UID:0 pgtables:376kB oom_score_adj:0
[121996.542525] Out of memory: Killed process 210249 (apt-check) total-vm:100788kB, ... UID:0 pgtables:228kB oom_score_adj:0
[121996.882131] systemd[1]: snapd.service: Watchdogtimeout (limit 5min)
[121997.311208] systemd[1]: Failed to start Dailyapt download activities.
[179235.303036] Out of memory: Killed process 292938(apt-check) total-vm:190376KB, ... UID:0 pgtables:372kB oom_score_adj:0

而这台机器已经关闭了apt自动更新, 一番搜索之后发现snapd可能会引起这个问题:

  1. snap list
1
2
3
4
Name    Version        Rev    Tracking       Publisher   Notes
core20 20240416 2318 latest/stable canonical✓ base
lxd 5.0.3-80aeff7 29351 5.0/stable/… canonical✓ -
snapd 2.63 21759 latest/stable canonical✓ snapd
  1. 删除snap各个包(有依赖关系)
1
2
3
sudo snap remove --purge lxd
sudo snap remove --purge core20
sudo snap remove --purge snapd
  1. 删除snap
1
2
sudo apt remove snapd
sudo apt purge snapd
  1. 添加apt配置文件防止snapd重新被安装回来

sudo vim /etc/apt/preferences.d/nosnap.pref

1
2
3
Package: snapd
Pin: release a=*
Pin-Priority: -10
  1. 清除apt缓存, 重新更新一下(可选)

sudo apt clean && sudo apt update

在完全删除掉snapd之后, 目前机器已经正常运行了两三天…

后续

后来发现还是不太行, 解决方案是给这个内存超级小的机器加上Swap. 因为阿里云没创建swap, 而且还把swappiness设置成了0! 为防止奇怪的事情发生, 弄成crontab脚本每分钟跑一下好了.

创建并启用swap

1
2
3
4
dd if=/dev/zero of=/swap.img bs=1M count=1024
chmod 600 /swap.img
mkswap /swap.img
swapon /swap.img

添加分钟级任务 sudo crontab -e

1
2
3
4
@reboot swapon -s | grep -q swap || swapon /swap.img
@reboot echo 60 > /proc/sys/vm/swappiness
* * * * * swapon -s | grep -q swap || swapon /swap.img
* * * * * echo 60 > /proc/sys/vm/swappiness

参考

Terminate unattended-upgrades or whatever is using apt in ubuntu 18.04 or later editions

How to Remove Snap Packages in Ubuntu Linux

How do I configure swappiness?

How to read oom-killer syslog messages?

How can I check if swap is active from the command line?

Linux Partition HOWTO: 9. Setting Up Swap Space

How to Clear RAM Memory Cache, Buffer and Swap Space on Linux

Swappiness: What it Is, How it Works & How to Adjust

设备是HP Ultrium 6-SCSI, 使用LTO-6磁带进行备份, 磁带空间大约为2TB

安装 mt-st 工具管理磁带

1
sudo mt -f /dev/nst0 status

返回大概是这样的

1
2
3
4
5
6
SCSI 2 tape drive:
File number=0, block number=0, partition=0.
Tape block size 0 bytes. Density code 0x5a (LTO-6).
Soft error count since last status=0
General status bits on (41010000):
BOT ONLINE IM_REP_EN

tar工具备份出来的tar包没有对文件顺序有明确的要求, 最终顺序由 readdir 决定, 某些情况下可能不符合要求, 可以提前生成一个文件列表提供给tar.

1
find tobackupdirname -print0 | sort -z > /tmp/filelist.txt

如果等待tar打包的文件总大小超过了磁带总大小, 需要启用MultiVolume支持 (建议在tmux内执行保证复制不会中断)

1
sudo tar -cvf /dev/nst0 -M --no-recursion --null -T /tmp/filelist.txt

这样tar就会在空间写满的时候提示换盘:

1
2
...
Prepare volume #2 for ‘/dev/nst0’ and hit return:

更换磁盘后回车, tar就会继续进行备份了

当然也可以尝试使用LTFS进行数据的备份, 此处不再赘述.

参考

How do I create a tar file in alphabetical order?

Tar Splitting Into Standalone Volumes