1. 云计算时代的Linux基本功:为什么命令行的手感决定你的天花板
接手云上业务这五六年,我最大的感受是:云平台的控制台和可视化面板确实越来越强,但真正决定一个运维或者后端工程师能走多远的,依然是Linux命令行的基本功。很多人在本地虚拟机里敲命令敲得飞起,一上云就露馅——安全组不会配、镜像不会选、磁盘不会挂载、日志不会排查,最后只能对着工单系统干瞪眼。
这篇笔记是我在实际云环境部署、迁移、排障过程中沉淀下来的实操记录,涵盖Linux常用命令、用户权限管理、文件处理、Docker容器化、网络性能诊断以及面试高频考点。所有内容都是我在真实环境里一步步试出来的,不是教科书式罗列,而是带着场景的实战复盘。无论是刚入行的运维新人,还是想把Linux功底夯实的后端开发,都可以对照这篇笔记在自己的云主机上过一遍。
先回答一个问题:为什么云环境里的Linux操作和本地不一样?核心差异有两点。第一,云主机的网络、存储、安全都是“软件定义”的,很多底层操作会通过云API间接影响系统行为,比如安全组规则和iptables的关系、云盘快照和LVM快照的区别。第二,云主机通常一开机就是最小化安装,没有桌面环境,没有图形工具,一切操作都靠Shell,这反而逼着你把命令行的底子打牢。所以,下面这些内容不是零散的知识点,而是一条完整的“从裸机到可用”的实操链路。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 云主机初始化:从裸机到可用的最短路径
2.1 新建用户与权限分配:别一上来就用root裸奔
拿到一台新云主机,第一件事不是急着装环境,而是建一个日常使用的普通用户。很多人图省事全程用root,出事的时候连操作审计都做不了。我的习惯是三步走:创建用户、设置密码、加入sudo组。
bash复制# 创建用户并指定家目录和Shell
useradd -m -d /home/deploy -s /bin/bash deploy
# 设置密码
passwd deploy
# 加入sudo组(CentOS系为wheel,Ubuntu系为sudo)
usermod -aG wheel deploy
# 验证切换
su - deploy
sudo whoami
这里有个细节容易被忽略:useradd和adduser在CentOS和Ubuntu上的行为不一样。CentOS的useradd默认不创建家目录,需要加-m参数;Ubuntu的adduser是交互式脚本,会自动创建家目录并设置密码。我建议在脚本化部署时统一用useradd加显式参数,避免不同发行版带来的差异。
权限分配这块,很多人只知道加sudo组,但sudo的权限粒度其实可以很细。比如我只想让某个用户能重启nginx,不想给他整个root权限,就在/etc/sudoers.d/下单独建文件:
bash复制# /etc/sudoers.d/nginx
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx
这样既能满足日常运维需求,又不会把整个系统的钥匙交出去。云环境里多租户隔离本来就是安全基石,本地操作习惯如果不同步升级,迟早要吃大亏。
2.2 SSH安全加固:云上主机的第一道防线
云主机的SSH端口默认22,从创建那一刻起就会被全网扫描器盯上。我每次开新机器都会按这个顺序加固,实测能挡掉99%的暴力破解。
第一步改端口。修改/etc/ssh/sshd_config,把Port 22改成一个高位端口,比如Port 62222。注意提前把新端口加入云平台的安全组规则,不然改完端口直接连不上。
第二步禁用密码登录、启用密钥对。这个在云平台创建机器时最好就配好密钥,后面再补也可以:
bash复制ssh-keygen -t ed25519 -C "deploy@cloud"
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 62222 deploy@<服务器IP>
然后修改sshd_config:
plaintext复制PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
AllowUsers deploy
第三步是fail2ban兜底。即使禁了密码登录,SSH服务本身的日志还是会刷屏,配置fail2ban可以自动封禁扫描IP,减少无意义的日志压力。我在生产环境用这个组合跑了两年,登录日志基本都是干净的。
2.3 系统更新与最小化安装原则
云主机初始化还有一个常被忽略的点:系统更新。我见过很多人的机器一开机就是各种旧版本依赖堆在那里,等到部署应用时才暴露出一堆兼容性问题。建议初始化时先跑一次全量更新:
bash复制# Ubuntu/Debian
apt update && apt upgrade -y
# CentOS/RHEL系列
yum update -y # 老版本
dnf update -y # 8以上
装软件包也是个学问。云上环境尽量遵循最小化安装原则,缺什么补什么,不要图省事把一整组开发工具都装上去。一是减少攻击面,二是降低系统组件之间的版本冲突概率。比如装nginx,就只装nginx本体,对应的nginx-mod-*模块按需添加,不要一键全部装上。
3. 存储与文件处理:云盘上的实战经验
3.1 解压文件乱码的根治方案
这个坑我踩了不止一两次。从Windows上传的zip包,在Linux下一解压,文件名全变成乱码。原因很简单:Windows的zip默认使用GBK/GB18030编码压缩文件名,而Linux下的unzip默认按UTF-8解码,两边对不上。
网上有各种临时办法,比如用Python脚本批量改名,但最省事的方案是装unar。这个工具会自动识别压缩包的编码并正确转码:
bash复制# Ubuntu/Debian
apt install -y unar
# 然后再解压
unar 中文文件名.zip
如果条件受限装不了unar,也有个折中方案,用Python的zipfile配合编码转换处理:
bash复制python3 -c "
import zipfile, os, sys
z = zipfile.ZipFile(sys.argv[1])
for f in z.infolist():
try:
name = f.filename.encode('cp437').decode('gbk')
except:
name = f.filename
z.extract(f, os.path.dirname(os.path.abspath(sys.argv[1])))
os.rename(os.path.join(os.getcwd(), f.filename), name)
" 文件名.zip
但说实话,这个Python方案有不少边界情况处理不干净,嵌套目录、重名文件都会出问题。生产环境我直接用unar,一劳永逸。
3.2 磁盘爆满排查:不只是df -h
云主机磁盘满了,第一反应是df -h看哪块盘占用高,这只是第一步。真正干活的时候要区分两种情况:文件占满和inode占满。
文件占满好理解,du -sh /*逐级往下查就能定位大文件:
bash复制du -h --max-depth=1 / | sort -hr | head -20
但inode占满是更隐蔽的坑。明明df -h显示还有十几G,但系统报错“No space left on device”。这种情况通常是某个目录下生成了海量小文件。我用这个命令排查:
bash复制df -i
find / -xdev -type f | wc -l
有次排查一个临时目录,发现里面有几十万个sess_开头的会话文件,全是PHP-FPM没清理干净的session,直接占满了inode。清理之后再给PHP-FPM配上session回收策略,问题才算根治。
云盘还有一个特性需要注意:普通云盘删除文件后,磁盘空间不会立即释放给系统,通常需要等云平台的后台回收任务执行。如果df -h显示空间没变化,不要急着重启,先等等看,或者用fstrim主动触发回收:
bash复制fstrim -v /
这个命令在SSD云盘上效果明显。传统机械盘不需要,但现在云平台基本都是SSD,这个操作可以纳入常规运维脚本。
3.3 日志管理:先学会删,再学会查
日志是排障的第一手资料,但日志文件本身也是磁盘杀手。系统日志、应用日志、nginx访问日志,跑个半年不清理,几十G空间就没了。我的策略是logrotate做轮转加压缩,保留周期根据业务重要性来定。
nginx日志的logrotate配置大概是这样的:
plaintext复制/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 640 nginx adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
这里有个细节:nginx轮转日志后要发USR1信号让它重新打开日志文件,否则nginx还是往旧文件里写。很多新手配了logrotate发现日志不轮转,八成是漏了这一步。
查日志也有技巧。tail -f看实时日志是最基础的,但真正排查问题时我会先用grep定位时间段,再用awk抽字段聚合统计。比如排查某段时间的5xx错误:
bash复制grep "2025-06-01T14:" access.log | awk '{print $9}' | sort | uniq -c | sort -rn
一行命令能告诉你那段时间各个状态码的分布,比肉眼刷屏高效得多。
4. 容器化入门:Docker在云环境里的正确打开方式
4.1 Docker安装与镜像加速配置
现在云上部署新服务,我基本都会优先考虑容器化。Docker的安装本身不复杂,官方给了很完整的脚本:
bash复制curl -fsSL https://get.docker.com | bash
systemctl enable --now docker
但国内网络环境下,拉取公共镜像会出现断流、超时。这个问题好在有成熟的解决方案:配置镜像加速器。不同云平台的加速器地址不一样,修改/etc/docker/daemon.json即可:
json复制{
"registry-mirrors": ["https://your-mirror-address"]
}
然后重启Docker生效:
bash复制systemctl daemon-reload
systemctl restart docker
配置完之后记得验证一下:
bash复制docker info | grep -A 5 "Registry Mirrors"
4.2 容器的资源限制与常用操作
容器不是免费的午餐,不限制资源的话,一个跑飞的应用能拖垮整台宿主机。我的习惯是创建容器时固定CPU和内存上限:
bash复制docker run -d \
--name web-server \
--cpus=2 \
--memory=2g \
--memory-swap=2g \
--restart=always \
-p 8080:80 \
nginx:1.24
--memory和--memory-swap设置成相同值,等于禁用了swap,防止容器把内存压力传导到宿主机。--cpus限制的是CPU配额,2表示最多用满两个核。
日常运维最常用的几个操作,我总结成一个速查表:
| 操作 | 命令 |
|---|---|
| 查看运行中的容器 | docker ps |
| 查看所有容器(含退出) | docker ps -a |
| 进入容器Shell | docker exec -it <容器名> /bin/bash |
| 查看容器日志 | docker logs -f --tail 200 <容器名> |
| 查看容器资源占用 | docker stats |
| 停止并删除容器 | docker rm -f <容器名> |
| 清理无用镜像 | docker image prune -a |
容器管理还有一个我强烈推荐的习惯:给容器打标签。--label project=xxx这种,在容器多了以后按项目筛选会非常方便。
4.3 容器与宿主机文件互操作的两个坑
第一个坑是文件权限。容器内进程默认以root运行,挂载宿主机的目录后,会在宿主机上生成root归属的文件。比如nginx容器把日志写到/var/log/nginx,宿主机上看这些文件全是root所有,后续清理脚本跑不动。我一般用-u参数指定容器运行用户,或者挂载前先把目录权限调好:
bash复制mkdir -p /data/nginx/logs
chown -R 1000:1000 /data/nginx/logs # nginx容器内用户UID通常是1000
docker run -d \
--name nginx \
-v /data/nginx/logs:/var/log/nginx \
nginx:1.24
第二个坑是容器重启后IP变化。如果应用间用容器IP通信,容器一重启IP就变了,服务直接挂掉。解决方案有两个:一是用--network自定义网络,容器间通过容器名互相访问;二是用--network host,容器直接复用宿主机的网络栈。云上生产环境,我推荐自定义网络加容器名通信,既隔离又稳定:
bash复制docker network create myapp
docker run -d --name db --network myapp mysql:8
docker run -d --name app --network myapp myapp:latest
这样app容器里访问数据库直接连db:3306就行,IP随便变。
5. 网络与性能排查:云上服务不慢的秘密
5.1 用iperf3实测网络带宽
很多人在云上定位性能问题,动不动就怀疑带宽不够,实际上目标主机之间的链路质量用iperf3测一下就清楚了。iperf3是Client/Server模式,先在一台机器上启动服务端,再用另一台机器当客户端去测。
服务端:
bash复制iperf3 -s
客户端:
bash复制iperf3 -c <服务器IP> -t 30 -P 4
-t 30表示测试30秒,-P 4表示用4个并发连接。这里有个关键点:默认是用TCP测,但如果想了解链路本身的裸带宽,可以加-u用UDP测:
bash复制iperf3 -c <服务器IP> -t 30 -u -b 100M
-b 100M指定目标带宽,测出来的结果会显示实际的丢包率和带宽。如果TCP测试结果远低于预期,而UDP测试丢包率很高,基本可以判断是网络链路质量或云平台带宽限速问题;如果TCP测试接近带宽上限,那问题大概率出在应用层/协议栈上,不用再折腾网络了。
加压测试时注意,-P的并发数不要一次开太大,我之前一次开16个并发,直接把测试机的CPU跑满了,反而测不出真实带宽。
5.2 DNS配置的典型问题
云主机上DNS解析出问题,表现很诡异:ping公网IP能通,但ping域名不通;curl某个网站超时,换一个又正常。这种问题八成是/etc/resolv.conf配置的问题。
现在主流发行版都带systemd-resolved,直接改/etc/resolv.conf会被系统覆盖。正确做法是修改netplan或NetworkManager的配置。Ubuntu 20.04以上用netplan的话,配置在/etc/netplan/下:
yaml复制network:
version: 2
ethernets:
eth0:
dhcp4: true
nameservers:
addresses: [223.5.5.5, 119.29.29.29]
修改后执行netplan apply生效。这里我踩过的坑是:有些云平台的DHCP会强制覆盖DNS配置,你手动改了netplan,重启网卡后又被拉回去。解决方法是设置dhcp4-overrides:
yaml复制network:
version: 2
ethernets:
eth0:
dhcp4: true
dhcp4-overrides:
use-dns: false
nameservers:
addresses: [223.5.5.5, 119.29.29.29]
另外排查DNS问题,dig比nslookup好用得多,尤其能看清楚响应时间和查询路径:
bash复制dig @223.5.5.5 www.example.com
指定DNS服务器查询,能快速确认是本地解析问题还是上游DNS故障。
5.3 进程与资源排查三板斧
云上应用变慢了,我先看三个东西:负载、内存、磁盘IO,对应uptime、free -h、iostat。大多数性能问题都能在这三步里定位到方向。
uptime看的是1分钟、5分钟、15分钟的负载均值。如果1分钟负载远高于15分钟,说明系统最近才开始繁忙;如果15分钟负载一直很高,那就是持续过载,要考虑扩容或者优化应用。
free -h看内存时不能只看available,还要关注swap的使用情况。swap用了不少但available充足,说明内存回收策略有问题;swap占用持续增长,多半是内存泄漏。
iostat看磁盘IO等待时间:
bash复制iostat -x 2 3
重点关注%util和await两列。%util接近100%说明磁盘已满负荷,await高于20ms说明IO延迟偏高。配合pidstat或者top按D状态进程过滤,就能找到具体是哪个进程在疯狂读写磁盘:
bash复制top -b -n 1 | grep D
一个D状态的进程如果长时间不消退,大概率是IO堵塞,这时候去看磁盘健康度和云平台的IOPS监控指标,比在系统里瞎试强得多。
6. 从实战到面试:Linux学习路线与高频考点
6.1 Linux面试高频考点拆解
带过不少新人,也当过面试官,我发现Linux相关的面试题来来回回就那么几个方向,但能真正答透的人不多。
第一个高频方向是常用命令。不是单问命令用法,而是给一个场景让你说出排查思路。比如“用户反馈网站访问慢,你怎么排查”,这种题考察的是命令的综合运用能力:先看uptime确认负载、再看top看进程、用vmstat看上下文切换、用iostat看磁盘、用ss看连接数、配合tcpdump抓包。能答出完整链路的人,基本功基本过关。
第二个方向是用户与权限。考rwx权限、umask、setuid/setgid/sticky bit这些概念。我建议认真对比一个文件在普通用户和root下执行的区别,把SUID占位符的实际行为理解透,比背一堆命令参数有用。
第三个方向是系统启动流程。从BIOS到GRUB再到内核初始化、systemd启动服务,这条链路是理解系统故障的基础,很多启动类问题都要靠这个知识链路去排查。
第四个方向是网络。ping、traceroute、ss、iptables这些工具的适用场景要说清楚。尤其iptables,至少要理解nat表和filter表的区别,以及云平台安全组和iptables之间的关系。
6.2 从命令到原理的进阶路径
Linux学习最容易陷入的误区是“背命令大全”。命令是工具,不是知识体系。我自己的经验是:用命令解决一个真实问题,比背二十条命令有用得多。装完系统,强迫自己不用可视化工具,把网卡配好、服务跑起来、日志查出来,走完这一遍,命令自然就记住了。
进阶的方向是理解内核机制。热搜词里有个“内核动态加载file_operations拦截read/write”,这个其实就是Linux内核模块开发的典型场景,属于比较深入的方向了。我自己也写过简单的字符设备驱动,理解file_operations结构体注册、read/write回调函数的实现逻辑之后,再回头看应用层的文件读写,视角完全不一样。
但说实话,如果不是做内核或驱动开发,普通运维不需要一上来就啃内核源码。先掌握系统调用和用户态工具就够了。比如strace跟踪一个进程的read/write系统调用,能看到应用到底在忙什么:
bash复制strace -p 12345 -e trace=read,write -f
这比动不动就重编译内核或者加载内核模块要实用得多。先会走再会跑,学习的路径不能跳步。
还有一个建议是留意国产化Linux系统的适配。这几年国产操作系统的使用场景越来越多,核心命令和标准发行版基本一致,但包管理器、服务管理这些细节可能有差异。会了CentOS和Ubuntu两套体系,再切到国产系统,大概只需要半天就能上手。
7. 写在笔记之后:几条实操心得
这些年在云上摸爬滚打,有几点体会特别深。第一,云平台是放大器,本地环境的问题在云上会被无限放大。比如本地VM内存不够顶多卡一下,云主机内存不够直接触发OOM,连带整个业务不可用。所以带云环境的操作,每一步都要留退路,改配置前先备份,删数据前先确认。
第二,能写脚本解决的事情不要手动操作。云上动辄几十台机器,手动敲命令一方面是效率低,另一方面是容易敲错。我平时习惯把重复操作写成Shell脚本或者Ansible playbook,哪怕只是简单的批量建用户、批量分发密钥,脚本化之后安全性和可追溯性都会好很多。
第三,日志和监控是运维的双眼。云平台自带的监控指标要认真看,配合系统层面的top、iostat、ss这些命令,双视角交叉验证,才能快速定位问题根因。我见过不少同行排障时只看云平台监控,系统内部的全是盲区,最后绕了一大圈才发现问题出在应用本身。
最后分享一个我一直在用的小习惯:每次处理完一个奇怪的线上问题,把排查思路、命令、结论写成一篇短文存下来,过一段时间回头看,会发现自己的知识体系在悄悄变厚。这篇Linux云计算实战笔记,某种意义上也是这些短文的汇总。如果你的目标是把Linux功底打扎实,不妨从这篇笔记里的场景开始,一台云主机练起来,遇到问题解决问题,慢慢就能形成自己的方法论。
