DNS基础概念(一)DNS概述

DNS是一个层次化的分布式数据库,其全称为域名系统(Domain Name System),它存储用于互联网主机名与IP地址相互映射的信息,及其它互联网所用到的数据。DNS系统是由柏克大学发展的BIND软件(Berkeley Internet Name Domain)所提供。现目前的BIND的为9.x,现网上大多数都简称叫BIND9 ;BIND9 软件分发包括了一个名字服务器,named,和量和解析库,liblwres和libbind。如果想了解更多或下载更高的版本,可到此站点去查询与下载: http://www.isc.org/software/bind

BIND与DNS区别:DNS是一种因特网的通信协议名称,BIND这是提供这个DNS服务的软件;在TCP/IP网络中有非常重要的地位,能够提供域名与IP地址的解析服务。

(二)DNS工作原理

域名系统DNS是类似于一个树状数据结构,树中的每个节点实质都是负责某个特定区域的一台服务器,通过这些节点,对整个域名空间进行划分,成为一个层次结构,这种结构类似与UNIX文件系统的层次结构,根的名字“.”来表示,并称之为根域名(root domain)根域的下一级是顶级域名,顶级域名又分为两种划分方法,地理域和通用域,地理域则是为了世界上每个国家或地区等设置的,如中国是cn,日本jp,美国us,台湾tw。等等。通用域则是通过不同的机构类别设置的顶级域名,如org、edu 等等。如下图:

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(1)

(三)常见的顶级域名列表

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(2)

随着网络快速增长,后来就出现了,以国家或地区区分的Domain name。

(四)域名服务的解析原理和过程

DNS解析示例:

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(3)

(五)DNS服务的相关记录说明

DNS高可用智能解析方案

本DNS高可用方案基于基于CVM云服务器,在VPC内网的进行DNS服务器的构建,可实现内网域名解析的需求。同时本方案设计结合了腾讯云CLB产品提供了负载均衡能力,也可通过多个CLB实现对接多台RS接节点,分担前端解析压力,同时支持多可用区部署。

(一)方案特点

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(4)

(二)方案实现功能(三)解析流程路径

1)客户端访问企业内部域名

2)客户端访问腾讯云内网域名

3)客户端访问外网域名

注意 :

详情参考腾讯云官网文档《关于安全组53端口配置的公告》

https://cloud.tencent.com/document/product/213/35533

DNS高可用智能解析方案实现

本次方案采用了两台节点进行此方案的实践。若在云上的生成环境需结合客户业务的详细需求进行节点数量,CLB数量,不同的地域调整即可。

(一)设置主机名

[root@VM-2-15-centos ~] hostnamectl set-hostname node4.rocky.com [root@VM-2-16-centos ~] hostnamectl set-hostname node5.rocky.com

(二)配置/etc/hosts

[root@node4 ~]# cat /etc/hosts 127.0.0.1 VM-6-15-centos VM-6-15-centos 127.0.0.1 localhost.localdomain localhost 127.0.0.1 localhost4.localdomain4 localhost4 10.0.6.15 node4 node4.rocky.com 10.0.6.16 node5 node5.rocky.com

(三)安装DNS软件

[root@node4 ~]# yum -y install bind [root@node5 ~]# yum -y install bind

(四)DNS主配置文件

