阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Kubernetes DNS 简介

459次阅读
没有评论

共计 8024 个字符,预计需要花费 21 分钟才能阅读完成。

环境

$ sudo lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.2 LTS
Release:    16.04
Codename:   xenial

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.4", GitCommit:"7243c69eb523aa4377bce883e7c0dd76b84709a1", GitTreeState:"clean", BuildDate:"2017-03-07T23:53:09Z", GoVersion:"go1.7.4", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.4", GitCommit:"7243c69eb523aa4377bce883e7c0dd76b84709a1", GitTreeState:"clean", BuildDate:"2017-03-07T23:34:32Z", GoVersion:"go1.7.4", Compiler:"gc", Platform:"linux/amd64"}

介绍

从 Kubernetes 1.3 开始,DNS 通过使用插件管理系统cluster add-on,成为了一个内建的自启动服务。
Kubernetes DNS 在 Kubernetes 集群上调度了一个 DNS Pod 和 Service,并配置 kubelet,使其告诉每个容器使用 DNS Service 的 Ip 来解析 DNS 名称。

什么是 DNS 名称

集群中定义的每个 Service(包括 DNS Service 它自己)都被分配了一个 DNS 名称。默认的,Pod 的 NDS 搜索列表中会包含 Pod 自己的命名空间和集群的默认域,下面我们用示例来解释以下。
假设有一个名为 foo 的 Service,位于命名空间 bar 中。运行在 bar 命名空间中的 Pod 可以通过 DNS 查找 foo 关键字来查找到这个服务,而运行在命名空间 quux 中的 Pod 可以通过关键字 foo.bar 来查找到这个服务。

支持的 DNS 模式

下面的章节详细的描述了支持的记录(record)类型和 layout。

Services

普通(非 headless)的 Service 都被分配了一个 DNS 记录,该记录的名称格式为my-svc.my-namespace.svc.cluster.local,通过该记录可以解析出服务的集群 IP。
Headless(没有集群 IP)的 Service 也被分配了一个 DNS 记录,名称格式为my-svc.my-namespace.svc.cluster.local。与普通 Service 不同的是,它会解析出 Service 选择的 Pod 的 IP 列表。

SRV records

SRV records 用于为命名端口服务,这些端口是 headless 或者普通 Service 的一部分。对于每个命名端口,SRV record 的格式为:_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster.local。对于普通服务来说,这会解析出端口号和 CNAMEmy-svc.my-namespace.svc.cluster.local。对于 headless 服务来说,这会解析出多个结果,一个是 service 后端的每个 pod,一个是包含端口号,和格式为 auto-generated-name.my-svc.my-namespace.svc.cluster.local 的 pod 的 CNAME。

向后兼容性

kube-dns 的之前版本,使用了格式为my-svc.my-namespace.cluster.local(svc 这一层是后面加上的)的名称。但这种格式不再被支持了。

Pods

pod 会被分配一个 DNS 记录,名称格式为 pod-ip-address.my-namespace.pod.cluster.local
比如,一个 pod,它的 IP 地址为1.2.3.4,命名空间为default,DNS 名称为 cluster.local,那么它的记录就是:1-2-3-4.default.pod.cluster.local
当 pod 被创建时,它的 hostname 设置在 Pod 的metadata.name 中(写 yaml 的时候应该很清楚这点)。
在 v1.2 版本中,用户可以指定一个 Pod 注解,pod.beta.kubernetes.io/hostname,用于指定 Pod 的 hostname。这个 Pod 注解,一旦被指定,就将优先于 Pod 的名称,成为 pod 的 hostname。比如,一个 Pod,其注解为 pod.beta.kubernetes.io/hostname: my-pod-name,那么该 Pod 的 hostname 会被设置为 my-pod-name。
v1.2 中还引入了一个 beta 特性,用户指定 Pod 注解,pod.beta.kubernetes.io/subdomain,来指定 Pod 的 subdomain。比如,一个 Pod,其 hostname 注解设置为“foo”,subdomain 注解为“bar”,命名空间为“my-namespace”,那么它最终的 FQDN 就是“foo.bar.my-namespace.svc.cluster.local”
在 v1.3 版本中,PodSpec 有了hostnamesubdomain字段,用于指定 Pod 的 hostname 和 subdomain。它的优先级则高于上面提到的 pod.beta.kubernetes.io/hostnamepod.beta.kubernetes.io/subdomain
示例:

apiVersion: v1
kind: Service
metadata:
  name: default-subdomain
spec:
  selector:
    name: busybox
  clusterIP: None
  ports:
    - name: foo # Actually, no port is needed.
      port: 1234 
      targetPort: 1234
---
apiVersion: v1
kind: Pod
metadata:
  name: busybox1
  labels:
    name: busybox
spec:
  hostname: busybox-1
  subdomain: default-subdomain
  containers:
  - image: busybox
    command:
      - sleep
      - "3600"
    name: busybox
---
apiVersion: v1
kind: Pod
metadata:
  name: busybox2
  labels:
    name: busybox
spec:
  hostname: busybox-2
  subdomain: default-subdomain
  containers:
  - image: busybox
    command:
      - sleep
      - "3600"
    name: busybox

如果一个 headless service 中,多个 pod 都在同一个命名空间里,并且 subdomain 名称也相同,集群的 KubeDNS 还是会为每个 Pod 返回完整而合格的 hostname。给定一个 Pod,其 hostname 设置为 busybox-1,subdomain 设置为default-subdomain,同一个命名空间中的 headless Service 名为default-subdomain,那么 pod 自己的 FQDN 就是“busybox-1.default-subdomain.my-namespace.svc.cluster.local”
在 Kubernetes v1.2 里,Endpoint 对象还使用了注解endpoints.beta.kubernetes.io/hostnames-map。它的值就是 json 格式中的map[string(IP)][endpoints.HostRecord],比如‘{“10.245.1.6”:{HostName:“my-webserver”}}’。如果 Endpoint 是用于 headless service 的,就会为其创建一个格式为 …svc 的记录。以 json 格式为例,如果 Endpoint 用于名为“bar”的 headless service,其中一个 Endpoint 的 ip 为“10.245.1.6”,就会创建一个名为“my-webserver.bar.my-namespace.svc.cluster.local” 的记录,查询该记录就会得到“10.245.1.6”。这个 Endpoint 注解一般不需要终端用户来指定,但可以被内部服务控制器使用,来实现上面的特性。
在 v1.3 中,Endpoint 对象可以为任何一个 Endpoint 指定 hostname 和 IP。hostname 字段会覆盖 endpoints.beta.kubernetes.io/hostnames-map 注解的值。
在 v1.3 中,以下注解被弃用了:pod.beta.kubernetes.io/hostnamepod.beta.kubernetes.io/subdomainendpoints.beta.kubernetes.io/hostnames-map

如何测试 DNS 是否工作

创建一个简单地 Pod,使用测试环境

创建一个名为 busybox.yaml 文件,使用下面的内容:

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - image: busybox
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always

使用该文件创建 pod:

kubectl create -f busybox.yaml

等待 pod 进入 running 状态

获取 pod 状态:

$ kubectl get pods busybox

你会看到:

NAME      READY     STATUS    RESTARTS   AGE
busybox   1/1       Running   0          m

确认 DNS 是否工作

一旦 pod 处于 running 状态时,可以使用 exec nslookup 来查询状态:

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

你应该看到类似的结果:

Server:    10.0.0.10
Address 1: 10.0.0.10

Name:      kubernetes.default
Address 1: 10.0.0.1

如果出现上述结果,则说明 DNS 正常工作。

故障排查

如果 nslookup 失败,检查以下选项:

检查本地 DNS 配置

检查 pod 的 resolv.conf 文件。

$ kubectl exec busybox cat /etc/resolv.conf

确认搜索路径和 name sever 被设置成类似下面的样子(注意搜索路径可能因云提供商不同而有所差异):

search default.svc.cluster.local svc.cluster.local cluster.local google.internal c.gce_project_id.internal
nameserver 10.0.0.10
options ndots:5

快速诊断

如下的错误表明 kube-dns add-on 或者相关服务有问题:

$ kubectl exec -ti busybox -- nslookup kubernetes.default
Server:    10.0.0.10
Address 1: 10.0.0.10

nslookup: can't resolve'kubernetes.default'

或者

$ kubectl exec -ti busybox -- nslookup kubernetes.default
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

nslookup: can't resolve'kubernetes.default'

检查 NDS pod 是否运行

使用 kubectl get pods 命令来确认 DNS pod 是否正在运行。

