首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >实战DNS:从理论到线上应用,收藏

实战DNS:从理论到线上应用,收藏

作者头像
用户11081884
发布2026-07-20 19:42:27
发布2026-07-20 19:42:27
230
举报

你有没有过这样的体验?

打开某个网站,浏览器半天没反应。

右下角突然弹出来一行字:服务器未响应。

你会不会下意识地骂一句:破网!

其实很多时候,不是网的问题。

是DNS出了问题。


什么是DNS?

你可以把它理解成互联网的电话簿。

每一个网站都像一家公司,有自己的地址(IP)。但一串数字不好记。

于是有了域名,就像公司的名字。

DNS就像一个智能查号台。

你输入域名,它告诉你对应的IP。

没有DNS,你上网就得像记电话号码一样背IP地址。

想象一下:每次打开微信要输入123.123.123.123,得多麻烦。

DNS服务器示意图
DNS服务器示意图

DNS系统将域名解析为IP地址

💡 知识点

DNS(Domain Name System)是因特网上作为域名和IP地址相互映射的一个分布式数据库。通过主机名获取对应的IP地址的过程称为域名解析。DNS协议运行在UDP协议之上,使用端口号53。


DNS的出现及演化

在网络早期,使用IP地址进行通信是可行的,但随着网络规模的扩大,记忆众多的数字IP地址变得不切实际。

于是,UNIX系统中出现了hosts文件,用于记录主机名与IP地址的对应关系。

然而,随着互联网的进一步发展,hosts文件的维护和同步问题日益突出,DNS系统应运而生。

DNS通过分布式数据库的方式,实现了域名和IP地址的高效映射,并不断演化至今,形成了多层架构体系。

DNS层级结构
DNS层级结构

DNS域名的层级结构


域名解析是怎么个流程?

当你打开一个网页的时候,浏览器其实做了这些事。

先翻自己的小本本(本地缓存)看看有没有记过。

要是没有,就会去问家里的DNS服务器。

服务器也会先看自己的小本本(服务器缓存)。

有就直接告诉你答案。

没有的话,它就得开始打电话问别人。

从最顶层的根域服务器问起,一层一层往下找。

最后找到这个域名对应的IP,再告诉你。

顺便把答案存在自己的小本本里,下回再有人问就不用再去问别人了。

DNS解析流程
DNS解析流程

DNS域名解析的完整流程

📋 解析步骤

当客户端需要解析一个域名时,DNS服务器会按照以下步骤进行处理:

  1. 检查DNS服务器的缓存,若找到请求的地址或名字,立即向客户机发送应答信息。
  2. 若缓存中没有,就在自身的数据库中查找,若找到则返回应答。
  3. 若仍未找到,将请求发送给根域DNS服务器,并依次从根域查找顶级域,再由顶级域查找二级域,依此类推,直到找到要解析的地址或名字,然后将解析结果返回给客户机,并在缓存中存储。
  4. 若最终没有找到,则返回错误信息。

DNS服务器有哪些类型?

就像一家公司里的各个岗位。

DNS服务器实物
DNS服务器实物

DNS服务器实物

  • 主DNS服务器存储着原始资料的DNS服务器。
  • 从DNS服务器通过自动更新方式从主DNS服务器同步数据的DNS服务器,也称为辅助DNS服务器。
  • 缓存服务器不负责本地解析,采用递归方式转发客户机查询请求,并返回结果给客户机,同时缓存查询结果,也叫递归服务器。
  • 转发器当发现非本机负责的查询请求时,不再向根域发起请求,而是直接转发给指定的一台或多台服务器,自身不缓存查询结果。

DNS里都存了些啥记录?

就像不同的电话号码类型。

  • SOA可理解为对自己DNS的备注说明文本,一般与NS一致。
  • NS域的授权名称服务器。
  • MX域的邮件交换器,需跟一个优先级值,越小越高。
  • AIPV4主机地址。
  • AAAAIPV6主机地址。
  • PTR解析IP的指针,反向记录。
  • CNAME权威名称,定义别名记录。

DNS命名规范

DNS命名允许使用26个英文字母、10个数字以及连词号"-",且最多63字节长度。

若不按照此规范,bind也支持,但可能需要在master-view文件上配置check-names ignore


DNS查询工具介绍

  • Host命令大多数系统、软件库调用的解析命令,如php中。
  • Nslookup能够反映出是哪个dnsserver返回的结果。
  • Dig返回整个解析过程的详细路径,类似traceroute。

