使用containerdns的理由

先说下我们为什么要使用containerdns,事实上该项目开源时间并不长,而且没有完善的社区,也没有丰富的文档。说白了,我们选中它,是因为它刚好切合我们的需求。

目前市面上支持kubernetes的开源dns并不多,除了containerdns,就只有skydns和官方的kubedns。

我们先说下官方的kubedns:

kubedns是kubernetes官方的,而且是官方出品,我们毫不怀疑,它一定是对kubernetes支持最好的,官方还提供了各种自动扩展的特性。但是有两点满足不了我的需求:

  1. 需要部署到kubernetes集群中,这在大多数应用场景下其实是优点。但我们有多套不同的kubernretes集群,这些集群中总不能各自都部署一套containerdns,然后再在外部部署一套bind来帮忙这些containerdns做转发吧?我们多套集群需要依赖一个公共的dns来做所有域名的解析。当然事实上,我们也可以把kubedns独立部署,但是k8s提供的和动扩展等功能就无法使用了。而且kubedns只能解析一个一级域名,比如cluster.local。如果我两套kubernetes集群,集群1使用cluster.local,集群2使用cluster2.local。这个时候,单套kubedns将变的无能为力。
  2. 在早期kubernetes默认采用skydns的时候,是将解析存储到etcd中。后来kubernetes使用kubedns将解析存储到内存中。虽然提升了解析效率,但是把所有解析一股脑放到内存中的做法并没有在大型应用中得到验证,如果有大量的解析情况下,内存的占用是个不得不考虑的问题。

然后说下skydns:

其实在上面说kubedns的时候,基本也都提到了skydns的缺点:

  1. 将数据直接存储到etcd中,每一次解析都是对etcd的访问,效率不高
  2. skydns也面临跟kubedns同样的问题,单套skydns只能解析一个一级域名,当我需要它同时解析cluster.local和cluster2.local的时候,它就会变的无能为力。

最后再回头说containerdns:

containerdns支持多个域名解析,最终的解析也会写入etcd中,同时会利用缓存来缓存一部分解析以提升解析效率。基本上解决了上面说到的kubedns和skydns的问题。

这就是我们最终选用containerdns的原因。

同时这里需要感谢下京东containerdns的开发团队,尤其是陈书刚大大,帮我解答了很多疑惑,也帮忙解决了很多相关的问题!

部署

项目地址:https://github.com/tigcode/containerdns

具体的项目介绍及containerdns相关原理,请直接参考项目文档,也可以直接参考这篇文档:

http://www.sohu.com/a/150240329_683048

我这里不再做详细说明。只是说下我们在使用过程中遇到的一些坑。

先简单的说下配置:

我们这里就用到了项目中的两个组件,分别是containerdns和containerdns-kubeapi。

安装方法也直接参考官网即可。

需要说明的是etcd的api需要使用v3版本

我这里采用将获取到的二进制打进镜像中,使用docker部署的方式,下面直接给出docker-compose配置:

version: "2"
services:
etcd:
image: dk-reg.op.douyuyuba.com/library/etcd-amd64:3.1.10
restart: always
network_mode: host
volumes:
- "/home/www/server/etcd:/data/etcd"
- "/etc/localtime:/etc/localtime"
environment:
ETCDCTL_API: "3"
command: etcd -name etcd1 -data-dir /data/etcd
containerdns:
image: dk-reg.op.douyuyuba.com/kubernetes/containerdns
restart: always
network_mode: host
volumes:
- "/etc/containerdns:/etc/containerdns"
environment:
ETCDCTL_API: "3"
containerdns-kubeapi:
image: dk-reg.op.douyuyuba.com/kubernetes/containerdns-kubeapi
restart: always
network_mode: host
volumes:
- "/etc/containerdns:/etc/containerdns"
environment:
ETCDCTL_API: "3"

如果不使用docker部署的话,启动方式如下:

nohup containerdns -config-file /etc/containerdns/containerdns.conf &> /tmp/containerdns.log &

nohup containerdns-kubeapi -config-file /etc/containerdns/containerdns-api.conf &> /tmp/containerdns-kubeapi.log &

配置

containerdns.conf示例:

