
正文
k8s插件go语言 k8s clientgo 编程
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
coredns源码分析
CoreDNS是使用go语言编写的快速灵活的DNS服务,采用链式插件模式,每个插件实现独立的功能,底层协议可以是tcp/udp,也可以是TLS,gRPC等。默认监听所有ip地址,可使用bind插件指定监听指定地址。
格式如下
SCHEME是可选的,默认值为dns://,也可以指定为tls://,grpc://或者https://。
ZONE是可选的,指定了此dnsserver可以服务的域名前缀,如果不指定,则默认为root,表示可以接收所有的dns请求。
PORT是选项的,指定了监听端口号,默认为53,如果这里指定了端口号,则不能通过参数-dns.port覆盖。
一块上面格式的配置表示一个dnsserver,称为serverblock,可以配置多个serverblock表示多个dnsserver。
下面通过一个例子说明,如下配置文件指定了4个serverblock,即4个dnsserver,第一个监听端口5300,后面三个监听同一个端口53,每个dnsserver指定了特定的插件。
下图为配置的简略图
a. 从图中可看到插件执行顺序不是配置文件中的顺序,这是因为插件执行顺序是在源码目录中的plugin.cfg指定的,一旦编译后,顺序就固定了。
b. .根serverblock虽然指定了health,但是图中却没有,这是因为health插件不参与dns请求的处理。能处理dns请求的插件必须提供如下两个接口函数。
dns请求处理流程
收到dns请求后,首先根据域名匹配zone找到对应的dnsserver(最长匹配优先),如果没有匹配到,则使用默认的root dnsserver。
找到dnsserver后,就要按照插件顺序执行其中配置的插件,当然并不是配置的插件都会被执行,如果某个插件成功找到记录,则返回成功,否则根据插件是否配置了fallthrough等来决定是否执行下一个插件。
plugin.cfg
源码目录下的plugin.cfg指定了插件执行顺序,如果想添加插件,可按格式添加到指定位置。
源码目录下的Makefile根据plugin.cfg生成了两个go文件:zplugin.go和zdirectives.go。
core/dnsserver/zdirectives.go将所有插件名字放在一个数组中。
codedns 主函数
codedns.go 首先导入了包"github.com/coredns/coredns/core/plugin",此包内只有一个文件zplugin.go,此文件为自动生成的,主要导入了所有的插件,执行每个插件的init函数。
接着执行 run.go Run
此文件又引入了包"github.com/coredns/coredns/core/dnsserver",其init函数在 dnsserver/register.go 文件中,如下所示,主要是注册了serverType
剩下的就是解析参数,解析配置文件后,执行caddy.Start。
这里就是根据配置文件中指定的serverblock,执行插件的setup进行初始化,创建对应的server,开始监听dns请求
tcp协议调用Serve,udp协议调用ServePacket
收到DNS请求后,调用ServeDNS,根据域名匹配dnsserver,如果没有匹配不到则使用根dnsserver,然后执行dnsserver中配置的插件
以k8s插件为例
参考
//如何写coredns插件
//coredns源码分析
//NodeLocal DNSCache
相关问答
Q1: k8s架构原理
k8s是google公司使用go语言开发,借鉴borg系统开发出来的。
k8s集群服务器主要分为两类角色,分别为master和node。
api serverk8s插件go语言: k8s网关,所有指令请求都必须经过apiserver。
schedulerk8s插件go语言: 调度器 根据调度算法,将请求资源调度到某一个node节点。
controllerk8s插件go语言: 控制器,维护k8s资源对象。
etcd: 分布式存储组件,用于存储资源对象。
docker: 运行容器的基础环境,容器引擎。
kubelet: 每个node节点都存在一份,在node节点上的资源操作指令均由kubelet执行,从etcd扫描相关请求,在节点上执行请求。
kube-proxy: 代理服务,负载均衡
fluentd: 日志收集服务
pod: 是k8s管理的基本单位(最小单元),pod 内部是容器
k8s是用来管理容器的,但是不直接操作容器,最小操作单元为pod
特点:
pod是一个虚拟化的分组(有自己的ip地址、主机名),pod相当于独立主机,可以封装一个或多个容器。通常情况下,一个pod中要么部署一个服务,要么部署多个相关的服务
1、pod底层网络和数据存储:
pod底层网络和存储主要依赖pause容器,该容器作用如下:
2、pod内部容器使用localhost相互访问
3、pod内部容器创建之前必须先创建pause
Q2: kubernetes 是什么语言开发的
kubernetes是go语言写的k8s插件go语言,k8s插件go语言他里面有一些restful api接口,是开源容器应用自动化部署技术,也就是大家经常说的k8s。
kubernetes(k8s)是自动化容器操作的开源平台,这些操作包括部署,调度和节点集群间扩展。如果k8s插件go语言你曾经用过Docker容器技术部署容器,那么可以将Docker看成Kubernetes内部使用的低级别组件。Kubernetes不仅仅支持Docker,还支持Rocket,这是另一种容器技术。
使用Kubernetes可以:
自动化容器的部署和复制
随时扩展或收缩容器规模
将容器组织成组,并且提供容器间的负载均衡
很容易地升级应用程序容器的新版本
提供容器弹性,如果容器失效就替换它,等等...
K8s学习有一个前提条件,需要先掌握docker,如果你没有docker基础的话,那还不能学习 K8s k8s它底层的部署容器的那么容器本来就是docker。
可以看看这个视频教程,还是非常认真仔细的k8s插件go语言!
Q3: apisix和controller如何通信
为什么突然又绕到了apisix,其实是因为调研nginx-ingress就很容易联想到是不是要替换为其他网关ingress实现,比如apisix-ingress,进而想到的肯定是apisix;
这些概念到底有什么区别?
apisix 和 apisix-ingress-controller: apisix是一套体系,apisix-ingress-controller是k8s环境下基于go语言开发的一套自定义CRD,他负责响应apisix自定义资源的创建,监听k8s服务资源的创建变更,同步到apisix网关,apisix网关本身由openresty、nginx组成,主要是由Lua语言在nginx执行的各个阶段插入钩子,实现动态化,且基于etcd+灵活的插件机制,让变更更灵活且立即生效;
nginx-ingress和apisix-ingress-controller: nginx-ingress是k8s体系中目前使用最广的路由网关,比如阿里默认的控制台ingress创建就是使用的它;他集合了nginx+nginx-ingress-controller,拉代码可以看出,nginx-ingress-controller完成了与k8sapiserver交互,获取最新的服务配置变更,生成最新nginx配置,除此之外的通讯机制是通过Httppost请求将变更通知到到luanginx侧,ngx.timer在balancer中通过定时器进行动态化
apisix-ingress-controller监控k8s服务变更、自定义CRD及资源创建、将配置同步到apisix;网络请求通过apisix网关作为入口,通过apisix-ingress-controller同步k8s的上游变更
apisix比其他的有啥好?插件灵活,功能多,周边
Q4: 09-kubernetes中的域名解析流程
从Kubernetes 1.11版本开始,Kubernetes集群的DNS服务由CoreDNS提供。CoreDNS是CNCF基金会的一个项目,是用Go语言实现的高性能、插件式、易扩展的DNS服务端。CoreDNS解决了KubeDNS的一些问题,例如dnsmasq的安全漏洞、externalName不能使用stubDomains设置,等等。
CoreDNS支持自定义DNS记录及配置upstream DNS Server,可以统一管理Kubernetes基于服务的内部DNS和数据中心的物理DNS。
CoreDNS没有使用多个容器的架构,只用一个容器便实现了KubeDNS内3个容器的全部功能。
从kubernetes官方提供的 coredns.yml 文件中,不难看出coredns服务配置至少需要一个ConfigMap、一个Deployment和一个Service共3个资源对象。ConfigMap coredns 主要配置文件Corefile的内容:
其中主要有二个地方来解析配置
1、这段配置的意思是cluster.local后缀的域名都是kubernetes内部域名,coredns会监控service的变化来修改域名的记录
2、如果coredns没有找到dns记录,则去找 /etc/resolv.conf 中的 nameserver 解析
接下来使用一个带有nslookup工具的Pod来验证DNS服务能否正常工作:
通过nslookup进行测试。
查找defaul命名空间存在的ng-deploy-80服务
如果某个Service属于不同的命名空间,那么在进行Service查找时,需要补充Namespace的名称,组合成完整的域名。下面以查找kubernetes-dashboard服务为例,
众所周知, DNS 服务器用于将域名转换为 IP (具体为啥要转换建议复习下 7 层网络模型). Linux 服务器中 DNS 解析配置位于 /etc/resolv.conf , 在 Pod 中也不例外,
DNS 策略可以逐个 Pod 来设定。当前kubernetes支持这4中DNS 策略
如果我们不填dnsPolicy, 默认策略就是 ClusterFirst 。
kubelet 在起 pause 容器的时候,会将其 DNS 解析配置初始化成集群内的配置。配置: 它的 nameserver 就是指向 coredns 的
k8s里面有4种DNS策略, 而coredns使用的DNS策略就是Default, 这个策略的意思就是继承宿主机上的/etc/resolve.conf, 所以coredns Pod 里面的/etc/resolve.conf 的内容就是宿主机上的内容。
在集群中 pod 之间互相用 svc name 访问的时候,会根据 resolv.conf 文件的 DNS 配置来解析域名,下面来分析具体的过程。
pod 的 resolv.conf 文件主要有三个部分,分别为 nameserver、search 和 option。而这三个部分可以由 K8s 指定,也可以通过 pod.spec.dnsConfig 字段自定义。
nameserver
resolv.conf 文件的第一行 nameserver 指定的是 DNS 服务的 IP,这里就是 coreDNS 的
clusterIP:
也就是说所有域名的解析,都要经过coreDNS的虚拟IP 10.100.0.2 进行解析, 不论是内部域还是外部域名。
search 域
resolv.conf 文件的第二行指定的是 DNS search 域。解析域名的时候,将要访问的域名依次带入 search 域,进行 DNS 查询。
比如我要在刚才那个 pod 中访问一个域名为 ng-deploy-80的服务,其进行的 DNS 域名查询的顺序是:
options
resolv.conf 文件的第三行指定的是其他项,最常见的是 dnots。dnots 指的是如果查询的域名包含的点 “.” 小于 5,则先走 search 域,再用绝对域名;如果查询的域名包含点数大于或等于 5,则先用绝对域名,再走 search 域。K8s 中默认的配置是 5。
也就是说,如果我访问的是 a.b.c.e.f.g ,那么域名查找的顺序如下:
通过 svc 访问
在 K8s 中,Pod 之间通过 svc 访问的时候,会经过 DNS 域名解析,再拿到 ip 通信。而 K8s 的域名全称为 "service-name.namespace.svc.cluster.local",而我们通常只需将 svc name 当成域名就能访问到 pod,这一点通过上面的域名解析过程并不难理解。
参考
(1)K8S落地实践 之 服务发现(CoreDNS)
(2)自定义 DNS 服务
(3)Kubernetes 服务发现之 coreDNS
(4)Kubernetes 集群 DNS 服务发现原理
(5)Kubernetes之服务发现和域名解析过程分析
k8s插件go语言的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于k8s clientgo 编程、k8s插件go语言的信息别忘了在本站进行查找喔。







