8.16-8.17每日一讲
1. 如何配置 DNS 的主从同步?
主从同步靠 Zone Transfer(区域传输) 实现,从服务器通过 AXFR(全量)或 IXFR(增量)从主服务器拉取区域数据。
配置分三步:
1. 主服务器(Master)
- 区域文件中声明允许传输:
allow-transfer { 192.168.1.2; }; // 允许从服务器 IP
also-notify { 192.168.1.2; }; // 主动通知从服务器更新
2. 从服务器(Slave)
- 声明自己是从属区域:
zone "example.com" {
type slave;
file "slaves/example.com.zone"; // 本地缓存副本
masters { 192.168.1.1; }; // 主服务器 IP
};
3. 同步机制
- 主服务器用 SOA 记录的 serial 序号 判断版本。改 zone 时必须递增 serial(否则从服务器不更新)。
- 主服务器通过
NOTIFY主动通知从服务器,从服务器比对 serial 后发起传输。 - 从服务器也可按 SOA 的 refresh/retry 周期定时查询。
关键点:serial 不递增是主从不同步最常见的坑;生产环境建议用日期+序号格式如 2026081501。
2. 如何实现 DNS 的负载均衡和故障转移?
DNS 层面的负载均衡和故障转移,核心思路是一个域名解析出多个 IP,配合健康检查和 TTL 控制。
负载均衡
- 多 A/AAAA 记录:一个域名配置多个 IP,客户端随机或轮询取一个(浏览器一般随机挑)。
- DNS 轮询(Round Robin):同一域名多个记录,解析器轮流返回不同 IP,把流量分散到多台服务器。
- 地区/运营商就近解析:按请求来源(地理或运营商)返回最近的机房 IP,用智能 DNS 服务实现。
- 加权/权重:给不同记录设权重,让性能好的机器承担更多流量。
故障转移
- 健康检查:监控服务器或线路状态,挂了就把对应 IP 从解析结果中摘除。
- TTL 调低:把记录 TTL 设成 30~60 秒甚至更低,故障后客户端能较快拿到更新后的解析结果。
- 被动故障转移:配合 CDN 或 HTTP 层的重试/切换,客户端访问失败自动换下一个 IP。
一般配合链路:智能 DNS 做调度 → 健康检查判断在线 → 失败摘除/切换 → 低 TTL 让变更快速生效 → 业务侧做连接重试兜底。
典型工具:云厂商的智能 DNS/全局负载均衡(如阿里云 DNS 全局流量管理 GTM、AWS Route 53)、Keepalived+第三方 DNS 探测这类自建方案。
3.解释 DNS 的 EDNS 和DNSSEC 是什么?
EDNS 和 DNSSEC 是 DNS 协议栈上两个互相独立、但经常一起部署的扩展。
EDNS(扩展机制,RFC 6891)
老 DNS 报文里有个固定字段叫 OPT,但响应报文的 udp payload size 被写死为 512 字节。EDNS 新增了一种 OPT 伪记录(pseudo-record),携带在附加区中,用来:
- 扩大 UDP 报文大小(最高可达 4096 字节或更大),减少 TCP 回退
- 传递客户端子网信息(ECS,RFC 7871),服务商据此做就近解析
- 传递 DNSSEC OK(DO)标志,表明客户端要 DNSSEC 记录
- 协商 DNS Cookie 等其他新能力
EDNS 本身不提供安全,它只是协议的"能力协商层"。
DNSSEC(域名系统安全扩展,RFC 4033–4035)
用于解决 DNS 数据被篡改/伪造(DNS 投毒)的信任问题。它通过给 DNS 记录做数字签名,保证"查到的数据确实是权威源发的、且未被改动":
- 每个权威域用私钥对自己的记录签名(RRSIG)
- 公钥通过 DNSKEY 记录发布,形成一条从根区逐级向下到目标域的信任链
- 解析器用信任锚(根区公钥)逐级验证签名
- NSEC/NSEC3 记录用来做"无此记录"的认证响应,证明某条记录确实不存在,防止区间投毒
两者关系
EDNS 是 DNSSEC 的"运输前提":DNSSEC 的 RRSIG、DNSKEY 等额外记录会让报文超过 512 字节,必须靠 EDNS 扩充 UDP 大小才能传输;解析器也是通过 EDNS 的 DO 位声明"我要验证 DNSSEC"。所以实践中总是 EDNS 先落地,DNSSEC 依赖它工作。
4.如何清理 DNS 缓存?
清理 DNS 缓存的命令取决于操作系统。
Linux(systemd-resolved,多数现代发行版):
sudo systemd-resolve --flush-caches
新版本用 resolvectl flush-caches,两者等价。用 resolvectl statistics 可以验证缓存是否已清空。
Linux(nscd,较老的发行版):
sudo systemctl restart nscd # 或
sudo nscd -i hosts
macOS:
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
Windows:
ipconfig /flushdns
浏览器独立缓存:Chrome/Edge 在地址栏访问 chrome://net-internals/#dns 点 Clear host cache;Firefox 清历史里的缓存即可,或用扩展。
注意区分两类缓存:系统层面由 resolver(systemd-resolved、dnsmasq 等)负责,改了 /etc/resolv.conf 或换了 DNS 服务器后需要清;浏览器和 curl 这类客户端还有自己的连接级缓存,出问题时要单独清。
5.如何实现智能DNS(解析到离用户最近的IP)?
智能 DNS 的核心思路:由权威 DNS 服务器根据客户端来源地域/网络归属,返回不同的解析结果,把用户引导到离他最近的节点 IP。
设备向本地递归 DNS(比如运营商的 114 或公共的 8.8.8.8)发查询,递归 DNS 拿到的是它自己的出口 IP,而不是终端的 IP。所以智能 DNS 判断「客户端在哪」,实际判断的是递归服务器的位置。
主流实现方式有 4 种:
1. 基于 GeoDNS 的配置(最简单) 权威 DNS 服务商(如 Cloudflare、阿里云 DNS、AWS Route 53)支持把记录按地区区分:
- Route 53 的 Geolocation Routing:按递归服务器所在国家/州返回对应 IP。
- 阿里云/腾讯云的「地域线路」解析:按省、运营商(电信/联通/移动)分别配置 A 记录。
- 适用:CDN 边缘、多机房业务。缺点是粒度到省/国,市区级不够细。
2. EDNS Client Subnet(ECS)—— 现在的主流` 这是优化的关键。RFC 7871 允许递归 DNS 在查询里附带发起终端的网络前缀(通常是 /24),权威服务器据此判断终端真实位置,而不是递归服务器的位置。
- Google Public DNS、Cloudflare 1.1.1.1 都支持 ECS。
- 阿里云/DNSPod 等国内服务商也支持。
- 适用:对精度有要求的场景。前提是终端用的递归 DNS 得支持 ECS。
3. 自建智能 DNS 服务(可编程、最灵活) 自己跑一个权威 DNS(如 PowerDNS、BIND,或 Go 写的自定义解析器),收到查询后:
- 用 IP 地理库(如 MaxMind GeoLite2、IP2Location)查请求来源归属。
- 结合实时节点状态(延迟、负载、存活)选最优 IP 返回。
- 可以做成「最近节点优先 + 故障自动切换」。
4. DNS 负载均衡 + Anycast 节点用一个 Anycast IP,靠 BGP 路由协议让各运营商/地区的流量自动走向最近的节点。严格说这算「网络层就近」,但配合 DNS 返回同一个 Anycast IP,效果就是天然就近 + 高可用。适合自建多机房或高防场景。
6.CDN 的 DNS 解析原理是什么?
CDN 的核心是把用户请求调度到离他最近的节点,DNS 解析是其中最关键的一环。
标准 CDN DNS 解析流程:
-
本地解析:用户访问域名(如
cdn.example.com),先查本地 DNS 缓存和 hosts,没有再走递归查询。 -
递归到 CDN 权威 DNS:本地 DNS 服务器逐级查询,最后把请求交给域名 CNAME 指向的 CDN 厂商权威 DNS(如
cdn.example.com的 CNAME 是xxx.cdn.cloud.com,最终由云厂商的 DNS 处理)。 -
GSLB 调度(关键):CDN 权威 DNS 不只是返回 IP,而是基于 GSLB(全局负载均衡)算法,综合多个维度选出最优节点:
- 客户端 IP 归属地(就近原则)
- 节点实时负载、健康状况
- 网络链路质量、运营商(电信/联通/移动)
- 用户配置的调度策略(如海外优先、成本优先)
-
返回节点 IP:GSLB 返回选中的边缘节点 IP,本地 DNS 缓存该结果(TTL 时间内)。
-
建立连接:浏览器拿到 IP,直接请求该 CDN 边缘节点,命中缓存则直接返回。
两个关键点:
- CNAME + 权威 DNS 归属:CDN 能接管解析,是因为域名 CNAME 到 CDN 厂商,厂商的权威 DNS 才掌握最终 IP 的分配权。
- DNS 是"入口",调度决策在 GSLB:普通 DNS 只做域名→IP 映射,CDN 的 DNS 还要结合实时网络和节点状态做智能调度,这是和普通 DNS 的本质区别。
总结:CDN 利用 CNAME 把域名解析权交给自己的权威 DNS,再用 GSLB 根据用户位置和节点状态动态返回最优边缘节点 IP。
7.NFS v3 和 NFS v4 的主要区别是什么?
NFS v3 和 NFS v4 的主要区别集中在协议设计、状态管理、安全性和文件句柄这几个层面:
状态与锁
- NFS v3:无状态(stateless)。文件锁(NLM)是独立于 NFS 协议的,用单独的 lock manager 实现,崩溃后锁会丢失、需要恢复。
- NFS v4:有状态(stateful)。锁、打开(OPEN)、租约(lease)全部由协议自身管理,崩溃后通过租约续期和 RECLAIM 机制恢复,锁语义更可靠。
传输协议
- v3:依赖中间协议 RPC 之上的 portmapper 提供辅助服务(mount, lock, status 等服务各自占用端口,衍生大量端口开放需求)。
- v4:把 mount、lock、ACL 等功能并入一个协议、合并到一个端口(2049),简化了防火墙配置。
文件句柄与安全
- v3:全局命名空间,配合 mount 协议才能挂载;安全基于 AUTH_SYS(明文 UID/GID)。
- v4:引入伪文件系统根(pseudo-fs root),客户端只要连到根即可发现所有可导出的子树;安全内置 GSSAPI/Kerberos(RPCSEC_GSS),加密和认证比 v3 强。
操作能力
- v4 增加 COMPOUND 操作,把多个 RPC 合成一次往返,减少网络开销(延迟敏感场景更友好)。
- v4 支持 ACL(NFSv4 ACL,比 v3 的 POSIX 风格更细)、有类型文件、原子操作更完善。
兼容与普及
- v3 更老、更简单,兼容旧系统广泛;v4 是现代 Linux/存储的主流默认。
总结:v3 无状态、锁和挂载靠外围协议、明文安全;v4 有状态、协议自管理锁与会话、内置安全与复合操作。 现代生产环境推荐 v4。
8.NFS 依赖的 rpcbind 服务的作用是什么?
rpcbind 服务的作用:它是 RPC(Remote Procedure Call,远程过程调用)的端口映射器,负责把 RPC 程序号映射到实际的 TCP/UDP 端口号。
具体来说:
核心职责 NFS 早期版本(NFSv3 及更早)基于 RPC 协议通信。RPC 程序本身不绑定固定端口,而是动态分配端口,客户端不知道服务在哪个端口。rpcbind 就像一个"电话总机",维护一张表:程序号 → 端口号。客户端想访问某个 RPC 服务时,先问 rpcbind"这个服务在哪个端口",拿到端口后再建立连接。
工作流程
- 服务端启动 NFS、mountd、nlockmgr 等 RPC 服务时,向本机 rpcbind 注册自己的程序号和端口
- 客户端发 RPC 请求给 rpcbind 的固定端口 111,查询目标程序号
- rpcbind 返回对应的实际端口
- 客户端再连到该端口完成通信
跟 NFS 的关系
- NFSv3 依赖 rpcbind,因为 NFS、mountd、nlockmgr 都通过它动态注册端口
- NFSv4 不再需要 rpcbind——它用固定端口 2049,且 mount 协议整合进了 NFS 协议本身
- 所以如果启用了防火墙或用 NFSv3,必须放行 rpcbind(端口 111)和 NFS 相关动态端口,否则客户端无法挂载
常见坑 防火墙环境里,NFSv3 的动态端口是随机的,很难只开放 111。常见做法要么切换 NFSv4,要么配置固定端口后只放行这些端口,要么干脆让 rpcbind 和 NFS 在可信网段内不设防火墙。
rpcbind 就是 NFSv3 的"端口查询总机",NFSv4 则绕开了它。
9.如何配置 NFS 服务器和客户端?
NFS 服务端和客户端的配置方法如下。
服务端配置
- 安装软件包(Debian/Ubuntu:
nfs-kernel-server,RHEL/CentOS:nfs-utils) - 编辑
/etc/exports声明导出目录,每行一条,格式:目录 允许的主机(选项)
/data 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
- 生效配置:
exportfs -rav,或重启服务systemctl restart nfs-server - 查看已导出:
exportfs -v
客户端配置
- 安装客户端包(Debian/Ubuntu:
nfs-common,RHEL/CentOS:nfs-utils) - 创建挂载点并挂载
mkdir -p /mnt/data
mount -t nfs 192.168.1.10:/data /mnt/data
新版内核也可省略 -t nfs
- 查看挂载:
df -h或mount | grep nfs - 开机自动挂载:写入
/etc/fstab
192.168.1.10:/data /mnt/data nfs defaults,_netdev 0 0
_netdev 确保网络就绪后再挂载
常用导出选项
ro/rw:只读 / 读写sync:数据同步写入磁盘,更安全但略慢no_root_squash:保留客户端 root 权限(默认root_squash会将其映射为 nobody,更安全)no_subtree_check:禁用子树检查,提升性能
排障命令
showmount -e 服务器IP:查看服务端导出了哪些目录- 服务端
ss -tlnp | grep 2049:确认 NFS 端口在监听 - 客户端挂载失败时,先测试连通性
ping和showmount
10.如何配置 NFS 的共享权限和用户映射?
NFS 权限配置分两层:导出层(服务端)和文件系统层,两者都要配。
服务端导出(/etc/exports)
/data 192.168.1.0/24(rw,sync,no_root_squash,no_subtree_check)
关键选项:
ro/rw:只读/读写root_squash/no_root_squash:是否把客户端 root 压制成匿名用户(默认 squash,安全)all_squash:所有用户都映射成匿名用户,配anonuid/anongid指定no_subtree_check:禁用子树检查,提升性能sync/async:写盘策略
改完 exportfs -ra 生效。
用户映射(核心)
NFS 本身不做认证,靠 UID/GID 数字匹配。映射方式:
- 默认(root_squash):客户端 root →
nobody(nfsnobody),普通用户按 UID 直接对应 - all_squash + anonuid/anongid:所有客户端用户统一映射到指定本地用户(如 Web 服务器用户 www-data)
- idmapd(用于 Kerberos 的 NFSv4 域映射):客户端和服务端 UID 不同时,靠
nfsidmap/idmapd.conf做用户名↔UID 映射,只在 Kerberos(krb5)时真正生效
文件系统层权限
即使导出为 rw,还得看目录的实际属主/权限位。两个必须:
- 目录属主:服务端
chown user:group /data - 权限位:
chmod(普通文件系统权限控制)
建议
- 客户端和服务端保持相同 UID/GID
- 读写共享用
rw,no_root_squash前要三思——等于把 root 权限给了客户端 - 场景对齐示例:共享给 www-data 用户 → 服务端
chown -R www-data:www-data /data,导出rw,all_squash,anonuid=<wwwdata_uid>,anongid=<wwwdata_gid>
配置顺序:先改 /etc/exports → exportfs -ra → 确认目录属主和权限 → 客户端 mount -t nfs。
11.如何让客户端开机自动挂载 NFS?
客户端开机自动挂载 NFS,核心是配置 /etc/fstab。
在 /etc/fstab 追加一行:
server:/export/path /mnt/nfs nfs defaults,_netdev 0 0
关键参数说明:
_netdev:告诉系统等网络就绪后再挂载,避免开机时网络未初始化导致挂载失败。这是必备参数。- 也可加
noauto让 fstab 不自动挂载,配合 systemd 单元或 autofs 按需挂载。 - 建议配
nofail:即使挂载失败也不阻塞开机流程。
配置后验证:
systemctl daemon-reload
mount -a # 测试是否正常挂载
findmnt /mnt/nfs # 确认挂载结果
补充:
- 顺序问题:
_netdev能解决大部分问题。若仍失败,可改用 systemd 的.mount单元文件,写明After=network-online.target和Wants=network-online.target。 - 服务端依赖:如需确保启用了本地 rpcbind / nfs 客户端服务(systemd 下
nfs-client.target),一般默认启用。
这是最稳妥的实现:_netdev 保证网络就绪后挂载,nofail 防止挂载失败拖垮开机。
12.NFS 客户端挂载失败,如何排查?
NFS 客户端挂载失败排查,按层递进:
- 网络层
ping <server>:验证连通性rpcinfo -p <server>:确认 rpcbind 在跑、nfs 服务已在注册- 防火墙/安全组:放行 2049(nfs)、111(rpcbind)、20048(mountd)、4045(nlockmgr) 等端口
- 服务层(在服务端执行)
systemctl status nfs-server:确保服务在运行showmount -e <server>:客户端查看服务端导出的目录,确认要挂载的路径确实被导出- 导出配置
/etc/exports:检查目录名、权限(ro/rw)、allowed 网段是否覆盖你的客户端 IP
- 挂载命令层
- 精简参数重试:
mount -t nfs <server>:/path /mnt -o vers=4.2 - 看
/var/log/messages或journalctl:NFS 的报错大多在这里,能直接告诉你原因(比如No such file or directory是导出路径写错、Permission denied是权限/网段问题、mount.nfs: Connection timed out是网络不通)
- 常见高频原因
- 客户端缺 nfs 工具:没装 nfs-utils(
mount.nfs不存在) - 挂载点目录不存在:先
mkdir -p /mnt - 版本不匹配:老内核配高 vers,或高内核配低 vers,显式指定
vers=试试 - 导出目录在
/etc/exports里没加sync/no_root_squash等必要参数导致行为异常