0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
电子发烧友
开通电子发烧友VIP会员 尊享10大特权
海量资料免费下载
精品直播免费看
优质内容免费畅学
课程9折专享价
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

記一次容器環(huán)境下出現(xiàn)Address not available

OSC開(kāi)源社區(qū) ? 來(lái)源:阿里云云原生 ? 2023-08-03 10:43 ? 次閱讀

困惑的源地址

Cloud Native

pod 創(chuàng)建后一段時(shí)間一直是正常運(yùn)行,突然有一天發(fā)現(xiàn)沒(méi)有新的連接創(chuàng)建了,業(yè)務(wù)上是通過(guò) pod A 訪問(wèn) svc B 的 svc name 的方式,進(jìn)入 pod 手動(dòng)去 wget 一下,發(fā)現(xiàn)報(bào)錯(cuò)了 Address not available,為何會(huì)報(bào)錯(cuò)這個(gè)呢?

大概示例圖如下:



7e298742-3122-11ee-9e74-dac502259ad0.png



為什么會(huì)出現(xiàn) Address not available,是什么地址不可用,查了很多資料,根據(jù) POSIX(Portable Operating System Interface for UNIX)標(biāo)準(zhǔn)的錯(cuò)誤定義中找到了相關(guān)的定義,同樣說(shuō)的還不是很清楚。

錯(cuò)誤代碼參考連接:[errno.3[1]]


EADDRNOTAVAIL               
    Address not available (POSIX.1-2001).

容易被忽視的內(nèi)核參數(shù)

Cloud Native

通過(guò) netstat -an 查看到連接 svc 的地址,其中 estab 狀態(tài)的連接數(shù),已經(jīng)到達(dá)了可用的隨機(jī)端口數(shù)量閾值,無(wú)法在新建連接了。

7e51de22-3122-11ee-9e74-dac502259ad0.png


最后通過(guò)修改了內(nèi)核參數(shù)隨機(jī)端口 net.ipv4.ip_local_port_range 端口范圍才得以解決的。 我們可以知道 Linux 的內(nèi)核定義的隨機(jī)端口 32768 ~ 60999,可能在業(yè)務(wù)設(shè)計(jì)場(chǎng)景中,比較容易被忽略的,我們都知道,每一個(gè) TCP 連接都是由四元組(源 IP,源端口,目的 IP,目的端口)構(gòu)成的,只要四元組中其中一個(gè)元組發(fā)生了變化,就可以創(chuàng)建一個(gè) TCP 連接的。當(dāng)一個(gè) POD 要訪問(wèn)一個(gè)固定的目的 IP + 目的端口的時(shí)候,那么每一個(gè) TCP 連接的變量就只剩下源端口是隨機(jī)的了,所以如果在需求就是需要?jiǎng)?chuàng)建大量長(zhǎng)連接的話,要么就調(diào)大內(nèi)核隨機(jī)端口,要么就調(diào)整業(yè)務(wù)。

相關(guān)內(nèi)核參考連接:[ip-sysctl.txt[2]]



ip_local_port_range - 2 INTEGERS
  Defines the local port range that is used by TCP and UDP to
  choose the local port. The first number is the first, the
  second the last local port number.
  If possible, it is better these numbers have different parity
  (one even and one odd value).
  Must be greater than or equal to ip_unprivileged_port_start.
  The default values are 32768 and 60999 respectively.

同樣的問(wèn)題還可能出現(xiàn)什么類型的報(bào)錯(cuò)呢?

Cloud Native

手動(dòng)調(diào)小了 net.ipv4.ip_local_port_range,之后進(jìn)行復(fù)現(xiàn)。

同樣的問(wèn)題,分別嘗試了 curl,nc,wget 命令,報(bào)錯(cuò)都不一樣,這就犯難了。 難道就不能統(tǒng)一一下嗎?

curl: (7) Couldn't connect to server

nc: bind: Address in use

wget: can't connect to remote host (1.1.1.1): Address not available

7e5be836-3122-11ee-9e74-dac502259ad0.png

那么就通過(guò) strace 命令進(jìn)程分析一下看看,跟蹤指定系統(tǒng)調(diào)用名稱 它們都會(huì)創(chuàng)建 socket(), 然后發(fā)現(xiàn) wget/curl 命令是通過(guò) connect() 函數(shù),而 nc 命令先是是通過(guò) bind() 函數(shù)調(diào)用, 如果報(bào)錯(cuò)就不會(huì)繼續(xù)調(diào)用 connect() 函數(shù)了。 7e738400-3122-11ee-9e74-dac502259ad0.png

