NodeLocal DNS介绍及部署应用

1 NodeLocal DNS是什么?

NodeLocal DNSCache 通过在集群节点上运行一个 DaemonSet 来提高 clusterDNS 性能和可靠性。处于 ClusterFirst 的 DNS 模式下的 Pod 可以连接到 kube-dns 的 serviceIP 进行 DNS 查询。通过 kube-proxy 组件添加的 iptables 规则将其转换为 CoreDNS 端点。通过在每个集群节点上运行 DNS 缓存,NodeLocal DNSCache 可以缩短 DNS 查找的延迟时间、使 DNS 查找时间更加一致,以及减少发送到 kube-dns 的 DNS 查询次数。

借助这种新架构,Pod 将可以访问在同一节点上运行的 DNS 缓存代理,从而避免 iptables DNAT 规则和连接跟踪。 本地缓存代理将查询 kube-dns 服务以获取集群主机名的缓存缺失(默认为 "cluster.local" 后缀)。

2 为什么使用NodeLocal DNS?

  • 使用当前的 DNS 体系结构,如果没有本地 kube-dns/CoreDNS 实例,则具有最高 DNS QPS 的 Pod 可能必须延伸到另一个节点。 在这种场景下,拥有本地缓存将有助于改善延迟。
  • 跳过 iptables DNAT 和连接跟踪将有助于减少 conntrack 竞争并避免 UDP DNS 条目填满 conntrack 表。
  • 从本地缓存代理到 kube-dns 服务的连接可以升级为 TCP。 TCP conntrack 条目将在连接关闭时被删除,相反 UDP 条目必须超时 (默认 nf_conntrack_udp_timeout 是 30 秒)。
  • 将 DNS 查询从 UDP 升级到 TCP 将减少由于被丢弃的 UDP 包和 DNS 超时而带来的尾部等待时间; 这类延时通常长达 30 秒(3 次重试 + 10 秒超时)。 由于 nodelocal 缓存监听 UDP DNS 查询,应用不需要变更。
  • 在节点级别对 DNS 请求的度量和可见性。
  • 可以重新启用负缓存,从而减少对 kube-dns 服务的查询数量。
  • 避免IPVS缺陷导致的DNS概率性解析超时问题
  • 默认解析使用UDP,UDP默认返回报文长度为512字节,大于512字节后就会将包丢弃,升级为TCP协议可以解决这个问题。TCP可以进行数据包的切片可以完整的得到返回的response

3 工作原理

  1. 配置了NodeLocal DNS本地缓存的Pod,默认会通过NodeLocal DNSCache监听于节点上的IP(169.254.20.10)解析域名。
  2. NodeLocal DNSCache本地若无缓存应答解析请求,则会通过kube-dns服务请求CoreDNS进行解析
  3. CoreDNS对于非集群内域名,会通过VPC DNS服务器进行解析
  4. 已注入DNS本地缓存的Pod,当无法连通NodeLocal DNSCache时,会继而直接通过kube-dns服务连接到CoreDNS进行解析,此链路为备用链路
  5. 未注入DNS本地缓存的Pod,会通过标准的kube-dns服务链路连接到CoreDNS进行解析

4 安装NodeLocal DNS

4.1 获取部署文件

将文件保存为nodelocaldns.yaml,文件地址:

https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml

4.2 修改配置

4.2.1 IPV6配置

如果使用 IPv6,在使用 'IP:Port' 格式的时候需要把 CoreDNS 配置文件里的所有 IPv6 地址用方括号包起来。 如果你使用上述的示例清单, 需要把配置行 L70 修改为: "health [__PILLAR__LOCAL__DNS__]:8080"。

4.2.2 变量配置

把清单里的变量更改为正确的值。

# 获取coredns的IP
$ kubedns=`kubectl get svc coredns -n kube-system -o jsonpath={.spec.clusterIP}`
 
# 表示集群域,默认就是 cluster.local
domain=cluster.local
 
# 表示 DNSCache 本地的 IP,默认为169.254.20.10
localdns=169.254.20.10
 
<cluster-domain> 的默认值是 "cluster.local"。
<localdns> 是 NodeLocal DNSCache 选择的本地侦听 IP 地址。

如果 kube-proxy 运行在 IPTABLES 模式: 

sed -i "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/__PILLAR__DNS__SERVER__/$kubedns/g" nodelocaldns.yaml

node-local-dns Pod 会设置 __PILLAR__CLUSTER__DNS__ 和 __PILLAR__UPSTREAM__SERVERS__。 在此模式下, node-local-dns Pod 会同时侦听 kube-dns 服务的 IP 地址和 <node-local-address> 的地址,以便 Pod 可以使用其中任何一个 IP 地址来查询 DNS 记录。

如果 kube-proxy 运行在 IPVS 模式:

sed -i "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/,__PILLAR__DNS__SERVER__//g; s/__PILLAR__CLUSTER__DNS__/$kubedns/g" nodelocaldns.yaml

在此模式下,node-local-dns Pod 只会侦听 <node-local-address> 的地址。 node-local-dns 接口不能绑定 kube-dns 的集群 IP 地址,因为 IPVS 负载均衡使用的接口已经占用了该地址。 node-local-dns Pod 会设置 __PILLAR__UPSTREAM__SERVERS__

4.3 将NodeLocalDNS 部署到集群

4.3.1 灰度部署

如果是线上集群,推荐不要直接apply 文件,采用灰度的方式部署。可以在yaml中增加配置如下:

spec:
  nodeSelector:
    nodelocaldns: "true"

4.3.2 node打标签

挑选集群的一些机器打上nodelocaldns=true的标签

for i in `cat 1.txt`; do kubectl  label node $i nodelocaldns=true;done

4.3.3 apply 文件

kubectl apply -f nodelocaldns.yaml 

4.3.4 验证

这个时候需要进入到pod内验证服务是否有异常 (这些打了标签的node 上面的pod)
验证方式:
   1) pod内是否可以解析外网域名(前提条件 node节点可以访问域名)
   2) pod内解析内网域名
   2) pod内解析集群service name
如果都没有问题,说明部署NodeLocalDNS后并没有影响我们集群现有的服务

4.3.5 取消节点亲和性配置

将yaml中NodeSelect 配置注释,重新apply 

kubectl apply -f nodelocaldns.yaml 

4.3.6 pod信息查看

查看kube-system 命名空间下的node-local-dns pod

kubectl  get pod -n kube-system | grep node-local

自此NodeLocalDNS就部署完成了,但是还没有应用到它。

5 应用NodeLocal DNSCache

为了能使应用原本请求CoreDNS的流量改为由DNS缓存DaemonSet代理,需要使Pod内部的中nameservers配置成169.254.20.10和kube-dns对应的IP地址,有以下几种方式可以选择:

  • 方式一:借助DNSConfig动态注入控制器在Pod创建时配置DNSConfig自动注入。
  • 方式二:创建Pod时手动指定DNSConfig。
  • 方式三:修改kubelet参数,并重启节点kubelet。存在业务中断风险,不推荐使用此方式。

第一种方式:

需要集群具备adminssion webhook功能,或者可以使用第三方的一些插件完成部署

  • adminssion webhook:基于Admission Webhook机制拦截Pod创建的请求,自动注入使用DNS缓存的Pod DNSConfig信息。

第二种方式:

如果用了原生的部署方式,可以在生产环境采用第二种应用方式

应用方式(以helm为例):业务的每一个服务都是通过helm 模板渲染生成一个chart, 其hekm模版会在gitlab代码仓库管理,所以只要修改helm 模板,服务重新发布即可使用NodeLocal DNSCache了。也可以手动修改yaml文件。具体方式需要看业务当前环境是怎么部署的服务了。下面是helm具体配置

{{-if eq .Values.cluster "offline" }}
      dnsPolicy: None
      dnsConfig:
        nameservers: ["169.254.20.10","10.11.128.10"]
        searches:
        - yidian-prod.svc.cluster.local
        - default.svc.cluster.local
        - svc.cluster.local
        - cluster.local
        - yidian.com
        - yidian-inc.com
        options:
        - name: ndots
          value: "3"
        - name: attempts
          value: "2"
        - name: timeout 
          value: "1"
{{- end }}

第三种方式:

不建议使用尤其是生产环境禁止使用

  • 如果是二进制部署的集群,需要修改/etc/systemd/system/kubelet.service.d/10-kubeadm.conf 文件中的--cluster-dns=xxx.xxx.xxx.xxx参数。

        查看kbuelet启动依赖的配置文件

ps -elf | grep kubelet | grep cluster-dns  
systemctl  status  kubelet
  • 如果是kubeadm部署的集群,修改/var/lib/kubelet/config.yaml文件中的clusterDNS参数

六、验证

上面使用的第二种方式,需要重新发布才可以生效。下图是发布后pod内部的状况,可以看到pod内有两行nameserver信息第一行为NodeLocalDNS的IP,第二行是coreDNS的IP。

验证方式:
   1) pod内是否可以解析外网域名(前提条件 node节点可以访问域名)
   2) pod内解析内网域名
   2) pod内解析集群service name

下面是nodelocaldns.yaml,也可以使用我的yaml,需要注意的是对应的那些变量要做变更,一定要改coredns的ip