怎么部署DNS服务器?

BIND9是目前最流行的DNS服务器软件。我们可以通过它搭建自己的DNS服务器。

BIND9安装界面
BIND9安装界面

BIND9安装配置界面

环境准备

配置yum源,使用CentOS6自带的yum源,并确保机器可以解析外网域名且能连接公网。

部署单台DNS

使用yum安装bind:

代码语言:javascript
复制
# 使用 yum 安装 bind
yum install bind-utils bind bind-devel bind-chroot

编辑/etc/named.conf文件:

代码语言:javascript
复制
# 编辑 /etc/named.conf 文件
vi /etc/named.conf

# 配置内容示例
options {
  version "1.1.1";
  listen-on port 53 {any;};
  directory "/var/named/chroot/etc/";
  pid-file "/var/named/chroot/var/run/named/named.pid";
  allow-query { any; };
  Dump-file "/var/named/chroot/var/log/binddump.db";
  Statistics-file "/var/named/chroot/var/log/named_stats";
  zone-statistics yes;
  memstatistics-file "log/mem_stats";
  empty-zones-enable no;
  forwarders {202.106.196.115;8.8.8.8; };
};

key "rndc-key" {
        algorithm hmac-md5;
        secret "Eqw4hClGExUWeDkKBX/pBg==";
};

controls {
       inet 127.0.0.1 port 953
               allow { 127.0.0.1; } keys { "rndc-key"; };
 };

logging {
  channel warning {
    file "/var/named/chroot/var/log/dns_warning" versions 10 size 10m;
    severity warning;
    print-category yes;
    print-severity yes;
    print-time yes;
  };
  channel general_dns {
    file "/var/named/chroot/var/log/dns_log" versions 10 size 100m;
    severity info;
    print-category yes;
    print-severity yes;
    print-time yes;
  };
  category default {
    warning;
  };
  category queries {
    general_dns;
  };
};

include "/var/named/chroot/etc/view.conf";

编辑/etc/rndc.key文件:

代码语言:javascript
复制
# 编辑 /etc/rndc.key 文件
vi /etc/rndc.key

# 配置内容示例
key "rndc-key" {
        algorithm hmac-md5;
        secret "Eqw4hClGExUWeDkKBX/pBg==";
};

编辑/etc/rndc.conf文件:

代码语言:javascript
复制
# 编辑 /etc/rndc.conf 文件
vi /etc/rndc.conf

# 配置内容示例
key "rndc-key" {
        algorithm hmac-md5;
        secret "Eqw4hClGExUWeDkKBX/pBg==";
};

options {
        default-key "rndc-key";
        default-server 127.0.0.1;
        default-port 953;
};

编辑/var/named/chroot/etc/view.conf文件:

代码语言:javascript
复制
# 编辑 /var/named/chroot/etc/view.conf 文件
vi /var/named/chroot/etc/view.conf

# 配置内容示例
view "View" {
  zone "lnh.com" {
        type    master;
        file    "lnh.com.zone";
        allow-transfer {
                10.255.253.211;
        };
        notify  yes;
        also-notify {
                10.255.253.211;
        };
  };
};

编辑/var/named/chroot/etc/lnh.com.zone文件:

代码语言:javascript
复制
# 编辑 /var/named/chroot/etc/lnh.com.zone 文件
vi /var/named/chroot/etc/lnh.com.zone

# 配置内容示例
$ORIGIN .
$TTL 3600       ; 1 hour
lnh.com                  IN SOA  op.lnh.com. dns.lnh.com. (
                                2000       ; serial
                                900        ; refresh (15 minutes)
                                600        ; retry (10 minutes)
                                86400      ; expire (1 day)
                                3600       ; minimum (1 hour)
                                )
                        NS      op.lnh.com.
$ORIGIN lnh.com.
shanks              A       1.2.3.4
op              A       1.2.3.4

修改目录权限,并启动服务:

代码语言:javascript
复制
# 修改目录权限,并启动服务
cd /var && chown -R named.named named/
/etc/init.d/named start
chkconfig named on

# 测试解析
dig @127.0.0.1 shanks.lnh.com

部署主从DNS

同样使用yum安装bind:

代码语言:javascript
复制
# 同样使用 yum 安装 bind
yum install bind-utils bind bind-devel bind-chroot

编辑/etc/named.conf文件(与单台DNS配置类似)。

编辑/etc/rndc.key/etc/rndc.conf文件(与单台DNS配置相同)。

