排解 VM 之間的內部連線問題
不論 Compute Engine VM 位於同一個虛擬私有雲 (VPC) 網路 (共用虛擬私有雲或獨立虛擬私有雲),或是透過虛擬私有雲網路對等互連的兩個虛擬私有雲網路,本文會分別針對這些 VM 之間的連線問題提供疑難排解步驟。我們假設 VM 會分別使用其虛擬網路介面控制器 (vNIC) 的內部 IP 位址進行通訊。
本指南中的步驟適用於 Compute Engine VM 和 Google Kubernetes Engine 節點。
如要查看其他特定疑難排解情境,請按一下頁面底部的「提供意見回饋」連結,並告訴我們。
本指南適用的 VM 和 VPC 設定如下:
- 在單一 VPC 網路中,使用內部 IP 位址的 VM 到 VM 連線。
- 在共用虛擬私有雲網路中,使用內部 IP 位址的 VM 對 VM 連線。
- 使用虛擬私有雲網路對等互連功能,在不同虛擬私有雲網路中使用內部 IP 位址的 VM 對 VM 連線。
本指南中使用的指令適用於所有 Google 提供的 OS 映像檔。如果您使用的是自有的 OS 映像檔,可能需要安裝工具。
量化問題
- 如果您認為自己遇到封包完全遺失的情況,請參閱排解完全連線失敗問題。
- 如果您遇到延遲、部分封包遺失,或是連線中斷的逾時問題,請參閱這篇文章,瞭解如何排解造成處理量問題的網路延遲或遺失問題。
排解連線失敗問題
以下各節提供 VM 之間完全內部連線失敗問題的疑難排解步驟。如果您遇到的是延遲時間增加或連線逾時情形,請跳至排解網路延遲或損失問題,導致處理量降低。
判斷連線值
首先,請收集下列資訊:
- 在「VM instances」(VM 執行個體) 頁面中,為兩個 VM 收集下列資訊:
- VM 名稱
- VM 區域
- 進行通訊的 vNIC 內部 IP 位址
從目的地伺服器軟體的設定中收集下列資訊:
- 第 4 層通訊協定
- 目的地通訊埠
舉例來說,如果目的地是 HTTPS 伺服器,通訊協定為 TCP,通訊埠通常為
443
,但您的特定設定可能會使用其他通訊埠。
如果您在多個 VM 上遇到問題,請選取發生問題的單一來源和單一目的地 VM,並使用這些值。一般來說,您不需要連線的來源連接埠。
取得這項資訊後,請繼續調查底層 Google 網路的問題。
調查底層 Google 網路的問題
如果您使用的設定是最近未變更的現有設定,問題可能出在基礎 Google 網路。請查看 Network Intelligence Center 效能資訊主頁,瞭解 VM 可用區之間的封包遺失情況。如果在發生網路逾時期間,區域之間的封包遺失率增加,可能表示虛擬網路底層的實體網路有問題。在提交支援案件前,請先查看 Google Cloud 狀態資訊主頁,瞭解是否有已知問題。
如果問題似乎不是底層 Google 網路的問題,請繼續檢查防火牆規則是否設定錯誤 Google Cloud 。
檢查 Google Cloud中的防火牆規則是否設定錯誤
連線測試會分析兩個 VM 之間的 VPC 網路路徑設定,並顯示程式設計的設定是否「應」允許流量。如果系統不允許流量,結果會顯示 Google Cloud 輸出或輸入防火牆規則是否封鎖流量,或是是否沒有可用的路徑。
連線測試也可能會透過在 VM 的虛擬機器管理程序之間傳送封包,動態測試路徑。如果執行這些測試,系統會顯示這些測試的結果。
連線測試只會檢查 VPC 網路的設定。不會測試作業系統防火牆或作業系統路徑,也不會測試 VM 上的伺服器軟體。
以下程序說明如何從Google Cloud 主控台執行連線測試。如要瞭解其他執行測試的方式,請參閱「執行連線測試」。
請按照下列程序建立及執行測試:
前往 Google Cloud 控制台的「Connectivity Tests」頁面。
在專案下拉式選單中,確認您位於正確的專案中,或指定正確的專案。
按一下「建立連線能力測試」。
為測試命名。
指定下列屬性:
- 通訊協定
- 來源端點 IP 位址
- 來源專案和虛擬私有雲網路
- 目的地端點 IP 位址
- 目的地專案和 VPC 網路
- 目的地通訊埠
按一下 [建立]。
測試會立即執行。如要查看結果圖表,請在「結果詳細資料」欄中按一下「查看」。
- 如果結果指出連線遭到 Google Cloud防火牆規則捨棄,請判斷所需的安全性設定是否應允許連線。您可能需要向安全性或網路管理員詢問詳細資訊。如果應允許流量,請檢查下列項目:
- 查看「一律封鎖的流量」清單。如果流量遭到 Google Cloud 封鎖 (如一律封鎖的流量清單所述),現有設定就無法運作。
- 前往「防火牆政策」頁面查看防火牆規則。如果防火牆設定錯誤,請建立或修改防火牆規則,允許連線。這個規則可以是 VPC 防火牆規則或階層防火牆政策規則。
- 如果有正確設定的防火牆規則會封鎖這類流量,請洽詢安全性或網路管理員。如果貴機構的安全性規定指出 VM 不應相互連線,您可能需要重新設計設定。
- 如果結果顯示 VPC 連線路徑沒有問題,問題可能出在下列任一項目:
- 訪客作業系統設定問題,例如防火牆軟體問題。
- 用戶端或伺服器應用程式的問題,例如應用程式凍結或設定為監聽錯誤的通訊埠。
後續步驟將逐步引導您檢查這些可能性。接著,請參閱「從 VM 內部測試 TCP 連線」一文。
從 VM 內部測試 TCP 連線
如果 VM-VM 連線能力測試未偵測到 VPC 設定問題,請開始測試 OS-OS 連線能力。您可以透過下列步驟判斷以下事項:
- 如果 TCP 伺服器正在監聽指定的通訊埠
- 伺服器端防火牆軟體是否允許從用戶端 VM 連線至該通訊埠
- 用戶端防火牆軟體是否允許連線至伺服器上的該通訊埠
- 確認伺服器端路由表已正確設定,可轉送封包
- 是否已正確設定用戶端路由表格,以便轉送封包
您可以使用 Linux 或 Windows 2019 搭配 curl
測試 TCP 握手,也可以使用 Windows PowerShell 搭配 New-Object System.Net.Sockets.TcpClient
指令進行測試。本節的工作流程應會產生下列任一結果:連線成功、連線逾時或連線重設。
- 成功:如果 TCP 握手動作順利完成,表示作業系統防火牆規則並未封鎖連線,作業系統會正確轉送封包,且某種伺服器會在目的地連接埠上進行偵聽。如果是這種情況,問題可能出在應用程式本身。如要確認,請參閱「檢查伺服器記錄,瞭解伺服器行為資訊」。
- 逾時:如果連線逾時,通常表示發生下列其中一種情況:
- 該 IP 位址沒有機器
- 某處有防火牆會悄悄丟棄您的封包
- OS 封包路由會將封包傳送至無法處理的目的地,或是不對稱路由會將回傳封包傳送至無效路徑
重設:如果連線正在重設,表示目的地 IP 會收到封包,但作業系統或應用程式會拒絕封包。這可能表示下列任一情況:
- 封包傳送至錯誤的機器,且未設定為回應該通訊埠上的該通訊協定
- 封包已抵達正確的機器,但沒有伺服器在該通訊埠上聆聽
- 封包已抵達正確的機器和通訊埠,但較高層級的通訊協定 (例如 SSL) 無法完成握手程序
- 防火牆正在重設連線。這比防火牆靜默捨棄封包的機率低,但仍有可能發生。
Linux
在 Google Cloud 控制台中,前往「Firewall policies」(防火牆政策) 頁面。
請確認有防火牆規則,允許從 IAP 連線至 VM 的 SSH 連線,或建立新的防火牆規則。
前往 Google Cloud 控制台的「VM instances」(VM 執行個體) 頁面。
找出來源 VM。
在該 VM 的「連線」欄中,按一下「SSH」。
在用戶端機器的指令列上執行下列指令。將 DEST_IP:DEST_PORT 替換為目的地 IP 位址和通訊埠。
curl -vso /dev/null --connect-timeout 5 DEST_IP:DEST_PORT
Windows
前往 Google Cloud 控制台的「VM instances」(VM 執行個體) 頁面。
找出來源 VM。
請使用「連線至 Windows VM」一文所述的方法之一,連線至 VM。
在用戶端機器的指令列上執行下列指令:
- Windows 2019:
curl -vso /dev/null --connect-timeout 5 DEST_IP:DEST_PORT
- Windows 2012 或 Windows 2016 Powershell:
PS C:> New-Object System.Net.Sockets.TcpClient('DEST_IP',DEST_PORT)`
- Windows 2019:
連線成功
以下結果表示 TCP 握手成功。如果 TCP 握手完成,則問題與 TCP 連線逾時或重設無關。而是發生在應用程式層級。如果連線成功,請繼續查看伺服器記錄,瞭解伺服器行為相關資訊。
Linux 和 Windows 2019
$ curl -vso /dev/null --connect-timeout 5 192.168.0.4:443
「Connected to」行表示 TCP 握手成功。
Expire in 0 ms for 6 (transfer 0x558b3289ffb0) Expire in 5000 ms for 2 (transfer 0x558b3289ffb0) Trying 192.168.0.4... TCP_NODELAY set Expire in 200 ms for 4 (transfer 0x558b3289ffb0) Connected to 192.168.0.4 (192.168.0.4) port 443 (#0) > GET / HTTP/1.1 > Host: 192.168.0.4:443 > User-Agent: curl/7.64.0 > Accept: */* > Empty reply from server Connection #0 to host 192.168.0.4 left intact
Windows 2012 和 2016
PS C:\> New-Object System.Net.Sockets.TcpClient('DEST_IP_ADDRESS', PORT)
連線成功結果。「Connected: True」這行就很重要。
Available : 0 Client : System.Net.Sockets.Socket Connected : True ExclusiveAddressUse : False ReceiveBufferSize : 131072 SendBufferSize : 131072 ReceiveTimeout : 0 SendTimeout : 0 LingerState : System.Net.Sockets.LingerOption NoDelay : False
連線逾時
以下結果表示連線已逾時。如果連線逾時,請繼續驗證伺服器 IP 位址和通訊埠。
Linux 和 Windows 2019
$ curl -vso /dev/null --connect-timeout 5 DEST_IP_ADDRESS:PORT
連線逾時結果:
Trying 192.168.0.4:443... Connection timed out after 5000 milliseconds Closing connection 0
Windows 2012 和 2016
PS C:\> New-Object System.Net.Sockets.TcpClient('DEST_IP_ADDRESS', PORT)
連線逾時結果:
New-Object: Exception calling ".ctor" with "2" argument(s): "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. 192.168.0.4:443"
重設連線
重設是指裝置將 RST 封包傳回用戶端,通知用戶端連線已終止。連線可能會因下列其中一個原因而重設:
- 接收伺服器未設定為接受該通訊埠的該通訊協定連線。這可能是因為封包傳送至錯誤的伺服器或通訊埠,或是伺服器軟體設定錯誤。
- 防火牆軟體拒絕連線
如果連線已重設,請繼續確認您存取的是正確的 IP 位址和通訊埠。
Linux 和 Windows 2019
$ curl -vso /dev/null --connect-timeout 5 DEST_IP_ADDRESS:PORT
連線重設結果:
Trying 192.168.0.4:443... connect to 192.168.0.4 port 443 failed: Connection refused Failed to connect to 192.168.0.4 port 443: Connection refused Closing connection 0
Windows 2012 和 2016
PS C:\> New-Object System.Net.Sockets.TcpClientt('DEST_IP_ADDRESS', PORT)
連線重設結果:
New-Object: Exception calling ".ctor" with "2" argument(s): "No connection could be made because the target machine actively refused it. 192.168.0.4:443"
驗證伺服器 IP 位址和通訊埠
在伺服器上執行下列任一指令。這些值會指出是否有伺服器在必要的連接埠上待命。
Linux
$ sudo netstat -ltuvnp
輸出內容顯示 TCP 伺服器會在通訊埠 22 上監聽任何目的地 IP 位址 (0.0.0.0
),並接受來自任何來源位址 (0.0.0.0
) 和任何來源通訊埠 (*
) 的連線。PID/程式名稱資料欄會指定與 Socket 繫結的可執行檔。
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 588/sshd tcp6 0 0 :::22 :::* LISTEN 588/sshd udp 0 0 0.0.0.0:68 0.0.0.0:* 334/dhclient udp 0 0 127.0.0.1:323 0.0.0.0:* 429/chronyd udp6 0 0 ::1:323 :::* 429/chronyd
Windows
PS C:\> Get-NetTcpConnection -State "LISTEN" -LocalPort DEST_PORT
輸出內容會顯示指令執行結果,其中 DEST_PORT 設為 443
。這份輸出內容顯示 TCP 伺服器會在 443
通訊埠上監聽任何位址 (0.0.0.0
),接受來自任何來源位址 (0.0.0.0
) 和任何來源通訊埠 (0
) 的連線。OwningProcess 欄位則代表監聽 Socket 的程序程序 ID。
LocalAddress LocalPort RemoteAddress RemotePort State AppliedSetting OwningProcess ------------ --------- ------------- ---------- ----- -------------- ------------- :: 443 :: 0 Listen 928 0.0.0.0 443 0.0.0.0 0 Listen 928
如果您發現伺服器未繫結至正確的連接埠或 IP,或是遠端前置字串與您的用戶端不符,請參閱伺服器的說明文件或洽詢供應商,以解決問題。伺服器必須繫結至特定介面的 IP 位址或 0.0.0.0
,且必須接受來自正確用戶端 IP 前置字或 0.0.0.0
的連線。
如果應用程式伺服器已繫結至正確的 IP 位址和連接埠,則可能是用戶端存取錯誤的連接埠、較高層級的通訊協定 (通常是 TLS) 主動拒絕連線,或是防火牆拒絕連線。
確認用戶端和伺服器使用相同的 TLS 版本和加密格式。
請確認您的用戶端是否存取正確的通訊埠。
如果上述步驟無法解決問題,請繼續檢查用戶端和伺服器上的防火牆是否有封包捨棄問題。
檢查用戶端和伺服器上的防火牆是否遺失封包
如果用戶端 VM 無法連線至伺服器,但伺服器正在監聽正確的通訊埠,則其中一個 VM 可能正在執行防火牆軟體,該軟體會捨棄與連線相關聯的封包。使用下列指令,檢查用戶端和伺服器 VM 上的防火牆。
如果有規則封鎖流量,您可以更新防火牆軟體,允許流量。如果您要更新防火牆,請在準備和執行指令時小心謹慎,因為防火牆設定錯誤可能會封鎖非預期的流量。建議您先設定 VM 序列控制台存取權,再繼續操作。
Linux iptables
檢查封包計數,瞭解每個已安裝的 iptables 鏈結和規則處理的封包數量。將來源和目的地 IP 位址和通訊埠與 iptables 規則指定的前置字串和通訊埠進行比較,判斷要比對哪些 DROP 規則。
如果相符的規則顯示連線逾時時的捨棄次數增加,請參閱 iptables 說明文件,將正確的 allow
規則套用至適當的連線。
$ sudo iptables -L -n -v -x
這個範例的 INPUT 鏈結顯示,從任何 IP 位址到任何 IP 位址的封包,如果使用目的地 TCP 通訊埠 5000
,就會在防火牆中遭到捨棄。「pkts」欄指出規則已捨棄 10342 個封包。做為測試,如果您建立的連線遭到這項規則捨棄,您會看到 pkts 計數器增加,確認行為。
Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 10342 2078513 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:5000
您可以使用下列指令,在 iptables 中新增輸入或輸出規則:
輸入規則:
$ sudo iptables -A INPUT -p tcp -s SOURCE_IP_PREFIX --dport SERVER_PORT -j ACCEPT
輸出規則:
$ sudo iptables -A OUTPUT -p tcp -d DEST_IP_PREFIX --dport DEST_PORT -j ACCEPT
Windows 防火牆
請在 Windows 防火牆中確認連線是否允許從用戶端傳出,並輸入至伺服器。如果有規則封鎖流量,請在 Windows 防火牆中進行必要修正,允許連線。您也可以啟用 Windows 防火牆記錄功能。
Windows 防火牆的預設 DENY 行為是將遭拒絕的封包靜默捨棄,導致逾時。
這項指令會檢查伺服器。如要檢查用戶端 VM 上的輸出規則,請將 -match
值變更為 Outbound
。
PS C:\> Get-NetFirewallPortFilter | `
>> Where-Object LocalPort -match "PORT" | `
>> Get-NetFirewallRule | `
>> Where-Object {$_.Direction -match "Inbound" -and $_.Profile -match "Any"}
Name : {80D79988-C7A5-4391-902D-382369B4E4A3} DisplayName : iperf3 udp Description : DisplayGroup : Group : Enabled : True Profile : Any Platform : {} Direction : Inbound Action : Allow EdgeTraversalPolicy : Block LooseSourceMapping : False LocalOnlyMapping : False Owner : PrimaryStatus : OK Status : The rule was parsed successfully from the store. (65536) EnforcementStatus : NotApplicable PolicyStoreSource : PersistentStore PolicyStoreSourceType : Local
您可以使用下列指令,為 Windows 新增防火牆規則。
輸出規則:
PS C:\> netsh advfirewall firewall add rule name="My Firewall Rule" dir=out action=allow protocol=TCP remoteport=DEST_PORT
輸入規則:
PS C:\> netsh advfirewall firewall add rule name="My Firewall Rule" dir=in action=allow protocol=TCP localport=PORT
第三方軟體
第三方應用程式防火牆或防毒軟體也可能會中斷或拒絕連線。請參閱供應商提供的說明文件。
如果發現防火牆規則有問題並且已修正,請重新測試連線情形。如果問題並非出在防火牆規則,請繼續檢查 OS 路由設定。
檢查 OS 轉送設定
作業系統路由問題可能來自下列其中一種情況:
- 由於路由複雜度增加,因此 VM 最常發生路由問題
- 在 Google Cloud 中使用單一網路介面建立的 VM 上,只有在有人手動修改預設路由表時,才會發生路由問題
- 在從內部部署遷移的 VM 上,VM 可能會保留內部部署所需的路由或 MTU 設定,但這會導致 VPC 網路發生問題
如果您使用的是具備多個網路介面的 VM,則必須設定路由,才能將資料傳送至正確的 vNIC 和子網路。舉例來說,VM 可能會設定路由,將內部子網路的流量傳送至一個 vNIC,但預設閘道 (目的地 0.0.0.0/0
) 則設在另一個具有外部 IP 位址或 Cloud NAT 存取權的 vNIC 上。
您可以逐一檢查個別路徑,或查看整個 VM 路由表,以便查看路徑。如果上述兩種方法都顯示了路由表的問題,請參閱「視需要更新路由表」中的步驟。
查看所有路線
列出所有路徑,瞭解 VM 上已有哪些路徑。
Linux
$ ip route show table all
default via 10.3.0.1 dev ens4 10.3.0.1 dev ens4 scope link local 10.3.0.19 dev ens4 table local proto kernel scope host src 10.3.0.19 broadcast 10.3.0.19 dev ens4 table local proto kernel scope link src 10.3.0.19 broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1 local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1 local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1 broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1 ::1 dev lo proto kernel metric 256 pref medium fe80::/64 dev ens4 proto kernel metric 256 pref medium local ::1 dev lo table local proto kernel metric 0 pref medium local fe80::4001:aff:fe03:13 dev ens4 table local proto kernel metric 0 pref medium multicast ff00::/8 dev ens4 table local proto kernel metric 256 pref medium
Windows
PS C:\> Get-NetRoute
ifIndex DestinationPrefix NextHop RouteMetric ifMetric PolicyStore ------- ----------------- ------- ----------- -------- ----------- 4 255.255.255.255/32 0.0.0.0 256 5 ActiveStore 1 255.255.255.255/32 0.0.0.0 256 75 ActiveStore 4 224.0.0.0/4 0.0.0.0 256 5 ActiveStore 1 224.0.0.0/4 0.0.0.0 256 75 ActiveStore 4 169.254.169.254/32 0.0.0.0 1 5 ActiveStore 1 127.255.255.255/32 0.0.0.0 256 75 ActiveStore 1 127.0.0.1/32 0.0.0.0 256 75 ActiveStore 1 127.0.0.0/8 0.0.0.0 256 75 ActiveStore 4 10.3.0.255/32 0.0.0.0 256 5 ActiveStore 4 10.3.0.31/32 0.0.0.0 256 5 ActiveStore 4 10.3.0.1/32 0.0.0.0 1 5 ActiveStore 4 10.3.0.0/24 0.0.0.0 256 5 ActiveStore 4 0.0.0.0/0 10.3.0.1 0 5 ActiveStore 4 ff00::/8 :: 256 5 ActiveStore 1 ff00::/8 :: 256 75 ActiveStore 4 fe80::b991:6a71:ca62:f23f/128 :: 256 5 ActiveStore 4 fe80::/64 :: 256 5 ActiveStore 1 ::1/128 :: 256 75 ActiveStore
查看個別路線
如果問題似乎出在特定 IP 前置字串,請檢查用戶端和伺服器 VM 中是否有適當的來源和目的地 IP 路徑。
Linux
$ ip route get DEST_IP
良好結果:
系統會顯示有效路線。在這種情況下,封包會從介面 ens4
傳出。
10.3.0.34 via 10.3.0.1 dev ens4 src 10.3.0.26 uid 1000 cache
錯誤結果:
這項結果證實封包會遭到捨棄,因為沒有通往目的地網路的路徑。確認路由表包含正確的出口介面路徑。
**RTNETLINK answers: Network is unreachable
Windows
PS C:\> Find-NetRoute -RemoteIpAddress "DEST_IP"
良好結果:
IPAddress : 192.168.0.2 InterfaceIndex : 4 InterfaceAlias : Ethernet AddressFamily : IPv4 Type : Unicast PrefixLength : 24 PrefixOrigin : Dhcp SuffixOrigin : Dhcp AddressState : Preferred ValidLifetime : 12:53:13 PreferredLifetime : 12:53:13 SkipAsSource : False PolicyStore : ActiveStore Caption : Description : ElementName : InstanceID : ;:8=8:8:9<>55>55:8:8:8:55; AdminDistance : DestinationAddress : IsStatic : RouteMetric : 256 TypeOfRoute : 3 AddressFamily : IPv4 CompartmentId : 1 DestinationPrefix : 192.168.0.0/24 InterfaceAlias : Ethernet InterfaceIndex : 4 InterfaceMetric : 5 NextHop : 0.0.0.0 PreferredLifetime : 10675199.02:48:05.4775807 Protocol : Local Publish : No State : Alive Store : ActiveStore ValidLifetime : 10675199.02:48:05.4775807 PSComputerName : ifIndex : 4
錯誤結果:
Find-NetRoute : The network location cannot be reached. For information about network troubleshooting, see Windows Help.
At line:1 char:1
+ Find-NetRoute -RemoteIpAddress "192.168.0.4"
+ ----------------------------------------
+ CategoryInfo : NotSpecified: (MSFT_NetRoute:ROOT/StandardCimv2/MSFT_NetRoute) [Find-NetRoute], CimException
+ FullyQualifiedErrorId : Windows System Error 1231,Find-NetRoute
這個指令可確認封包會遭到捨棄,因為沒有通往目的地 IP 位址的路徑。確認您有預設閘道,且閘道已套用至正確的 vNIC 和網路。
更新路徑資料表
如有需要,您可以將路徑新增至作業系統的路由表。建議您先熟悉指令,並瞭解可能的影響,再執行指令來更新路由 VM 的路由表。使用路徑更新指令的方式不當,可能會導致 VM 發生非預期問題或連線中斷。建議您先設定 VM 序列控制台存取權,再繼續操作。
如需更新路徑的操作說明,請參閱作業系統的說明文件。
如果發現路徑有問題並且已修正,請重新測試連線。如果路由不是問題所在,請繼續進行檢查介面 MTU。
檢查 MTU
VM 的介面 MTU 應與其所連結的 VPC 網路 MTU 相符。理想情況下,彼此通訊的 VM 也應具有相符的 MTU。MTU 不相符通常不會對 TCP 造成影響,但可能會對 UDP 造成影響。
檢查 VPC 的 MTU。如果 VM 位於兩個不同的網路中,請檢查兩個網路。
gcloud compute networks describe NET_NAME --format="table(name,mtu)"
檢查用戶端和伺服器網路介面的 MTU 設定。
Linux
$ netstat -i
lo (loopback) 介面的 MTU 一律為 65536,因此可在這個步驟中忽略。
Kernel Interface table Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg ens4 1460 8720854 0 0 0 18270406 0 0 0 BMRU lo 65536 53 0 0 0 53 0 0 0 LRU
Windows
PS C:\> Get-NetIpInterface
迴送假設介面一律會使用 4294967295 的 MTU,因此可在這個步驟中忽略。
ifIndex InterfaceAlias Address NlMtu(Bytes) Interface Dhcp Connection PolicyStore Family Metric State ------- -------------- ------- ------------ --------- ---- ---------- ----------- 4 Ethernet IPv6 1500 5 Enabled Connected ActiveStore 1 Loopback Pseudo-Interface 1 IPv6 4294967295 75 Disabled Connected ActiveStore 4 Ethernet IPv4 1460 5 Enabled Connected ActiveStore 1 Loopback Pseudo-Interface 1 IPv4 4294967295 75 Disabled Connected Active
如果介面和網路 MTU 不相符,您可以重新設定介面 MTU。詳情請參閱「VM 和 MTU 設定」。如果兩者相符,且您已按照上述步驟排解問題,那麼問題很可能是出在伺服器本身。如需伺服器問題疑難排解指南,請參閱「查看伺服器記錄,瞭解伺服器行為」一文。
查看伺服器記錄,瞭解伺服器行為
如果上述步驟無法解決問題,應用程式可能會導致逾時。檢查伺服器和應用程式記錄,找出可解釋您所見行為的行為。
要檢查的記錄來源:
- VM 的 Cloud Logging
- VM 序列記錄
- Linux syslog 和 kern.log,或 Windows 事件檢視器
如果問題仍未解決
如果問題仍未解決,請參閱「取得支援」一節,瞭解後續步驟。您可以將先前疑難排解步驟的輸出內容提供給其他協作者,這麼做非常實用。
排解造成總處理量問題的網路延遲或資料遺失問題
網路延遲或遺失問題通常是因為 VM 或網路路徑中的資源耗盡或瓶頸。有時網路中斷可能會導致連線逾時。例如 vCPU 耗盡或 vNIC 飽和,導致延遲時間增加和封包遺失,進而降低網路效能。
下列操作說明假設連線並未持續逾時,而是您發現容量或效能受限的問題。如果您發現封包完全遺失,請參閱「排解完全連線失敗問題」。
延遲時間的變化幅度如果很小,例如延遲時間變化幅度只有幾毫秒,這都是正常現象。延遲時間會因網路負載或 VM 內的排隊情形而異。
判斷連線值
首先,請收集下列資訊:
- 在「VM instances」(VM 執行個體) 頁面中,為兩個 VM 收集下列資訊:
- VM 名稱
- VM 區域
- 進行通訊的 vNIC 內部 IP 位址
- 從目的地伺服器軟體的設定中收集下列資訊:
- 第 4 層通訊協定
- 目的地通訊埠
如果您在多個 VM 上遇到問題,請選取發生問題的單一來源和單一目的地 VM,並使用這些值。一般來說,您不需要連線的來源連接埠。
取得這項資訊後,請繼續調查底層 Google 網路的問題。
調查底層 Google 網路的問題
如果您使用的設定是最近未變更的現有設定,問題可能出在基礎 Google 網路。請查看 Network Intelligence Center 效能資訊主頁,瞭解 VM 可用區之間的封包遺失情況。如果在發生網路逾時期間,區域之間的封包遺失率增加,可能表示虛擬網路底層的實體網路有問題。在提交支援案件前,請先查看 Google Cloud 狀態資訊主頁,瞭解是否有已知問題。
如果問題似乎不是底層 Google 網路的問題,請繼續檢查握手延遲。
檢查握手延遲時間
所有以連線為基礎的通訊協定在進行連線設定握手時,都會產生一些延遲。每個通訊協定握手都會增加負擔。舉例來說,在 SSL/TLS 連線中,TCP 交握必須先完成,SSL/TLS 交握才能開始,接著 TLS 交握也必須完成,才能傳輸資料。
同區域的握手延遲時間通常可以忽略不計,但與全球其他地區的握手可能會在連線啟動時造成更長的延遲。 Google Cloud 如果您在遠端地區有資源,可以檢查是否因協定握手而導致延遲。
Linux 和 Windows 2019
$ curl -o /dev/null -Lvs -w 'tcp_handshake: %{time_connect}s, application_handshake: %{time_appconnect}s' DEST_IP:PORT
tcp_handshake: 0.035489s, application_handshake: 0.051321s
- tcp_handshake 是指從用戶端傳送初始 SYN 封包到用戶端傳送 TCP 握手確認訊息的時間長度。
- application_handshake 是指從 TCP 握手的首個 SYN 封包到 TLS (通常) 握手完成的時間。
- 額外握手時間 = application_handshake - tcp_handshake
Windows 2012 和 2016
不適用於預設 OS 工具。如果防火牆規則允許,您可以使用 ICMP 往返時間做為參考。
如果延遲時間超過握手所需時間,請繼續參閱決定 VM 類型的最大總處理量。
判斷 VM 類型的最大處理量
VM 網路輸出總處理量受限於 VM CPU 架構和 vCPU 數量。請參閱「網路頻寬」頁面,判斷 VM 的潛在傳出頻寬。
如果 VM 無法滿足傳出要求,請考慮升級至容量較大的 VM。如需操作說明,請參閱「變更執行個體的機器類型」。
如果機器類型應允許足夠的傳出頻寬,請調查永久磁碟用量是否會干擾網路傳出。永久磁碟作業最多可占 VM 總網路傳輸量的 60%。如要判斷永久磁碟作業是否可能干擾網路傳輸量,請參閱「檢查永久磁碟效能」。
虛擬機器人網路入口不會受到虛擬私有雲網路或 VM 執行個體類型的限制。而是由 VM 作業系統或應用程式的封包佇列和處理效能決定。如果外送頻寬足夠,但您遇到入站問題,請參閱檢查伺服器記錄,瞭解伺服器行為相關資訊。
檢查介面 MTU
您可以設定虛擬私有雲網路的 MTU。VM 上介面的 MTU 應與所連結虛擬私有雲網路的 MTU 值相符。在虛擬私有雲網路對等互連的情況下,不同網路中的 VM 可以有不同的 MTU。發生這種情況時,請將較小的 MTU 值套用至相關聯介面。MTU 不相符通常不會對 TCP 造成影響,但可能會對 UDP 造成影響。
檢查 VPC 的 MTU。如果 VM 位於兩個不同的網路中,請檢查兩個網路。
gcloud compute networks describe NET_NAME --format="table(name,mtu)"
檢查網路介面的 MTU 設定。
Linux
lo (迴圈) 介面一律會設為 65536 的 MTU,因此可在這個步驟中忽略。
$ netstat -i
Kernel Interface table Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg ens4 1460 8720854 0 0 0 18270406 0 0 0 BMRU lo 65536 53 0 0 0 53 0 0 0 LRU
Windows
PS C:\> Get-NetIpInterface
迴送假裝介面一律會設為 4294967295,因此可在這個步驟中忽略。
ifIndex InterfaceAlias Address NlMtu(Bytes) Interface Dhcp Connection PolicyStore Family Metric State ------- -------------- ------- ------------ --------- ---- ---------- ----------- 4 Ethernet IPv6 1500 5 Enabled Connected ActiveStore 1 Loopback Pseudo-Interface 1 IPv6 4294967295 75 Disabled Connected ActiveStore 4 Ethernet IPv4 1460 5 Enabled Connected ActiveStore 1 Loopback Pseudo-Interface 1 IPv4 4294967295 75 Disabled Connected Active
如果介面和網路 MTU 不相符,您可以重新設定介面 MTU。如需更新 Windows VM MTU 的操作說明,請參閱「VM 和 MTU 設定」。如果相符,問題可能出在伺服器可用性。接下來,請檢查記錄,查看 VM 是否重新啟動、停止或即時遷移,瞭解 VM 在相關時間內是否發生任何問題。
檢查記錄,瞭解 VM 是否已重新啟動、停止或即時遷移
在 VM 的生命週期中,使用者可以重新啟動 VM,為Google Cloud 維護作業進行即時遷移,或是在極少數情況下,如果含有 VM 的實體主機發生故障,VM 可能會遺失並重新建立。這些事件可能會導致延遲時間或連線逾時時間暫時增加。如果 VM 發生上述任一情況,系統就會記錄事件。
如要查看 VM 的記錄,請按照下列步驟操作:
在 Google Cloud 控制台中,前往「Logging」頁面。
選擇發生延遲的時間範圍。
使用下列記錄查詢,判斷是否在延遲發生的時間範圍內發生 VM 事件:
resource.labels.instance_id:"INSTANCE_NAME" resource.type="gce_instance" ( protoPayload.methodName:"compute.instances.hostError" OR protoPayload.methodName:"compute.instances.OnHostMaintenance" OR protoPayload.methodName:"compute.instances.migrateOnHostMaintenance" OR protoPayload.methodName:"compute.instances.terminateOnHostMaintenance" OR protoPayload.methodName:"compute.instances.stop" OR protoPayload.methodName:"compute.instances.reset" OR protoPayload.methodName:"compute.instances.automaticRestart" OR protoPayload.methodName:"compute.instances.guestTerminate" OR protoPayload.methodName:"compute.instances.instanceManagerHaltForRestart" OR protoPayload.methodName:"compute.instances.preempted" )
如果 VM 未在相關時間內重新啟動或遷移,問題可能出在資源耗盡。如要確認,請繼續參閱檢查網路和 OS 統計資料,瞭解是否因資源耗盡而遺失封包。
檢查網路和作業系統統計資料,找出因資源耗盡而遺棄的封包
「資源耗盡」是個一般術語,指的是 VM 上的某些資源 (例如傳出頻寬) 處理能力不足。資源耗盡可能導致封包定期捨棄,進而造成連線延遲或逾時。這些逾時情形可能不會在用戶端或伺服器啟動時顯示,但隨著系統耗盡資源,可能會隨時間出現。
以下列出可顯示封包計數器和統計資料的指令。其中一些指令會重複其他指令的結果。在這種情況下,您可以使用最適合自己的指令。請參閱各個部分的附註,進一步瞭解執行指令的預期結果。建議您在不同時間執行指令,看看是否會在問題發生時出現棄用或錯誤。
Linux
使用
netstat
指令查看網路統計資料。$ netstat -s
TcpExt: 341976 packets pruned from receive queue because of socket buffer overrun 6 ICMP packets dropped because they were out-of-window 45675 TCP sockets finished time wait in fast timer 3380 packets rejected in established connections because of timestamp 50065 delayed acks sent
netstat 指令會輸出網路統計資料,其中包含依據通訊協定計算的封包丟棄值。封包遭到捨棄,可能是應用程式或網路介面資源耗盡的結果。查看計數器原因,瞭解計數器為何增加。
檢查 kern.log 是否有與
nf_conntrack: table full, dropping packet
相符的記錄。Debian:
cat /var/log/kern.log | grep "dropping packet"
CentOS:
sudo cat /var/log/dmesg | grep "dropping packet"
這個記錄表示 VM 的連線追蹤表已達到可追蹤的連線數量上限。往後與這個 VM 的連線可能會逾時。如果已啟用 conntrack,您可以使用以下命令找出連線數量上限:
sudo sysctl net.netfilter.nf_conntrack_max
您可以修改 sysctl
net.netfilter.nf_conntrack_max
,或將 VM 工作負載分散至多個 VM 以減輕負載,藉此提高追蹤連線數量上限的值。
Windows UI
Perfmon
- 使用 Windows 選單搜尋「perfmon」,然後開啟該程式。
- 在左選單中依序選取「成效」>「監控工具」>「成效監控」。
- 在主檢視畫面中,按一下綠色加號「+」,即可在監控圖表中新增效能計數器。以下是您需要留意的計數器:
- 網路介面卡
- 輸出佇列長度
- 傳出封包遭到捨棄
- 封包傳出錯誤
- 已接收但遭捨棄的封包
- 已接收封包錯誤
- 已接收的封包數不明
- 網路介面
- 輸出佇列長度
- 傳出封包遭到捨棄
- 封包傳出錯誤
- 已接收但遭捨棄的封包
- 已接收封包錯誤
- 已接收的封包數不明
- 每個處理器的網路介面卡活動
- 每秒低資源接收指示
- 每秒接收的資源封包數偏低
- 處理器
- % 中斷時間
- % 特權時間
- % 處理器時間
- 使用者時間百分比
- 網路介面卡
Pefmon 可讓您在時間序列圖上繪製上述計數器。在進行測試或伺服器受到影響時,這項功能可提供有用的資訊。當 VM 達到 CPU 吞吐量限制時,中斷時間和特權時間等 CPU 相關計數器的尖峰值可能會顯示飽和問題。當 CPU 飽和時,可能會發生封包捨棄和錯誤,導致封包在由用戶端或伺服器通訊端處理前就遺失。最後,在 CPU 飽和期間,輸出佇列長度也會增加,因為更多封包會排入處理佇列。
Windows Powershell
PS C:\> netstat -s
IPv4 Statistics Packets Received = 56183 Received Header Errors = 0 Received Address Errors = 0 Datagrams Forwarded = 0 Unknown Protocols Received = 0 Received Packets Discarded = 25 Received Packets Delivered = 56297 Output Requests = 47994 Routing Discards = 0 Discarded Output Packets = 0 Output Packet No Route = 0 Reassembly Required = 0 Reassembly Successful = 0 Reassembly Failures = 0 Datagrams Successfully Fragmented = 0 Datagrams Failing Fragmentation = 0 Fragments Created = 0
netstat 指令會輸出網路統計資料,其中包含依據通訊協定計算的封包丟棄值。封包遭到捨棄,可能是應用程式或網路介面資源耗盡的結果。
如果您發現資源耗盡,可以嘗試將工作負載分散到更多執行個體、將 VM 升級為資源較多的 VM、根據特定效能需求調整 OS 或應用程式、在搜尋引擎中輸入錯誤訊息來尋找可能的解決方案,或是使用「如果您仍有問題」一節所述的其中一種方法尋求協助。
如果資源耗盡並非問題所在,問題可能出在伺服器軟體本身。如需伺服器軟體問題的疑難排解指南,請參閱「檢查伺服器記錄,瞭解伺服器行為」一文。
查看伺服器記錄,瞭解伺服器行為
如果上述步驟未顯示任何問題,逾時問題可能是由應用程式行為造成,例如 vCPU 用盡導致的處理停滯。請查看伺服器和應用程式記錄,找出您遇到的行為。
舉例來說,如果伺服器因上游系統 (例如負載資料庫) 而導致延遲時間增加,可能會將過多要求排入佇列,導致記憶體用量和 CPU 等待時間增加。這些因素可能會導致連線失敗或通訊端連結緩衝區溢位。
TCP 連線偶爾會遺失封包,但選擇性確認和封包重傳通常會復原遺失的封包,避免連線逾時。相反地,請考慮應用程式伺服器失敗或重新部署導致逾時,進而導致連線暫時失敗。
如果您的伺服器應用程式需要連線至資料庫或其他服務,請確認連結的服務效能良好。您的應用程式可能會追蹤這些指標。
如果問題仍未解決
如果問題仍未解決,請參閱「取得支援」一節,瞭解後續步驟。將疑難排解步驟的輸出內容提供給其他協作者,這麼做很有幫助。
後續步驟
- 如果問題仍未解決,請參閱「資源」頁面。