[root@node4 ~]# cat /etc/named.conf // // named.conf // // Provided by Red Hat bind package to configure the ISC BIND named(8) DNS // server as a caching only nameserver (as a localhost DNS resolver only). // // See /usr/share/doc/bind*/sample/ for example named configuration files. // // See the BIND Administrator's Reference Manual (ARM) for details about the // configuration located in /usr/share/doc/bind-{version}/Bv9ARM.html acl "trusted-recursion" { # 设置acl localhost; 10.0.0.0/16; }; options { listen-on port 53 { any; }; #设置监听端口,也可写具体的网段 listen-on-v6 port 53 { any; }; directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; recursing-file "/var/named/data/named.recursing"; secroots-file "/var/named/data/named.secroots"; allow-query { any; }; #开放查询 allow-recursion { trusted-recursion; }; #指定允许哪些主机可以从缓存中获取答案。 allow-query-cache { trusted-recursion; }; # 指定允许那些主机可以通过本服务器进行递归查询。 /* - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion. - If you are building a RECURSIVE (caching) DNS server, you need to enable recursion. - If your recursive DNS server has a public IP address, you MUST enable access control to limit queries to your legitimate users. Failing to do so will cause your server to become part of large scale DNS amplification attacks. Implementing BCP38 within your network would greatly reduce such attack surface */ recursion yes; dnssec-enable no; dnssec-validation no; # 关闭dnssec安全验证 /* Path to ISC DLV key */ #bindkeys-file "/etc/named.root.key"; managed-keys-directory "/var/named/dynamic"; pid-file "/run/named/named.pid"; session-keyfile "/run/named/session.key"; forwarders { 183.60.83.19; # 腾讯云VPCGW DNS地址 183.60.82.98; # 腾讯云VPCGW DNS地址 }; }; logging { channel default_debug { file "data/named.run"; severity dynamic; }; }; zone "." IN { type hint; file "named.ca"; }; #include "/etc/named.rfc1912.zones"; include "/etc/named.root.key"; zone "rocky.com" { # 域名 type master; #主DNS file "dynamic/rocky.com.zone"; # zone file path #正向区域文件 notify yes; }; zone "6.0.10.in-addr.arpa" in { type master; file "dynamic/6.0.10.in-addr.arpa.zone"; #反向区域文件 notify yes; };

(五)DNS区域文件配置

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(5)

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(6)

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(7)

分别在node4和node5进行服务启动及检查服务状态是否正常。

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(8)

#客户端访问企业内部域名 [root@node4 ~]# nslookup www.rocky.com Server: 10.0.6.15 Address: 10.0.6.15#53 Name: www.rocky.com Address: 10.0.6.100 [root@node4 ~]# nslookup 10.0.6.100 100.6.0.10.in-addr.arpa name = www.rocky.com. #客户端访问外网域名 [root@node4 ~]# nslookup www.baidu.com Server: 10.0.6.15 Address: 10.0.6.15#53 Non-authoritative answer: www.baidu.com canonical name = www.a.shifen.com. Name: www.a.shifen.com Address: 110.242.68.3 Name: www.a.shifen.com Address: 110.242.68.4 #客户端访问腾讯云内网服务域名 [root@node4 ~]# nslookup mirrors.tencent.com Server: 10.0.6.15 Address: 10.0.6.15#53 Non-authoritative answer: mirrors.tencent.com canonical name = mirrors.cloud.tencent.com. mirrors.cloud.tencent.com canonical name = mirrors.cloud.tencent.com.cdn.dnsv1.com. mirrors.cloud.tencent.com.cdn.dnsv1.com canonical name = 14io0gsu.sched.dma.tdnsv5.com. Name: 14io0gsu.sched.dma.tdnsv5.com Address: 113.240.69.235 Name: 14io0gsu.sched.dma.tdnsv5.com Address: 113.240.69.180 [root@node4 ~]#

服务验证通过,符合预期,node5分别也进行相关解析验证。

(七)LB配置

新建内网LB,配置监听端口为UDP:53,加权轮询。

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(9)

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(10)

选择板绑定的RS节点,确认即可

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(11)

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(12)

(八)客户端验证

[root@node6 ~]# cat /etc/resolv.conf ; generated by /usr/sbin/dhclient-script #nameserver 183.60.83.19 #nameserver 183.60.82.98 nameserver 10.0.2.2 #内网LB地址 #解析业务域名