在从服务器上配置从属区域,编辑/var/named/chroot/etc/view.conf文件:

代码语言:javascript
复制
# 编辑 /var/named/chroot/etc/view.conf 文件,在从服务器上配置从属区域
vi /var/named/chroot/etc/view.conf

# 配置内容示例(从服务器)
view "SlaveView" {
        zone "lnh.com" {
             type    slave;
             masters {10.6.0.253; };
             file    "slave.lnh.com.zone";
        };
};

修改主服务器上的配置,将从服务器节点IP加入,并修改lnh.com.zone将serial+1:

代码语言:javascript
复制
# 修改主服务器上的 view.conf 配置,将从服务器节点 IP 加入,并修改 lnh.com.zone 将 serial+1
vi /var/named/chroot/etc/view.conf  # 在主服务器上添加从服务器 IP
vi /var/named/chroot/etc/lnh.com.zone  # 将 serial 值+1

在从服务器上修改目录权限,并启动服务:

代码语言:javascript
复制
# 在从服务器上修改目录权限,并启动服务
cd /var && chown -R named.named named/
/etc/init.d/named start
chkconfig named on

# 回到主节点,执行 rndc reload
rndc reload

添加各种记录

在master节点的/var/named/chroot/etc/lnh.com.zone文件中添加记录:

代码语言:javascript
复制
# 在 master 节点的 /var/named/chroot/etc/lnh.com.zone 文件中添加记录
vi /var/named/chroot/etc/lnh.com.zone

# 添加 A 记录示例
a               A       192.168.122.100

# 添加 CNAME 记录示例
cname            CNAME   a.lnh.com.

# 添加 MX 记录示例
mx               MX 5       192.168.122.101

添加PTR记录,编辑master节点的/var/named/chroot/etc/view.conf文件:

代码语言:javascript
复制
# 添加 PTR 记录,编辑 master 节点的 /var/named/chroot/etc/view.conf 文件
vi /var/named/chroot/etc/view.conf

# 添加 PTR 区域配置示例
zone "168.192.in-addr.arpa" {
        type    master;
        file    "168.192.zone";
        allow-transfer {
                10.6.0.254;
        };
        notify  yes;
        also-notify {
                10.6.0.254;
        };
  };

编辑master节点的/var/named/chroot/etc/168.192.zone文件:

代码语言:javascript
复制
# 编辑 master 节点的 /var/named/chroot/etc/168.192.zone 文件
vi /var/named/chroot/etc/168.192.zone

# 配置内容示例
$TTL 3600       ; 1 hour
@                  IN SOA  op.lnh.com. dns.lnh.com. (
                                2004       ; serial
                                900        ; refresh (15 minutes)
                                600        ; retry (10 minutes)
                                86400      ; expire (1 day)
                                3600       ; minimum (1 hour)
                                )
                        NS      op.lnh.com.
102.122     IN      PTR     a.lnh.com.

修改文件权限并重新加载配置:

代码语言:javascript
复制
# 修改文件权限并重新加载配置
chown named.named 168.192.zone
rndc reload

在slave节点上编辑view.conf文件,添加PTR区域配置:

代码语言:javascript
复制
# 在 slave 节点上编辑 view.conf 文件,添加 PTR 区域配置
vi /var/named/chroot/etc/view.conf

# 配置内容示例(从服务器)
zone "168.192.in-addr.arpa" {
             type    slave;
             masters {10.5.35.14; };
             file    "slave.168.192.zone";
        };

# 使 slave 配置生效
rndc reload

在两台机器上进行ptr记录的解析测试:

代码语言:javascript
复制
# 在两台机器上进行 ptr 记录的解析测试
host 192.168.122.102 127.0.0.1

通过DNS实现服务的负载均衡

当然可以。给一个域名配置多个IP地址,每次访问的时候DNS服务器会轮询返回不同的IP。这样就能把流量分摊到不同的服务器上。

就像一家餐厅开了好几家分店,客人来了就给分配到不同的分店,避免一家店太忙了。

DNS负载均衡原理
DNS负载均衡原理
代码语言:javascript
复制
# 在 master 节点的 /var/named/chroot/etc/lnh.com.zone 文件中添加多条 A 记录
vi /var/named/chroot/etc/lnh.com.zone

# 添加 A 记录示例
a               A       192.168.122.102

# 将 serial 值+1并重新加载配置
rndc reload

# 在 master 和 slave 上解析测试
host a.lnh.com 127.0.0.1

配置DNS视图(智能DNS)

