<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何解決 Kubernetes 的 DNS 延遲問題

          共 2737字,需瀏覽 6分鐘

           ·

          2021-07-08 08:45

          由于 Linux 內(nèi)核中的缺陷,在 Kubernetes 集群中你很可能會碰到惱人的 DNS 間歇性 5 秒延遲問題(社區(qū) issue 為 #56903[1])。雖然 issue 已經(jīng)關(guān)閉了,但并不是說這個問題已經(jīng)完全解決了,所以在管理和維護(hù) Kubernetes 集群時,我們需要注意繞開這個缺陷。

          為什么會有 DNS 間歇性延遲問題

          為什么在 Kubernetes 集群會碰到這個間歇性 5 延遲的問題呢?Weave works 發(fā)布了一篇博客Racy conntrack and DNS lookup timeouts[2]詳細(xì)介紹了問題的原因。

          簡單來說,由于 UDP 是無連接的,內(nèi)核 netfilter 模塊在處理同一個 socket 上的并發(fā) UDP 包時就可能會有三個競爭問題。以下面的 conntrack 和 DNAT 工作流程為例:

          由于 UDP 的 connect 系統(tǒng)調(diào)用不會立即創(chuàng)建 conntrack 記錄,而是在 UDP 包發(fā)送之后才去創(chuàng)建,這就可能會導(dǎo)致下面三種問題:
          1. 兩個 UDP 包在第一步 nf_conntrack_in 中都沒有找到 conntrack 記錄,所以兩個不同的包就會去創(chuàng)建相同的 conntrack 記錄(注意五元組是相同的)。
          2. 一個 UDP 包還沒有調(diào)用 get_unique_tuple 時 conntrack 記錄就已經(jīng)被另一個 UDP 包確認(rèn)了。
          3. 兩個 UDP 包在 ipt_do_table 中選擇了兩個不同端點(diǎn)的 DNAT 規(guī)則。

          所有這三種場景都會導(dǎo)致最后一步 __nf_conntrack_confirm 失敗,從而一個 UDP 包被丟棄。由于 GNU C 庫和 musl libc 庫在查詢 DNS 時,都會同時發(fā)出 A 和 AAAA DNS 查詢,由于上述的內(nèi)核競爭問題,就可能會發(fā)生其中一個包被丟掉的問題。丟棄之后客戶端會超時重試,超時時間通常是 5 秒。

          上述的第三個問題至今還沒有修復(fù),而前兩個問題則已經(jīng)修復(fù)了,分別包含在 5.0 和 4.19 中:

          1. netfilter: nf_nat: skip nat clash resolution for same-origin entries[3] (包含在內(nèi)核 v5.0 中)
          2. netfilter: nf_conntrack: resolve clash for matching conntracks[4] (包含在內(nèi)核 v4.19 中)

          在公有云中,這些補(bǔ)丁有可能也會包含在舊的內(nèi)核版本中。比如在 Azure 上,這兩個問題已經(jīng)包含在 v4.15.0-1030.31 和 v4.18.0-1006.6 中。

          如何避免這個問題

          要避免 DNS 延遲的問題,就要設(shè)法繞開上述三個問題,所以就有下面幾種方法:

          1. 禁止并發(fā) DNS 查詢,比如在 Pod 配置中開啟 single-request-reopen 選項(xiàng)強(qiáng)制 A 查詢和 AAAA 查詢使用相同的 socket:
          dnsConfig:
            options:
              - name: single-request-reopen
          1. 禁用 IPv6 從而避免 AAAA 查詢,比如可以給 Grub 配置 ipv6.disable=1 來禁止 ipv6(需要重啟節(jié)點(diǎn)才可以生效)。

          2. 使用 TCP 協(xié)議,比如在 Pod 配置中開啟 use-vc 選項(xiàng)強(qiáng)制 DNS 查詢使用 TCP 協(xié)議:

          dnsConfig:
            options:
              - name: single-request-reopen
              - name: ndots
                value: "5"
              - name: use-vc
          1. 使用 Nodelocal DNS Cache[5],所有 Pod 的 DNS 查詢都通過本地的 DNS 緩存查詢,避免了 DNAT,從而也繞開了內(nèi)核中的競爭問題。你可以執(zhí)行下面的命令來部署它(注意它會修改 Kubelet 配置并重啟 Kubelet):
          kubectl apply -f https://github.com/feiskyer/kubernetes-handbook/raw/master/examples/nodelocaldns/nodelocaldns-kubenet.yaml

          參考資料

          [1]

          #56903: https://github.com/kubernetes/kubernetes/issues/56903

          [2]

          Racy conntrack and DNS lookup timeouts: https://www.weave.works/blog/racy-conntrack-and-dns-lookup-timeouts

          [3]

          netfilter: nf_nat: skip nat clash resolution for same-origin entries: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4e35c1cb9460240e983a01745b5f29fe3a4d8e39

          [4]

          netfilter: nf_conntrack: resolve clash for matching conntracks: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ed07d9a021df6da53456663a76999189badc432a

          [5]

          Nodelocal DNS Cache: https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns/nodelocaldns


          瀏覽 72
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  视频一区在线看 | 久久人人操 | 久久伊人青青 | 天天干天天爽天天碰天天摸 | 免费一区区三区四区 |