文章目录

  • 一、DNS服务概述
  • 二、CoreDNS配置解析
  • 三、Pod的dns策略
    • 1)Pod dns策略
    • 2)测试解析结果
  • 四、测试CoreDNS
    • 1)pod验证
    • 2)创建service和Deployment来验证
    • 3)宿主机上解析域名验证

一、DNS服务概述

service发现是k8s中的一个重要机制,其基本功能为:在集群内通过服务名对服务进行访问,即需要完成从服务名到ClusterIP的解析。
k8s主要有两种service发现机制:环境变量和DNS。没有DNS服务的时候,k8s会采用环境变量的形式,但一旦有多个service,环境变量会变复杂,为解决该问题,我们使用DNS服务。

DNS服务在kubernetes中经历了三个阶段(SkyDNS-》KubeDNS-》CoreDNS):

  • 【第一阶段】在kubernetes 1.2版本时,dns服务使用的是由SkyDNS提供的,由4个容器组成:kube2sky、skydns、etcd和healthz。etcd存储dns记录;kube2sky监控service变化,生成dns记录;skydns读取服务,提供查询服务;healthz提供健康检查。
  • 【第二阶段】在kubernetes 1.4版本开始使用KubeDNS,有3个容器组成:kubedns、dnsmasq和sidecar。kubedns监控service变化,并记录到内存(存到内存提高性能)中;dnsmasq获取dns记录,提供dns缓存,提供dns查询服务;sidecar提供健康检查。
  • 【第三阶段】从kubernetes >=1.11版本开始,dns服务有CoreDNS提供,coredns支持自定义dns记录及配置upstream dns server,可以统一管理内部dns和物理dns。coredns只有一个coredns容器。下面是coredns的架构。

二、CoreDNS配置解析

下面是coredns的配置模板

apiVersion: v1
kind: ConfigMap
metadata:name: corednsnamespace: namespace-test
data:Corefile: |.:53 {errorshealthreadykubernetes cluster.local  10.200.0.0/16 {pods insecureupstream 114.114.114.114fallthrough in-addr.arpa ip6.arpanamespaces namespace-test}prometheus :9153forward . /etc/resolv.confcache 30loopreloadloadbalance}

CoreDNS的主要功能是通过插件系统实现的。它实现了一种链式插件的结构,将dns的逻辑抽象成了一个个插件。常见的插件如下:

  • loadbalance:提供基于dns的负载均衡功能
  • loop:检测在dns解析过程中出现的简单循环问题
  • cache:提供前端缓存功能
  • health:对Endpoint进行健康检查
  • kubernetes:从kubernetes中读取zone数据
  • etcd:从etcd读取zone数据,可以用于自定义域名记录
  • file:从文件中读取zone数据
  • hosts:使用/etc/hosts文件或者其他文件读取zone数据,可以用于自定义域名记录
  • auto:从磁盘中自动加载区域文件
  • reload:定时自动重新加载Corefile配置文件的内容
  • forward:转发域名查询到上游dns服务器
  • proxy:转发特定的域名查询到多个其他dns服务器,同时提供到多个dns服务器的负载均衡功能
  • prometheus:为prometheus系统提供采集性能指标数据的URL
  • pprof:在URL路径/debug/pprof下提供运行是的西能数据
  • log:对dns查询进行日志记录
  • errors:对错误信息镜像日志记录

三、Pod的dns策略

1)Pod dns策略

  • Default: 继承Pod所在宿主机的DNS设置
  • ClusterFirst:优先使用kubernetes环境的dns服务,将无法解析的域名转发到从宿主机继承的dns服务器
  • ClusterFirstWithHostNet:和ClusterFirst相同,对于以hostNetwork模式运行的Pod应明确知道使用该策略
    None: 忽略kubernetes环境的dns配置,通过spec.dnsConfig自定义DNS配置
  • 自定义Dns配置可以通过spec.dnsConfig字段进行设置,可以设置如下信息
    1. nameservers:一组dns服务器的列表,最多可设置3个
    2. searchs:一组用于域名搜索的dns域名后缀,最多6个
    3. options:配置其他可选参数,例如ndots、timeout等
      例如:
spec:dnsPolicy: "None"dnsConfig:nameservers:- 1.2.3.4searchs:- xx.ns1.svc.cluster.local- xx.daemon.comoptions:- name: ndotsvalues: "2"

pod被创建后,容器内的/etc/resolv.conf会根据这个信息进行配置。

2)测试解析结果

之前安装k8s集群的时候就已经安装过CoreDNS,所以这里就不重复讲解安装了,不清楚的,看这里

创建nslookup服务

$ cat >busybox.yaml<<EOF
apiVersion: v1
kind: Pod
metadata:name: busyboxnamespace: default
spec:containers:- name: busyboximage: busybox:1.28command:- sleep- "3600"imagePullPolicy: IfNotPresentrestartPolicy: Always
EOF

查看并验证

$ kubectl create -f busybox.yaml
$ kubectl get pods busybox
$ kubectl exec busybox -- cat /etc/resolv.conf

容器内 resolv 文件的配置

nameserver 10.1.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

ndots:5:如果查询的域名包含的点 “.” 不到 5 个,那么进行 DNS 查找,将使用非完全限定名称(或者叫绝对域名),如果你查询的域名包含点数大于等于 5,那么 DNS 查询,默认会使用绝对域名进行查询。

Kubernetes 域名的全称,必须是 service-name.namespace.svc.cluster.local 这种模式,服务名。

$ kubectl exec -ti busybox -- nslookup kubernetes.default

四、测试CoreDNS

1)pod验证

现在我们来创建一个busybox的pod,测试一下pod内是否可以解析

$ cat >busybox.yaml<<EOF
apiVersion: v1
kind: Pod
metadata:name: busyboxnamespace: default
spec:containers:- name: busyboximage: busybox:1.28command:- sleep- "3600"imagePullPolicy: IfNotPresentrestartPolicy: Always
EOF

创建并测试解析kubernetes.default

$ kubectl apply -f busybox.yaml
$ kubectl get pods busybox
$ kubectl exec busybox -- cat /etc/resolv.conf
$ kubectl exec -ti busybox -- nslookup kubernetes.default
$ kubectl exec -ti busybox -- nslookup kubernetes.default.svc.cluster.local

2)创建service和Deployment来验证

cat >dns-Service-Deployment-test001.yaml<<EOF
apiVersion: v1
kind: Service
metadata:name: nginx-svc-oldlabels:app: nginx-svc
spec:selector:app: nginxports:- protocol: TCPport: 80targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-old
spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginxports:- containerPort: 80
EOF

创建

$ kubectl apply -f dns-Service-Deployment-test001.yaml
$ kubectl get pod|grep  nginx-old
$ kubectl get svc nginx-svc-old


直接在宿主机上验证

$ nslookup nginx-svc-old.default.svc


发现直接在宿主机上是不能解析域名的。然后用以下yaml创建了一个busybox作为调试工具:

$ cat >dns-Deployment-test002.yaml<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:name: busybox-deployment
spec:replicas: 1selector:matchLabels:app: busyboxtemplate:metadata:labels:app: busyboxspec:restartPolicy: Alwayscontainers:- name: busyboxcommand:- sleep- "3600"image: busybox
EOF

这里用的是截止2021/10/08,busybox的最新镜像。创建好之后,exec进入容器,执行测试命令。

$ kubectl apply -f dns-Deployment-test002.yaml
$ kubectl get pod|grep busybox-deployment
$ kubectl exec  -ti busybox-deployment-5bc85cc8d9-gkjgj -- sh
# 访问上面service的域名
$ nslookup nginx-svc-old.default.svc


发现也是无法解析。
根据coredns解析集群内域名原理可知:

服务 a 访问服务 b,对于同一个 Namespace下,可以直接在 pod 中,通过 curl b 来访问。对于跨 Namespace 的情况,服务名后边对应 Namespace即可,比如 curl b.default。DNS 如何解析,依赖容器内 resolv 文件的配置。

查看busybox容器内的resolve.conf文件:

$ kubectl exec  -ti busybox-deployment-5bc85cc8d9-gkjgj -- sh
$ nslookup nginx-svc-old.default.svc
$ cat /etc/resolv.conf


