服务网格中的DNS代理具备缓存DNS代理的功能。当服务网格收到来自应用程序的DNS查询时,Sidecar代理将进行透明地拦截并提供解析能力。本文介绍如何在ASM中启用和使用DNS代理功能。
前提条件
已创建ASM实例,且ASM实例为1.8.3.17及以上版本。具体操作,请参见创建ASM实例。
已添加集群到ASM实例。具体操作,请参见添加集群到ASM实例。
为default命名空间注入Sidecar。具体操作,请参见开启Sidecar自动注入。
背景信息
ACK集群默认部署了一套DNS服务,为工作负载提供域名解析功能,使得在Kubernetes集群中运行的应用程序可以使用DNS解析来发现集群中的其他服务。
DNS服务器运行在每个Kubernetes集群中,每个Pod都会使用内部DNS服务器进行域名解析。默认情况下DNS请求不会被Sidecar代理拦截,并且每个应用程序都会在打开与其他服务的连接之前尝试解析DNS名称。在ASM中启用DNS代理功能后,收到来自应用程序的DNS查询时,Sidecar代理将进行透明地拦截并提供解析能力,加快域名解析的速度。
启用DNS代理功能
场景一:全局启用DNS代理功能
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择
。在全局页签下单击DNS代理功能,打开启用DNS代理功能开关,单击更新设置。
重启Pod,使DNS配置在应用中生效。
登录容器服务管理控制台。
在控制台左侧导航栏,单击集群。
在集群列表页面,单击目标集群名称或者目标集群右侧操作列下的详情。
在集群管理页左侧导航栏,选择 。
在容器组页面,单击目标Pod右侧操作列下的 。
在提示对话框,单击确定。
稍等一段时间,容器重启后配置生效。
场景二:针对特定命名空间启用DNS代理功能
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择
。在Sidecar代理配置页面,单击命名空间页签。
选择命名空间,单击DNS代理功能,选中启用DNS代理功能,打开右侧的开关,单击更新设置。
重启Pod,使DNS配置在应用中生效。
登录容器服务管理控制台。
在控制台左侧导航栏,单击集群。
在集群列表页面,单击目标集群名称或者目标集群右侧操作列下的详情。
在集群管理页左侧导航栏,选择 。
在容器组页面,单击目标Pod右侧操作列下的 。
在提示对话框,单击确定。
稍等一段时间,容器重启后配置生效。
场景三:针对特定Pod启用DNS代理功能
您需要在Pod的YAML文件中添加注释,才能为特定的Pod启用DNS代理功能。
登录容器服务管理控制台。
在控制台左侧导航栏,单击集群。
在集群列表页面,单击目标集群名称或者目标集群右侧操作列下的详情。
在集群管理页左侧导航栏,选择 。
在无状态页面目标应用右侧操作列下选择 。
在编辑 YAML对话框中spec参数下添加以下注释,然后单击更新。
annotations: proxy.istio.io/config: | proxyMetadata: ISTIO_META_DNS_CAPTURE: "true" ISTIO_META_DNS_AUTO_ALLOCATE: "true"
重启Pod,使DNS配置在应用中生效。
登录容器服务管理控制台。
在控制台左侧导航栏,单击集群。
在集群列表页面,单击目标集群名称或者目标集群右侧操作列下的详情。
在集群管理页左侧导航栏,选择 。
在容器组页面,单击目标Pod右侧操作列下的 。
在提示对话框,单击确定。
稍等一段时间,容器重启后配置生效。
使用DNS代理功能
步骤一:创建集群外服务
使用集群外服务将aliyun.com添加到服务网格内部维护的服务注册表中。
登录ASM控制台。
在左侧导航栏,选择 。
在网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。
在网格详情页面左侧导航栏,选择 ,然后在右侧页面,单击使用YAML创建。
在创建页面选择命名空间,选择任意场景模版,将以下内容服务复制到文本框中,然后单击创建。
apiVersion: networking.istio.io/v1beta1 kind: ServiceEntry metadata: name: test1-mydnsproxying spec: hosts: - aliyun.com location: MESH_EXTERNAL ports: - number: 443 name: https protocol: TLS resolution: DNS
步骤二:部署示例应用
使用以下内容,创建名为sleep.yaml的文件。
执行以下命令,部署Sleep应用。
kubectl apply -f sleep.yaml
执行以下命令,查看Sleep Pod是否成功启动。
kubectl get pod |grep sleep
预期输出:
NAME READY STATUS RESTARTS AGE sleep-66cd8f684f-nxw8v 2/2 Running 0 16m
步骤三:为Sleep容器启用DNS代理功能
登录容器服务管理控制台。
在控制台左侧导航栏,单击集群。
在集群列表页面,单击目标集群名称或者目标集群右侧操作列下的详情。
在集群管理页左侧导航栏,选择 。
在无状态页面目标应用右侧操作列下选择 。
在编辑 YAML对话框中spec参数下添加以下注释,然后单击更新。
annotations: proxy.istio.io/config: | proxyMetadata: ISTIO_META_DNS_CAPTURE: "true" ISTIO_META_DNS_AUTO_ALLOCATE: "true"
重启Pod,使DNS配置在Sleep应用中生效。
登录容器服务管理控制台。
在控制台左侧导航栏,单击集群。
在集群列表页面,单击目标集群名称或者目标集群右侧操作列下的详情。
在集群管理页左侧导航栏,选择 。
在容器组页面,单击Sleep容器右侧操作列下的 。
在提示对话框,单击确定。
稍等一段时间,容器重启后配置生效。
步骤四:验证使用DNS代理功能是否成功
查看istio-init容器的日志。
登录容器服务管理控制台。
在控制台左侧导航栏,单击集群。
在集群列表页面,单击目标集群名称或者目标集群右侧操作列下的详情。
在集群管理页左侧导航栏,选择 。
在容器组页面,单击Sleep容器的名称。
在容器详情页面单击日志页签,设置容器为istio-init。
可以看到以下日志。
-A OUTPUT -p udp --dport 53 -d 192.168.0.10/32 -j REDIRECT --to-port 15053 -A ISTIO_OUTPUT -p tcp --dport 53 -d 192.168.0.10/32 -j REDIRECT --to-ports 15053
Sidecar代理会拦截来自应用程序容器的所有DNS查询,拦截的方式与通过iptables规则拦截其他类型的流量相同。Istio添加了额外的iptables规则来将所有发送到Kubernetes DNS服务(例如CoreDNS服务)的端口53(TCP和UDP)上的DNS数据包重定向到端口15053。
查看pilot-agent进程监听的端口。
在集群管理页左侧导航栏,选择 。
在容器组页面单击Sleep容器右侧操作列下的终端,单击istio-proxy。
在istio-proxy容器中执行以下命令,查看pilot-agent进程监听的端口。
netstat -anp |grep 15053
预期输出:
tcp 0 0 127.0.0.1:15053 0.0.0.0:* LISTEN 1/pilot-agent udp 0 0 127.0.0.1:15053 0.0.0.0:* 1/pilot-agent
DNS查询被重定向到在Sidecar代理容器中运行的pilot-agent进程中,可以看到该进程正在监听端口15053。
访问aliyun.com。
在集群管理页左侧导航栏,选择 。
在容器组页面单击Sleep容器右侧操作列下的终端,单击sleep。
在Sleep容器中执行以下命令,访问aliyun.com。
curl -v https://aliyun.com
预期输出:
* Trying 240.240.**.**:443... * Connected to aliyun.com (240.240.**.**) port 443 (#0)
可以看到返回的地址是240.240.**.**,该地址是服务网格自动分配的虚拟IP,而不是真实的公开的IP地址。服务网格使用iptables劫持了对kube-dns的请求,并将请求路由到了Pod中运行的Sidecar Proxy。当应用程序Pod将aliyun.com解析为虚拟IP并发出请求时,虚拟IP将被替换为Sidecar Proxy中解析的实际公共IP地址。
为DNS代理启用调试日志
为DNS代理和pilot-agent启用调试日志后,pilot-agent将记录来自应用程序容器的每个DNS查询。
登录容器服务管理控制台。
在控制台左侧导航栏,单击集群。
在集群列表页面,单击目标集群名称或者目标集群右侧操作列下的详情。
在集群管理页左侧导航栏,选择 。
在无状态页面目标应用右侧操作列下选择 。
在编辑 YAML对话框中spec参数下添加以下注释,然后单击更新。
annotations: sidecar.istio.io/agentLogLevel: "dns:debug"
在集群中执行以下命令,查看调试日志。
kubectl logs -n default sleep-85fdfd8896-2ctq4 -c istio-proxy | grep debug
可以在日志中看到
found=true
,说明DNS查询在本地注册表中找到了域名,并将对域名进行解析。