線上故障,這次是kube-proxy的鍋

nanjingfm發表於2021-12-31

k8s環境,假設呼叫鏈路是A呼叫B。

  • A呼叫B報超時錯誤
  • 服務B介面監控發現延遲正常(就好像A並沒有呼叫B一樣)
  • B是php服務,階段性出現php_network_getaddresses: getaddrinfo failed報錯

DNS問題?

先從這個報錯查起php_network_getaddresses: getaddrinfo failed

搜尋這個錯誤,谷歌、百度會告訴你dns解析的問題,解析失敗會報這個錯。

image-20211231204225990

但實際上,我們不論在pod裡面還是在node機器上ping對應訪問的域名,都是可以成功解析的。

排查陷入尷尬的境地,感覺是網路問題,為什麼呢?

  • 上游請求下游,大量超時,但是下游卻響應正常,感覺因為網路有問題,請求沒有到達下游,或者下游返回的時候上游沒有收到。
  • getaddrinfo failed表示有時候dns解析有問題,但是能排除dns本身的問題,可能還是網路的問題,但是請求或者響應有問題。

網路問題?

網路問題可能是哪些問題呢?

  • 頻寬滿了?

    • 不是,檢查過node的頻寬,雖然頻寬佔用挺高的,但是遠沒有達到上限

      image-20211231210551405

  • LB超載了?

    • 不是,雖然問題期間連結數上升了不少,但是還是沒有到達上限。目前主要問題是請求超時,因為請求不能快速結束,所以需要更多的連結,連結數上升也說得通。

      image-20211231211355372

機器問題?

  • CPU、記憶體、負載高了?

    • 不是,指標正常

      image-20211231210706177

  • 看看node主機有沒有報錯?

    • demsg,看到有如下報錯:dropping packet不就是丟包的意思麼?

      LSSHdauu1J

現在定位的問題是conntrack table滿了,導致丟包。那conntrack是什麼呢?

conntrack連線跟蹤,大概意思是Linux為每一個經過網路堆疊的資料包,生成一個新的連線記錄項 (Connection entry)。此後,所有屬於此連線的資料包都被唯一地分配給這個連線,並標識連線的狀態。

檢視conntrack的上限和當前值,上線是52.4w,當前已經是52.2w,已經接近上限了。

image-20211231212258139

執行命令sysctl -w net.netfilter.nf_conntrack_max=2310720,提高上限,此時問題收斂。

問題覆盤期間,運維同學提到net.netfilter.nf_conntrack_max這個值在去年的時候已經調整到231w了,為啥現在又變回來了?

考慮到k8skube_proxy元件和conntrack有絕對關係,然後谷歌了下,看到kube-proxy有幾個相關的引數。

33j87MuF5A

看了下我們kube-proxy的啟動命令/usr/local/bin/kube-proxy --config=/var/lib/kube-proxy/config.conf --hostname-override=cn-beijing-xxx,配置檔案是空的,也就是都是使用這些引數的預設值,--conntrack-max-per-core代表每個cpu核跟蹤的最大NAT數量,預設值是32768。我們是16核的機器,16*32768=524288,524288和系統中的net.netfilter.nf_conntrack_max值是一致的。

net.netfilter.nf_conntrack_max為啥變化了呢

運維同學很確定這個引數值在去年就修改過,這個事情我也有印象。繼續谷歌,看到了這邊文章《kube-proxy conntracker設定》,大概意思是,kube-proxy的啟動引數中如果沒有設定–conntrack-max引數,則對比–conntrack-min和–conntrack-max-per-core的值與cpu核數的大小取其大者返回max值,預設值是32768 * CPU 核數,最後呼叫SetMax設定conntrack-max的值

所以是kube-proxy重啟的時候修改了系統的net.netfilter.nf_conntrack_max值。這是一個坑,不踩真的不知道。

再回想,昨天運維確實升級重啟過kube-proxy….

  • 上游請求下游,上游超時,下游響應正常,大機率是網路的問題。

  • 網路的問題,是node主機conntrack達到上限,導致丟包,丟包導致微服務請求超時。

  • net.netfilter.nf_conntrack_max這個引數在kube-proxy啟動的時候會重新設定,所以要設定好kube-proxy啟動引數。

  • 再看到php_network_getaddresses: getaddrinfo failed報錯,排除dns本省的問題,很可能就是網路丟包導致的

  • 阿里雲已經有相關監控和告警了

    image-20211231215148806# 現象