这个文件中,配置的 DNS Server,一般就是 K8S 中,coredns的 Service 的 ClusterIP,这个IP是虚拟IP,无法ping,但可以访问。

在容器内发请求时,会根据 /etc/resolv.conf 进行解析流程。选择 nameserver 10.1.0.10 进行解析,然后用nginx-svc-old ,依次带入 /etc/resolve.conf 中的 search 域,进行DNS查找,分别是:
search 内容类似如下(不同的pod,第一个域会有所不同)

search default.svc.cluster.local svc.cluster.local cluster.local

nginx-svc-old.default.svc.cluster.local -> nginx-svc-old.svc.cluster.local -> nginx-svc-old.cluster.local

$ kubectl exec  -ti busybox-deployment-5bc85cc8d9-gkjgj -- sh
$ ping nginx-svc-old
$ ping nginx-svc-old.default

直到找到为止。所以,我们执行 ping nginx-svc-old,或者执行 ping nginx-svc-old.default,都可以完成DNS请求,这2个不同的操作,会分别进行不同的DNS查找步骤。

根据以上原理,查看到busybox内的域名/etc/resolv.conf没有问题,nameserver指向正确的kube-dns的service clusterIP。

这下更加怀疑core-dns有问题了。
但查看coredns日志,可以看到并没有报错:

$ kubectl get pod -n kube-system|grep dns
$ kubectl logs -f coredns-7f6cbbb7b8-cn44w -n kube-system
$ kubectl logs -f coredns-7f6cbbb7b8-gf82k -n kube-system


那就说明不是coredns问题了。。
经过一番查找,发现是busybox版本问题。busybox<=1.28.4

发现都说是busybox镜像的问题,从1.28.4以后的镜像都存在这问题。把镜像换成1.28.4试试?修改yaml版本号:

$ kubectl apply -f dns-Deployment-test002.yaml
$ kubectl get pod|grep busybox-deployment
$ kubectl exec  -ti busybox-deployment-564c775bbd-g6228 -- sh
$ nslookup nginx-svc-old.default.svc
# exit
$ kubectl get svc


确实可以成功解析域名了。所以这样看还真是busybox版本问题了。

3)宿主机上解析域名验证

nameserver关键字,如果没指定nameserver就找不到DNS服务器,其它关键字是可选的。nameserver表示解析域名时使用该地址指定的主机为域名服务器。其中域名服务器是按照文件中出现的顺序来查询的,且只有当第一个nameserver没有反应时才查询下面的nameserver,一般不要指定超过3个服务器

在宿主上/etc/resolv.conf中nameserver如下:

$ kubectl get svc -n kube-system
$ kubectl get pod -n kube-system -o wide|grep dns
$ kubectl exec  -ti busybox-deployment-564c775bbd-g6228 -- cat /etc/resolv.conf
$ cat /etc/resolv.conf


后面四个是k8s dns的配置,把后面四个都放到前面来,再验证:

nameserver 10.1.0.10
nameserver 10.244.2.137
nameserver 10.244.2.138
search default.svc.cluster.local svc.cluster.local cluster.local

$ nslookup nginx-svc-old
$ cat /etc/resolv.conf
$ nslookup baidu.com


可以看到现在可以解析了。也不影响外网域名解析,但是最好还是不要指定超过3个服务器。

