别再被Linux网络配置折磨了!一文搞定CentOS、Ubuntu、RHEL网络设置的那些坑
最近在群里看到好多小伙伴都在问Linux网络配置的问题,有的说CentOS 7升级到8之后网络配置文件找不到了,有的说Ubuntu的netplan怎么这么难用,还有人抱怨RHEL的网络服务老是起不来。我也是被这个问题搞得焦头烂额,有一次配置服务器网络,折腾了一很久,最后发现是NetworkManager和network服务冲突了...
今天就来聊聊Linux网络配置这个话题,把我这些年踩过的坑和总结的经验分享给大家。
为什么Linux网络配置这么复杂?
说起来也挺无奈的,Linux发行版那么多,每个都有自己的网络配置方式。RedHat系的用一套,Debian系的用另一套,新版本又和老版本不一样。就像我们平时用的手机,安卓和iOS操作方式完全不同,同一个品牌的不同版本界面也会变。
我记得刚开始接触Linux的时候,用的是CentOS 6,网络配置还算简单,就是编辑/etc/sysconfig/network-scripts/下面的配置文件。后来CentOS 7出来了,多了个NetworkManager,配置方式又变了。再后来CentOS 8直接把network服务给废弃了,只能用NetworkManager。你说这不是折腾人吗?
不过话说回来,这些变化也不是没有道理的。新的网络管理工具确实功能更强大,支持动态配置,图形界面也更友好。只是我们这些搞运维的,总是要适应各种变化。
CentOS系列的网络配置
先说说CentOS,这个应该是大家接触最多的发行版了。
CentOS 6/7 传统配置方式
在CentOS 6和7上,最传统的方式就是直接编辑配置文件。网卡配置文件一般在/etc/sysconfig/network-scripts/目录下,文件名格式是ifcfg-网卡名。
# 查看网卡名称
ip addr show
# 或者用老命令
ifconfig -a
比如我要配置eth0网卡的静态IP,就编辑/etc/sysconfig/network-scripts/ifcfg-eth0文件:
TYPE=Ethernet
BOOTPROTO=static
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=192.168.1.100
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=8.8.8.8
DNS2=8.8.4.4
这里有几个参数需要注意:
- BOOTPROTO:启动协议,static表示静态IP,dhcp表示动态获取
- ONBOOT:开机是否启动网卡,一般设置为yes
- IPADDR:IP地址
- NETMASK:子网掩码,也可以用PREFIX=24这种CIDR格式
- GATEWAY:网关地址
配置完成后重启网络服务:
systemctl restart network
# 或者只重启某个网卡
ifdown eth0 && ifup eth0
我之前遇到过一个坑,就是配置文件里有多余的空格或者特殊字符,导致网络服务启动失败。所以编辑配置文件的时候一定要小心,最好用vim的话开启语法高亮。
CentOS 7/8 NetworkManager方式
CentOS 7开始引入了NetworkManager,这个工具确实方便很多,支持命令行和图形界面配置。
用nmcli命令可以很方便地配置网络:
# 查看网络连接状态
nmcli con show
# 配置静态IP
nmcli con mod eth0 ipv4.addresses 192.168.1.100/24
nmcli con mod eth0 ipv4.gateway 192.168.1.1
nmcli con mod eth0 ipv4.dns "8.8.8.8 8.8.4.4"
nmcli con mod eth0 ipv4.method manual
# 激活配置
nmcli con up eth0
NetworkManager的好处是配置立即生效,不需要重启网络服务。而且它会自动生成传统的配置文件,兼容性比较好。
不过我发现有些同事不太习惯用nmcli,觉得命令太长记不住。其实可以用tab键自动补全,多用几次就熟悉了。
RHEL 8/9 的变化
RHEL 8开始,传统的network服务被完全移除了,只能使用NetworkManager。这个变化刚开始确实让人不适应,特别是一些自动化脚本需要重写。
RHEL 9又引入了一些新特性,比如更好的网络团队(team)和绑定(bond)支持。不过基本的配置方式和RHEL 8差不多。
Ubuntu系列的网络配置
Ubuntu的网络配置和CentOS完全不同,特别是从18.04开始引入netplan之后,很多人都不太适应。
Ubuntu 16.04及之前版本
老版本的Ubuntu使用的是/etc/network/interfaces文件:
# 静态IP配置
auto eth0
iface eth0 inet static
address 192.168.1.100
netmask 255.255.255.0
gateway 192.168.1.1
dns-nameservers 8.8.8.8 8.8.4.4
# DHCP配置
auto eth0
iface eth0 inet dhcp
配置完成后重启网络:
sudo /etc/init.d/networking restart
# 或者
sudo service networking restart
这种配置方式比较直观,语法也不复杂。但是功能相对简单,不支持一些高级特性。
Ubuntu 18.04+ Netplan配置
从18.04开始,Ubuntu引入了netplan作为网络配置工具。配置文件是YAML格式,位于/etc/netplan/目录下。
# /etc/netplan/01-netcfg.yaml
network:
version: 2
renderer: networkd
ethernets:
eth0:
dhcp4: false
addresses:
- 192.168.1.100/24
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
应用配置:
sudo netplan apply
YAML格式对缩进要求很严格,必须用空格不能用tab。我刚开始用的时候经常因为缩进问题导致配置失败,后来养成了用vim显示空白字符的习惯。
netplan的好处是支持多种后端(networkd和NetworkManager),配置也比较灵活。但是YAML语法确实需要适应一下。
Debian系列配置
Debian的网络配置和Ubuntu早期版本类似,主要使用/etc/network/interfaces文件。
# /etc/network/interfaces
source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 192.168.1.100/24
gateway 192.168.1.1
DNS配置在/etc/resolv.conf文件中:
nameserver 8.8.8.8
nameserver 8.8.4.4
重启网络服务:
sudo systemctl restart networking
Debian 11开始也可以选择使用NetworkManager,但默认还是传统的配置方式。这个不错,我很喜欢!
网络配置的常见问题和解决方案
网卡名称变化问题
现在的Linux系统网卡名称不再是传统的eth0、eth1,而是类似ens33、enp0s3这样的名称。这是因为systemd引入了可预测的网络接口命名规则。
如果想改回传统命名,可以在grub配置中添加参数:
# 编辑/etc/default/grub
GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"
# 更新grub配置
grub2-mkconfig -o /boot/grub2/grub.cfg
不过我个人建议还是适应新的命名规则,因为它确实更稳定,不会因为硬件变化导致网卡名称改变。
NetworkManager和network服务冲突
在CentOS 7上,如果同时启用了NetworkManager和network服务,可能会出现冲突。一般建议只使用其中一个:
# 使用NetworkManager
systemctl enable NetworkManager
systemctl disable network
# 或者使用传统network服务
systemctl enable network
systemctl disable NetworkManager
DNS配置不生效
有时候配置了DNS服务器,但是解析还是有问题。这可能是因为/etc/resolv.conf被其他程序覆盖了。
在使用NetworkManager的系统上,DNS配置应该通过NetworkManager设置,而不是直接编辑/etc/resolv.conf。
网络配置后无法连接
配置静态IP后如果无法连接网络,首先检查几个方面:
- IP地址是否和网关在同一网段
- 网关地址是否正确
- DNS服务器是否可达
- 防火墙规则是否阻止了连接
可以用这些命令进行诊断:
# 检查IP配置
ip addr show
# 检查路由表
ip route show
# 测试网关连通性
ping 192.168.1.1
# 测试DNS解析
nslookup www.baidu.com
一些实用的网络配置技巧
配置网络别名
有时候需要在一个网卡上配置多个IP地址,可以使用网络别名:
# CentOS方式
cp /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth0:1
# 修改ifcfg-eth0:1文件中的IP地址
# 或者用ip命令临时添加
ip addr add 192.168.1.101/24 dev eth0
配置网络绑定(bond)
在生产环境中,为了提高网络可靠性,经常需要配置网络绑定:
# 创建bond配置文件
# /etc/sysconfig/network-scripts/ifcfg-bond0
DEVICE=bond0
TYPE=Bond
BONDING_MASTER=yes
BOOTPROTO=static
IPADDR=192.168.1.100
NETMASK=255.255.255.0
BONDING_OPTS="mode=1 miimon=100"
然后配置物理网卡:
# /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
BOOTPROTO=none
MASTER=bond0
SLAVE=yes
# /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
TYPE=Ethernet
BOOTPROTO=none
MASTER=bond0
SLAVE=yes
重启网络服务后,两块网卡就会绑定在一起,提供冗余和负载均衡。
使用nmtui图形界面
对于不熟悉命令行的同事,我一般推荐用nmtui这个文本图形界面工具:
nmtui
这个工具提供了菜单式的操作界面,用方向键和回车就能完成网络配置,比较适合新手使用。
不同环境下的网络配置策略
物理服务器环境
物理服务器的网络配置相对简单,一般就是配置静态IP。需要注意的是要提前规划好IP地址段,避免冲突。我们公司的做法是用Excel表格记录每台服务器的网络信息,包括IP、MAC地址、用途等。
虚拟化环境
在VMware或者KVM环境中,网络配置需要考虑虚拟交换机的设置。有时候虚拟机网络不通,不一定是虚拟机内部配置问题,可能是虚拟交换机或者宿主机网络配置有问题。
我遇到过一次,虚拟机怎么配置都上不了网,最后发现是VMware的NAT服务没有启动。这种问题排查起来比较麻烦,需要从虚拟机到宿主机逐层检查。
云环境配置
在阿里云、腾讯云这些公有云环境中,网络配置又有所不同。云服务器通常使用cloud-init进行初始化配置,支持在创建实例时指定网络参数。
# cloud-init网络配置示例
network:
version: 1
config:
- type: physical
name: eth0
subnets:
- type: static
address: 10.0.0.100/24
gateway: 10.0.0.1
云环境的好处是网络配置相对标准化,但是要注意安全组规则的设置,有时候网络不通是因为安全组阻止了流量。
网络配置的自动化实践
随着服务器数量增加,手动配置网络显然不现实。我们团队现在主要用Ansible进行批量配置。
Ansible网络配置模板
- name: Configure network interface
template:
src: ifcfg-eth0.j2
dest: /etc/sysconfig/network-scripts/ifcfg-{{ ansible_default_ipv4.interface }}
backup: yes
notify: restart network
- name: Restart network service
systemd:
name: network
state: restarted
when: ansible_os_family == "RedHat"
模板文件ifcfg-eth0.j2:
TYPE=Ethernet
BOOTPROTO=static
DEVICE={{ ansible_default_ipv4.interface }}
ONBOOT=yes
IPADDR={{ server_ip }}
NETMASK={{ server_netmask }}
GATEWAY={{ server_gateway }}
DNS1={{ dns_server1 }}
DNS2={{ dns_server2 }}
这样可以根据不同服务器的变量自动生成配置文件,大大提高了效率。
配置管理的最佳实践
- 版本控制:所有网络配置都要纳入Git管理,方便追踪变更历史。
- 环境隔离:开发、测试、生产环境使用不同的IP段,避免相互影响。
- 文档化:维护详细的网络拓扑图和IP地址分配表。
- 监控告警:部署网络监控工具,及时发现网络异常。
我们现在用Zabbix监控网络状态,一旦发现网络中断或者延迟过高,会立即发送告警信息。
网络故障排查思路
网络问题排查是运维工作中的常见任务,我总结了一套比较实用的排查思路:
分层排查法
按照OSI七层模型从下往上排查:
- 物理层:检查网线、网卡指示灯
- 数据链路层:检查交换机端口状态
- 网络层:检查IP配置、路由表
- 传输层:检查端口监听状态
- 应用层:检查应用程序配置
常用排查命令
# 检查网卡状态
ethtool eth0
# 检查网络连通性
ping -c 4 192.168.1.1
# 检查路由
traceroute 8.8.8.8
# 检查端口
netstat -tlnp | grep :80
ss -tlnp | grep :80
# 检查DNS解析
dig www.baidu.com
nslookup www.baidu.com
# 抓包分析
tcpdump -i eth0 host 192.168.1.100
有一次我们的Web服务突然访问很慢,用ping测试网络延迟正常,最后用tcpdump抓包发现是DNS解析慢导致的。换了DNS服务器后问题就解决了。
安全考虑
网络配置不仅要考虑功能,还要考虑安全性:
防火墙配置
# CentOS 7/8 使用firewalld
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --reload
# Ubuntu使用ufw
ufw allow ssh
ufw allow 80/tcp
ufw enable
SSH安全配置
# 修改/etc/ssh/sshd_config
Port 2222 # 修改默认端口
PermitRootLogin no # 禁止root直接登录
PasswordAuthentication no # 禁用密码认证,只允许密钥认证
网络访问控制
可以通过iptables或者云安全组限制网络访问:
# 只允许特定IP访问SSH
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
这些安全措施看起来简单,但是在实际环境中经常被忽视。我见过不少因为网络安全配置不当导致的安全事件。
总结
Linux网络配置确实比较复杂,不同发行版有不同的方式,新老版本之间也有差异。但是掌握了基本原理和常用方法,处理起来也不算太难。
关键是要理解每种配置方式的特点:
- 传统配置文件方式适合静态环境,配置相对固定
- NetworkManager适合需要动态配置的场景
- netplan提供了统一的配置接口,语法相对现代化
我的建议是选择一种方式深入掌握,然后再了解其他方式。这样遇到不同环境时也能快速适应。
最重要的是多实践多总结。网络配置这种东西,光看理论没用,必须自己动手配置才能真正掌握。我当年就是在虚拟机里反复练习,把各种配置方式都试了一遍。
现在云计算和容器技术发展很快,网络配置也在不断演进。比如Kubernetes的网络模型、Docker的网络配置等,都需要我们持续学习。
技术在变,但基础原理不会变。掌握好Linux网络配置的基础知识,对理解更复杂的网络架构也很有帮助。
希望这篇文章能帮到大家解决一些实际问题。如果你在网络配置过程中遇到了其他问题,或者有什么好的经验分享,欢迎在评论区讨论。毕竟技术这东西,大家一起交流才能进步得更快。
如果这篇文章对你有帮助,别忘了点赞转发支持一下!想了解更多运维实战经验和技术干货,记得关注微信公众号@运维躬行录,我会持续分享更多接地气的运维知识和踩坑经验。让我们一起在运维这条路上互相学习,共同进步!