DNS 接入

技术原理

Polaris 的 DNS 服务发现接入方案中,Polaris 是您的控制平面,Polaris Sidecar 作为本地 DNS 服务器实现服务发现以及动态路由。

Kubernetes 场景

  • polaris-server: 北极星服务端,处理服务注册以及服务发现请求。
  • polaris-controller: 完成 polaris-sidecar 容器注入到业务 POD 中,并下发 iptables 指令拦截业务容器的 DNS 请求,将其转发到 polaris-sidecar 中
  • polaris-sidecar: 作为本地 DNS 服务器,将 DNS 域名解析为北极星中的服务,实现服务发现。

虚拟机场景

  • polaris-server: 北极星服务端,处理服务注册以及服务发现请求。
  • polaris-sidecar: 作为本地 DNS 服务器,将 DNS 域名解析为北极星中的服务,实现服务发现。

配置解读

虚拟机

  • polaris-sidecar.yaml 内容和配置介绍如下:
bind: 0.0.0.0             # DNS 服务器监听IP
port: 53                  # DNS 服务器监听端口
namespace: default        # polaris-sidecar 所在的命名空间
polaris:
  addresses:
    - ${POLARIS_ADDRESS}  # Polaris Server访问地址, 示例:127.0.0.1:8091
  location:
    providers:
      - type: local # 当前仅支持local插件
        options:
          region: ${REGION}  # 地址位置信息,可设置环境变量REGION或直接赋值
          zone: ${ZONE} # 地址位置信息,可设置环境变量ZONE或直接赋值
          campus: ${CAMPUS} # 地址位置信息,可设置环境变量CAMPUS或直接赋值
  nearby_match_level: campus # 就近路由匹配范围
recurse: # 递归解析,当 polaris-sidecar 自己无法解析域名时,会转发给上一级 DNS 服务器继续解析
  enable: true
  timeoutSec: 1
resolvers: # DNS 解析插件
  - name: dnsagent                  # DNS 代理插件
    enable: true                    # 插件是否启用
    dns_ttl: 10                     # dns 记录的客户端 TTL
    suffix: "."                     # 决定哪些域名解析会被 polaris-sidecar 解析,默认为全部域名,示例:".abc"
    option:
      route_labels: "key: value"    # 主调方的静态标签信息,用于服务路由, 示例: "key1:value1,key2:value2"

容器

  • dnsagent在k8s环境下,在主调方的部署 yaml 中支持如下配置,说明和示例如下
  • 路由配置:主调方的静态标签信息,key 为 env, value 为 dev;
  • 递归配置:开启递归解析,请求下一个 nameserver 的超时时间为 5 秒;
  • dns代理解析配置:解析的后缀为.dns-test,客户端 DNS 解析记录TTL 为 3 秒;
  • 就近路由配置:地理信息为 region为huanan,zone 为ap-guangzhou,campus 为ap-guangzhou-6,就近路由匹配范围为 campus
spec:
  template:
    metadata:
      labels:
        env: dev
      annotations:
        polarismesh.cn/sidecarConfig: |
          {
            "recurse": {
              "enabled": true,
              "timeout": 5
            },
            "dns": {
              "suffix": ".dns-test",
              "ttl": 3
            },
            "location": {
              "region": "huanan",
              "zone": "ap-guangzhou",
              "campus": "ap-guangzhou-6",
              "match_level": "campus"
            }
          }
......

快速接入

基于 DNS 的北极星服务发现接入支持虚拟机以及 kubernetes 两种部署环境。您可以根据实际部署场景选择其中一种接入方式。

虚拟机接入

部署 polaris

如果已经部署好了 polaris,可忽略这一步。

安装 polaris-sidecar

  • 虚拟机安装过程需要使用 root 用户或者具有超级管理员权限的用户来执行,并且确保 53(udp/tcp)端口没有被占用。

  • 需要从 Releases 下载最新版本的安装包。

  • 上传安装包到虚拟机环境中,并进行解压,进入解压后的目录。

    unzip polaris-sidecar-release_$version.$os.$arch.zip
    

修改 polaris-sidecar 配置

  • 修改 polaris.yaml,写入部署好的北极星服务端的地址,端口号使用8091(GRPC端口)。

  • 进入解压后的目录,执行 tool/start.sh 进行启动,然后执行 tool/p.sh 查看进程是否启动成功。

    # bash tool/start.sh
    # bash ./tool/p.sh
    root     15318     1  0 Jan22 ?        00:07:50 ./polaris-sidecar start
    
  • 使用 root 权限修改 /etc/resolv.conf,在文件中添加 nameserver 127.0.0.1,并且添加到所有的 nameserver 记录前面,如下:

    ; generated by /usr/sbin/dhclient-script
    nameserver 127.0.0.1
    nameserver x.x.x.x
    

验证

使用格式为<service>.<namespace>的域名进行访问,预期可以获得服务下某个实例的 IP 地址。

➜ dig polaris.checker.polaris

...
;; ANSWER SECTION:
polaris.checker.polaris. 10 IN AAAA ::ffff:127.0.0.1
...

到这里,在虚拟机环境下通过 DNS 接入北极星的服务发现就完成了。

Kubernetes 接入

部署 polaris

如果已经部署好了 polaris,可忽略这一步。