apiVersion: v1
kind: ServiceAccount
metadata:
  name: node-local-dns
  namespace: kube-system
  labels:
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
---
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: coredns
---
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
        bind 169.254.20.10 __PILLAR__DNS__SERVER__
        forward . 10.11.128.10 {
                force_tcp
        }
        prometheus :9253
        health 169.254.20.10:8080
        }
    in-addr.arpa:53 {
        errors
        cache 30
        reload
        loop
        bind 169.254.20.10 __PILLAR__DNS__SERVER__
        forward . 10.11.128.10 {
                force_tcp
        }
        prometheus :9253
        }
    ip6.arpa:53 {
        errors
        cache 30
        reload
        loop
        bind 169.254.20.10 __PILLAR__DNS__SERVER__
        forward . 10.11.128.10 {
                force_tcp
        }
        prometheus :9253
        }
    .:53 {
        errors
        cache 30
        reload
        loop
        bind 169.254.20.10 __PILLAR__DNS__SERVER__
        forward . __PILLAR__UPSTREAM__SERVERS__ {
               force_tcp
        }
        prometheus :9253
        }
---
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:
      maxUnavailable: 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: hub.kce.ksyun.com/ksyun/k8s-dns-node-cache:1.22.8
        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: 8080
          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
---
# A headless service is a service with a service IP but instead of load-balancing it will return the IPs of our associated Pods.
# We use this to expose metrics to Prometheus.
apiVersion: v1
kind: Service
metadata:
  annotations:
    prometheus.io/port: "9253"
    prometheus.io/scrape: "true"
  labels:
    k8s-app: node-local-dns
  name: node-local-dns
  namespace: kube-system
spec:
  clusterIP: None
  ports:
    - name: metrics
      port: 9253
      targetPort: 9253
  selector:
    k8s-app: node-local-dns

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/396130.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

函数模板与模板的特例化

函数模板 模板的意义&#xff1a;对类型进行参数化 模板类型参数 c使用class、typename关键字定义模板类型参数 函数模板&#xff1a;不进行编译&#xff0c;因为类型还不知道 template <typename T>//定义一个模板参数列表 bool compare(T a,T b)//compare是一个函…

通用二进制方式安装MySQL8.0.x

一、必要说明 1、系统&#xff1a;openEuler操作系统 2、版本&#xff1a;MySQL - 8.0.36 3、下载地址&#xff1a;https://dev.mysql.com/get/Downloads/MySQL-8.0 二、安装步骤 1、下载glibc版本的Mysql [rootnode2 ~]# wget -c https://dev.mysql.com/get/Downloads/MySQ…

C++ bfs反向建图(六十)【第七篇】

今天我们来学习一下bfs反向建图 1.bfs的反向建图 我们之前在图上求最短路都是求从起点出发到每个点的最短路&#xff0c;不过有时候我们也会遇到让求每个点到终点的最短路的问题&#xff0c;此时我们可以怎么做呢&#xff1f; 如果从每个点出发&#xff0c;用 BFS 搜索到终点…

测试开发【Mock平台】13基础:拦截器服务实现(四) 简单规则匹配逻辑

【Mock平台】为系列测试开发教程&#xff0c;从0到1编码带你一步步使用Spring Boot 和 Antd React框架完成搭建一个测试工具平台&#xff0c;希望作为一个实战项目对各位的测试开发学习之路有帮助&#xff0c;关注公众号发送“mock”获取github项目源码地址&#xff0c;大奇一个…

RocketMQ—RocketMQ消息重复消费问题

RocketMQ—RocketMQ消息重复消费问题 重复消费问题的描述 什么情况下会发生重复消费的问题&#xff1a; 生产者多次投递消息&#xff1a;如果生产者发送消息时&#xff0c;连接有延迟&#xff0c;MQ还没收到消息&#xff0c;生产者又发送了一次消息&#xff1b; 消费者方扩容…

【漏洞复现-通达OA】通达OA WHERE_STR 存在前台SQL注入漏洞

一、漏洞简介 通达OA(Office Anywhere网络智能办公系统)是由北京通达信科科技有限公司自主研发的协同办公自动化软件,是与中国企业管理实践相结合形成的综合管理办公平台。通达OA WHERE_STR存在前台SQL注入漏洞,攻击者可通过该漏洞获取数据库敏感信息。 二、影响版本 ●…

将其它输入法的词库转换为微软拼音输入法的自学习词库

上班第一天&#xff0c;我删除了搜狗输入法 曾几何时&#xff0c;搜狗拼音输入法&#xff0c;以丰富的词库&#xff0c;实用的设置成为我电脑端主要的中文输入法。但新年上班的第一天&#xff0c;我彻底删除了它&#xff0c;回归到微软拼音输入法。因为&#xff0c;最近&#…

同学在外包干了两年的点点点,24岁人就快废了