简单来说,就是可以根据访问者的位置返回不同的IP。比如一个网站在北京和上海都有服务器,来自北京的用户就分配到北京的服务器,这样速度更快。来自上海的用户就分配到上海的服务器。就像打车软件会把你分配到最近的司机那里。

智能DNS地理位置解析
智能DNS地理位置解析

智能DNS根据用户位置返回最近的服务器

在master节点的/var/named/chroot/etc/named.conf文件中添加acl规则:

代码语言:javascript
复制
# 在 master 节点的 /var/named/chroot/etc/named.conf 文件中添加 acl 规则
vi /var/named/chroot/etc/named.conf

# 添加 acl 规则示例
acl group1 {
  10.5.35.14;
};

acl group2 {
  10.5.35.15;
};

编辑/var/named/chroot/etc/view.conf文件,配置不同的视图:

代码语言:javascript
复制
# 编辑 /var/named/chroot/etc/view.conf 文件,配置不同的视图
vi /var/named/chroot/etc/view.conf

# 配置视图示例
view "GROUP1" {
  match-clients { group1; };
  zone "viewlnh.com" {
    type master;
    file "group1.viewlnh.com.zone";
  };
};

view "GROUP2" {
  match-clients { group2; };
  zone "viewlnh.com" {
    type master;
    file "group2.viewlnh.com.zone";
  };
};

编辑不同的区域文件,设置对应的域名解析记录:

代码语言:javascript
复制
# 编辑不同的区域文件,设置对应的域名解析记录
vi /var/named/chroot/etc/group1.viewlnh.com.zone

# 配置内容示例
$ORIGIN .
$TTL 3600       ; 1 hour
viewlnh.com                  IN SOA  op.viewlnh.com. dns.viewlnh.com. (
                                2005       ; serial
                                900        ; refresh (15 minutes)
                                600        ; retry (10 minutes)
                                86400      ; expire (1 day)
                                3600       ; minimum (1 hour)
                                )
                        NS      op.viewlnh.com.
$ORIGIN viewlnh.com.
op                 A       192.168.122.1
view               A       192.168.122.1

vi /var/named/chroot/etc/group2.viewlnh.com.zone

# 配置内容示例
$ORIGIN .
$TTL 3600       ; 1 hour
viewlnh.com                  IN SOA  op.viewlnh.com. dns.viewlnh.com. (
                                2005       ; serial
                                900        ; refresh (15 minutes)
                                600        ; retry (10 minutes)
                                86400      ; expire (1 day)
                                3600       ; minimum (1 hour)
                                )
                        NS      op.viewlnh.com.
$ORIGIN viewlnh.com.
op                 A       192.168.122.2
view               A       192.168.122.2

修改文件所属权限并重新加载配置:

代码语言:javascript
复制
# 修改文件所属权限并重新加载配置
chown named.named /var/named/chroot/etc/group*.zone
rndc reload

# 在不同的主机上进行域名解析测试
# 主机 A 上执行
host view.viewlnh.com 127.0.0.1

# 主机 B 上执行
host view.viewlnh.com 127.0.0.1

企业级DNS是怎么搭建的?

硬件选型

选择12c以上配置的CPU,16G内存,千兆网络。

初始化系统

关闭selinux和iptables,调整ulimit限制。

代码语言:javascript
复制
# 关闭 selinux
vi /etc/selinux/config

# 将 SELINUX=enforcing 改为 SELINUX=disabled

# 关闭 iptables
chkconfig iptables off

# 调整 ulimit 限制
echo -e '* soft nproc 65536\n* hard nproc 65536\n* soft nofile 65536\n* hard nofile 65536\n' >>  /etc/security/limits.conf

构建高性能、高可用DNS

采用lvs-dr模式负载均衡,多idc,多套dns集群,通过master-slave技术保证dns配置的一致性。在物理层、服务层和客户端层分别采取相应措施,确保系统的高可用性和高性能。

企业级DNS全球服务架构

DNS系统架构
DNS系统架构

压测

安装queryperf,下载并编译bind源码,编辑域名记录文件,进行压测,评估dns-server的性能。

代码语言:javascript
复制
# 安装 queryperf
wget http://ftp.isc.org/isc/bind9/9.7.3/bind-9.7.3.tar.gz
tar zxf bind-9.7.3.tar.gz
cd bind-9.7.3/contrib/queryperf/
./configure
make

# 将 queryperf 拷贝至 /usr/bin/ 下
cp queryperf /usr/bin/