[root@node6 ~]# nslookup www.rocky.com Server: 10.0.2.2 Address: 10.0.2.2#53 Name: www.rocky.com Address: 10.0.6.100 #解析腾讯内网域名 [root@node6 ~]# nslookup mirrors.tencent.com Server: 10.0.2.2 Address: 10.0.2.2#53 Non-authoritative answer: mirrors.tencent.com canonical name = mirrors.cloud.tencent.com. mirrors.cloud.tencent.com canonical name = mirrors.cloud.tencent.com.cdn.dnsv1.com. mirrors.cloud.tencent.com.cdn.dnsv1.com canonical name = 14io0gsu.sched.dma.tdnsv5.com. Name: 14io0gsu.sched.dma.tdnsv5.com Address: 113.240.69.180 Name: 14io0gsu.sched.dma.tdnsv5.com Address: 113.240.69.235 [root@node6 ~]# nslookup myqcloud.com Server: 10.0.2.2 Address: 10.0.2.2#53 Non-authoritative answer: Name: myqcloud.com Address: 0.0.0.1 #解析外网域名 [root@node6 ~]# nslookup www.jd.com Server: 10.0.2.2 Address: 10.0.2.2#53 Non-authoritative answer: www.jd.com canonical name = www.jd.com.gslb.qianxun.com. www.jd.com.gslb.qianxun.com canonical name = jd-abroad.cdn20.com. Name: jd-abroad.cdn20.com Address: 121.57.82.89 Name: jd-abroad.cdn20.com Address: 36.111.141.54 Name: jd-abroad.cdn20.com Address: 121.57.82.88 Name: jd-abroad.cdn20.com Address: 121.57.82.17 Name: jd-abroad.cdn20.com Address: 42.81.145.189 Name: jd-abroad.cdn20.com Address: 113.24.194.72 Name: jd-abroad.cdn20.com Address: 240e:918:1a00:201::33 Name: jd-abroad.cdn20.com Address: 240e:928:101::1e Name: jd-abroad.cdn20.com Address: 240e:918:1a00:201::15 Name: jd-abroad.cdn20.com Address: 240e:925:2:101::6

验证通过, 符合预期。

(九)DNS高可用智能解析方案总结

本方案采用Linux系统自带的DNS软件进行DNS高可用环境的构建,结合了内网CLB使其解析调度RS更加灵活。同时实现了客户端对企业内网域名,腾讯云内外网域名的解析需求。另外这里务必注意RS在内网进行构建,安全组限制53端口的来源IP。

CoreDNS高可用方案

本篇主要介绍通过自建CoreDNS集群来提供DNS内外域名解析,及腾讯内网DNS功能,这里采用CoreDNS ETCD集群方式来实现。方案特点:

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(13)

(一)CoreDNS

CoreDNS基于用Go编写的是一个DNS服务器,链接插件,每个插件执行一个(DNS)功能。相对于其他DNS如:BIND、Knot、PowerDNS和Unbound不同之处,在于它非常灵活,几乎所有功能都外包到插件中 ,插件也可以是独立的,也能协同工作。可以利用插件对你的DNS数据做你想做的事情。如果有些功能不是现成的,你可以通过编写插件来添加,和Caddy Server具有相同的模型:链接插件。

插件化(Plugins):基于Caddy服务器框架,CoreDNS实现了一个插件链的架构,将大量应用端的逻辑抽象成插件形式暴露给使用者。CoreDNS以预配置的方式将不同的插件串成一条链,按序执行插件链上的逻辑。

配置简单:引入表达力更强的DSL,即Corefile形式的配置文件。

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(14)

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(15)

注意这里有两个不同的端口:5300和53。在内部,每个端口都会生成一个dnsserver.Server。即使有四个服务器块,我们也只能得到两个实际的服务器。CoreDNS会将所有与同一端口相关的服务器块收集起来,并将它们合并到相同的dnsserver.Server中。服务器将在端口上多重查询,根据区域将它们传递到不同的插件链。它为区域选择最特定的匹配服务器块。如果没有匹配的服务器块,则返回SERVFAIL。

