Kubernetes DNS 简介
环境
$ 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的DNS搜索列表中会包含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有了hostname
和subdomain
字段,用于指定Pod的hostname和subdomain。它的优先级则高于上面提到的pod.beta.kubernetes.io/hostname
和pod.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/hostname
,pod.beta.kubernetes.io/subdomain
, endpoints.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 7m
确认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'
检查DNS 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 1h
...
如果没有相关的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 1h
...
该服务会默认地被创建,或者如果你手动创建了该服务,但是该服务却并没有在上述命令中出现,请查看 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
Kubernetes DNS 简介的更多相关文章
- Kubernetes DNS安装配置
#镜像在谷歌上需要FQ###################################下载kubernetes#DNS#cd kubernetes/cluster/addons/dns#修改tr ...
- 附004.Kubernetes Dashboard简介及使用
一 Kubernetes dashboard简介 1.1 Web UI简介 dashboard是基于Web的Kubernetes用户界面.可以使用dashboard将容器化应用程序部署到Kuberne ...
- Kubernetes项目简介
Kubernetes项目简介 Kubernetes 是 Google 团队发起的开源项目,它的目标是管理跨多个主机的容器,提供基本的部署,维护以及运用伸缩,主要实现语言为 Go 语言.Kubernet ...
- Kubernetes DNS 高阶指南(转发别人 解析很详细)
转发地址:http://www.jintiankansha.me/t/Js1R84GGAl DNS 是 Kubernetes 的核心功能之一,Kubernetes 通过 kube-dns 或 Cor ...
- Docker Kubernetes(K8s)简介
入职了新公司,使用了Docker和K8s,需要有一个基础的了解,对网络上相关信息进行了简单总结. 一Docker 1简介: Docker 将应用程序与该程序的依赖,打包在一个文件里面.运行这个文件,就 ...
- Kubernetes DNS服务配置案例
首先创建DNS服务的RC配置文件skydns-rc.yaml apiVersion: v1 kind: ReplicationController metadata: name: kube-dns-v ...
- [转] Kubernetes K8S 简介
[From] https://blog.csdn.net/zhangxxxww/article/details/73547251 Kubernetes(k8s)是自动化容器操作的开源平台,这些操作包括 ...
- Kubernetes DNS的配置
Kubernetes集群机制通过DNS进行服务名和ip的映射,如果没有配置dns,你可以通过下面命令查询到集群ip kubectl get svc --namespace=kube-system 得到 ...
- dns简介
dns(domain name system),它是提供域名到ip的解析功能的系统.它和普通的系统一样,也是运行在服务器之上的. 1.dns指定的ip是用来干嘛的? 这个ip指向dns系统所在的机器. ...
随机推荐
- HttpWebRequest 模拟网站登录获取数据
此文档仅仅是一个BaseCode,已做后续查阅 项目使用IBM Platform Symphony分布式平台,所有业务处理都在这个分布式平台上计算,需求是获取这些计算机机群的运行状态,和每一个服务的的 ...
- 数据库:oracle,MySQL,SqlServer 安装资源分享
1. oracle 11g: 链接:http://pan.baidu.com/s/1bppaqR1 密码:http 2. mysql 链接:http://pan.baidu.com/s/1jH8O ...
- gulp快速入门&初体验
前言 一句话先 gulp 是一个可以简单和自动化"管理"前端文件的构建工具 先说我以前的主要工作,我主要是做游戏服务端的,用c++/python,所以我对东西的概念理解难免要套到自 ...
- v3学院带你一次性认清UART、RS-232、RS-422、RS-485的区别
通讯问题,和交通问题一样,也有高速.低速.拥堵.中断等等各种情况.如果把串口通讯比做交通,UART比作车站,那么一帧的数据就好比汽车.汽车跑在路上,要遵守交通规则.如果是市内,一般限速30.40,而高 ...
- 3450: Tyvj1952 Easy
3450: Tyvj1952 Easy Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 269 Solved: 198[Submit][Status] ...
- OpenStack/devstack with Neutron on Ubuntu 14 (2)
在前面的文章中,已经完成了devstack的安装.下面,我会介绍如何使用neutron 首先创建两个neutron net, vmnet1 和vmnet2 stack@ubuntu:~/devstac ...
- 详解JDBC连接数据库
一.概念 1. 为了能让程序操作数据库,对数据库中的表进行操作,每一种数据库都会提供一套连接和操作该数据库的驱动,而且每种数据库的驱动都各不相同,例如mysql数据库使用mysql驱动,oracle数 ...
- 添加swagger api文档到node服务
swagger,一款api测试工具,详细介绍参考官网:http://swagger.io/ ,这里主要记录下怎么将swagger api应用到我们的node服务中: 1.任意新建node api项目, ...
- 深入解读Python的unittest并拓展HTMLTestRunner
unnitest是Python的一个重要的单元测试框架,对于用Python进行开发的同事们可能不需要对他有过深入的了解会用就行,但是,对于自动化测试人员我觉得是要熟知unnitest的执行原理以及相关 ...
- AutoIt 脚本小试——刷网易云音乐歌单
AutoIt 确实是个很强大的脚本工具. 如果早知道有这个,当初是怎么都不会去学易语言的 (๑•̀ω•́๑) 这是个简单脚本 = ๛ก(ー̀ωー́ก) 用来增加歌单播放次数和个人的听歌量. 原理不过 ...