Kubernetes(k8s)DNS(CoreDNS)介绍相关推荐

  1. 【kubernetes/k8s概念】Kubernetes1.12从零开始(初):课程介绍与官方文档汇总

    说明 资料和交流方式 Kubernetes的文档介绍 Kubernetes中的术语与资源的操作方法 Kubernetes的API约定与启用方法 Kubernetes中资源(Object)的定义 kub ...

  2. kubernetes(k8s)-介绍2

    kubernetes(k8s)-安装(二) 什么是Kubernetes Kubernetes是一个开源平台,用于跨主机群集自动部署,扩展和操作应用程序容器,提供以容器为中心的基础架构. 使用Kuber ...

  3. Kubernetes(K8s)Events介绍(上)

    Kubernetes Events虽不常被提起,却意义非凡.它存储在Etcd里,记录了集群运行所遇到的各种大事件.本系列文章将一步一步地揭开Kubernetes Events的神秘面纱. 师出有名 前 ...

  4. 【为K8s的coredns配置上游DNS服务器】

    为K8s的coredns配置上游DNS服务器 一.背景描述 二.如何修改coredns达到目的 三.修改coredns 解析指定域名走指定dns ①.get coredns configmap ②.修 ...

  5. Kubernetes入门一:介绍及环境准备

    Kubernetes学习笔记 本节主要介绍: Kubernetes的一些基础知识 Kubernetes集群搭建的相关操作内容 前言 1. 部署的演变过程: 整个部署的演变过程如图所示: 传统部署时代: ...

  6. Centos7 安装部署Kubernetes(k8s)集群过程

    1.系统环境 服务器版本 docker软件版本 CPU架构 CentOS Linux release 7.9 Docker version 20.10.12 x86_64 2.前言 如下图描述了软件部 ...

  7. Kubernetes ~ k8s 从入门到入坑。

    Kubernetes ~ k8s 从入门到入坑. 文章目录 Kubernetes ~ k8s 从入门到入坑. 1. Kubernetes 介绍. 1.1 应用部署方式演变. 1.2 kubernete ...

  8. Kubernetes系列之Helm介绍篇

    本次系列使用的所需部署包版本都使用的目前最新的或最新稳定版,安装包地址请到公众号内回复[K8s实战]获取 介绍 Helm 是 Deis 开发的一个用于 Kubernetes 应用的包管理工具,主要用来 ...

  9. Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列目录

    0.目录 整体架构目录:ASP.NET Core分布式项目实战-目录 k8s架构目录:Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列目录 一.感谢 在此感谢.net ...

  10. 【博客496】k8s dns解析与服务发现原理

    k8s dns解析 集群内域名解析原理 Kubernetes 集群节点上 kubelet 有--cluster-dns=${dns-service-ip} 和 --cluster-domain=${d ...

最新文章

  1. 几个步骤,让你的 iOS 代码容易阅读
  2. 遇到问题为何该自己动手
  3. TF之AutoML之AdaNet框架:AdaNet框架的简介、特点、使用方法详细攻略
  4. 简单聊聊AspNetCore的启动流程
  5. 计算机仿真技术-基于matlab的电子信息类课程课后答案,计算机仿真技术:基于MATLAB的电子信息类课程(第4版)...
  6. windows拷贝内容到ubuntu中
  7. tensorflow 初认识
  8. 破坏计算机系统信息罪司法解释,破坏计算机信息系统罪司法解释是怎样的的呢?...
  9. [实验]一个小的局域网
  10. .net core 中使用httpclient下载文件
  11. 运动控制卡培训--运动控制卡疑问解答l
  12. c语言经纬度和大地坐标转换,经纬度与我国54、80大地坐标转换的小工具
  13. Imagination发布开源项目:适配PowerVR IP的Vulkan驱动和编译器合入Mesa 3D 图形库
  14. 【Numpy】1. n维数组,dtype,切片,索引
  15. ubuntu14.04编译ijkplayer备忘
  16. 基于PYNQ的AD采集系统
  17. C语言之关系运算符与逻辑运算符小结
  18. 洞见2022中国企业服务年会 易趋荣获2021中国信创项目管理优秀企业
  19. 北京一日行之十二——植物园、蜜蜂馆、碧云寺、香山
  20. 波澜不惊 波澜不惊波澜不惊

热门文章

  1. 计算机平均工资公式数值型,你知道平均工资怎么算的吗?为什么总是被平均?...
  2. 在 Intel NUC 上安装 Linux
  3. 如何批量制作srt字幕呢?
  4. 马上情人节了,写个爱心跳动代码给我表白吧
  5. 安装Chrome插件时出现的“程序包无效”解决方法
  6. 机器学习--SVM(支持向量机)核函数原理以及高斯核函数
  7. php 接入 paypal 支付
  8. 【PyAutoGUI操作指南】03 键盘控制功能+实现热键组合+ KEYBOARD_KEYS
  9. 常见的货币及其英文缩写简写
  10. 宝贝一到夜间就找妈妈,怎么让宝贝不再黏自己?