$ kubectl get pods --namespace=kube-system -l k8s-app=kube-dns

应该会有如下的结果:

NAME                                                       READY     STATUS    RESTARTS   AGE
...
kube-dns-v19-ezo1y                                         3/3       Running   0           h
...

如果没有相关的 pod 运行,或者 pod 状态为 failed/completed,那么就说明你的环境下,没有默认部署 DNS add-on,你需要手动部署它。

检查 DNS pod 中的错误

使用 kubectl log 命令来查看 DNS 守护程序的日志。

$ kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c kubedns
$ kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c dnsmasq
$ kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c healthz

如果有任何可疑的日志,每一行开头的 W,E,F 字母分别表示警告、错误和故障。请搜索这些错误日志的条目,或者通过 kubernetes issues 页面来报错非预期的错误。

DNS 服务是否启动

使用 kubectl get service 命令来查看 DNS 服务是否已经启动。

$ kubectl get svc --namespace=kube-system

你会看到:

NAME                    CLUSTER-IP     EXTERNAL-IP   PORT(S)             AGE
...
kube-dns                10.0.0.10      <none>        53/UDP,53/TCP        h
...

该服务会默认地被创建,或者如果你手动创建了该服务,但是该服务却并没有在上述命令中出现,请查看 debugging services page 页面获取更多信息。

是否暴露了 DNS Endpoint?

可通过 kubectl get endpoints 命令来确认是否暴露了 DNS Endpoint。

$ kubectl get ep kube-dns --namespace=kube-system

你应该会看到下面的结果:

NAME       ENDPOINTS                       AGE
kube-dns   10.180.3.17:53,10.180.3.17:53    1h

如果没有看到 Endpoint,那么请查看 debugging services page 页面。
若要查看更多的 Kubernetes DNS 示例,请在 Kubernetes Github 仓库中查看 cluster-dns examples。

如何工作

运行的 Kubernetes DNS pod 包含 3 个容器——kubedns、dnsmasq 和一个叫做 healthz 的健康检查容器。kubedns 进程监视 Kubernetes master 上 Service 和 Endpoint 的改变,并在内存中维护 lookup 结构用于服务 DNS 请求。dnsmasq 容器增加 DNS 缓存,从而提升性能。healthz 容器提供一个单点的健康检查 Endpoint,检查 dnsmasq 和 kubedns 的健康程度。
DNS pod 以服务的形式暴露出来,它拥有一个静态 IP。一旦被创建,kubelet 就使用 --cluster-dns=10.0.0.10 标识,将 DNS 配置信息传递给每个容器。
DNS 名称也需要域。本地域是可以配置的,在 kubelet 中,使用 --cluster-domain=<default local domain> 参数。
Kubernetes 集群的 DNS 服务(基于 SkyDNS 库)支持 forward lookup(A recoreds),service lookup(SRV records)和反向 IP 地址查找(PTR recoreds)。

从 node 继承 DNS

当运行 pod 时,kubelet 会预先考虑集群的 DNS 服务,并在 node 本地的 DNS 设置中搜索路径。如果 node 能够解析 DNS 名称,那么 pod 也可以做到。
如果你希望在 pod 中使用不同的 DNS,那么你可以使用 kubelet 的 --resolv-conf 参数。该设置意味着 pod 不会从 node 继承 DNS。设置该值为其他的文件路径,意味着会使用该文件来配置 DNS,而不是/etc/resolv.conf

已知的问题

Kubernetes 安装默认并不会使用集群的 DNS 配置来设置 Kubernetes node 的 resolv.conf 文件,因为该进程依赖于发行版的配置。
Linux 的 libc 有着 3 个 DNS nameserver和 6 个 DNS 搜索记录的限制,Kubernetes 需要消耗一个 nameserver 和 3 个搜索记录。这意味着如果一个本地配置已经使用了 3 个 nameserver 或者使用了 3 个以上的搜索记录,那么这些配置可能会丢失。有一个临时方案,node 可以运行 dnsmasq,它可以提供更多的 nameserver 选项,但不能提供更多的搜索选项。你也可以使用 kubelet 的--resolv-conf 选项。
如果你使用的是 Alpine 3.3 或更早的版本,DNS 可能不能正常的工作,这是已知的问题。可以查看这里获取更多信息。

References

Docs for the DNS cluster addon