[Dns]
dns-domains = wh01
dns-addr = 0.0.0.0:
ex-nameservers = "114.114.114.114:53"
inDomainServers = test.com@xx.xx.xx.xx:
inDomainServers =""
cacheSize =
ip-monitor-path = /containerdns/monitor/status/ [Log]
log-dir = /var/log/containerdns
log-level =
log-to-stdio = true [Etcd]
etcd-servers = http://127.0.0.1:2379
etcd-certfile = ""
etcd-keyfile = ""
etcd-cafile = "" [Fun]
random-one = false
hone-one = false [Stats]
statsServer = 127.0.0.1:
statsServerAuthToken =

简要的说下:

  • ex-nameservers:对于公网的地址解析,转发到公网的dns上
  • inDomainServers:对于内网其他域名的解析(即不由containerdns解析的域名)转发到指定的内网dns上,可以指定多个,用%分隔,这里给个官方的示例:inDomainServers = hades.local@10.8.65.104:53%tmp.containerdns.local@192.168.169.41:53
  • [Stats]是一个暴露的状态接口,后面会详细说明

containerdns-api.conf示例:

[General]
host = xx.xx.xx.xx
etcd-server = http://127.0.0.1:2379
etcd-certfile = ""
etcd-keyfile = ""
etcd-cafile = "" ip-monitor-path = /containerdns/monitor/status [Kube2DNS]
kube-domain = wh01.
kube-enable = YES
kube-config-file = /etc/containerdns/bootstrap.kubeconfig
#svc-ip-source = clusterIP
#kube-enable=NO [DNSApi]
api-enable = YES
api-domains = wh01.
api-address = 0.0.0.0:
containerdns-auth = abcdef123456789

简要的说下:

  • host:用于标识当前进程运行在哪个服务器上,当有多个不同的服务器上同时启动该进程抓取数据到etcd时,用于区分数据来自哪个服务器。
  • kube-config-file:这里指定的是我们连接kubernetes集群时,用的kubeconfig,需要通过该文件授权以后才能访问到kube-apiserver接口
  • svc-ip-source:这个需要详细说下,我们在k8s上执行kubectl get svc时,可以看到如下输出:
    kubectl get svc
    NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    infovod-stress None <none> /TCP 64d
    kubernetes 10.254.0.1 <none> /TCP 176d

可以看到,一个service对应的有两个IP,分别是CLUSTER-IP和EXTERNAL-IP,这两个ip具体的区别,请自行google,不属于containerdns的范畴。这里要说的是,默认containerdns-kube-api拿到的是EXTERNAL-IP的值,当然如果是使用headless service这种方式的话,解析会拿到实际pod的ip。但拿不到CLUSTER-IP的值,这样一来,默认情况下,创建kubernetes时,自动创建的kubernetes.default.svc的解析就拿不到了。如果你的应用依赖于CLUSTER-IP的话,则需要开启svc-ip-source选项,并将其值设置为clusterIP。

相关问题

1.手动写入解析的问题
上面我们说到svc-ip-source的问题,其实在之前,并不支持该项配置,这个时候像kubernetes.default.svc的解析,就只能通过手动写入。遗憾的是,containerdns手动的命令行配置已经废弃,我们这里又没有办法去直接调接口修改配置。所以采取了一种很粗暴的方式,直接按照其etcd中解析的存储格式,手动往etcd中插入一条数据,如下:

etcdctl put /containerdns/bj02/svc/default/kubernetes/ip/ '{"type":"A","source":"user","host":"10.254.0.1","ttl":30,"priority":10,"weight":10}'

需要说明的是,如果是由containerdns-kubeapi抓取的数据,source标识为svc,手动写入的数据,source需要标识为user,否则的话,会被定时冲掉。

2.监控的问题

关于containerdns中qps的监控,containerdns.conf配置文件提供了[Stats]的配置,默认监听到本地的9600端口,调用方式如下:

curl -H "Content-Type:application/json;charset=UTF-8" -X GET  http://127.0.0.1:9600/containerdns/stats/payapi-pre.php.svc.wh01.?token=123456789

{"reqCount":,"lastQueryTime":"2017-12-13T10:20:42.727212277+08:00","firstQueryTime":"2017-12-13T10:20:39.42317166+08:00"}

需要说明的是,如果指定的域名从没被请求解析过,会抛出domain not found的异常。