# 编辑域名记录文件 test.txt
# 文件内容示例
www.baidu.com A
www.baidu.com A
www.baidu.com A
www.baidu.com A
www.baidu.com A

# 压测命令
queryperf -d test.txt -s 8.8.8.8

监控

结合zabbix实现系统基础性能、loopback地址绑定状态、dns数据一致性、dns响应时间和每秒请求数等的监控。

代码语言:javascript
复制
# dns 每秒请求数监控脚本示例
#!/bin/bash

# rndc stats
STATS='/var/named/chroot/var/log/named_stats'

if [[ $# -ne 1 ]]
then
  echo "$0 [querys]"
  exit 2
else
  which=$1
fi

if [[ -f "${STATS}" ]]
then
  echo > ${STATS}
  rndc stats >/dev/null 2>&1
else
  echo "${STATS} not found."
  exit 2
fi

case ${which} in
querys)
  RESULT=`awk '{if ($2=="QUERY") {print $1}}' ${STATS}`
;;
*)
  echo "$0 [querys]"
  exit 2
;;
esac

echo ${RESULT}

自动化

通过saltstack实现自动、批量安装、部署dns,并采用自定义的配置管理方案,将dns配置与数据库结合,实现对域名的增删改查操作的自动化。

安全

时刻关注dns相关的漏洞和补丁,选择可靠的域名服务商,对服务器登录日志进行监控分析。

DNS安全防护
DNS安全防护

企业级DNS安全防护架构

日常运维规范

确保所有监控均处于生效状态,新机器在saltstack上完成初始化和安装、部署操作,针对dns架构调整的操作在流量低谷时进行,对集群扩容操作时对新加入节点做压测并检测重启后各项指标是否正常,关注dns相关新闻。


DNS有哪些发展趋势?

  • DNSmasq适用于小型网络的DNS和DHCP配置工具,可提高dns解析性能并减轻dns server的压力。
  • Httpdns在有中国特色的互联网环境中,解决域名缓存和用户跨网访问缓慢等问题,适用于app场景。
  • Bind的稳定性目前最为稳定、高效的dns解析方案,仍将在未来一段时间内占据重要地位。

DNS的常见问题和排障

  • DNS需要开通53的udp和tcp正常情况下优先使用udp,受限时使用tcp。
  • 运维同学反馈dns不能用先恢复业务,再排查问题,如检查iptables是否影响服务。
  • 收到报警提示dns虚地址不能正常解析检查系统间藕合性,避免因一个组件故障导致整个系统问题。
  • 开发反馈调用微信支付接口超时确认问题是否出现在域名解析环节,尝试更换forward的公网dns解决。

面试时经常会问到的DNS问题

递归查询和迭代查询有啥区别?

递归查询与迭代查询
递归查询与迭代查询

递归查询与迭代查询的区别

  • 递归查询客户机和服务器之间,服务器代为查询并返回结果。
  • 迭代查询服务器之间,逐级查询,最终返回结果。

域名解析的完整流程是什么样的?

  1. 客户端发出DNS请求。
  2. DNS服务器检查缓存、自身配置,若找到则返回结果。
  3. 若未找到,将请求发送给根域DNS服务器,逐级查找,直到找到解析结果并返回给客户端。
  4. 若未找到,返回错误信息。

写在最后

DNS是互联网最基础的服务之一。看起来简单,但是很重要。

几乎每一次网络访问都会用到它。但因为它默默无闻,所以经常被忽略。

了解DNS的原理和部署方法,对于运维人员来说是必备的技能。

最好的网络是你感觉不到它存在的网络。


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-01-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Nicholas与Pypi 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是DNS?
  • DNS的出现及演化
  • 域名解析是怎么个流程?
  • DNS服务器有哪些类型?
  • DNS里都存了些啥记录?
  • DNS命名规范
  • DNS查询工具介绍
  • 怎么部署DNS服务器?
    • 环境准备
    • 部署单台DNS
  • 部署主从DNS
  • 添加各种记录
  • 通过DNS实现服务的负载均衡
  • 配置DNS视图(智能DNS)
  • 企业级DNS是怎么搭建的?
    • 硬件选型
    • 初始化系统
    • 构建高性能、高可用DNS
    • 压测
    • 监控
    • 自动化
    • 安全
    • 日常运维规范
  • DNS有哪些发展趋势?
  • DNS的常见问题和排障
  • 面试时经常会问到的DNS问题
    • 递归查询和迭代查询有啥区别?
    • 域名解析的完整流程是什么样的?
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档