前言 简单的说下&#xff0c;我大学的一个同学&#xff0c;毕业后我自己去了自研的公司&#xff0c;他去了外包&#xff0c;快两年了我薪资、技术各个方面都有了很大的提升&#xff0c;他在外包干的这两年人都要废了&#xff0c;技术没一点提升&#xff0c;学不到任何东西&…

辽宁博学优晨教育科技有限公司视频剪辑培训靠谱吗?

在数字媒体日益繁荣的今天&#xff0c;视频剪辑已成为一项炙手可热的技能。不少培训机构纷纷涉足这一领域&#xff0c;辽宁博学优晨教育科技有限公司便是其中之一。然而&#xff0c;面对众多的选择&#xff0c;很多人不禁要问&#xff1a;辽宁博学优晨教育科技有限公司的视频剪…

中国传媒网CEO徐晓艺:媒体融合发展业态新媒体年后在沪召开

近日,在“坚守媒体初心,拥抱AI时代”2023外滩新媒体年会上,有多项合作达成。 在当前竞争激烈的市场环境中,媒体宣传已经成为企业品牌推广不可或缺的一环。对于很多企业来说往往会犯一个错误,就是默默地参加了展会,并没有进行媒体营销。展会是一种非常有力的宣传和推广方式,可以…

网络安全综合实验

1.实验拓扑 在这里注意因为第四个要求配置双击热备&#xff0c;我们可以第一时间配置&#xff0c;避免二次重复配置消耗时间 4、FW1和FW3组成主备模式的双机热备 具体配置位置在系统-->高可靠性-->双机热备-->配置 这里上行链路有两组&#xff0c;分别为电信和移动&…

RK356x U-Boot研究所(驱动篇)4.2.2 DRM代码结构分析

谈到 drm 就涉及到 libdrm 库,它是一个跨驱动的中间件,它允许用户空间应用(例如作为Mesa和2D驱动程序)通过DRI与内核通信协议。 如下DRM结构图: libdrm 是DRM下沟通驱动和用户层的库。过去APP可能是使用open(framebuff)这样的方式来和图形驱动沟通,但是在现在的硬件演化…

【项目管理】CMMI-项目监督和控制

项目监督和控制&#xff08;Monitoring and Control, MC&#xff09;的目的是通过周期性地跟踪项目计划的各种性能参数如工作产品的规模、工作量、成本、进度、风险等&#xff0c;不断地了解项目的进展情况&#xff0c;以便当项目实际进展状况显著偏离项目计划时能够及时采取纠…

【Flink入门修炼】1-4 Flink 核心概念与架构

前面几篇文章带大家了解了 Flink 是什么、能做什么&#xff0c;本篇将带大家了解 Flink 究竟是如何完成这些的&#xff0c;Flink 本身架构是什么样的&#xff0c;让大家先对 Flink 有整体认知&#xff0c;便于后期理解。 一、Flink 组件栈 Flink是一个分层架构的系统&#xf…

Shiro-05-5 分钟入门 shiro 安全框架实战笔记

序言 大家好&#xff0c;我是老马。 前面我们学习了 web 安全之 Spring Security 入门教程 这次我们来一起学习下另一款 java 安全框架 shiro。 什么是Apache Shiro&#xff1f; Apache Shiro是一个功能强大且易于使用的Java安全框架&#xff0c;它为开发人员提供了一种直…

压缩感知——革新数据采集的科学魔法

引言&#xff1a; 在数字时代&#xff0c;数据以及数据的收集和处理无处不在。压缩感知(Compressed Sensing, CS)是一种新兴的数学框架&#xff0c;它挑战了我们传统上对数据采集和压缩的看法&#xff0c;给医学图像、天文观测、环境监测等领域带来了颠覆性的影响。但到底什么…

模板(函数模板)---C++

模板目录 模板1.模板概念&#xff12;.泛型编程 1.函数模板1.1 函数模板语法1.2 函数模板注意事项1.3 普通函数与函数模板的区别1.4 普通函数与函数模板的调用规则1.5 模板的局限性1.6 函数模板案例 模板 1.模板概念 模板就是建立通用的模具&#xff0c;大大提高复用性。 模板…

HCIA-HarmonyOS设备开发认证V2.0-轻量系统内核内存管理-静态内存

目录 一、内存管理二、静态内存2.1、静态内存运行机制2.2、静态内存开发流程2.3、静态内存接口2.4、实例2.5、代码分析&#xff08;待续...&#xff09;坚持就有收货 一、内存管理 内存管理模块管理系统的内存资源&#xff0c;它是操作系统的核心模块之一&#xff0c;主要包括…

百度地图接口 | 实现校验收货地址是否超出配送范围

目录 1. 环境准备 2. 代码开发 2.1 application.yml 2.2 OrderServiceImpl &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用开发、数据结构和算法&#xff0c;初步涉猎Py…