如圖,通過(guò)對(duì) B/S 架構(gòu)的分析如下,connect() 是在客戶端創(chuàng)建 socket 后建立的。


7e942dcc-3122-11ee-9e74-dac502259ad0.png

引發(fā)思考

Cloud Native

為什么 wget/curl 同樣調(diào)用的是 connect() 函數(shù)報(bào)錯(cuò)的,為何報(bào)錯(cuò)還是不一樣的?

每一個(gè)客戶端程序都會(huì)有自定義的 errorcode,在同樣的 connect() 函數(shù)報(bào)錯(cuò)后 ,wget 是直接輸出了 POSIX 標(biāo)準(zhǔn)的錯(cuò)誤定義 Address not available,而 curl 會(huì)輸出自己的定義錯(cuò)誤碼和對(duì)應(yīng)的提示信息 curl: (7) Couldn't connect to server,錯(cuò)誤代碼是 7,curl 的報(bào)錯(cuò)定義在 lib/strerror.c。

7eba84c2-3122-11ee-9e74-dac502259ad0.png7ed4c2c4-3122-11ee-9e74-dac502259ad0.png


為什么 connect() 函數(shù)和 bind() 函數(shù)報(bào)錯(cuò)不一樣?

函數(shù)不同,錯(cuò)誤的定義也就不同,從 POSIX 標(biāo)準(zhǔn)的錯(cuò)誤定義都能找到。


EADDRINUSE               
    Address already in use (POSIX.1-2001).        
EADDRNOTAVAIL               
    Address not available (POSIX.1-2001).

是不是所有情況下都是這樣輸出呢?

Cloud Native

那么直接找了一臺(tái) Centos7.9 的系統(tǒng),安裝 curl 、wget、 nc 等工具,同樣改小端口范圍的情況下會(huì)出現(xiàn)如下報(bào)錯(cuò) Cannot assign requested address,從這里可以得知某些鏡像(alpine、busybox) 里,使用相同的命令工具對(duì)相同的情況下報(bào)錯(cuò)會(huì)不同。因?yàn)檫@些鏡像里可能為了縮小整個(gè)鏡像大小,對(duì)于一些基礎(chǔ)命令都會(huì)選擇 busybox 工具箱(上面的 wget 和 nc 就來(lái)自于 busybox 工具箱里的,參考 busybox 文檔:Busybox Command Help[3])來(lái)使用,所以就造成在問(wèn)題定位方面困擾了。

Linux 系統(tǒng)中用于包含與錯(cuò)誤碼相關(guān)的定義:/usr/include/asm-generic/errno.h

7f050862-3122-11ee-9e74-dac502259ad0.png



#define  EADDRNOTAVAIL  99  /* Cannot assign requested address */

容器環(huán)境下,端口配置最佳實(shí)踐

Cloud Native

可修改范圍

理論上來(lái)是 0~65535 都能使用, 但是 0~1023 是特權(quán)端口,已經(jīng)預(yù)留給一下標(biāo)準(zhǔn)服務(wù),如 HTTP:80,SSH:22 等,只能特權(quán)用戶使用,同時(shí)也避免未授權(quán)的用戶通過(guò)流量特征攻擊等所以建議端口調(diào)大的話可以將隨機(jī)端口范圍限制在 1024-65535 之間。

如何正確配置 Pod 源端口

普通 Pod 源端口修改方法

從 kubernetes 社區(qū)得知可以通過(guò)安全上下文修改 securityContext[4],還有可以通過(guò) initContainers 容器給特權(quán)模式 mount -o remount rw /proc/sys 的方式修改,此修改方式只會(huì)在 pod 的網(wǎng)絡(luò)命名空間中生效。

securityContext


...
securityContext:
  sysctls:       
    - name: net.ipv4.ip_local_port_range           
      value: 1024 65535

initContainers


      initContainers:
        - command:
            - /bin/sh
            - '-c'
            - |
              sysctl -w net.core.somaxconn=65535
              sysctl -w net.ipv4.ip_local_port_range="1024 65535"
          securityContext:
            privileged: true
...

hostnetwork 模式 pod 修改注意事項(xiàng)

