zl程序教程

您现在的位置是:首页 >  其他

当前栏目

走马观花云原生技术(2):DNS服务CoreDNS

技术服务 原生 DNS 走马观花 CoreDNS
2023-06-13 09:13:08 时间

‍CoreDNS是一个Go语言实现的DSN服务。它是CNCF基金会中16个已毕业项目中的一员。

那CoreDNS又在云原生架构中起到什么作用呢?

一)

DNS服务想必我们都大致知道是什么,它是提供域名与IP映射关系的一种服务。

我们都知道互联网是基于IP的,不管是IPV4还是IPV6,都不是非常好记,于是发明了域名的概念。但访问一个具体的服务,最终仍然依赖的是IP,所以就需要DNS服务来提供一个查询能力,

这就是DNS服务的作用。

二)

那我们想知道,在云原生架构中,CoreDNS有什么作用?或者换个方式提问,为什么云原生架构中,需要一个DNS服务?

在云原生架构中,有一个重要的特征,就是服务会自动扩容与收缩

云原生架构中,可能有非常多的服务,甚至是成百上千个也是很常见的。而通常每一个服务又有成百上千,甚至上万个实例。

当然,K8S这样的容器编排工具,简化了我们的部署与运营,我们只需要告诉K8S,我们需要用户这个服务在部署中运行100个实例,K8S会自动帮我们做到这一切,无须我们一个一个去部署与启动。这非常方便。

现在有一个问题来了,怎么知道这100个实例在部署中的网络地址?

再进一步,一些实例会出现错误,K8S会自动移除错误的实例,并自动启动新的实例以补充;随着业务扩充,我们可能会将100个升级为200个实例,也有可能在一些特定的时期,我们将一些不重的服务数量降低,以优先满足重要的服务。所以,在微服务或云原生架构中,一个重要的点是:

服务是不可预测的,它会随时被创建,移除或变更

但在一个系统中,服务是要提供API的,无论是Http Rest或是gRPC,调用这个服务总得知道这个服务地址是啥,在哪,IP是多少等,但是由于前面说的云原生架构中,服务是不可预测的,这就需要一个方案来解决查找服务的能力。

三)

这就是服务的注册与查找了。在微服务架构中,大家熟悉的可能是类似zookeper,etcd等方案,服务启动时主动向一个服务注册中心注册自己的信息,服务中心再提供查找能力。

这的确是一个很好的解决方案,事实上现在相当一部分仍然是这样做的。但这种方式,存在几个明显的缺点:

  1. 1. 需要代码主动去编写注册及查找服务的逻辑,每个模块都要实现,非常不高效,且依赖一个第三方注册与查找服务
  2. 2. 云原生架构中,很多是异构的技术实现,不同语言与框架上,不一定能统一这种实现

因此,在K8S或Docker Swarm这样的容器编排工具中,都提供了基于DNS的服务注册与查找能力,更关键的是,这一切是在服务进程之外的架构支持,不需要代码去关心,简化了代码层级的很多工作。

服务注册

  1. 1. K8S在启动,停止任何容器服务时,均会向DNS注册对应的服务的名称与IP
  2. 2. DNS服务知晓所有服务的名称与IP关系,不论你有多少个服务实例,规模有多大,这些信息它都是明确的,并且不需要你写代码去干预这个过程
  3. 3. 云原生架构中的任何一个服务,想要调用另一个服务,只需要知道另一个服务的名称就可以了。K8S容器编排会查询DNS并返回IP给此服务

是不是非常方便。

以一个nginx配置为例

upstream user {
  #只需指定服务的名称`user
   server user:8080;
}

server {
    listen  80;
    location / {
       proxy_pass http://user;
    }
 }

在云原生架构中,你只需要配置服务在K8S中的名称user(K8S有自己的服务名称规则,这里简化了下)就可以了。无须关心后面有多少个实例在运行,100个也好,200个也好,K8S都会通过DNS返回所有的实例IP给nginx

不管是HTTP或是gRPC,上面这种方式都是合适的。如果你使用的是gRPC,代码可能是这样的

 //这是Kotlin代码
private val managedChannel by lazy {
  ManagedChannelBuilder
  .forTarget("dns:///user:8081")
  .defaultLoadBalancingPolicy("round_robin")
  .usePlaintext()
  .build()
}

关键代码是dns:///user:8081,我们只需要指定要查找的服务的DNS名称就可以了。无须关心部署中它有多少个实例,每个实例的具体地址是多少,K8S会正确返回DNS信息。

四)

自K8S 1.21版本开始,CoreDNS取代kube-dns成为K8S中默认的DNS实现,因为CoreDNS更高效与安全。而自1.24版本开始,kube-dns将不再被支持,CoreDNS将成为K8S中唯一支持的DNS实现。

这就是CoreDNS在云原生架构中的作用。

这是个支撑服务,使用云原生架构中,可能大部分时候你不需要关心CoreDNS的存在,你只需要知道K8S是依赖CoreDNS提供了这种能力,你在设计架构时,可能根据需要考虑是否用上这样的服务查找能力。