天天看點

混沌工程之ChaosMesh使用之四模拟網絡Duplicate包

今天我們來玩一下ChaosMesh模拟網絡duplicate包的情況。同時也要看一下對應用産生的直接影響。

目标

模拟網絡重複包。

配置

  • yaml檔案配置
[root@s5 ChaosMesh]# cat network-duplicate.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
  name: network-duplicate
  namespace: chaos
spec:
  action: duplicate
  mode: one
  selector:
    labelSelectors:
      "k8s.kuboard.cn/name": "svc-7dmall"
  duplicate:
    duplicate: "40"
    correlation: "25"
  duration: "10s"
  scheduler:
    cron: '@every 15s'           

複制

  • 界面配置
混沌工程之ChaosMesh使用之四模拟網絡Duplicate包
混沌工程之ChaosMesh使用之四模拟網絡Duplicate包

執行

  • 在指令行執行:
[root@s5 ChaosMesh]# kubectl apply -f network-duplicate.yaml
networkchaos.chaos-mesh.org/network-duplicate created           

複制

  • 在界面上配置完成送出後即開始執行。

驗證

  1. 進入被模拟的POD,先檢視qdisc上增加的規則,再執行tcpdump抓包。
- 檢視qdisc上的規則
[root@svc-7dmall-664d59f75b-whtvc /]# tc qdisc ls dev eth0
qdisc netem 1: root refcnt 2 limit 1000 duplicate 40%
[root@svc-7dmall-664d59f75b-whtvc /]#

- 執行tcpdump抓包
[root@svc-7dmall-664d59f75b-whtvc /]# tcpdump -i eth0 -w networkduplicate.cap
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes


^C195 packets captured
195 packets received by filter
0 packets dropped by kernel
[root@svc-7dmall-664d59f75b-whtvc /]#           

複制

從上面的結果看抓到了195個包。

2. 進入pod所在機器或用其他工具把抓到的檔案複制到本地。

[root@s7 ~]# docker cp 3d4ab3241d8a:/networkduplicate.cap ./           

複制

3. 用wireshark打開檢視。

混沌工程之ChaosMesh使用之四模拟網絡Duplicate包

确實出現了大量的重複包。

正常抓包結果是這樣的:

混沌工程之ChaosMesh使用之四模拟網絡Duplicate包

4. 用jmeter開始一個線程通路應用,持續60s,看下有什麼差別。

  • 有重複包的結果:
混沌工程之ChaosMesh使用之四模拟網絡Duplicate包
  • 無重複包的結果:
混沌工程之ChaosMesh使用之四模拟網絡Duplicate包

從上面的結果來看,産生重複包的時候,對性能的影響還是不小的。

應用直接的感受就是:響應時間長、TPS下降。

使用者直接的感受就是:慢但有響應或慢直到報錯。

5. 進入被模拟的POD,再次檢視qdisc上的規則

[root@svc-7dmall-664d59f75b-whtvc /]# tc qdisc ls dev eth0
qdisc noqueue 0: root refcnt 2
[root@svc-7dmall-664d59f75b-whtvc /]#           

複制

恢複

  • 在界面上停止案例
混沌工程之ChaosMesh使用之四模拟網絡Duplicate包
  • 用指令行停止案例
[root@s5 ChaosMesh]# kubectl delete -f network-duplicate.yaml
networkchaos.chaos-mesh.org "network-duplicate" deleted
[root@s5 ChaosMesh]#           

複制

重傳原理邏輯說明和RTO計算過程

重複包産生的原因有很多,像應用故障、網絡裝置故障、服務當機等等。

我們這裡主要來說明一下重傳的邏輯。

決定封包重傳機制的是重傳計時器(retransmission timer),它的功能是維護重傳逾時值(retransmission timeout)。

發出封包後,重傳計時器啟動,收到ACK後計時器停止。如果未收到ACK,發送方認為封包丢失并重傳,同時RTO加倍;如果2倍RTO之後還沒收到ACK,則再次重傳。

在linux中重傳次數預設最大為15次,由兩個參數控制:

net.ipv4.tcp_retries1 = 3
net.ipv4.tcp_retries2 = 15           

複制

tcp_retries1 = 3 是指重傳了3次後,如果還沒收到ACK,則後續重傳中會先更新路由。

tcp_retries2 = 15 是指最多重傳15次,15次都傳不成功,那就放棄了。

正常情況下,你看到這裡就可以結束了。但也不排除有些人想看明白RTO的計算邏輯。那就接着看。

也許你會問RTO是多長時間?在Linux源碼中,有這樣的定義(源碼路徑include/net/tcp.h,在我這個3.10版本的核心代碼中是134、135行):

#define TCP_RTO_MAX  ((unsigned)(120*HZ))
#define TCP_RTO_MIN  ((unsigned)(HZ/5))           

複制

看到這裡,知道RTO有最大最小值,分别是 HZ/5 和 120*HZ 。但是又有疑問,那HZ是什麼值?你可以在系統中執行如下指令獲得。

[root@s5 ~]# cat /boot/config-`uname -r` | grep '^CONFIG_HZ='
CONFIG_HZ=1000           

複制

在我的系統中值是1000,也就是說RTO的最小值是200、最大值是120000(機關是毫秒)。

但是這個RTO又是怎麼算來的呢?這個值由__tcp_set_rto(3.10源碼路徑include/net/tcp.h中606-609行)函數算出(其中srtt的計算邏輯,我就不展開了,越說越多越容易亂,有興趣的可以自己去查查資料)。

static inline u32 __tcp_set_rto(const struct tcp_sock *tp)
{
  return (tp->srtt >> 3) + tp->rttvar;
}           

複制

這個函數算出來的值不可以小于TCP_RTO_MIN的值。

而RTO的最大值又由誰來确定呢?那就是tcp_bound_rto(3.10源碼路徑include/net/tcp.h中600-604行)了。

static inline void tcp_bound_rto(const struct sock *sk)
{
  if (inet_csk(sk)->icsk_rto > TCP_RTO_MAX)
    inet_csk(sk)->icsk_rto = TCP_RTO_MAX;
}           

複制

以上就是RTO的計算邏輯。

留下思考的空間:

1. 怎麼分析網絡包重傳的原因?

2. 有沒有設定最小RTO的函數?