parted / fdisk —— 分区表管理
一句话定义
parted 和 fdisk 都是分区工具:在裸盘上创建/修改/删除分区表(GPT 或 MBR),把盘切成多个逻辑区。parted 更现代(支持 GPT、命令行脚本化、支持大盘),fdisk 更老(90% 教程仍在用、交互式更易)。
典型场景
- 装机:给新数据盘分区
- 云盘扩容:扩底层盘 → 扩分区 → 扩文件系统
- 检查分区表:
parted /dev/sdb print - K8s 准备 PVC 用的本地盘
- 修复损坏分区表
分区表两种:GPT vs MBR
| MBR | GPT | |
|---|---|---|
| 最大盘 | 2 TB | 9.4 ZB(无限) |
| 最大主分区数 | 4 | 128 |
| 备份 | 没有 | 表头 + 末尾各一份 |
| BIOS / UEFI | BIOS | UEFI(也兼容 BIOS) |
| 推荐场景 | 老系统 / 兼容性 | 新系统 / 大盘 / 默认选 GPT |
现代场景全用 GPT。除非你装老 Windows / 旧 BIOS 系统。
看现有分区表
parted /dev/sdb print
# Model: ATA Some Disk (scsi)
# Disk /dev/sdb: 500GB
# Sector size (logical/physical): 512B/4096B
# Partition Table: gpt
# Disk Flags:
#
# Number Start End Size File system Name Flags
# 1 1049kB 500GB 500GB ext4 data
或者 lsblk:
lsblk /dev/sdb
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
# sdb 8:16 0 500G 0 disk
# └─sdb1 8:17 0 500G 0 part /data
或者 fdisk(只读模式):
fdisk -l /dev/sdb
parted —— 现代用法(首选)
交互模式
parted /dev/sdb
(parted) print # 看
(parted) mklabel gpt # 创建 GPT 分区表(清空原表)
(parted) mkpart primary ext4 0% 100% # 建分区(用 0% / 100% 自动对齐)
(parted) print
(parted) quit
非交互(脚本里)
parted -s /dev/sdb mklabel gpt
parted -s /dev/sdb mkpart primary ext4 0% 100%
parted -s /dev/sdb print
-s script mode(不交互、不提示)。
-a optimal 加上对齐:
parted -a optimal -s /dev/sdb mkpart primary ext4 0% 100%
0% 和 100% 让 parted 自动算"最佳对齐"位置——避免性能损失。
fdisk —— 经典交互(更易学)
fdisk /dev/sdb
进入交互界面:
Command (m for help):
常用命令:
| 键 | 作用 |
|---|---|
g | 创建新 GPT 分区表 |
o | 创建新 MBR 分区表 |
n | 新建分区 |
d | 删除分区 |
p | 打印当前分区表 |
t | 改分区类型 |
w | 写入并退出(这一步才真生效) |
q | 不保存退出 |
m | 帮助 |
w之前所有改动都在内存里——q退出就什么没改。错了不要慌、q重来。
fdisk 新建分区一次流程
$ fdisk /dev/sdb
Command (m for help): g # GPT
Created a new GPT disklabel ...
Command (m for help): n # 新建
Partition number (1-128, default 1): <Enter>
First sector (...): <Enter> # 默认起始
Last sector (...): <Enter> # 默认用完整盘
Command (m for help): p # 验证
Disk /dev/sdb: 500 GiB ...
Command (m for help): w # 写入
The partition table has been altered.
关键流程:新盘的完整分区步骤
# 0. 看盘(确认是新盘 / 想格式化的盘!)
lsblk
# /dev/sdb 500G 空白
# 1. 创建 GPT 分区表
parted -s /dev/sdb mklabel gpt
# 2. 创建一个分区占满整盘
parted -a optimal -s /dev/sdb mkpart primary ext4 0% 100%
# 3. 看
parted /dev/sdb print
# Number Start End Size File system Name Flags
# 1 1049kB 500GB 500GB primary
# 4. 内核刷新(通常自动)
partprobe /dev/sdb
ls /dev/sdb*
# /dev/sdb /dev/sdb1 ← 看到 sdb1
# 5. 格式化(详见 mkfs.md)
mkfs.ext4 -L data /dev/sdb1
# 6. 挂载(详见 mount.md / fstab.md)
mkdir -p /data
mount /dev/sdb1 /data
在线扩容:扩盘后扩分区
云上经常这么干:先在控制台把云盘从 100G 扩到 500G,然后在系统里:
# 1. 确认底层盘大小变了
lsblk /dev/sdb
# /dev/sdb 500G
# └─/dev/sdb1 100G ← 分区还是 100G
# 2. 让 parted 扩展分区
parted /dev/sdb resizepart 1 100%
# 或交互式
parted /dev/sdb
(parted) print
(parted) resizepart 1 100% # 扩到 100%
# 3. 让内核知道(部分场景需要)
partprobe /dev/sdb
# 4. 看
lsblk /dev/sdb
# /dev/sdb 500G
# └─/dev/sdb1 500G ← 分区也 500G
# 5. 扩文件系统(详见 mkfs.md)
resize2fs /dev/sdb1 # ext4
# 或
xfs_growfs /data # xfs(参数是挂载点)
# 6. 看
df -h /data
Cloud 友好工具:growpart(cloud-utils 包)
apt install cloud-guest-utils
growpart /dev/sdb 1 # 扩 sdb 的分区 1 到剩余空间
growpart 比手动 parted 更安全,会做边界检查。云镜像里默认有。
看分区类型(GPT 类型 GUID)
parted /dev/sdb
(parted) print
# 1 ... data
GPT 分区有"类型 GUID"标识用途:
Linux filesystem——0FC63DAF-8483-4772-8E79-3D69D8477DE4(默认)Linux swap——0657FD6D-...Linux LVM——E6D6D379-...EFI System——C12A7328-...
设置类型:
parted /dev/sdb set 1 lvm on
parted /dev/sdb set 1 boot on # EFI
parted /dev/sdb set 1 swap on
K8s 数据盘通常不需要——默认类型够了。
删分区
parted -s /dev/sdb rm 1 # 删 sdb1
删之前先 umount + 备份。删了的分区表/数据基本不可恢复。
完整清盘(所有数据没了):
wipefs -a /dev/sdb # 清掉所有 fs / 分区表标记
# 或者
parted -s /dev/sdb mklabel gpt # 直接覆盖一个新空 GPT
fdisk vs parted —— 该用哪个?
| 场景 | 推荐 |
|---|---|
| 脚本 / 自动化 | parted -s |
| 交互学习 / 不熟悉 | fdisk |
| 大盘(> 2TB) | parted(fdisk 不支持 MBR 大盘) |
| 在线扩容 | parted resizepart |
| 看分区表 | 都行,parted print 或 fdisk -l |
| LVM / 复杂分区 | parted |
训练营建议:脚本里用 parted -s,手敲探索用 fdisk。
实战例子
Day0 给 m4 / m5 加数据盘
for h in m4 m5; do
ssh $h "
parted -s /dev/sdb mklabel gpt &&
parted -a optimal -s /dev/sdb mkpart primary ext4 0% 100% &&
sleep 1 && partprobe /dev/sdb &&
mkfs.ext4 -L k8s-data /dev/sdb1 &&
mkdir -p /var/lib/k8s-data &&
echo \"UUID=\$(blkid -s UUID -o value /dev/sdb1) /var/lib/k8s-data ext4 defaults,noatime,nofail 0 2\" >> /etc/fstab &&
mount -a &&
df -h /var/lib/k8s-data
"
done
云扩盘后在线扩容
# 在云控制台把云盘从 100G 扩到 500G
# 在节点上:
growpart /dev/sdb 1
resize2fs /dev/sdb1
df -h /var/lib/k8s-data # 显示 500G
常见踩坑
坑 1:分区名 /dev/sdb 还是 /dev/sdb1
mkfs.ext4 /dev/sdb ← 整盘格式化
mkfs.ext4 /dev/sdb1 ← 分区格式化
mount /dev/sdb /data ← 通常不工作(除非整盘 mkfs)
mount /dev/sdb1 /data ← 标准做法
parted / fdisk 操作的对象是整盘 /dev/sdb。mkfs / mount 操作的是分区 /dev/sdb1。
坑 2:分区表写完内核没识别
parted -s /dev/sdb mkpart primary ext4 0% 100%
ls /dev/sdb*
# 只看到 /dev/sdb,没 /dev/sdb1
内核需要刷分区表:
partprobe /dev/sdb
# 或
udevadm settle
# 或
kpartx -av /dev/sdb # LVM 工具
通常 partprobe 解决。最坏 reboot(极少需要)。
坑 3:mklabel 把现有数据全清
parted /dev/sdb mklabel gpt
# Warning: The existing disk label on /dev/sdb will be destroyed and all data on this disk will be lost.
# 跑下去 → 所有现有分区 + 数据消失
mklabel 是"重新初始化分区表",原表上的分区记录全没。文件系统数据本身可能没被覆盖(只是表指针没了),但已经不可访问、不可挂载——除非用专门数据恢复工具。
不要随意 mklabel 已有数据的盘。
坑 4:parted 'set' 和 'mkpart' 名字概念混
parted /dev/sdb mkpart primary ext4 0% 100% # 第二个参数 "primary" 是名字 / type
GPT 没有 primary / extended / logical 的概念(那是 MBR)——但 parted 接受 primary 作为兼容写法。这里"primary"实际是分区名字。
更清楚的写法:
parted /dev/sdb mkpart "data" ext4 0% 100%
parted /dev/sdb name 1 "data" # 也能改
坑 5:对齐错误 → 性能差
parted /dev/sdb mkpart primary 1MB 100GB # 1MB 起步可能没对齐 4K 物理扇区
加 -a optimal 或者起止位置用百分比:
parted -a optimal /dev/sdb mkpart primary 0% 100%
现代 SSD / 4K 扇区盘对对齐敏感,不对齐性能降 20-30%。
坑 6:resizepart 之后忘了扩 fs
parted /dev/sdb resizepart 1 100%
df -h /data
# 还是老大小
分区扩了 ≠ 文件系统扩了。必须再跑 resize2fs / xfs_growfs。
坑 7:误以为 parted resizepart 必须 umount
parted /dev/sdb resizepart 1 100%
# 在线就行
ext4 / xfs 都支持在线 resize 分区 + 在线扩 fs。不需要 umount。但缩通常要 umount(且 xfs 根本不能缩)。
坑 8:fdisk 退出后没 w
fdisk /dev/sdb
# 删了、建了 ... 全在内存里
q ← 不保存退出
# 啥都没变
只有 w 把更改写盘。q 是"反悔"。故意设计——避免误改。
坑 9:在 LVM PV 上跑 parted
LVM 用的盘 / 分区在 /dev/sdb 上有 LVM 元数据。parted 看不到 LV 视角。要管 LVM 用 pvcreate / vgcreate / lvcreate。
K8s local volume 一般直接用普通分区,避免 LVM 复杂性。