coredns.io:5300 { file /etc/coredns/zones/coredns.io.db } example.io:53 { errors log file /etc/coredns/zones/example.io.db } example.net:53 { file /etc/coredns/zones/example.net.db } .:53 { errors log health rewrite name foo.example.com foo.default.svc.cluster.local }

(二)ETCD

ETCD是一种高度一致的分布式键值存储,它提供了一种可靠的方式来存储需要由分布式系统或机器集群访问的数据。它在网络分区期间优雅地处理领导选举,并能够容忍机器故障。

dns服务器腾讯云(基于腾讯云自建高可用DNS方案实践)(16)

从上面架构图中我们可以看到,ETCD主要分为四个部分。

HTTP Server:用于处理用户发送的API请求以及其它etcd节点的同步与心跳信息请求。

Store:用于处理etcd支持的各类功能的事务,包括数据索引、节点状态变更、监控与反馈、事件处理与执行等等,是etcd对用户提供的大多数API功能的具体实现。

Raft:Raft强一致性算法的具体实现,是etcd的核心。

WAL:Write Ahead Log(预写式日志)是etcd的数据存储方式。除了在内存中存有所有数据的状态以及节点的索引外,etcd就通过WAL进行持久化存储。在WAL中所有的数据提交前都会事先记录日志,Snapshot是为了防止数据过多而进行的状态快照,Entry表示存储的具体日志内容。

(三)配置ETCD集群

这里采用三台云服务器作为CoreDNS节点的后端数据库,ETCD架构逻辑具备选举master机制,分别为node1~node3。

[root@node1~]# yum -y install etcd [root@node11 ~]# systemctl enable etcd; systemctl start etcd Created symlink from /etc/systemd/system/multi-user.target.wants/etcd.service to /usr/lib/systemd/system/etcd.service.

[root@node1 etcd]# egrep ^[A-Z] etcd.conf ETCD_DATA_DIR="/var/lib/etcd/node1.etcd" ETCD_LISTEN_PEER_URLS="http://10.0.2.4:2380" ETCD_LISTEN_CLIENT_URLS="http://10.0.2.4:2379,http://127.0.0.1:2379" ETCD_NAME="node1" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.0.2.4:2380" ETCD_ADVERTISE_CLIENT_URLS="node1=http://10.0.2.4:2379" ETCD_INITIAL_CLUSTER="node1=http://10.0.2.4:2379,node2=http://10.0.2.8:2379,node3=http://10.0.2.15:2379" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new"

[root@node2 ~]# egrep ^[A-Z] /etc/etcd/etcd.conf ETCD_DATA_DIR="/var/lib/etcd/node2.etcd" ETCD_LISTEN_PEER_URLS="http://10.0.2.8:2380" ETCD_LISTEN_CLIENT_URLS="http://10.0.2.8:2379,http://127.0.0.1:2379" ETCD_NAME="node2" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.0.2.8:2380" ETCD_ADVERTISE_CLIENT_URLS="http://10.0.2.8:2379" ETCD_INITIAL_CLUSTER="node1=http://10.0.2.4:2380,node2=http://10.0.2.8:2380,node3=http://10.0.2.15:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new" [root@node2 ~]#

[root@node3 ~]# egrep ^[A-Z] /etc/etcd/etcd.conf ETCD_DATA_DIR="/var/lib/etcd/node3.etcd" ETCD_LISTEN_PEER_URLS="http://10.0.2.15:2380" ETCD_LISTEN_CLIENT_URLS="http://10.0.2.15:2379,http://127.0.0.1:2379" ETCD_NAME="node3" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.0.2.15:2380" ETCD_ADVERTISE_CLIENT_URLS="http://10.0.2.15:2379" ETCD_INITIAL_CLUSTER="node1=http://10.0.2.4:2380,node2=http://10.0.2.8:2380,node3=http://10.0.2.15:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new"

