k8s node dns本地缓存

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 讲解k8s node dns本地缓存

01 引言

声明:本文为《Kubernetes权威指南:从Docker到Kubernetes实践全接触(第5版)》的读书笔记

由于在Kubernetes集群中配置的DNS服务 是一个名为 “kube-dns” 的Service, 所以容器应用都通过其ClusterIP地址(例如169.169.0.100)去执行服务名的DNS域名解析。这对于大规模集群可能引起以下两个问题:

  • 集群DNS服务压力增大(这可以通过自动扩容缓解)
  • 由于DNS服务的IP地址是ServiceClusterIP地址,所以会通过kube- proxy设置的iptables规则进行转发,可能导致域名解析性能很差,原因是Netfilter 在做DNAT转换时可能会引起conntrack冲突,从而导致DNS查询产生5s的延时

为了解决这两个问题,Kubernetes引入了Node本地DNS缓存NodeLocal DNSCache)来提高整个集群的DNS域名解析的性能,本文来讲解下。

02 Node本地DNS缓存

使用Node本地DNS缓存的好处如下

  • 在没有本地DNS缓存时,集群DNS服务的Pod很可能在其他节点上,跨主机访问会增加网络延时,使用Node本地DNS缓存可 显著减少跨主机查询的网络延时
  • 跳过iptables DNAT和连接跟踪将有助于 减少conntrack竞争,并避免UDP DNS记录填满conntrack表
  • 本地缓存到集群DNS服务的连接协议可以升级为TCP。TCP conntrack条目将在连接关闭时被删除;默认使用UDP时,conntrack条目只能等到超时时间过后才被删除,操作系统的默认超时时间(nf_conntrack_udp_timeout),为30s;
  • 将DNS查询从UDP升级为TCP,将减少由于丢弃的UDP数据包和DNS超时而引起的尾部延迟(tail latency),UDP超时时间可能会长达30s(3次重试, 每次10s);
  • 提供Node级别DNS解析请求的度量 (Metrics)和可见性 (visibility) 可以重新启用负缓存(Negative caching)功能,减少对集群DNS服务的查询数量

2.1 工作流程

Node本地DNS缓存(NodeLocal DNSCache)的工作流程如图所示,客户端Pod首先会通过本地DNS缓存进行域名解析,当缓存中不存在域名时,会将请求转发到集群DS服务进行解析
在这里插入图片描述

2.2 部署Node本地DNS缓存工具

配置文件nodelocaldns.yaml的内容如下,主要包括 ServiceAccount、Daemonset、ConfigMap和Service 几个资源对象。

2.2.1 资源对象配置


Service Account的定义如下:

apiVersion: v1
kind: ServiceAccount
metadata: 
    name: node-local-dns
    namespace: kube-system 
    labels:
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: Reconcile

Service的定义如下:

apiVersion: v1
kind: Service
metadata:
    name: kube-dns-upstream
    namespace: kube-system 
    labels:
        k8s-app: kube-dns
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: Reconcile 
        kubernetes.io/name: "KubeDNSUpstream"
spec:
    ports:
    - name: dns
      port: 53
      protocol: UDP
      targetPort: 53
    - name: dns-tcp
      port: 53
      protocol: TCP
      targetPort: 53
    selector:
      k8s-app: kube-dns

ConfigMap的定义如下:

apiversion: v1
kind: ConfigMap
metadata:
    name: node-local-dns
    namespace: kube-system 
    labels:
        addonmanager.kubernetes.io/mode: Reconcile
data:
Corefile: |
    cluster.local:53 {
        errors
        cache{
            success 9984 30 
            denial 9984 5
        }
        reload
        loop
        bind169.254.20.10
        forward.169.169.0.100{
            force tcp
        }
        prometheus 9253
        hea1th169.254.20.10:8081 
        }
    in-addr.arpa:53 {
        errors 
        cache 30 
        reload
        loop
        bind 169.254.20.10
        forward . 169.169.0.100{
            force tcp
        }
        prometheus 9253 
        }
    ip6.arpa:53 {
        errors 
        cache 30 
        reload
        loop
        bind 169.254.20.10
        forward . 169.169.0.100{
            force tcp
        }
        prometheus 9253
        }
    .:53 {
        errors 
        cache 30 
        reload
        loop
        bind 169.254.20.10
        forward . 169.169.0.100{
            force tcp
        }
        prometheus 9253 
        }