containerdns配置说明的更多相关文章

  1. kubernetes 1.9部署实践

    目录 简要说明 环境说明 安装前的约定 配置etcd 生成相关证书 证书类型说明 cfssl配置 证书相关配置 生成ca证书 生成kubernetes证书 生成kubectl证书 生成kube-pro ...

  2. NHibernate之映射文件配置说明

    NHibernate之映射文件配置说明 1. hibernate-mapping 这个元素包括以下可选的属性.schema属性,指明了这个映射所引用的表所在的schema名称.假若指定了这个属性, 表 ...

  3. WCF服务器证书配置说明-没有能够进行密钥交换的私钥,或者进程可能没有访问私钥的权限

    WCF服务器证书配置说明 1.创建证书: makecert.exe -sr LocalMachine -ss My -a sha1 -n CN=XXX -sky exchange -pe 说明: -s ...

  4. log4net一些配置说明

    <configuration> <configSections> <section name="log4net" type="System. ...

  5. maven -- 学习笔记(二)之setting.xml配置说明(备忘)

    setting.xml配置说明,learn from:http://pengqb.javaeye.com,http://blog.csdn.net/mypop/article/details/6146 ...

  6. Atitit.mybatis的测试  以及spring与mybatis在本项目中的集成配置说明

    Atitit.mybatis的测试  以及spring与mybatis在本项目中的集成配置说明 1.1. Mybatis invoke1 1.2. Spring的数据源配置2 1.3. Mybatis ...

  7. syslog-ng 学习心得与配置说明

    配置说明syslog-ng的主配置文件存放在:/etc/syslog-ng/syslog-ng.conf 一.基础 系统自带版本: 引用 # rpm -qa|grep syslog-ng syslog ...

  8. keepalived工作原理和配置说明 腾讯云VPC内通过keepalived搭建高可用主备集群

    keepalived工作原理和配置说明 腾讯云VPC内通过keepalived搭建高可用主备集群 内网路由都用mac地址 一个mac地址绑定多个ip一个网卡只能一个mac地址,而且mac地址无法改,但 ...

  9. [Asp.net]Uploadify所有配置说明,常见bug问题分析

    引言 之前写过一篇使用swfupload上传图片的文章:周末大放送网站图片上传,水印,预览,截图,这里分析一下,当时使用uploadify上传,无法获取上传后,图片路径的问题.当时没有测试没有成功,一 ...

随机推荐

  1. Python写一个根据日期计算是星期几的模块

    import datetimedef get_week_day(date): week_day = { 0: '星期一', 1: '星期二', 2: '星期三', 3: '星期四', 4: '星期五' ...

  2. 【CS231N】3、Softmax分类器

    wiki百科:softmax函数的本质就是将一个K维的任意实数向量压缩(映射)成另一个K维的实数向量,其中向量中的每个元素取值都介于(0,1)之间. 一.疑问 二.知识点 1. softmax函数公式 ...

  3. Internet History, Technology and Security (Week3)

    Week3. Welcome to week 3! This is our fourth and final week of History where we make the connection ...

  4. 使用Fabric自动化你的任务

    Fabric是一个Python库,可以通过SSH在多个host上批量执行任务.你可以编写任务脚本,然后通过Fabric在本地就可以使用SSH在大量远程服务器上自动运行.这些功能非常适合应用的自动化部署 ...

  5. iOS- Exception Type: 00000020:什么是看门狗机制

      1.前言    前几天我们项目闪退之后遇到的一个Crash,之后逛了许多论坛,博客都没有找到满意的回复  在自己做了深入的研究之后,对iOS的看门狗机制有了一个基本的了解  而有很多奇怪的Cras ...

  6. 深入理解JAVA集合系列三:HashMap的死循环解读

    由于在公司项目中偶尔会遇到HashMap死循环造成CPU100%,重启后问题消失,隔一段时间又会反复出现.今天在这里来仔细剖析下多线程情况下HashMap所带来的问题: 1.多线程put操作后,get ...

  7. jquery 取消全选和全选功能 不全选

    代码如下 function ckSelectAll() { if ($('#ckSelectAll').is(':checked') == true) { $("INPUT[name='ch ...

  8. 微信小程序组件 模块化错和叹号

    wxml 页面 <import src="/pages/lianxi/lianxi.wxml" />  //引入文件 <view style='position: ...

  9. js 添加事件兼容性

    var tools = { //添加事件 addHandle: function (e, type, handle) { if (e.addEventListener) { e.addEventLis ...

  10. HDU4622_Reincarnation

    题目给出一个长为2000的字符串,和10000询问,每次询问从第l到第r个字符中间有多少个不同的子串. 其实,全部预处理.f[i][j]表示从i到j个字符的子串数.重构2000遍SAM. 对于新加入的 ...