启动与验证etcd服务

[root@node1 ~]# systemctl start etcd.service [root@node1 ~]# systemctl status etcd.service etcd.service - Etcd Server Loaded: loaded (/usr/lib/systemd/system/etcd.service; enabled; vendor preset: disabled) Active: active (running) since Tue 2022-02-15 13:50:16 CST; 10h ago Main PID: 10451 (etcd) CGroup: /system.slice/etcd.service └─10451 /usr/bin/etcd --name=node1 --data-dir=/var/lib/etcd/node1.etcd --listen-client-urls=http://10.0.2.4:2379,http://127.0.0.1:2379

[root@node1 ~]# etcdctl member list 5432b0f7395992d2: name=node1 peerURLs=http://10.0.2.4:2380 clientURLs=http://10.0.2.4:2379 isLeader=true 589358f881fe72a1: name=node2 peerURLs=http://10.0.2.8:2380 clientURLs=http://10.0.2.8:2379 isLeader=false bb72602d9eb35069: name=node3 peerURLs=http://10.0.2.15:2380 clientURLs=http://10.0.2.15:2379 isLeader=false [root@node1 ~]# etcdctl cluster-health member 5432b0f7395992d2 is healthy: got healthy result from http://10.0.2.4:2379 member 589358f881fe72a1 is healthy: got healthy result from http://10.0.2.8:2379 member bb72602d9eb35069 is healthy: got healthy result from http://10.0.2.15:2379 cluster is healthy

(四)多节点CoreDNS部署

这里面可结合客户业务需要进行CoreDNS服务器的环境构建,这里采用的coredns1.6.4 版本,官网最新1.9.x

[root@dns1 ~]# tar zxvf coredns_1.6.4_linux_amd64.tgz [root@dns1 ~]# mv coredns /usr/bin/ [root@dns1 ~]# mkdir /etc/coredns

[root@node1 ~]# cat /etc/coredns/Corefile . { # 监听tcp和udp的53端口 etcd node1.rocky.com node2.rocky.com node3.rocky.com 10.in-addr.arpa { # 配置启用etcd插件,后面可以指定域名 stubzones # 启用存根区域功能 path /skydns # etcd里面的路径 默认为/skydns,以后所有的dns记录就是存储在该存根路径底下 endpoint http://10.0.2.4:2379 http://10.0.2.8:2379 http://10.0.2.15:2379 # etcd访问地址,多个空格分开 upstream 183.60.83.19:53 183.60.82.98:53 # 设置要使用的上游解析程序解决指向外部域名的在etcd(认为CNAME)中找到的外部域名。 } cache 600 # 缓存600秒 loadbalance # 负载均衡,开启DNS记录轮询策略 forward . 183.60.82.98:53 183.60.83.19:53 # 上面etcd未查询到的请求转发给设置的DNS服务器解析 } myqcloud.com { cache 600 myqcloud.com loadbalance forward . 119.29.29.29:53 } tencent-cloud.com { hosts { 10.210.104.113 cls-i0fxloot.ccs.tencent-cloud.com 10.210.49.4 cls-88b89rhb.ccs.tencent-cloud.com 10.210.104.35 cls-o4rn1235.ccs.tencent-cloud.com fallthrough } }

[root@node1 ~]# cat /usr/lib/systemd/system/coredns.service [Unit] Description=CoreDNS DNS server Documentation=https://coredns.io After=network.target [Service] PermissionsStartOnly=true LimitNOFILE=1048576 LimitNPROC=512 CapabilityBoundingSet=CAP_NET_BIND_SERVICE AmbientCapabilities=CAP_NET_BIND_SERVICE NoNewPrivileges=true User=coredns WorkingDirectory=~ ExecStart=/usr/bin/coredns -conf=/etc/coredns/Corefile ExecReload=/bin/kill -SIGUSR1 $MAINPID Restart=on-failure [Install] WantedBy=multi-user.target [root@node1 ~]#