ConfigMap Corefile的主要配置参数如下:

  • bind 169.254.20.10 :node-local-dns需要绑定的本地IP地址,建议将其设置为169.254.0.0/16范围,确保不与集群内的其他IP冲突;
  • forward.169.169.0.100:在node-local-dns缓存中不存在域名记录时, 将转发到的上游DNS服务器IP设置为Kubernetes集群DNS服务(kube-dns)的IP,例如169.169.0.100;
  • health169.254.20.10:8081:健康检查端口号设置与Daemonset的livenessProbe一致,需要注意,node-local-dns网络模式设置了 hostNetwork=true,这个端口号也会被直接绑定到宿主机上,需要确保不与宿主机的其他应用冲突。

DaemonSet的定义如下:

apiVersion: apps/v1
kind: DaemonSet
metadata:
    name: node-local-dns 
    namespace: kube-system 
    labels:
        k8s-app: node-local-dns
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: Reconcile 
spec:
    updatestrategy:
        rollingUpdate:
            maxUnavai1able: 10% 
    selector:
        matchLabels:
            k8s-app: node-local-dns 
    template:
        metadata:
            labels:
                k8s-app: node-local-dns 
            annotations:
                prometheus.io/port: "9253" 
                prometheus.io/scrape: "true" 
        spec:
            priorityclassName: system-node-critical 
            serviceAccountName: node-local-dns 
            hostNetwork: true
            dnsPolicy: Default Don't use cluster DNS. 
            tolerations:
            - key: "CriticalAddonsOnly" 
              operator: "Exists"
            - effect: "NoExecute"
              operator: "Exists"
            - effect: "NoSchedule"
              operator: "Exists"
        containers:
        - name: node-cache
          image: k8s.gcr.io/k8s-dns-node-cache: 1.15.13 
            resources:
                requests:
                cpu: 25m
                memory: 5Mi
                args: ["-localip","169.254.20.10","-conf","/etc/Corefile","-upstreamsvc","kube-dns-upstream"]
            securityContext:
                privileged: true
            ports:
            - containerPort: 53
              name: dns
              protocol: UDP
            - containerPort: 53
              name: dns-tcp
              protocol: TCP
            - containerPort: 9253
              name: metrics
              protocol: TCP
            livenessProbe:
                httpGet:
                    host: 169.254.20.10
                    path: /health
                    port: 8081
                initialDelaySeconds: 60 
                timeoutSeconds: 5
            volumeMounts:
            - mountPath: /run/xtables.lock 
              name: xtables-lock
              readonly: false
            - name: config-volume 
              mountPath: /etc/coredns 
            - name: kube-dns-config 
              mountPath: /etc/kube-dns
        volumes:
        - name: xtables-lock
            hostPath:
                path: /run/xtables.lock 
                type: FileorCreate 
        - name: kube-dns-config 
          configMap:
            name: coredns
            optional: true
        - name: config-volume
            configMap:
                name: node-local-dns
                items:
                    - key: Corefile
                      path: Corefile.base

Daemonset node-local-dns的主要配置参数如下:

  • args: ["-localip" , "169.254.20.10" , "-conf" , "/etc/Corefile" , "upstreamsvc" , "kube-dns-upstream"]:将-localip参数设置为node-local-dns绑定的本地IP地址,对其他参数无须修改;
  • livenessProber中的健康检查端口号与ConfigMap中的一致;

另外,如果kube-proxy代理模式(-proxy-mode)使用的是ipvs模式,则还需要修改kubelet的启动参数-cluster-dns为node-local-dns绑定的本地IP地169.254.20.10。

2.2.2 部署

通过kubectl create命令创建node-local-dns服务:

kubectl create -f nodelocaldns.yaml 
serviceaccount/node-local-dns created 
service/kube-dns-upstream created 
configmap/node-local-dns created 
daemonset.apps/node-local-dns created

确认在每个Node上都运行了一个node-local-dns Pod:
在这里插入图片描述
在客户端Pod内对服务名的解析没有变化,仍然可以直接通过服务名访问其他服务,例如:
在这里插入图片描述

03 文末