1.22+ 集群以上就不建議修改 net.ipv4.ip_local_port_range,因?yàn)檫@會(huì)和 ServiceNodePortRange 產(chǎn)生沖突。 Kubernetes 的 ServiceNodePortRange 默認(rèn)是 30000~32767,Kubernetes 1.22 及以后的版本,去除了 kube-proxy 監(jiān)聽(tīng) NodePort 的邏輯,如果有監(jiān)聽(tīng)的話,應(yīng)用程序在選用隨機(jī)端口的時(shí)候,會(huì)避開(kāi)這些監(jiān)聽(tīng)中的端口。如果 net.ipv4.ip_local_port_range 的范圍和 ServiceNodePortRange 存在重疊,由于去掉了監(jiān)聽(tīng) NodePort 的邏輯,應(yīng)用程序在選用隨機(jī)端口的時(shí)候就可能選中重疊部分,比如 30000~32767,在當(dāng) NodePort 與內(nèi)核 net.ipv4.ip_local_port_range 范圍有沖突的情況下,可能會(huì)導(dǎo)致偶發(fā)的 TCP 無(wú)法連接的情況,可能導(dǎo)致健康檢查失敗、業(yè)務(wù)訪問(wèn)異常等問(wèn)題。更多信息,請(qǐng)參見(jiàn)Kubernetes 社區(qū) PR[5]

大量創(chuàng)建 svc 的時(shí)候減少創(chuàng)建監(jiān)聽(tīng)的步驟只是提交 ipvs/iptables 規(guī)則,這樣可以優(yōu)化連接性能 。另一個(gè)就解決某些場(chǎng)景下出現(xiàn)大量的 CLOSE_WAIT 占用 TCP 連接等問(wèn)題。在 1.22 版本之后就去掉了 PortOpener 邏輯。

kubernetes/pkg/proxy/iptables/proxier.go Line 1304 in f98f27b[6]



1304        proxier.openPort(lp, replacementPortsMap)

7f1968fc-3122-11ee-9e74-dac502259ad0.png

具體是如何沖突的呢? 測(cè)試環(huán)境是 k8s 1.22.10,kube-proxy 網(wǎng)絡(luò)模式 ipvs。以 kubelet 健康檢查為例,調(diào)整了節(jié)點(diǎn)的內(nèi)核參數(shù) net.ipv4.ip_local_port_range 為1 024~65535。

7f7e21f2-3122-11ee-9e74-dac502259ad0.png

部署 tcpdump 抓包,抓到有健康檢查失敗的事件后,停止抓包。

看到 kubelet 是用節(jié)點(diǎn) IP(192.168.66.27)+隨機(jī)端口 32582 向 pod 發(fā)起了 TCP 握手 podIP(192.168.66.65)+80,但是 pod 在 TCP 握手時(shí)回 SYN ACK 給 kubelet 的時(shí)候,目標(biāo)端口是 32582,卻一直在重傳。因?yàn)檫@個(gè)隨機(jī)端口剛好是某一個(gè)服務(wù)的nodeport,所以優(yōu)先被 IPVS 攔截給規(guī)則后端的服務(wù),但這個(gè)后端服務(wù) (192.168.66.9) 并沒(méi)有發(fā)起和 podIP(192.168.66.65)TCP 建連,所以后端服務(wù) (192.168.66.9) 直接是丟棄的。那么 kubelet 就不會(huì)收到 SYN ACK 回應(yīng),TCP 無(wú)法建聯(lián),所以導(dǎo)致健康檢查失敗。 這個(gè)報(bào)文看 kubelet 發(fā)起 TCP 握手,pod 回 syn ack 的時(shí)候一直重傳。


7f9366de-3122-11ee-9e74-dac502259ad0.png


實(shí)際是發(fā)送到了 32582 這個(gè) svc 的后端 pod 了,直接是丟棄。


7fbf524e-3122-11ee-9e74-dac502259ad0.png7fd6a26e-3122-11ee-9e74-dac502259ad0.png

增加前置判斷

所以 hostnework 可以加上一個(gè)判斷,通過(guò) initContainers 容器修改的時(shí)候,如果 podIP 和 hostIP 不相等才修改 net.ipv4.ip_local_port_range 參數(shù),避免誤操作導(dǎo)致修改節(jié)點(diǎn)的內(nèi)核參數(shù)。



      initContainers:
        - command:
            - /bin/sh
            - '-c'
            - |
              if [ "$POD_IP" != "$HOST_IP" ]; then
              mount -o remount rw /proc/sys
              sysctl -w net.ipv4.ip_local_port_range="1024 65535"
              fi
          env:
            - name: POD_IP
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: status.podIP
            - name: HOST_IP
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: status.hostIP
          securityContext:
            privileged: true
