k8s kube-dns和服务发现
k8s kube-dns 和服务发现
服务发现
kubernetes 提供了 service 的概念可以通过 VIP 访问 pod 提供的服务,但是在使用的时候还有一个问题:怎么知道某个应用的 VIP?比如我们有两个应用,一个 app,一个 是 db,每个应用使用 rc 进行管理,并通过 service 暴露出端口提供服务。app 需要连接到 db 应用,我们只知道 db 应用的名称,但是并不知道它的 VIP 地址。
最简单的办法是从 kubernetes 提供的 API 查询。但这是一个糟糕的做法,首先每个应用都要在启动的时候编写查询依赖服务的逻辑,这本身就是重复和增加应用的复杂度;其次这也导致应用需要依赖 kubernetes,不能够单独部署和运行(当然如果通过增加配置选项也是可以做到的,但这又是增加负责度)。
开始的时候,kubernetes 采用了 docker 使用过的方法——环境变量。每个 pod 启动时候,会把通过环境变量设置所有服务的 IP 和 port 信息,这样 pod 中的应用可以通过读取环境变量来获取依赖服务的地址信息。这种方式服务和环境变量的匹配关系有一定的规范,使用起来也相对简单,但是有个很大的问题:依赖的服务必须在 pod 启动之前就存在,不然是不会出现在环境变量中的。
更理想的方案是:应用能够直接使用服务的名字,不需要关心它实际的 ip 地址,中间的转换能够自动完成。名字和 ip 之间的转换就是 DNS 系统的功能,因此 kubernetes 也提供了 DNS 方法来解决这个问题。
部署 DNS 服务
DNS 服务不是独立的系统服务,而是一种 addon ,作为插件来安装的,不是 kubernetes 集群必须的(但是非常推荐安装)。可以把它看做运行在集群上的应用,只不过这个应用比较特殊而已。
DNS 有两种配置方式,在 1.3 之前使用 etcd + kube2sky + skydns 的方式,在 1.3 之后可以使用 kubedns + dnsmasq 的方式。
修改 kubelet 启动参数
不管以什么方式启动,对外的效果是一样的。要想使用 DNS 功能,还需要修改 kubelet
的启动配置项,告诉 kubelet,给每个启动的 pod 设置对应的 DNS 信息,一共有两个参数:--cluster_dns=10.10.10.10 --cluster_domain=cluster.local
,分别是 DNS 在集群中的 vip 和域名后缀,要和 DNS rc 中保持一致。
skydns
下面是这种方式的部署配置文件:
apiVersion: v1
kind: ReplicationController
metadata:labels:k8s-app: kube-dnskubernetes.io/cluster-service: "true"name: kube-dnsnamespace: kube-system
spec:replicas: 1selector:k8s-app: kube-dnstemplate:metadata:labels:k8s-app: kube-dnskubernetes.io/cluster-service: "true"spec:containers:- name: etcdcommand:- /usr/local/bin/etcd- "-listen-client-urls"- "http://127.0.0.1:2379,http://127.0.0.1:4001"- "-advertise-client-urls"- "http://127.0.0.1:2379,http://127.0.0.1:4001"- "-initial-cluster-token"- skydns-etcdimage: "gcr.io/google_containers/etcd:2.0.9"resources:limits:cpu: 100mmemory: 50Mi- name: kube2skyargs:- "-domain=cluster.local"- "-kube_master_url=http://10.7.114.81:8080"image: "gcr.io/google_containers/kube2sky:1.11"resources:limits:cpu: 100mmemory: 50Mi- name: skydnsargs:- "-machines=http://localhost:4001"- "-addr=0.0.0.0:53"- "-domain=cluster.local"image: "gcr.io/google_containers/skydns:2015-03-11-001"livenessProbe:exec:command:- /bin/sh- "-c"- "nslookup kubernetes.default.svc.cluster.local localhost >/dev/null"initialDelaySeconds: 30timeoutSeconds: 5ports:- containerPort: 53name: dnsprotocol: UDP- containerPort: 53name: dns-tcpprotocol: TCPresources:limits:cpu: 100mmemory: 50MidnsPolicy: Default
这里有两个需要根据实际情况配置的地方:
kube_master_url
: kube2sky 会用到 kubernetes master API,它会读取里面的 service 信息domain
:域名后缀,默认是cluster.local
,你可以根据实际需要修改成任何合法的值
然后是 Service 的配置文件:
apiVersion: v1
kind: Service
metadata:name: kube-dnsnamespace: kube-systemlabels:k8s-app: kube-dnskubernetes.io/cluster-service: "true"kubernetes.io/name: "KubeDNS"
spec:selector:k8s-app: kube-dnsclusterIP: 10.10.10.10ports:- name: dnsport: 53protocol: UDP- name: dns-tcpport: 53protocol: TCP
这里需要注意的是 clusterIP: 10.10.10.10
这一行手动指定了 DNS service 的 IP 地址,这个地址必须在预留的 vip 网段。手动指定的原因是为了固定这个 ip,这样启动 kubelet 的时候配置 --cluster_dns=10.10.10.10
比较方便,不需要再动态获取 DNS 的 vip 地址。
有了这两个文件,直接创建对象就行:
$ kubectl create -f ./skydns-rc.yml
$ kubectl create -f ./skydns-svc.yml
[root@localhost ~]# kubectl get svc,rc,pod --namespace=kube-system
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/kube-dns 10.10.10.10 <none> 53/UDP 1dNAME DESIRED CURRENT READY AGE
rc/kube-dns 1 1 1 41mNAME READY STATUS RESTARTS AGE
po/kube-dns-twl0q 3/3 Running 0 41m
kubeDNS
在 kubernetes 1.3 版本之后,kubernetes 改变了 DNS 的部署方式,变成了 kubeDNS + dnsmasq
,没有了 etcd
。在这种模式下,kubeDNS 是原来 kube2sky + skyDNS + etcd
,只不过它把数据都保存到自己的内存,而不是 kv store 中;dnsmasq
的引进是为了提高解析的速度,因为它可以配置 DNS 缓存。
这种部署方式的完整配置文件这里就不贴出来了,我放到了 github gist 上面,有兴趣可以查看。创建方法也是一样 kubectl create -f ./skydns-rc.yml
测试 DNS 可用性
不管那种部署很是,kubernetes 对外提供的 DNS 服务是一致的。每个 service 都会有对应的 DNS 记录,kubernetes 保存 DNS 记录的格式如下:
<service_name>.<namespace>.svc.<domain>
每个部分的字段意思:
- service_name: 服务名称,就是定义 service 的时候取的名字
- namespace:service 所在 namespace 的名字
- domain:提供的域名后缀,比如默认的
cluster.local
在 pod 中可以通过 service_name.namespace.svc.domain
来访问任何的服务,也可以使用缩写 service_name.namespace
,如果 pod 和 service 在同一个 namespace,甚至可以直接使用 service_name
。
NOTE:正常的 service 域名会被解析成 service vip,而 headless service 域名会被直接解析成背后的 pods ip。
虽然不会经常用到,但是 pod 也会有对应的 DNS 记录,格式是 pod-ip-address..pod.
,其中 pod-ip-address
为 pod ip 地址的用 -
符号隔开的格式,比如 pod ip 地址是 1.2.3.4
,那么对应的域名就是 1-2-3-4.default.pod.cluster.local
。
我们运行一个 busybox
来验证 DNS 服务能够正常工作:
/ # nslookup whoami
Server: 10.10.10.10
Address 1: 10.10.10.10Name: whoami
Address 1: 10.10.10.175/ # nslookup kubernetes
Server: 10.10.10.10
Address 1: 10.10.10.10Name: kubernetes
Address 1: 10.10.10.1/ # nslookup whoami.default.svc
Server: 10.10.10.10
Address 1: 10.10.10.10Name: whoami.default.svc
Address 1: 10.10.10.175/ # nslookup whoami.default.svc.transwarp.local
Server: 10.10.10.10
Address 1: 10.10.10.10Name: whoami.default.svc.transwarp.local
Address 1: 10.10.10.175
可以看出,如果我们在默认的 namespace default
创建了名为 whoami
的服务,以下所有域名都能被正确解析:
whoami
whoami.default.svc
whoami.default.svc.cluster.local
每个 pod 的 DNS 配置文件如下,可以看到 DNS vip 地址以及搜索的 domain 列表:
/ # cat /etc/resolv.conf
search default.pod.cluster.local default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.10.10.10
options ndots:5
options ndots:5
kubernetes DNS 原理解析
我们前面介绍了两种不同 DNS 部署方式,这部分讲讲它们内部的原理。
kube2sky 模式
这种模式下主要有三个容器在运行:
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
919cbc006da2 172.16.1.41:5000/google_containers/kube2sky:1.12 "/kube2sky /kube2sky " About an hour ago Up About an hour k8s_kube2sky.80a41edc_kube-dns-twl0q_kube-system_ea1f5f4d-15cf-11e7-bece-080027c09e5b_1bd3fdb4
73dd11cac057 172.16.1.41:5000/jenkins/etcd:live "etcd -data-dir=/var/" About an hour ago Up About an hour k8s_etcd.4040370_kube-dns-twl0q_kube-system_ea1f5f4d-15cf-11e7-bece-080027c09e5b_b0e5a99f
0b10ae639989 172.16.1.41:5000/jenkins/skydns:20150703-113305 "bootstrap.sh" About an hour ago Up About an hour k8s_skydns.73baf3b1_kube-dns-twl0q_kube-system_ea1f5f4d-15cf-11e7-bece-080027c09e5b_2860aa6d
这三个容器的作用分别是:
- etcd:保存所有的 DNS 数据
- kube2sky: 通过 kubernetes API 监听 Service 的变化,然后同步到 etcd
- skyDNS:根据 etcd 中的数据,对外提供 DNS 查询服务
kubeDNS 模式
这种模式下,kubeDNS
容器替代了原来的三个容器的功能,它会监听 apiserver 并把所有 service 和 endpoints 的结果在内存中用合适的数据结构保存起来,并对外提供 DNS 查询服务。
- kubeDNS:提供了原来 kube2sky + etcd + skyDNS 的功能,可以单独对外提供 DNS 查询服务
- dnsmasq: 一个轻量级的 DNS 服务软件,可以提供 DNS 缓存功能。kubeDNS 模式下,dnsmasq 在内存中预留一块大小(默认是 1G)的地方,保存当前最常用的 DNS 查询记录,如果缓存中没有要查找的记录,它会到 kubeDNS 中查询,并把结果缓存起来
每种模式都可以运行额外的 exec-healthz
容器对外提供 health check 功能,证明当前 DNS 服务是正常的。
- exec-healthz:运行某个命令,根据结果来对外提供
/healthz
结果
总结
推荐使用 kubeDNS 的模式来部署,因为它有着以下的好处:
- 不需要额外的存储,省去了额外的维护和数据保存的工作
- 更好的性能。通过 dnsmasq 缓存和直接把 DNS 记录保存在内存中,来提高 DNS 解析的速度
参考资料
- Deploy the DNS Add-on
- Kubernetes Admin Docs: Using DNS Pods and Services
- Deploying a Service on a Kubernetes Cluster
- kubernetes 技术分析之DNS
- Kubernetes DNS部署
- Kubernetes DNS Service Deep Dive - Part 1
- Kubernetes DNS Service技术研究
- Kubernetes(K8S)的服务发现和kube-dns插件
http://cizixs.com/2017/04/11/kubernetes-intro-kube-dns
http://jingyan.baidu.com/article/72ee561a6e2460e16138dff7.html
源码分析
http://blog.csdn.net/u010278923/article/details/70173635
k8s kube-dns 和服务发现
k8s kube-dns和服务发现相关推荐
- 理论+实操:K8S搭建dns内部服务与控制器controlls五种模式
文章目录 故障排查 一:控制器的类型 一: pod与控制器之间的关系 二:deployment 2.1 deployment概述 2.1 演示 2.1.1 编写yaml文件 2.1.2 创建pod 2 ...
- k8s部署-20-k8s的服务发现原理,k8s有几种服务发现规则
到现在为止,我们分别掌握了k8s部署.k8s镜像存储之harbor高可用,那么接下来是不是就应该实操了呢?不过不着急,实操之前我们要考虑下,还需要掌握什么呢? 是不是通信呀,这所有的前提都是在可以通信 ...
- k8s 服务发现 kubeDNS
k8s 服务发现 kubeDNS 一.k8s 服务发现 kubeDNS 1.1 kubeDNS 1.2 服务发现类型 1.2.1 基于环境变量的服务发现 1.2.2 基于DNS的服务发现 一.k8s ...
- DNS常用记录类型和服务发现(DNS解析)
DNS DNS(domain name system)主要用来把人类可识别的域名解析成网络层的IP地址.这个过程中负责查询的组件称之为DNS Resolver,它会查询本地cache和远程的DNS s ...
- Prometheus服务发现+Grafana炫酷的界面展示
目录 部署service discovery 相关概念 prometheus 服务发现机制 基于文件服务发现 文件发现的作用 基于DNS自动发现 基于consul发现 相关概念 安装consul_1. ...
- Prometheus 服务发现
文章目录 一.Prometheus 部署 二.部署监控其他节点 1. 主配置文件解析 2. server 节点配置 3. 加入slave节点监控 4. 验证是否加入成功 三.表达式浏览器 1. 表达式 ...
- Prometheus---部署及服务发现
文章目录 一.环境 二.准备工作 三.安装 四.表达式浏览器使用 4.1 cpu 4.2 内存使用率 五.service discover 服务发现 1. Prometheus 服务发现 2. pro ...
- docker (九)promethues的服务发现和grafana
promethues服务发现和grafana布置 一.部署service discovery服务发现 (一)相关概念 1.Prometheus指标抓取的生命周期 2.prometheus 服务发现机制 ...
- kubernetes容器集群管理(8)- pod基本管理和server服务发现
目录 一.pod基本管理 1.资源限制 2.调度约束 3.重启策略 4.健康检查 二.server管理 1.服务创建 2.服务发现 一.pod基本管理 Pod是Kubernetes创建或部署的最小/最 ...
- 服务发现存储仓库 etcd 使用简介
目录 经典应用场景 场景一:服务发现(Service Discovery) 场景二:消息发布与订阅 场景三:负载均衡 场景四:分布式通知与协调 场景五:分布式锁 场景六:分布式队列 场景七:集群监控与 ...
最新文章
- Tafficserver旁路接入方案综述
- Hadoop集群搭建(八:Hive的安装配置)
- Kotlin exception
- python按列输出字符_如何根据条件在Pandas中构建新列(新列应输出字符串)
- Android笔记:Activity
- SCCM PXE客户端无法加载DP(分发点)映像
- 【转】Microsoft Azure存储服务:存储账户****
- JavaScript读写.txt文档 - 方法篇
- WIN10中DOCKER的安装
- 数据分析数据可视化(一)
- 绅士宝智能机器人怎样_如何打败“机器人淘汰三原则”
- java删除目录下符合条件的文件
- Java基础 --存储数据
- spark: 二次排序-1
- MySQL 源码下载教程
- 商住楼和住宅楼的区别
- 织梦联动添加三级分类后无法添加二级分类的解决方案
- 微服务启动成功无法注册到服务注册中心
- MySQL(二)锁 ----- 表锁
- ‘kaggle视频游戏销售数据的可视化和分析‘项目实现
热门文章
- C指针原理(1)-ATT汇编
- 公众号推荐:Python入门、统计学、推荐系统、机器学习、深度学习、数据分析...
- 【学术相关】考研生对导师“嚣张发言”引热议:希望您今年招个女同学,不然我换导师!...
- 【Python】电商用户复购数据实战:图解Pandas的移动函数shift
- 通俗讲解和学习SQL
- 【数据集下载神器】体验1000+优质数据集极速下载
- Python工程能力进阶、数学基础、经典机器学习模型实战、深度学习理论基础和模型调优技巧……胜任机器学习工程师岗位需要学习什么?...
- 【Python基础】Python 10 个习惯用法,看看你都知道不?
- [PLM专题] 十分钟了解文本分类通用训练技巧
- 又一篇论文让我开始怀疑起了人生...