一台刚装好的Ubuntu服务器,摆在眼前的通常就是三件事:把IP配好,让系统别再随机漂移;把SSH调顺,省得每次都要跑到机房插键盘;再把磁盘空间规划明白,避免等根分区满了之后才开始后悔当初为什么没用LVM逻辑卷。这三件事看着独立,实际是一条线——网络不通SSH就连不上,SSH没法远程你就只能蹲在机器前面干活,而磁盘扩容如果安装阶段选了传统分区,等数据写满再想挪腾,那个酸爽程度足以劝退不少人。
这篇内容就是围绕这三个问题来的。我会从Ubuntu的IP配置(重点讲netplan的坑)、SSH的安全配置与排障,一路讲到LVM从原理到实操的完整扩容流程。整套方法在任何一台Ubuntu Server的物理机、虚拟机或云主机上都适用,哪怕你之前完全没碰过LVM,照着手敲一遍也能把磁盘扩明白,而且全程不用重启系统。
1. 装好系统后的第一关:IP配置不是"填个地址"那么简单
很多人的Linux网络启蒙还停留在/etc/network/interfaces,但Ubuntu从17.10开始默认就换成了netplan,到了18.04之后的LTS版本,netplan基本就是唯一选择了。第一次用的人很容易栽跟头——改完yaml文件习惯性地敲systemctl restart networking或者service network-manager restart,结果网络要么没变化,要么直接断连,最后只能乖乖跑回物理控制台。
1.1 先搞清楚你的Ubuntu用的是哪套网络管理方案
判断方式很简单,先看有没有netplan目录:
ls /etc/netplan/如果看到00-installer-config.yaml、01-netcfg.yaml这类以yaml结尾的文件,说明走的就是netplan。如果是老系统,看/etc/network/interfaces是否存在。另外还可以看当前系统里实际生效的IP是哪来的:
ip a如果看到网卡上标着inet地址,说明已经拿到IP了;如果只有inet6甚至什么都没有,那就要看是不是网卡在netplan里根本没被启用。
Ubuntu 20.04和22.04的Server版安装器默认生成的配置文件是/etc/netplan/00-installer-config.yaml,内容通常极其简单:
network: ethernets: ens33: dhcp4: true version: 2这种配置走的是DHCP,适合临时用。但如果要当服务器,IP漂移是个大问题——哪天DHCP租约变了,你的SSH连接就断了,所以静态IP基本是必须的。
1.2 netplan静态IP配置实战
改之前建议先备份:
sudo cp /etc/netplan/00-installer-config.yaml /etc/netplan/00-installer-config.yaml.bak然后编辑(文件名以自己的实际为准):
network: version: 2 renderer: networkd ethernets: ens33: dhcp4: false addresses: - 192.168.1.100/24 routes: - to: default via: 192.168.1.1 nameservers: addresses: - 223.5.5.5 - 8.8.8.8里面几个细节值得单独说一下:
renderer: networkd是Ubuntu Server的默认选择,NetworkManager通常用于桌面版。如果用Ubuntu Desktop但想保持和Server一致,也可以指定networkd。这个字段如果不写,netplan会自己猜,但显式写出来更稳妥。gateway4这个写法在老教程里很常见,但netplan新版本里已经废弃了,敲netplan generate会有警告,建议直接用routes段配置默认路由。- 缩进必须严格用两个空格,netplan的yaml解析器对格式极其苛刻,
eth0和ens33这类网卡名必须和ip a里看到的完全一致,少个e多个3都会报错。
配置保存之后,先做一次试运行,不要直接apply:
sudo netplan try这个命令会在10秒内测试新配置,如果网络正常就输入y确认;如果配置有问题把网络搞断了,等它超时自动回滚。我第一次配的时候就是靠这个命令救回来的,配错了也不至于跑机房。
确认没问题后再正式应用:
sudo netplan apply ip a看到网卡上出现预期IP、默认路由也正常,第一关就算过了。
1.3 配置完网络还是不通?从这几个方向快速定位
IP配进去了、路由也写了、DNS也填了,但就是ping不通外网,或者能ping通IP但域名解析不了。这种情况我在实际排障中遇到太多次,常见原因无非这么几类:
| 现象 | 大概率原因 | 排查命令 |
|---|---|---|
| 网卡有IP,但ping网关不通 | 网卡没启用或对端物理隔离 | ip link set ens33 up/ 查网线交换机 |
| ping IP通,ping域名不通 | DNS配置缺失或写错 | cat /etc/resolv.conf/nslookup baidu.com |
| apply后配置消失 | netplan文件语法错误导致回滚 | sudo netplan generate看报错 |
| 多网卡服务器IP错乱 | 接口名绑定不牢 | 检查配置文件是否用错了网卡名 |
还有一个Ubuntu 22.04之后才容易踩的坑:/etc/resolv.conf默认是systemd-resolved管理的软链接,你手动改这个文件,重启后就被覆盖回去了。正确做法是在netplan的nameservers段里配置DNS,然后交给systemd-resolved去处理。
2. SSH从"能连"到"好用":安全与便利的平衡
IP配好了,下一步就是把SSH彻底调顺。很多人只装了openssh-server能连上就完事了,但生产环境里SSH配置往往决定了你能不能安安稳稳睡个好觉——默认配置下,只要IP暴露在公网,扫描和暴力破解是24小时不停的。
2.1 最小可用配置:先让sshd跑起来
新装的Ubuntu Server如果安装时勾选了openssh,一般已经装了。没装就手动来:
sudo apt update sudo apt install openssh-server sudo systemctl status ssh注意服务名是ssh不是sshd,Ubuntu的systemd服务别名继承自Debian,写systemctl status sshd会提示找不到服务,这个习惯让不少人卡了好几秒。
能用密码登录之后,就要开始动手改/etc/ssh/sshd_config了。我的习惯是先备份再编辑:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak sudo vim /etc/ssh/sshd_config一份偏稳妥的基础配置长这样:
Port 22022 PermitRootLogin prohibit-password PasswordAuthentication yes PubkeyAuthentication yes X11Forwarding no ClientAliveInterval 120 ClientAliveCountMax 3Port 22022是换掉默认22端口,目的就是降低被扫描命中的概率,不是绝对安全但能少掉90%的爆破噪音。PermitRootLogin prohibit-password允许root用密钥登录但禁止密码登录,这个值是Ubuntu的默认值,没有特殊需求不要改成yes。ClientAliveInterval是保活参数,防止长时间挂机被中间网络设备静默断开。
改完检查语法再重启:
sudo sshd -t sudo systemctl restart sshsshd -t语法检查这一步别省,配置写错直接重启会导致连不上SSH,只能又跑回物理控制台改回来。
2.2 公钥登录配置与权限陷阱
密码登录虽然方便,但密码总归有被蹭的风险。用密钥登录才能真正省心。在客户端机器上生成密钥对:
ssh-keygen -t ed25519 -C "your_comment"现在新项目我基本都用ed25519,性能和安全性都比RSA好一个档位,只有极老的系统才需要用RSA兼容。生成之后把公钥推到服务器上:
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 22022 user@server_ip如果ssh-copy-id因为端口问题不好使,也可以手动追加:
cat ~/.ssh/id_ed25519.pub | ssh -p 22022 user@server_ip "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"权限问题是密钥登录失败的重灾区。~/.ssh目录必须是700,authorized_keys文件必须是600,owner必须是当前用户,这三条缺一条都会登录失败。很多人明明公钥放进去了就是连不上,ssh -v一看,server拒绝了pubkey,基本都是权限问题。
确认密钥能正常登录后,再把PasswordAuthentication改成no:
PasswordAuthentication no这样密码登录通道就彻底关了。之后就算有人拿到了你的用户名和弱密码,也没法直接进来。
2.3 SSH连不上的排查链路
我收到过太多次“SSH连不上,求救”的消息,每次都是同一套排查链路。先站在客户端看:
ssh -v -p 22022 user@server_ip-v参数会输出详细的握手过程。如果卡在Connection timed out,大概率是网络层面的问题,先ping一下服务器IP,再查防火墙。如果提示Connection refused,说明端口没人监听,要么sshd没起来,要么端口写错了。如果卡在Offering public key之后被拒绝,那就回上面看权限配置和PasswordAuthentication开关。
服务器端还要查一下监听状态:
sudo ss -tlnp | grep ssh正常情况下能看到*:22022在监听。如果只有127.0.0.1:22022,说明sshd只绑了本机回环地址,外部永远连不上,这个在改过ListenAddress的人里特别常见。
别忘了防火墙这一层。Ubuntu自带的ufw如果开着,检查一下端口有没有放行:
sudo ufw status sudo ufw allow 22022/tcp云主机用户还要确认安全组或防火墙策略里放行了对应端口。我遇到过几次“本地防火墙没拦、sshd正常监听、就是连不上”的情况,最后都是云平台安全组漏了端口。这个环节最容易忽略,但排查成本最高,一定放第一个查。
2.4 顺手加三道防护:端口、白名单、失败锁定
SSH暴露在公网,不搞点防护总觉得不踏实。除了改端口,我常用的还有三招:
第一招是AllowUsers白名单。在sshd_config里加一行:
AllowUsers user1 user2效果很直接:除了名单里的人,其他账号一律拒绝登录。这样就算有人猜到了别的用户名也没用。
第二招是fail2ban。它通过扫描SSH日志,对反复认证失败的IP进行临时封禁:
sudo apt install fail2ban sudo systemctl enable fail2ban sudo systemctl start fail2ban默认配置文件在/etc/fail2ban/jail.conf,实际使用建议复制成jail.local再改:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local sudo vim /etc/fail2ban/jail.local里面有现成的[sshd]段落,把enabled = true打开就行。实测下来,公网服务器上fail2ban平均一天能挡掉几百次恶意探测,后台日志清净不是一点半点。
第三招是限制root远程登录。把PermitRootLogin保持为prohibit-password,同时习惯性用一个普通用户登录,需要用root权限时再su -或者sudo。很多系统管理员喜欢直接root干活,但日志审计和风险控制的角度来看,这真不是一个好习惯。
3. 为什么磁盘扩容要优先考虑LVM:一个运维老手的选型逻辑
网络通了、SSH也能远程登录了。此时如果还处于系统刚装好的状态,正好是最适合重新审视磁盘规划的时间点。很多人装机时一路回车,稀里糊涂就把整块硬盘挂成了单个分区。等到某天df -h看到根分区100%,想扩才发现分区在磁盘末尾、前边全是数据,挪也挪不动,扩也扩不了,只能加新盘或者重装系统。
3.1 传统分区的坑与LVM的抽象层思维
传统分区表的逻辑是这样的:磁盘被切成若干固定大小分区,文件系统直接建在分区上。分区和磁盘的关系是一锤子买卖,建多大就是多大,想改大小就得在数据不动的前提下重新划分,而且根分区这种已经被挂载、正在被系统使用的分区,在传统工具下几乎无法在线操作。
LVM(Logical Volume Manager)解决的就是这个问题。它的思路是加了一个抽象层,把物理磁盘先统一纳入一个大池子,然后你从这个池子里随时划空间给逻辑卷用:
物理磁盘/分区(PV) → 资源池(VG) → 逻辑卷(LV) → 挂载文件系统传统分区相当于盖房子之前就把每间屋子大小定死了;LVM则相当于先把一整块地征下来,里面每个房间想扩就扩、想缩就缩。三层结构中,PV是物理卷,VG是卷组,LV是逻辑卷。它们对应关系可以简单记成:PV是原材料,VG是仓库,LV是最终领出来的商品。
LVM最核心的好处在于,当仓库不够用时,你只需要把一块新硬盘变成PV,然后vgextend进现成的VG,再lvextend给指定LV扩容。整个过程不需要卸载分区、不需要重启系统、不必停机,文件系统还是那个文件系统,数据完全无损。
3.2 安装阶段就该做的LVM规划(还没装的看这里)
Ubuntu Server安装器在分区这一步默认就有“使用LVM”的选项,但很多人不知道那是干什么的就跳过了。这里强烈建议:如果是装服务器,分区方案直接选“使用整个磁盘并设置LVM”。
进入自定义分区界面后,能够看到安装器自动创建了一个LVM卷组,通常是ubuntu-vg,下面有ubuntu-lv作为根分区。这时候你可以顺手做一件让自己未来省心的事:给ubuntu-lv只分配系统现在需要的空间(比如60GB),剩余空间留在VG里备用。日后无论是给根分区扩还是新建一个数据卷,都不用等加物理磁盘,直接在VG里划就好了。
有人会问,那我干脆把所有空间都给了根分区,以后不够了再扩不也一样吗?关键就在这——如果VG里没有预留空间,扩容就必须先物理加盘;如果VG里有预留,你就是从仓库直接调货,一步到位。而且Ubuntu的LVM安装模式下,逻辑卷名和卷组名都是固定的,相关命令照着本文输入就能用,几乎不需要额外适配。
4. 实操:把一块新磁盘平滑并入现有LVM卷组
接下来是整篇内容的重头戏。假设当前系统是一台跑了一段时间的Ubuntu服务器,根分区所在的VG已经用了大半,现在管理员往机器上加了一块新硬盘,目标就是让它变成LVM的一部分,给根分区或数据卷扩出空间。整个过程在系统运行状态下完成,不用重启。
4.1 Step 1 确认现状:先拍照再动刀
动任何存储操作之前,先把家底摸清楚。需要看的东西有五个维度:
# 查看物理磁盘与分区 sudo lsblk # 查看文件系统使用情况 sudo df -h # 查看物理卷 sudo pvs # 查看卷组 sudo vgs # 查看逻辑卷 sudo lvs我习惯把这五个命令的输出都记录下来再继续。实际操作中,lsblk能看到新加的磁盘,比如/dev/sdb没分区也没挂载;vgs能看到现有卷组的名称和剩余空间,比如卷组名叫ubuntu-vg,剩余空间是0;lvs能看到根逻辑卷的路径,通常是/dev/ubuntu-vg/ubuntu-lv。
这里有一个新手最容易犯的错:以为加完硬盘就能直接mkfs挂载使用,完全绕开了LVM。但这样一来新硬盘就成了独立分区,以后再扩容又回到传统分区的老路。既然系统用了LVM,新盘就该先收编进VG里统一管理。
4.2 Step 2 让系统认识新磁盘
如果新加的磁盘在lsblk里看不到,先别慌。物理机上可能是SCSI控制器没有自动扫描到新设备,可以手动触发重新扫描:
echo 1 | sudo tee /sys/class/scsi_host/host0/scan echo 1 | sudo tee /sys/class/scsi_host/host1/scan云主机上如果看不到,通常是因为云控制台做了“挂载”操作后,系统里还没有识别,可以试试重新扫描或者直接重启一下(云盘挂载场景不常用重启,但确实有效)。看到/dev/sdb出现在lsblk里之后,下一步决定是整块盘做PV还是分区后再做PV。
我的建议是:直接用整块磁盘做PV,不要先分区。LVM本身就能直接管理/dev/sdb这种块设备,不需要再走一遍fdisk建分区。只有一种情况需要先分区,就是磁盘上有一部分空间要留给其他用途,比如系统盘和数据盘分开放。绝大多数场景下,整盘PV最省事,而且后续扩容也不受分区表边界的影响。如果确实要分区,命令如下:
sudo parted /dev/sdb mklabel gpt sudo parted /dev/sdb mkpart primary ext4 1MiB 100%分区后系统里会多出/dev/sdb1。如果不分区,直接跳到下一步。
4.3 Step 3 扩展卷组与逻辑卷
把磁盘变成物理卷:
sudo pvcreate /dev/sdb如果之前分了区,这里写/dev/sdb1即可。执行完可以用sudo pvs确认新PV已经出现。
然后把PV加入现有VG。这里的卷组名称以上一步vgs查到的为准,Ubuntu默认是ubuntu-vg:
sudo vgextend ubuntu-vg /dev/sdb再查一次vgs,应该能看到VG的剩余空间从0变成了新磁盘的大小。到这里,磁盘已经进入了LVM的“仓库”,但逻辑卷还没变大,系统也还没多出空间。这一步不完成,扩容等于没做。
现在把VG里的可用空间全部划给根逻辑卷:
sudo lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv-l +100%FREE的意思是“把当前VG所有剩余空间都扩展给这个LV”,这个写法比每次手算具体大小可靠得多,也是我日常最常用的方式。如果只想扩固定大小,可以用-L +20G,不过既然VG里空间都空着,直接全给通常是最合理的。
4.4 Step 4 文件系统扩容:ext4与XFS两条路
LV扩展完,操作系统已经能看到新的块设备大小了,但文件系统还停留在旧尺寸。这一步是最多人漏掉的关键环节——只扩LV不扩文件系统,df -h里看到的可用容量纹丝不动。
这一步取决于根文件系统用的是ext4还是XFS。先查一下:
sudo findmnt -no FSTYPE /如果是ext4,用resize2fs:
sudo resize2fs /dev/ubuntu-vg/ubuntu-lv如果是XFS,用xfs_growfs:
sudo xfs_growfs /注意两个命令的参数形式完全不同。resize2fs后面跟设备路径,xfs_growfs后面跟挂载点路径。而且XFS只支持扩容不支持收缩,这一点和ext4不一样,后面会细讲。
执行完后再看df -h,根分区应该已经变大了。整个过程不需要卸载挂载点,不需要下架服务,真正的热扩容。
| 文件系统 | 在线扩容工具 | 参数写法 | 能否收缩 |
|---|---|---|---|
| ext4 | resize2fs | resize2fs /dev/vg/lv | 可以,但限制多 |
| XFS | xfs_growfs | xfs_growfs /挂载点 | 不可以 |
| btrfs | btrfs filesystem resize | max /挂载点 | 可以,但LVM组合较少见 |
5. 扩容之后:验证、回滚思维与典型翻车现场
扩容流程走完之后,很多人以为就万事大吉了,但真实生产环境里最重要的其实是最后这一步——验证和防护。我见过几个翻车案例,基本都是忽略了这个环节。
5.1 扩容效果验证与误操作回滚
扩完先确认几个数字都对得上:
sudo df -h sudo pvs sudo vgs sudo lvs理想状态是:df -h显示根分区容量变大;vgs显示VG剩余空间归零或变小;lvs显示LV大小变大。如果三者不一致,说明中间某一步漏了。
如果不小心扩错了逻辑卷、或者扩大了不想扩的那个,也还有回旋余地,前提是文件系统还没有执行resize2fs。这种时候可以直接缩减LV:
sudo lvreduce -L -10G /dev/ubuntu-vg/ubuntu-lv把多余的10G从LV里退回去,VG空间就还原了。这是唯一安全的回滚路径。如果已经执行了resize2fs,再想缩文件系统就麻烦得多——ext4虽然支持resize2fs配合lvreduce缩容,但一般要求先卸载分区,而根分区卸载基本等于自杀式操作。所以我的经验是:扩容前先确认目标LV对不对,扩完先验证再收工。
5.2 我见过的翻车案例与背后的教训
这些年看到过不少人在LVM扩容上栽跟头,总结下来主要有这么几类:
第一类是“扩了等于没扩”。这是出现频率最高的问题——LV明明扩了,df -h就是不变。原因基本都是忘了最后一步文件系统扩容。每次遇到这种求助,我都会先问“resize2fs或xfs_growfs执行了吗”,十次有八次对方一脸茫然。请大家记牢:lvextend是给逻辑卷扩容,resize2fs/xfs_growfs才是在文件系统层落实空间,两者缺一不可。
第二类是“新硬盘被挂成了独立分区”。操作倒是成功了,df -h也能看到新空间,但以后这块盘的空间用完,又得走一遍老路。LVM存在的意义就在这——统一管理、动态分配。既然用了LVM,新盘就应该先进VG,再分配给LV,不要贪图一时方便直接mkfs挂载。
第三类是在XFS文件系统上尝试收缩逻辑卷。XFS的设计就是不支持缩容,lvreduce强行把底下LV缩小之后,文件系统元数据还在原来的位置,再挂载就是一堆I/O错误,严重了直接数据损坏。所以看到文件系统是XFS,任何“缩”的想法都要立刻打消。
第四类是操作前没有备份就开始动存储。扩容本身是低风险操作,但“低风险”不等于“零风险”。如果是云主机,最先做的应该是在控制台打一个快照;物理机就尽量把关键数据先做一份备份。这样就算真出了岔子,花钱花时间也能救回来,不至于只能对着黑屏发呆。
5.3 一些散落但重要的习惯
最后聊几个不属于完整步骤、但实际运维里特别有用的习惯。
对于新扩容的分区,建议在/etc/fstab里记录挂载信息时要写UUID而不是设备名。比如新建了一个数据卷/dev/ubuntu-vg/data-lv并挂载到/data,可以在fstab里这样写:
UUID=$(sudo blkid -s UUID -o value /dev/ubuntu-vg/data-lv) sudo mkdir -p /data echo "UUID=$UUID /data ext4 defaults 0 2" | sudo tee -a /etc/fstab sudo mount -a用blkid动态获取UUID再写入,这样即使设备路径在重启后发生了变化,挂载也不会失效。
部署监控也是一件要做在前面的事。df -h要养成随手看的习惯,更规范的做法是给服务器配上磁盘使用率的监控告警,比如Prometheus + Grafana或云平台的监控插件,在磁盘用到85%之前就发出预警。很多扩容需求其实不该等到“满了才扩”,而是“快满了就扩”,这个节奏调整好,急活就变成了日常维护。
另外强调一个云环境和物理机环境的差别:物理机加盘后可能需要重新扫描SCSI总线才能识别,云主机通常还得在控制台先完成挂载,之后再进系统操作。不同云厂商流程稍有不同,但LVM这层的操作完全一致。练好一套LVM操作,到哪都吃得开。
在最后想再分享一个实际操作的小提醒。当你执行lvextend -l +100%FREE时,如果VG里同时有好几个LV,这个命令会把VG所有剩余空间全部给当前LV。生产环境里如果VG要让多个LV共享,建议改用-L +20G这种精确扩容,而不是一股脑全给。虽然多算一步,但能避免把某个LV撑得过大、而另一个需要空间的LV却没得用。简而言之:LVM的灵活是拿来规划用的,不是拿来偷懒用的。合理预留、按需分配,这套逻辑想清楚,磁盘管理就不再是头疼事了。