Istio流量管理实践之(4): 基于CoreDNS Plugin扩展实现Istio Service Entry的DNS寻址

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: Istio支持几种不同的拓扑结构,用于在单个集群之外分发应用程序的服务,例如在服务网格中的服务可以使用 ServiceEntry 来访问独立的外部服务或访问由另一个服务网格公开的服务(这种情况通常称之为网格联合)。

CoreDNS 及其Plugin扩展

CoreDNS是一个CNCF下的孵化级项目,它的前身是SkyDNS,主要目的是构建一个快速灵活的 DNS 服务器,让用户可以通过不同方式访问和使用 DNS 内的数据。基于 Caddy 服务器框架,CoreDNS 实现了一个插件链的架构,将大量逻辑抽象成插件Plugin的形式暴露给使用者,每个插件都执行DNS功能,例如Kubernetes 的 DNS 服务发现、Prometheus 监控等。

除了插件化之外,CoreDNS还有以下特性:

  • 配置简单化: 引入表达力更强的 DSL,即 Corefile 形式的配置文件(也是基于 Caddy 框架开发);
  • 一体化的解决方案:区别于 kube-dns,CoreDNS 编译出来就是一个单独的二进制可执行文件,内置了 cache,backend storage ,health check 等功能,无需第三方组件来辅助实现其他功能,从而使得部署更方便,内存管理更为安全;

Corefile 介绍

Corefile 是 CoreDNS 的配置文件(源于 Caddy 框架的配置文件 Caddyfile),定义了以下内容:

  • 服务器以什么协议监听在哪个端口(可以同时定义多个 server 监听不同端口)
  • 服务器负责哪个 zone 的 authoritative DNS 解析
  • 服务器将加载哪些插件

一个典型的 Corefile 格式如下所示:

ZONE:[PORT] {
    [PLUGIN] ...
}

其中,

  • ZONE:用于定义服务器负责的 zone;
  • PORT: 监听端口,可选项,默认为 53;
  • PLUGIN:定义服务器所要加载的插件plugin,每个 plugin 可以有多个参数;

Plugin工作机制

当 CoreDNS 启动后,它将根据配置文件启动不同 server ,每台 server 都拥有自己的插件链。当有 DNS 请求时,它将依次经历如下 3 步逻辑:

  • 如果有当前请求的 server 有多个 zone,将采用贪心原则选择最匹配的 zone;
  • 一旦找到匹配的 server,按照 plugin.cfg 定义的顺序执行插件链上的插件;
  • 每个插件将判断当前请求是否应该处理,将有以下几种可能:

    • 请求被当前插件处理
      插件将生成对应的响应并回给客户端,此时请求结束,下一个插件将不会被调用,如 whoami 插件;
    • 请求不被当前插件处理
      直接调用下一个插件。如果最后一个插件执行错误,服务器返回 SERVFAIL 响应;
    • 请求被当前插件以 Fallthrough 形式处理
      如果请求在该插件处理过程中有可能将跳转至下一个插件,该过程称为 fallthrough,并以关键字 fallthrough 来决定是否允许此项操作,例如 host 插件,当查询域名未位于 /etc/hosts,则调用下一个插件;

      • 请求在处理过程被携带 Hint
        请求被插件处理,并在其响应中添加了某些信息(hint)后继续交由下一个插件处理。这些额外的信息将组成对客户端的最终响应,如 metric 插件;

CoreDNS与Kubernetes

从Kubernetes 1.11开始,CoreDNS作为Kubernetes的DNS插件进入GA状态,Kubernetes推荐使用CoreDNS作为集群内的DNS服务。在阿里云容器服务Kubernetes 1.11.5及更新版本中默认安装使用CoreDNS作为DNS服务。通过如下命令可以查看CoreDNS配置信息:

# kubectl -n kube-system get configmap coredns -oyaml
apiVersion: v1
data:
  Corefile: |-
    .:53 {
        errors
        health
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           upstream
           fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        proxy . /etc/resolv.conf
        cache 30
        reload
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2018-12-28T07:28:34Z"
  name: coredns
  namespace: kube-system
  resourceVersion: "2453430"
  selfLink: /api/v1/namespaces/kube-system/configmaps/coredns
  uid: 2f3241d5-0a72-11e9-99f1-00163e105bdf

配置文件各参数的含义如下:

名称 含义
errors 错误会被记录到标准输出
health 健康状况,可以通过http://localhost:8080/health查看
kubernetes 根据服务的IP响应DNS查询请求,Cluster Domain默认为cluster.local
prometheus 可以通过http://localhost:9153/metrics获取prometheus格式的监控数据
proxy 本地无法解析后,向上级地址进行查询,默认使用宿主机的 /etc/resolv.conf 配置
cache 缓存时间

通过应用目录简便部署Istio CoreDNS

阿里云容器服务Kubernetes 1.11.5目前已经上线,可以通过容器服务管理控制台非常方便地快速创建 Kubernetes 集群。具体过程可以参考创建Kubernetes集群

点击左侧的应用目录,在右侧选中ack-istio-coredns,在打开的页面中点击参数, 可以通过修改参数配置进行定制化,如下所示:
图片.png

参数描述如下:

参数 描述 默认
replicaCount 指定副本数 number 1
coreDNSImage 指定coredns镜像名称 valid image tag coredns/coredns:1.2.2
coreDNSPluginImage 指定插件镜像名称 valid image name registry.cn-hangzhou.aliyuncs.com/aliacs-app-catalog/istio-coredns-plugin:v1.0-istio-1.1

修改之后,在右侧选择对应的集群、命名空间 istio-system 以及发布名称 istio-coredns,然后点击部署。几秒钟之后,Istio CoreDNS发布就可以创建出来,如下图所示:
图片.png

更改集群CoreDNS配置

可以通过执行以下命令来获取 istiocoredns服务的Cluster IP:

# kubectl get svc istiocoredns -n istio-system

NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
istiocoredns   ClusterIP   172.19.10.196   <none>        53/UDP,53/TCP   44m

更新集群的coredns的配置项configmap, 将此istiocoredns服务作为 *.global 域的上游DNS服务,在此配置项configmap中添加域 *.global,如下所示:

apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |-
    .:53 {
        errors
        health
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           upstream
           fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        proxy . /etc/resolv.conf
        cache 30
        reload
    }
    global:53 {
         errors
         cache 30
         proxy . {replace this with the actual cluster IP of this istiocoredns service}
    }

更改此配置项后,集群的CoreDNS容器会重新加载这些配置内容,可以通过如下命令行查看加载日志:

# kubectl get -n kube-system pod | grep coredns
coredns-8645f4b4c6-5frkg                                     1/1     Running   0          20h
coredns-8645f4b4c6-lj59t                                     1/1     Running   0          20h

# kubectl logs -f -n kube-system coredns-8645f4b4c6-5frkg
....
2019/01/08 05:06:47 [INFO] Reloading
2019/01/08 05:06:47 [INFO] plugin/reload: Running configuration MD5 = 05514b3e44bcf4ea805c87cc6cd56c07
2019/01/08 05:06:47 [INFO] Reloading complete

# kubectl logs -f -n kube-system coredns-8645f4b4c6-lj59t
....
2019/01/08 05:06:31 [INFO] Reloading
2019/01/08 05:06:32 [INFO] plugin/reload: Running configuration MD5 = 05514b3e44bcf4ea805c87cc6cd56c07
2019/01/08 05:06:32 [INFO] Reloading complete

创建ServiceEntry验证DNS解析

ServiceEntry 能够在 Istio 内部的服务注册表中加入额外的条目,从而让网格中自动发现的服务能够访问和路由到这些手工加入的服务。ServiceEntry 描述了服务的属性,即包括DNS 名称、虚拟IP、端口、协议以及端点等。这类服务可能是网格外的 API,或者是处于网格内部但却不存在于平台的服务注册表中的条目,例如需要和 Kubernetes 服务沟通的一组基于虚拟机VM提供的服务。

下面的例子中,使用了通配符定义 hosts,并指定了address,如下所示:

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: external-svc-serviceentry
spec:
  hosts:
  - '*.test.global'
  addresses:
  - 127.255.0.2
  ports:
  - number: 8080
    name: http1
    protocol: HTTP
  location: MESH_INTERNAL
  resolution: DNS
  endpoints:
  - address: 47.111.38.80
    ports:
      http1: 15443

执行如下命令查看容器 istiocoredns ,可以看到上述ServiceEntry的域名映射关系已经被加载:

# kubectl get po -n istio-system | grep istiocoredns
istiocoredns-cdc56b67-ngtkr                 2/2     Running   0          1h

# kubectl logs --tail 2 -n istio-system istiocoredns-cdc56b67-ngtkr -c istio-coredns-plugin
2019-01-08T05:27:22.897845Z    info    Have 1 service entries
2019-01-08T05:27:22.897888Z    info    adding DNS mapping: .test.global.->[127.255.0.2]

使用镜像 tutum/dnsutils 创建测试容器:

kubectl run dnsutils -it --image=tutum/dnsutils bash

进入容器命令行之后,执行dig 查看相应的域名解析:

root@dnsutils-d485fdbbc-8q6mp:/# dig +short 172.19.0.10 A service1.test.global
127.255.0.2
root@dnsutils-d485fdbbc-8q6mp:/# dig +short 172.19.0.10 A service2.test.global
127.255.0.2

总结

Istio支持几种不同的拓扑结构,用于在单个集群之外分发应用程序的服务,例如在服务网格中的服务可以使用 ServiceEntry 来访问独立的外部服务或访问由另一个服务网格公开的服务(这种情况通常称之为网格联合)。使用Istio CoreDNS为远程集群中的服务提供DNS解析,将允许现有的应用程序不需要修改就可以如同访问本集群内的服务一样。

相关文章
|
4月前
|
域名解析 Kubernetes 网络协议
k8s教程(service篇)-pod的dns域名
k8s教程(service篇)-pod的dns域名
495 0
|
6月前
|
Kubernetes 负载均衡 算法
【K8S系列】深入解析Service
【K8S系列】深入解析Service
81 0
【K8S系列】深入解析Service
|
6月前
|
Kubernetes 网络协议 数据安全/隐私保护
Kubernetes 的核心概念:Pod、Service 和 Namespace 解析
Kubernetes 的核心概念:Pod、Service 和 Namespace 解析
149 1
|
3月前
|
Shell Python Perl
深入理解Istio流量管理的熔断配置
创建目标规则,访问 httpbin 服务时应用熔断配置 在 fortio 服务中向 httpbin 服务的发出并发请求
94 3
深入理解Istio流量管理的熔断配置
|
4月前
|
域名解析 缓存 Kubernetes
k8s教程(service篇)-Node本地DNS缓存
k8s教程(service篇)-Node本地DNS缓存
144 0
k8s教程(service篇)-Node本地DNS缓存
|
4月前
|
Prometheus Kubernetes 网络协议
k8s教程(service篇)-DNS服务搭建和配置
k8s教程(service篇)-DNS服务搭建和配置
169 0
|
6月前
|
安全 前端开发 Cloud Native
Istio 探索:微服务的流量管理、安全性和策略加固
Istio 探索:微服务的流量管理、安全性和策略加固
41 0
|
6月前
|
网络协议 安全 云栖大会
2023 云栖大会 - “DNS+” 万物互联,寻址先行
DNS是用户访问互联网的入口,也是国家关键互联网基础设施。本论坛将联合DNS行业专家发布《“DNS+”发展白皮书》, 带来最新的DNS安全研究动态。论坛还将有基于融合场景的云解析DNS的产品、技术和生态策略重磅升级,并带来优秀客户案例分享。
|
6月前
|
存储 Kubernetes 负载均衡
【Kubernetes的Service Mesh发展历程及Istio架构、存储供应使用NFS flexvolume CSI接口】
【Kubernetes的Service Mesh发展历程及Istio架构、存储供应使用NFS flexvolume CSI接口】
|
8月前
|
Java 调度 Spring
深入解析 Java 中的 @Service 注解:优化业务逻辑的组织与管理
在现代软件开发中,良好的代码组织和业务逻辑的模块化是保持代码可维护性和可扩展性的重要因素。而 Java 中的 `@Service` 注解则是实现业务逻辑组织和管理的有力工具。通过该注解,我们可以将业务逻辑标记为服务组件,实现依赖注入和松耦合的架构。本文将带您深入探索 Java 中的 `@Service` 注解,揭示其作用、用法以及在实际开发中的应用场景。

推荐镜像

更多