美文网首页
k8s ndots 理解与配置优化

k8s ndots 理解与配置优化

作者: Yellowtail | 来源:发表于2022-03-02 17:59 被阅读0次

    [TOC]

    /etc/resolv.conf

    这个文件是 linux 里的一个配置文件,做 dns 解析用的

    https://linux.die.net/man/5/resolv.conf

    在 k8s pod 里长这个样子,pod 里面执行 cat /etc/resolv.conf

    nameserver 172.23.0.10
    search backend.svc.cluster.local svc.cluster.local cluster.local localdomain
    options ndots:5
    

    其中 nameserver 就是 corednsservice (也就是 kube-dns) 的 ip (虚拟ip,也叫 vip)
    search 是搜索顺序, backend 是pod所在命名空间
    options 是一些选项

    ndots 含义

    ndots 意思就是 点号. (dot) 的个数
    ndots: 5 就是 5个点号

    5个点号 的意思就是说
    对于一个 域名, 如果不是完全限定名(即某个域名不是以. 结尾, a.com 不是, a.com. 是)
    且点号数量少于5个, 那么就按照 search 的顺序,依次解析
    如果点号大于或者等于5, 直接解析

    如上面的 search 配置项表达的解析顺序就是

    1. backend.svc.cluster.local
    2. svc.cluster.local
    3. cluster.local
    4. localdomain

    举例说明
    假设有两个服务,ABA 现在要请求 B 的接口 GET /api/b/users
    那么请求可以长这个样子 GET http://B/api/b/usres, B 服务的name 可以当成 域名来用
    HTTP 报文如下

    GET /api/b/users HTTP/1.1
    Host: B
    Accept: */*
    Content-Type: application/json
    

    实际解析域名的时候,按照顺序解析,解析到就返回 ip
    顺序如下

    1. B.backend.svc.cluster.local
    2. B.svc.cluster.local
    3. B.cluster.local
    4. B.localdomain
    5. B

    也就是说我们访问B的服务,域名的写法可以有很多种,都是支持的,如:

    • GET http://B/api/b/usres
    • GET http://B.backend/api/b/usres
    • GET http://B.backend.svc/api/b/usres

    既然有这么多种写法,那么有没有最优解呢?

    数量对比试验

    ndots=5, 域名点号=4

    # cat /etc/resolv.conf
    nameserver 172.23.0.10
    search backend.svc.cluster.local svc.cluster.local cluster.local localdomain
    options ndots:5
    
    # host -av r-wz9f2fc78874fa04.redis.rds.aliyuncs.com
    Trying "r-wz9f2fc78874fa04.redis.rds.aliyuncs.com.backend.svc.cluster.local"
    Trying "r-wz9f2fc78874fa04.redis.rds.aliyuncs.com.svc.cluster.local"
    Trying "r-wz9f2fc78874fa04.redis.rds.aliyuncs.com.cluster.local"
    Trying "r-wz9f2fc78874fa04.redis.rds.aliyuncs.com.localdomain"
    Trying "r-wz9f2fc78874fa04.redis.rds.aliyuncs.com"
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29554
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
    
    ;; QUESTION SECTION:
    ;r-wz9f2fc78874fa04.redis.rds.aliyuncs.com. IN ANY
    
    ;; ANSWER SECTION:
    r-wz9f2fc78874fa04.redis.rds.aliyuncs.com. 19 IN A 172.16.4.243
    
    Received 116 bytes from 172.23.0.10#53 in 0 ms
    

    通过日志可以发现

    • 此时配置里的点号是5, ndots:5
    • 而我们的域名包含4个点 ., 4小于5,所以按照seacrh顺序添加后缀之后依次解析,都解析不到的情况下不加后缀去解析,日志Trying可以证明这一点

    可以看出来,策略就是: 优先把域名当成内网的来解析,内网解析不到就当成外网去解析

    ndots=4, 域名点号=4

     # cat /etc/resolv.conf
    nameserver 172.23.0.10
    search backend.svc.cluster.local svc.cluster.local cluster.local localdomain
    options ndots:4
    
     # host -av r-wz9f2fc78874fa04.redis.rds.aliyuncs.com
    Trying "r-wz9f2fc78874fa04.redis.rds.aliyuncs.com"
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37171
    ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
    
    ;; QUESTION SECTION:
    ;r-wz9f2fc78874fa04.redis.rds.aliyuncs.com. IN ANY
    
    ;; ANSWER SECTION:
    r-wz9f2fc78874fa04.redis.rds.aliyuncs.com. 30 IN A 172.16.4.243
    
    Received 116 bytes from 172.23.0.10#53 in 1 ms
    

    通过日志可以发现

    • 此时配置里的点号是4, ndots:4
    • 而我们的域名包含4个点 ., 4小于4,所以按照seacrh顺序解析,直接拿来解析,日志Trying可以证明这一点

    ndots=3, 域名点号=4

    # cat /etc/resolv.conf
    nameserver 172.23.0.10
    search backend.svc.cluster.local svc.cluster.local cluster.local
    options ndots:3
    
    # host -av r-wz9f2fc78874fa04.redis.rds.aliyuncs.com
    Trying "r-wz9f2fc78874fa04.redis.rds.aliyuncs.com"
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 549
    ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
    
    ;; QUESTION SECTION:
    ;r-wz9f2fc78874fa04.redis.rds.aliyuncs.com. IN ANY
    
    ;; ANSWER SECTION:
    r-wz9f2fc78874fa04.redis.rds.aliyuncs.com. 30 IN A 172.16.4.243
    
    Received 116 bytes from 172.23.0.10#53 in 1 ms
    
    • 此时配置里的点号是3, ndots:3
    • 而我们的域名包含4个点 ., 4小于3,所以按照seacrh顺序解析,直接拿来解析,日志Trying可以证明这一点

    上面都是外网域名,接下来试一下内网的

    ndots=3, 内网域名点号=1

    # cat /etc/resolv.conf
    nameserver 172.23.0.10
    search backend.svc.cluster.local svc.cluster.local cluster.local
    options ndots:3
    
    # host -av b.backend
    Trying "b.backend.backend.svc.cluster.local"
    Trying "b.backend.svc.cluster.local"
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41190
    ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
    
    ;; QUESTION SECTION:
    ;agent-app-service.backend.svc.cluster.local. IN    ANY
    
    ;; AUTHORITY SECTION:
    cluster.local.      30  IN  SOA ns.dns.cluster.local. hostmaster.cluster.local. 1568253402 7200 1800 86400 30
    
    Received 154 bytes from 172.23.0.10#53 in 1 ms
    
    • 1小于3,所以会尝试;
    • 在尝试第二次的时候就找到了

    如何调整

    终上所述,对于内网域名、外网域名,我们都希望尽可能少的进行 DNS 解析,以便提升性能
    对于内网域名,这个好说,因为都是我们的代码可以控制的,可以改;外网域名改不了,着重研究一下

    我们的服务对于外部调用比较频繁的大概有三类 redis mongodb es

    • redis
      r-xxx.redis.rds.aliyuncs.com 4个点号
    • mongodb
      dds-xxx.mongodb.rds.aliyuncs.com 4个点号
    • es
      es-xxx.elasticsearch.aliyuncs.com 3个点号

    想要外网地址不走k8s解析的,可以取最小值3

    所以,我们可以设置点号数量为 3

    1. 对于外部调用,3可以覆盖,直接解析
    2. 对于内部调用,直接要求大家写成全限定名 serviceName.namespace.svc.cluster.local. ,也是直接解析的

    之所以不设置为1 (毕竟设置为1也是可以的), 就是想保留这个特性,在手动测试的时候,因为不追求性能,所以可以少写一点,如 get http://b/api/users 很方便

    如何修改

    ndots 默认的值是1, coredns 将其设置成5了
    但是,想要修改 ndots ,不是去修改 coredns 的配置,走了一些弯路,这里贴出来

    coredns
    首先想的是去修改 CoreDNS 的配置项

    coredns 的配置文件复制出来,可以看见
    其配置文件并没有 ndots选项

    nameserver 100.100.2.136
    nameserver 100.100.2.138
    options timeout:2 attempts:3 rotate single-request-reopen
    

    手动修改

    进入容器里面手动修改是没有用的,需要重启网络模块才会生效
    一重启容器没了,改了等于白改

    init containers

    initContainers 也是一堆坑

    k8s yaml

    其实k8s 给我们提供了参数,叫做 dnsConfig, 如下所示

    dnsConfig:
            options:
              - name: ndots
                value: '3'
    dnsPolicy: ClusterFirst
    

    所以最后,我们选择了使用 k8s yaml 的方式来修改,对于老的服务直接修改;对于新的服务,在上线模板里配置好这个值

    参考文章

    https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/

    相关文章

      网友评论

          本文标题:k8s ndots 理解与配置优化

          本文链接:https://www.haomeiwen.com/subject/clqerrtx.html