k8s環境,假設呼叫鏈路是A呼叫B。

  • A呼叫B報超時錯誤
  • 服務B介面監控發現延遲正常(就好像A並沒有呼叫B一樣)
  • B是php服務,階段性出現php_network_getaddresses: getaddrinfo failed報錯

DNS問題?

先從這個報錯查起php_network_getaddresses: getaddrinfo failed

搜尋這個錯誤,谷歌、百度會告訴你dns解析的問題,解析失敗會報這個錯。

image-20211231204225990

但實際上,我們不論在pod裡面還是在node機器上ping對應訪問的域名,都是可以成功解析的。

排查陷入尷尬的境地,感覺是網路問題,為什麼呢?

  • 上游請求下游,大量超時,但是下游卻響應正常,感覺因為網路有問題,請求沒有到達下游,或者下游返回的時候上游沒有收到。
  • getaddrinfo failed表示有時候dns解析有問題,但是能排除dns本身的問題,可能還是網路的問題,但是請求或者響應有問題。

網路問題?

網路問題可能是哪些問題呢?

  • 頻寬滿了?

    • 不是,檢查過node的頻寬,雖然頻寬佔用挺高的,但是遠沒有達到上限

      image-20211231210551405

  • LB超載了?

    • 不是,雖然問題期間連結數上升了不少,但是還是沒有到達上限。目前主要問題是請求超時,因為請求不能快速結束,所以需要更多的連結,連結數上升也說得通。

      image-20211231211355372

機器問題?

  • CPU、記憶體、負載高了?

    • 不是,指標正常

      image-20211231210706177

  • 看看node主機有沒有報錯?

    • demsg,看到有如下報錯:dropping packet不就是丟包的意思麼?

      LSSHdauu1J

現在定位的問題是conntrack table滿了,導致丟包。那conntrack是什麼呢?

conntrack連線跟蹤,大概意思是Linux為每一個經過網路堆疊的資料包,生成一個新的連線記錄項 (Connection entry)。此後,所有屬於此連線的資料包都被唯一地分配給這個連線,並標識連線的狀態。

檢視conntrack的上限和當前值,上線是52.4w,當前已經是52.2w,已經接近上限了。

image-20211231212258139

執行命令sysctl -w net.netfilter.nf_conntrack_max=2310720,提高上限,此時問題收斂。

問題覆盤期間,運維同學提到net.netfilter.nf_conntrack_max這個值在去年的時候已經調整到231w了,為啥現在又變回來了?

考慮到k8skube_proxy元件和conntrack有絕對關係,然後谷歌了下,看到kube-proxy有幾個相關的引數。

33j87MuF5A

看了下我們kube-proxy的啟動命令/usr/local/bin/kube-proxy --config=/var/lib/kube-proxy/config.conf --hostname-override=cn-beijing-xxx,配置檔案是空的,也就是都是使用這些引數的預設值,--conntrack-max-per-core代表每個cpu核跟蹤的最大NAT數量,預設值是32768。我們是16核的機器,16*32768=524288,524288和系統中的net.netfilter.nf_conntrack_max值是一致的。

net.netfilter.nf_conntrack_max為啥變化了呢

運維同學很確定這個引數值在去年就修改過,這個事情我也有印象。繼續谷歌,看到了這邊文章《kube-proxy conntracker設定》,大概意思是,kube-proxy的啟動引數中如果沒有設定–conntrack-max引數,則對比–conntrack-min和–conntrack-max-per-core的值與cpu核數的大小取其大者返回max值,預設值是32768 * CPU 核數,最後呼叫SetMax設定conntrack-max的值

所以是kube-proxy重啟的時候修改了系統的net.netfilter.nf_conntrack_max值。這是一個坑,不踩真的不知道。

再回想,昨天運維確實升級重啟過kube-proxy….

  • 上游請求下游,上游超時,下游響應正常,大機率是網路的問題。

  • 網路的問題,是node主機conntrack達到上限,導致丟包,丟包導致微服務請求超時。

  • net.netfilter.nf_conntrack_max這個引數在kube-proxy啟動的時候會重新設定,所以要設定好kube-proxy啟動引數。

  • 再看到php_network_getaddresses: getaddrinfo failed報錯,排除dns本省的問題,很可能就是網路丟包導致的

  • 阿里雲已經有相關監控和告警了

    image-20211231215148806

本作品採用《CC 協議》,轉載必須註明作者和本文連結
您的點贊、評論和關注,是我創作的不懈動力。 學無止境,讓我們一起加油,在技術的衚衕裡越走越深!

相關文章