[root@node1 ~]# systemctl status coredns ● coredns.service - CoreDNS DNS server Loaded: loaded (/usr/lib/systemd/system/coredns.service; disabled; vendor preset: disabled) Active: active (running) since Tue 2022-02-15 16:13:43 CST; 4s ago Docs: https://coredns.io Main PID: 30288 (coredns) CGroup: /system.slice/coredns.service └─30288 /usr/bin/coredns -conf=/etc/coredns/Corefile Feb 15 16:13:43 node1.rocky.com systemd[1]: Started CoreDNS DNS server. Feb 15 16:13:43 node1.rocky.com coredns[30288]: .:53 Feb 15 16:13:43 node1.rocky.com coredns[30288]: myqcloud.com.:53 Feb 15 16:13:43 node1.rocky.com coredns[30288]: tencent-cloud.com.:53 Feb 15 16:13:43 node1.rocky.com coredns[30288]: ______ ____ _ _______ Feb 15 16:13:43 node1.rocky.com coredns[30288]: / ____/___ ________ / __ \/ | / / ___/ ~ CoreDNS-1.6.4 Feb 15 16:13:43 node1.rocky.com coredns[30288]: / / / __ \/ ___/ _ \/ / / / |/ /\__ \ ~ linux/amd64, ...dirty Feb 15 16:13:43 node1.rocky.com coredns[30288]: / /___/ /_/ / / / __/ /_/ / /| /___/ / Feb 15 16:13:43 node1.rocky.com coredns[30288]: \____/\____/_/ \___/_____/_/ |_//____/ Hint: Some lines were ellipsized, use -l to show in full. [root@node1 ~]# ^C [root@node1 ~]# systemctl enable coredns Created symlink from /etc/systemd/system/multi-user.target.wants/coredns.service to /usr/lib/systemd/system/coredns.service.

root@node1 ~]# etcdctl put /skydns/com/rocky/node1 '{"host":"10.0.2.4","ttl":10}' No help topic for 'put' [root@node1 ~]# export ETCDCTL_API=3 [root@node1 ~]# etcdctl put /skydns/com/rocky/node1 '{"host":"10.0.2.4","ttl":10}' OK [root@node1 ~]# vim .bashrc [root@node1 ~]# [root@node1 ~]# [root@node1 ~]# etcdctl put /skydns/com/rocky/node2 '{"host":"10.0.2.8","ttl":10}' OK [root@node1 ~]# etcdctl put /skydns/com/rocky/node3 '{"host":"10.0.2.15","ttl":10}' OK [root@node1 ~]# etcdctl put /skydns/com/rocky/node1 '{"host":"www.tam3.com","ttl":10}' OK [root@node1 ~]#

由于这里采用的测试环境, 需要结合具体业务进行相关设置。

(五)coredns验证

[root@node1 ~]# dig @node1 www.tam3.com ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.7 <<>> @node1 www.tam3.com ; (1 server found) ;; global options: cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1734 ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;www.tam3.com. IN A ;; ANSWER SECTION: www.tam3.com. 160 IN CNAME tam3.com. tam3.com. 160 IN A 3.33.152.147 tam3.com. 160 IN A 15.197.142.173 ;; Query time: 622 msec ;; SERVER: 10.0.2.4#53(10.0.2.4) ;; WHEN: Tue Feb 15 16:25:24 CST 2022 ;; MSG SIZE rcvd: 123

验证符合预期。

总结

本篇通过两种不同的形式在云上实现自建高可用DNS环境来解决企业在云上的内外网域名解析的需求。以上两个方案仅供参考,生产环境采用,需结合业务具体需求进行相关配置的调整。同时这里优先推荐采用腾讯云的DNS托管服务,有特殊业务需求可参考以上两个方案结合托管的DNS服务协同来处理。

,