...

如何正確配置 NodePort 范圍

在 Kubernetes中,APIServer 提供了 ServiceNodePortRange 參數(shù)(命令行參數(shù) --service-node-port-range),該參數(shù)是用于限制 NodePort 或 LoadBalancer 類型的 Service 在節(jié)點(diǎn)上所監(jiān)聽(tīng)的 NodePort 端口范圍,該參數(shù)默認(rèn)值為 30000~32767。在 ACK Pro 集群中,您可以通過(guò)自定義 Pro 集群的管控面參數(shù)修改該端口范圍。具體操作,請(qǐng)參見(jiàn)自定義 ACK Pro 集群的管控面參數(shù)[7]。

8003c776-3122-11ee-9e74-dac502259ad0.png


80158fd8-3122-11ee-9e74-dac502259ad0.png

在修改 NodePort 端口范圍時(shí)必須十分謹(jǐn)慎。務(wù)必保證 NodePort 端口范圍與集群節(jié)點(diǎn)上 Linux 內(nèi)核提供的 net.ipv4.ip_local_port_range 參數(shù)中的端口范圍不沖突。該內(nèi)核參數(shù) ip_local_port_range 控制了 Linux 系統(tǒng)上任意應(yīng)用程序可以使用的本地端口號(hào)范圍。ip_local_port_range 的默認(rèn)值為 32768~60999,Nodeport 默認(rèn)值為 30000~32767。

ACK 集群在默認(rèn)配置情況下,ServiceNodePortRange 參數(shù)和 ip_local_port_range 參數(shù)不會(huì)產(chǎn)生沖突。如果您此前為了提升端口數(shù)量限制調(diào)整了這兩個(gè)參數(shù)中任意一個(gè),導(dǎo)致兩者范圍出現(xiàn)重合,則可能會(huì)產(chǎn)生節(jié)點(diǎn)上的偶發(fā)網(wǎng)絡(luò)異常,嚴(yán)重時(shí)會(huì)導(dǎo)致業(yè)務(wù)健康檢查失敗、集群節(jié)點(diǎn)離線等。建議您恢復(fù)默認(rèn)值或同時(shí)調(diào)整兩個(gè)端口范圍到完全不重合。

調(diào)整端口范圍后,集群中可能存在部分 NodePort 或 LoadBalancer 類型的 Service 仍在使用 ip_local_port_range 參數(shù)端口范圍內(nèi)的端口作為 NodePort。此時(shí)您需要對(duì)這部分 Service 進(jìn)行重新配置以避免沖突,可通過(guò) kubectl edit 的方式直接將 spec.ports.nodePort 字段的值更改為未被占用的 NodePort。

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1410

    瀏覽量

    41113
  • 容器
    +關(guān)注

    關(guān)注

    0

    文章

    507

    瀏覽量

    22369
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4887

    瀏覽量

    70265
  • Address
    +關(guān)注

    關(guān)注

    0

    文章

    6

    瀏覽量

    7738

原文標(biāo)題:記一次容器環(huán)境下出現(xiàn)Address not available