本文主要讲解Node本地DNS缓存相关的概念,希望能帮助到大家,谢谢大家的阅读,本文完!

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
3月前
|
Kubernetes Ubuntu Windows
【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)
【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)
131 3
|
3月前
|
缓存 NoSQL Java
Redis深度解析:解锁高性能缓存的终极武器,让你的应用飞起来
【8月更文挑战第29天】本文从基本概念入手,通过实战示例、原理解析和高级使用技巧,全面讲解Redis这一高性能键值对数据库。Redis基于内存存储,支持多种数据结构,如字符串、列表和哈希表等,常用于数据库、缓存及消息队列。文中详细介绍了如何在Spring Boot项目中集成Redis,并展示了其工作原理、缓存实现方法及高级特性,如事务、发布/订阅、Lua脚本和集群等,帮助读者从入门到精通Redis,大幅提升应用性能与可扩展性。
71 0
|
3天前
|
存储 缓存 网络协议
如何防止DNS缓存中毒攻击(一)
DNS缓存中毒也称为DNS欺骗
22 10
|
3天前
|
缓存 网络协议 安全
如何防止DNS缓存中毒(Ⅱ)
服务器应该配置为尽可能少地依赖与其他DNS服务器的信任关系
20 10
|
17天前
|
缓存 网络协议 安全
如何防止DNS缓存中毒(Ⅱ)
防止DNS缓存中毒的方法包括:减少DNS服务器与其它服务器的信任关系;限制DNS服务器上的服务;使用最新版DNS;加强用户安全教育,如识别可疑网站,仅访问HTTPS网站等。部署SSL证书并选择符合国际Webtrust标准的CA机构,可进一步提高安全性。
28 1
|
17天前
|
存储 缓存 网络协议
如何防止DNS缓存中毒攻击(一)
DNS缓存中毒,即DNS欺骗,是一种通过利用DNS系统的漏洞,将用户流量从合法服务器导向虚假服务器的网络攻击。攻击者通过伪造DNS响应,使缓存服务器存储错误的IP地址,从而实现对合法URL的劫持。这不仅可能导致用户信息泄露,还可能使用户设备遭受恶意软件感染,对金融、医疗等关键领域造成严重影响。据统计,DNS攻击每年造成的平均损失高达223.6万美元,其中23%的攻击源自DNS缓存中毒。
45 0
|
2月前
|
存储 缓存 Java
在Spring Boot中使用缓存的技术解析
通过利用Spring Boot中的缓存支持,开发者可以轻松地实现高效和可扩展的缓存策略,进而提升应用的性能和用户体验。Spring Boot的声明式缓存抽象和对多种缓存技术的支持,使得集成和使用缓存变得前所未有的简单。无论是在开发新应用还是优化现有应用,合理地使用缓存都是提高性能的有效手段。
38 1
|
2月前
|
存储 缓存 Android开发
Android RecyclerView 缓存机制深度解析与面试题
本文首发于公众号“AntDream”,详细解析了 `RecyclerView` 的缓存机制,包括多级缓存的原理与流程,并提供了常见面试题及答案。通过本文,你将深入了解 `RecyclerView` 的高性能秘诀,提升列表和网格的开发技能。
66 8
|
3月前
|
存储 缓存 监控
警惕网络背后的陷阱:揭秘DNS缓存中毒如何悄然改变你的网络走向
【8月更文挑战第26天】DNS缓存中毒是一种网络攻击,通过篡改DNS服务器缓存,将用户重定向到恶意站点。攻击者利用伪造响应、事务ID猜测及中间人攻击等方式实施。这可能导致隐私泄露和恶意软件传播。防范措施包括使用DNSSEC、限制响应来源、定期清理缓存以及加强监控。了解这些有助于保护网络安全。
86 1
|
3月前
|
缓存 算法 前端开发
深入理解缓存淘汰策略:LRU和LFU算法的解析与应用
【8月更文挑战第25天】在计算机科学领域,高效管理资源对于提升系统性能至关重要。内存缓存作为一种加速数据读取的有效方法,其管理策略直接影响整体性能。本文重点介绍两种常用的缓存淘汰算法:LRU(最近最少使用)和LFU(最不经常使用)。LRU算法依据数据最近是否被访问来进行淘汰决策;而LFU算法则根据数据的访问频率做出判断。这两种算法各有特点,适用于不同的应用场景。通过深入分析这两种算法的原理、实现方式及适用场景,本文旨在帮助开发者更好地理解缓存管理机制,从而在实际应用中作出更合理的选择,有效提升系统性能和用户体验。
183 1

相关产品

  • 云解析DNS