Docker 中部署 Kubernetes http://www.linuxidc.com/Linux/2016-07/133020.htm

Kubernetes 集群部署  http://www.linuxidc.com/Linux/2015-12/125770.htm

OpenStack, Kubernetes, Mesos 谁主沉浮  http://www.linuxidc.com/Linux/2015-09/122696.htm

Kubernetes 集群搭建过程中遇到的问题及解决  http://www.linuxidc.com/Linux/2015-12/125735.htm

Kubernetes 集群部署  http://www.linuxidc.com/Linux/2015-12/125770.htm

Ubuntu 16.04 下安装搭建 Kubernetes 集群环境  http://www.linuxidc.com/Linux/2017-02/140555.htm

Ubuntu 上手动安装部署 Kubernetes 详细指南  http://www.linuxidc.com/Linux/2017-04/142514.htm

Kubernetes 的详细介绍:请点这里
Kubernetes 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-04/142647.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计8024字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
7980031
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
星哥带你玩飞牛NAS硬件03:五盘位+N5105+双网口的成品NAS值得入手吗

星哥带你玩飞牛NAS硬件03:五盘位+N5105+双网口的成品NAS值得入手吗

星哥带你玩飞牛 NAS 硬件 03:五盘位 +N5105+ 双网口的成品 NAS 值得入手吗 前言 大家好,我...
星哥带你玩飞牛NAS-16:飞牛云NAS换桌面,fndesk图标管理神器上线!

星哥带你玩飞牛NAS-16:飞牛云NAS换桌面,fndesk图标管理神器上线!

  星哥带你玩飞牛 NAS-16:飞牛云 NAS 换桌面,fndesk 图标管理神器上线! 引言 哈...
每天一个好玩的网站-手机博物馆-CHAZ 3D Experience

每天一个好玩的网站-手机博物馆-CHAZ 3D Experience

每天一个好玩的网站 - 手机博物馆 -CHAZ 3D Experience 一句话介绍:一个用 3D 方式重温...
从“纸堆”到“电子化”文档:用这个开源系统打造你的智能文档管理系统

从“纸堆”到“电子化”文档:用这个开源系统打造你的智能文档管理系统

从“纸堆”到“电子化”文档:用这个开源系统打造你的智能文档管理系统 大家好,我是星哥。公司的项目文档存了一堆 ...
安装Black群晖DSM7.2系统安装教程(在Vmware虚拟机中、实体机均可)!

安装Black群晖DSM7.2系统安装教程(在Vmware虚拟机中、实体机均可)!

安装 Black 群晖 DSM7.2 系统安装教程(在 Vmware 虚拟机中、实体机均可)! 前言 大家好,...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
4盘位、4K输出、J3455、遥控,NAS硬件入门性价比之王

4盘位、4K输出、J3455、遥控,NAS硬件入门性价比之王

  4 盘位、4K 输出、J3455、遥控,NAS 硬件入门性价比之王 开篇 在 NAS 市场中,威...
你的云服务器到底有多强?宝塔跑分告诉你

你的云服务器到底有多强?宝塔跑分告诉你

你的云服务器到底有多强?宝塔跑分告诉你 为什么要用宝塔跑分? 宝塔跑分其实就是对 CPU、内存、磁盘、IO 做...
星哥带你玩飞牛 NAS-10:备份微信聊天记录、数据到你的NAS中!

星哥带你玩飞牛 NAS-10:备份微信聊天记录、数据到你的NAS中!

星哥带你玩飞牛 NAS-10:备份微信聊天记录、数据到你的 NAS 中! 大家对「数据安全感」的需求越来越高 ...
每天一个好玩的网站-手机博物馆-CHAZ 3D Experience

每天一个好玩的网站-手机博物馆-CHAZ 3D Experience

每天一个好玩的网站 - 手机博物馆 -CHAZ 3D Experience 一句话介绍:一个用 3D 方式重温...
星哥带你玩飞牛NAS硬件02:某鱼6张左右就可拿下5盘位的飞牛圣体NAS

星哥带你玩飞牛NAS硬件02:某鱼6张左右就可拿下5盘位的飞牛圣体NAS

星哥带你玩飞牛 NAS 硬件 02:某鱼 6 张左右就可拿下 5 盘位的飞牛圣体 NAS 前言 大家好,我是星...