部署 polaris-controller

开启 polaris-sidecar 注入

  • 方式一: 通过label 命令为某个 kubernetes 命名空间启用 polaris-sidecar 注入:

    # 为某个 kubernetes 命名空间开启 polaris sidecar 的注入
    kubectl label namespace ${kubernetes namespace} polaris-injection=enabled
    # 设置注入的 polaris sidecar 以 dns 模式运行
    kubectl label namespace ${kubernetes namespace} polaris-sidecar-mode=dns 
    
  • 方式二:通过 kubectl apply -f ns.yaml 创建命名空间

    # k8s命名空间部署yaml-命名空间下pod默认注入sidecar
    apiVersion: v1
    kind: Namespace
    metadata:
      name: dns-test
      labels:
        # 往pod中注入polaris sidecar
        polaris-injection: enabled
        # sidecar类型为dns
        polaris-sidecar-mode: dns
    

验证

  • 下载样例部署文件

  • 执行部署:kubectl create -f deployment.yaml

  • 查看容器注入是否注入成功,启动自动注入后,polaris-controller 会将 Polaris Sidecar 容器注入到在此命名空间下创建的 pod 中。可以看到运行起来的 pod 均包含两个容器,其中第一个容器是用户的业务容器,第二个容器是由 Polaris Controller 注入器注入的 Polaris Sidecar 容器。您可以通过下面的命令来获取有关 pod 的更多信息:

    kubectl describe pods -l k8s-app=polaris-dns-provider --namespace=default
    
  • 进入验证 POD, 执行 curl 命令

    kubectl exec -it polaris-dns-consumer-xxx -n default -- /bin/bash
    
    curl http://echoserver.default:10000/echo
    

使用高级功能

在使用高级功能时,先创建一个测试服务,用于接下来的功能测试

  • 创建测试服务 test.echoserver

使用就近路由

可以通过设置环境变量,指定 polaris-sidecar 实例所处的地理位置信息,当 polaris-sidecar 执行 DNS 服务发现时,会根据自身的地域信息,对目标服务实例进行就近匹配。

假定一个场景:

  • 存在以下三个地域
    • region=region-1、zone=zone-1、campus=campus-1
    • region=region-2、zone=zone-2、campus=campus-2
    • region=region-3、zone=zone-3、campus=campus-3
  • polaris-sidecar 如果处于 region=region-1、zone=zone-1、campus=campus-1,则优先选择相同地域的实例

使用方式

  • 设置地域信息环境变量
    export REGION=${ REGION 信息 }
    export ZONE=${ ZONE 信息 }
    export CAMPUS=${ CAMPUS 信息 }
    
  • 重启 polaris-sidecar
    bash tool/stop.sh
    bash tool/start.sh
    

  • 调整主调的 annotation,配置 sidecarConfig 里面的 location 信息

    ...
    spec:
      template:
        metadata:
          annotations:
            polarismesh.cn/sidecarConfig: |
              {
                "location": {
                  "region": "region-1",
                  "zone": "zone-1",
                  "campus": "campus-1",
                  "match_level": "campus"
                }
              }
    ...
    
  • 重建 POD

    kubectl delete pod {POD 名称} --namespace {命名空间}
    

验证

执行 dig 命令验证

# 地域信息分别为 region=region-1、zone=zone-1、campus=campus-1
➜ dig test.echoserver.default     

...
;; ANSWER SECTION:
test.echoserver.default. 10     IN      A       1.1.1.1
...

# 地域信息分别为 region=region-2、zone=zone-2、campus=campus-2
➜ dig test.echoserver.default     

...
;; ANSWER SECTION:
test.echoserver.default. 10     IN      A       2.2.2.2
...

# 地域信息分别为 region=region-3、zone=zone-3、campus=campus-3
➜ dig test.echoserver.default

...
;; ANSWER SECTION:
test.echoserver.default. 10     IN      A       3.3.3.3
...

使用动态路由

假定一个场景:

  • 希望 env 为 dev 的请求,路由到 env 标签为 dev 的实例上
  • 希望 env 为 pre 的请求,路由到 env 标签为 pre 的实例上
  • 其他则路由到 env 标签为 prod 的实例上

使用方式

  • 调整 polaris-sidecar 配置文件
    ...
    resolvers:
      - name: dnsagent
        ...
        option: 
          route_labels: "env:dev"
    
  • 重启 polaris-sidecar
    bash tool/stop.sh
    bash tool/start.sh
    

  • 调整主调的静态标签信息
    ...
    spec:
      template:
        metadata:
          labels:
            env: dev
    ...
    
  • 重建 POD
    kubectl delete pod {POD 名称} --namespace {命名空间}
    

验证

执行 dig 命令验证

# 设置 route_labels: "env: dev"
➜ dig test.echoserver.default     

...
;; ANSWER SECTION:
test.echoserver.default. 10     IN      A       1.1.1.1
...

# 设置 route_labels: "env: pre"
➜ dig test.echoserver.default     

...
;; ANSWER SECTION:
test.echoserver.default. 10     IN      A       2.2.2.2
...

# 设置 route_labels: ""
➜ dig test.echoserver.default

...
;; ANSWER SECTION:
test.echoserver.default. 10     IN      A       3.3.3.3
...