文章出處:【微信號(hào):OSC開(kāi)源社區(qū),微信公眾號(hào):OSC開(kāi)源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 0人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    【freeRTOS開(kāi)發(fā)筆記】一次坑爹的freeTOS升級(jí)

    【freeRTOS開(kāi)發(fā)筆記】一次坑爹的freeTOS-v9.0.0升級(jí)到freeRTOS-v10.4.4
    的頭像 發(fā)表于 07-11 09:15 ?5153次閱讀
    【freeRTOS開(kāi)發(fā)筆記】<b class='flag-5'>記</b><b class='flag-5'>一次</b>坑爹的freeTOS升級(jí)

    使用HAProxy軟件的一次學(xué)習(xí)過(guò)程介紹

    一次學(xué)習(xí)過(guò)程
    發(fā)表于 06-13 10:48

    一次網(wǎng)站設(shè)計(jì)稿的方法

    一次網(wǎng)站設(shè)計(jì)稿
    發(fā)表于 06-16 09:43

    一次電池為什么不能被充電?

    一次電池為什么不能被充電? 一次電池不能被充電再生是構(gòu)成一次電池體系的本性所決定的,因?yàn)?b class='flag-5'>一次電池的電極反應(yīng)不可逆,也就是說(shuō),放電后的放電產(chǎn)
    發(fā)表于 10-28 15:29 ?5974次閱讀

    循環(huán)充放電一次就是少一次壽命嗎?

    循環(huán)充放電一次就是少一次壽命嗎?     循環(huán)就是使用,我們是在使用電池,關(guān)心的是使
    發(fā)表于 11-11 13:59 ?931次閱讀

    電池循環(huán)充放電一次就是少一次壽命嗎?

    電池循環(huán)充放電一次就是少一次壽命嗎? 循環(huán)就是使用,我們是在使用電池,關(guān)心的是使用的時(shí)間,為了衡量充電電池
    發(fā)表于 09-06 11:05 ?3676次閱讀

    一次CH552不識(shí)別無(wú)法下載解決辦法

    一次CH552不識(shí)別解決辦法插入鏈接與圖片如何插入段漂亮的代碼片生成個(gè)適合你的列表創(chuàng)建個(gè)表格設(shè)定內(nèi)容居中、居左、居右SmartyPa
    發(fā)表于 01-12 19:15 ?5次下載
    <b class='flag-5'>記</b><b class='flag-5'>一次</b>CH552不識(shí)別無(wú)法下載解決辦法

    電氣一次識(shí)圖基礎(chǔ)

    電氣一次識(shí)圖基礎(chǔ)
    的頭像 發(fā)表于 11-12 11:24 ?2290次閱讀

    一次消諧如何接線

    一次消諧如何接線 一次消諧器是種用于消除電力系統(tǒng)中諧波的裝置,通常需要與電容器和電抗器組合使用。在安裝一次消諧器時(shí),需要注意以下接線步驟:
    的頭像 發(fā)表于 03-22 16:50 ?2617次閱讀

    選擇一次消諧器時(shí)需要考慮的些重要標(biāo)準(zhǔn)

    器,而低電壓系統(tǒng)則更適合使用二消諧器。 2. 電容器容量:大容量電容器適用于一次消諧器,而小型電容器則更適合使用二
    的頭像 發(fā)表于 06-27 13:52 ?1126次閱讀

    一次調(diào)頻和二調(diào)頻的概念 一次調(diào)頻可以實(shí)現(xiàn)無(wú)差調(diào)節(jié)?

    一次調(diào)頻和二調(diào)頻的概念 一次調(diào)頻可以實(shí)現(xiàn)無(wú)差調(diào)節(jié)? 一次調(diào)頻和二調(diào)頻的概念 1.
    的頭像 發(fā)表于 10-17 16:15 ?1.1w次閱讀

    一次消諧裝置的種類介紹

    使用環(huán)境可以分為戶內(nèi)用和戶外用!般戶內(nèi)用的居多,如果用于戶外,采購(gòu)時(shí)需要特殊說(shuō)明! 一次消諧裝置根據(jù)電壓互感器的絕緣性能,需要分為:半絕緣一次消諧器和全絕緣
    的頭像 發(fā)表于 11-15 11:08 ?863次閱讀

    超級(jí)電容器和飛輪電池都屬于一次電池嗎

    超級(jí)電容器(也稱為超級(jí)電容或電化學(xué)電容器)和飛輪電池都是儲(chǔ)能技術(shù),但它們不屬于一次電池。
    的頭像 發(fā)表于 04-24 17:06 ?1564次閱讀

    一次消諧器的構(gòu)造

    今天來(lái)給大家介紹一下一次消諧器的構(gòu)造。 一次消諧器是種用于消除電力系統(tǒng)中的諧波及無(wú)功功率的裝置,它由感性元件和電容器構(gòu)成,感性元件用于吸收系統(tǒng)中的無(wú)功功率,而電
    的頭像 發(fā)表于 05-30 14:55 ?758次閱讀

    一次電池分類以及應(yīng)用場(chǎng)景詳解

    01 一次電池簡(jiǎn)介 一次電池即原電池(primarycell、primarybattery)(俗稱干電池),是放電后不能再充電使其復(fù)原的電池,通電電池有正極、負(fù)極電解以及容器和隔膜等組成。
    的頭像 發(fā)表于 09-30 17:52 ?2448次閱讀
    <b class='flag-5'>一次</b>電池分類以及應(yīng)用場(chǎng)景詳解

    電子發(fā)燒友

    中國(guó)電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會(huì)員交流學(xué)習(xí)
    • 獲取您個(gè)性化的科技前沿技術(shù)信息
    • 參加活動(dòng)獲取豐厚的禮品