理解網(wǎng)絡(luò)命名空間與 VETH Pair 對(duì)
如果你使用過 Docker 和 Kubernetes,那么可能應(yīng)該聽說過 network namespace(網(wǎng)絡(luò)命名空間),最近在我們的 《Kubernetes 網(wǎng)絡(luò)訓(xùn)練營》課程中學(xué)習(xí)到了 Linux 下面的 ip 命令的使用,本文我將演示如何使用命令通過一對(duì) veth 接口連接不同子網(wǎng)中的網(wǎng)絡(luò)命名空間的進(jìn)程。
網(wǎng)絡(luò)命名空間
我們知道容器運(yùn)行時(shí)使用 namespace(命名空間)內(nèi)核功能對(duì)系統(tǒng)資源進(jìn)行分區(qū),以實(shí)現(xiàn)某種形式的進(jìn)程隔離,這樣,對(duì)一個(gè)命名空間中資源的更改不會(huì)影響其他命名空間中的資源,包括進(jìn)程 ID、主機(jī)名、用戶 ID、文件名和網(wǎng)絡(luò)接口等。
網(wǎng)絡(luò)名稱空間可以虛擬化網(wǎng)絡(luò)堆棧,每個(gè)網(wǎng)絡(luò)名稱空間都有自己的資源,例如網(wǎng)絡(luò)接口、IP 地址、路由表、隧道、防火墻等,例如,iptables添加到網(wǎng)絡(luò)名稱空間的規(guī)則只會(huì)影響進(jìn)入和離開該名稱空間的流量。
ip 命令
ip 命令是用來顯示或操縱 Linux 主機(jī)的路由、網(wǎng)絡(luò)設(shè)備、策略路由和隧道,是 Linux 下較新的功能強(qiáng)大的網(wǎng)絡(luò)配置工具。
該命令的用法如下所示:
ip?[OPTIONS]?OBJECT?COMMAND?[ARGUMENTS]
#?where?
#???OPTIONS?are?general?global?options
#???OBJECT?:=?{?link?|?address?|?addrlabel?|?route?|
#?????rule?|?neigh?|?ntable?|?tunnel?|?tuntap?|?maddress?|?
#?????mroute?|?mrule?|?monitor?|?xfrm?|?netns?|?l2tp?|?
#?????tcp_metrics?}
#???COMMAND?is?the?action?to?perform?on?the?object,?such?as,
#?????show,?add,?del?etc.
#???ARGUMENTS?are?arguments?specific?to?the?kind?of?OBJECT?
#?????and?COMMAND
例如:
要添加一個(gè)新的網(wǎng)絡(luò)接口,使用 ip link add命令type ... 要分配一個(gè)新的 IP 地址范圍到一個(gè)接口,使用 ip addr add命令dev 要從路由表中刪除一條路由,使用 ip route del命令dev
選項(xiàng) -n 可以用來切換目標(biāo)命名空間,例如,要將 10.0.1.0/24 IP 地址范圍分配給 ns1 網(wǎng)絡(luò)命名空間內(nèi)的接口 veth0,使用ip -n ns1 addr add 10.0.1.0/24 dev veth0 命令即可 。
“?
”-n選項(xiàng)是ip netns exec的縮寫
配置第一個(gè)網(wǎng)絡(luò)命名空間
首先我們使用 ip link add 命令創(chuàng)建一對(duì)新的 veth 接口:veth0 和 veth1:
#?創(chuàng)建一對(duì)名為 veth0?和 veth1 的 veth 接口。
$?ip?link?add?veth0?type?veth?peer?name?veth1
#?確認(rèn)?veth0?已創(chuàng)建
$?ip?link?show?veth0
289:?veth0@veth1:??mtu?1500?qdisc?noop?state?DOWN?mode?DEFAULT?group?default?qlen?1000
????link/ether?5e:87:df:87:af:c7?brd?ff:ff:ff:ff:ff:ff
#?確認(rèn)?veth1?已創(chuàng)建
$?ip?link?show?veth1
288:?veth1@veth0:??mtu?1500?qdisc?noop?state?DOWN?mode?DEFAULT?group?default?qlen?1000
????link/ether?be:0d:a4:8c:9f:2a?brd?ff:ff:ff:ff:ff:ff
veth 接口通常被創(chuàng)建為一個(gè)對(duì),其中一端傳輸?shù)臄?shù)據(jù)會(huì)立即被另一端接收,這種類型的接口在容器運(yùn)行時(shí)通常用于在不同網(wǎng)絡(luò)命名空間之間傳輸數(shù)據(jù)包。
讓我們創(chuàng)建第一個(gè)網(wǎng)絡(luò)命名空間 ns1,然后我們可以將 veth0 接口分配給這個(gè)網(wǎng)絡(luò)命名空間,并將 10.0.1.0/24 的 IP 地址范圍分配給它。
#?創(chuàng)建?ns1?網(wǎng)絡(luò)命名空間
$?ip?netns?add?ns1
#?分配?veth0?接口到?ns1?網(wǎng)絡(luò)命名空間
$?ip?link?set?veth0?netns?ns1
#?將?10.0.1.0/24?IP?地址范圍分配給?veth0?接口
$?ip?-n?ns1?addr?add?10.0.1.0/24?dev?veth0
#?將?veth0?接口?up?起來
$?ip?-n?ns1?link?set?veth0?up
#?將?lo?接口?up?起來,因?yàn)榘l(fā)往?10.0.1.0/24?的數(shù)據(jù)(本地的)
#?(像?ping)要通過?local(本地)路由表
#?比如要?ping?自己
$?ip?-n?ns1?link?set?lo?up?
#?確認(rèn)接口已經(jīng)?up?起來
$?ip?-n?ns1?addr?show
1:?lo:??mtu?65536?qdisc?noqueue?state?UNKNOWN?group?default?qlen?1000
????link/loopback?00:00:00:00:00:00?brd?00:00:00:00:00:00
????inet?127.0.0.1/8?scope?host?lo
???????valid_lft?forever?preferred_lft?forever
????inet6?::1/128?scope?host
???????valid_lft?forever?preferred_lft?forever
289:?veth0@if288:??mtu?1500?qdisc?noqueue?state?LOWERLAYERDOWN?group?default?qlen?1000
????link/ether?5e:87:df:87:af:c7?brd?ff:ff:ff:ff:ff:ff?link-netnsid?0
????inet?10.0.1.0/24?scope?global?veth0
???????valid_lft?forever?preferred_lft?forever
現(xiàn)在如果我們從主機(jī)和 ns1 兩個(gè)網(wǎng)絡(luò)命名空間中去 ping veth0 接口會(huì)發(fā)生什么呢?
#?veth0?不在主機(jī)的根網(wǎng)絡(luò)命名空間中
$?ip?link?show?veth0????????????
Device?"veth0"?does?not?exist.
#?從主機(jī)網(wǎng)絡(luò)命名空間中?ping?不通
$?ping?-c10?10.0.1.0
PING?10.0.1.0?(10.0.1.0)?56(84)?bytes?of?data.
^C
---?10.0.1.0?ping?statistics?---
3?packets?transmitted,?0?received,?100%?packet?loss,?time?1999ms
我們可以看到直接在主機(jī)的根網(wǎng)絡(luò)命名空間中是找不到 veth0 這個(gè)接口的,當(dāng)然也是 ping 不同 10.0.1.0 這個(gè)地址的,因?yàn)樗麄儽唤壎ǖ?ns1 這個(gè)網(wǎng)絡(luò)命名空間中,所以我們?cè)诓僮鞯臅r(shí)候需要切換到這個(gè)命名空間下面。
$?ip?netns?exec?ns1?ping?-c10?10.0.1.0
PING?10.0.1.0?(10.0.1.0)?56(84)?bytes?of?data.
64?bytes?from?10.0.1.0:?icmp_seq=1?ttl=64?time=0.121?ms
64?bytes?from?10.0.1.0:?icmp_seq=2?ttl=64?time=0.063?ms
64?bytes?from?10.0.1.0:?icmp_seq=3?ttl=64?time=0.066?ms
64?bytes?from?10.0.1.0:?icmp_seq=4?ttl=64?time=0.109?ms
^C
---?10.0.1.0?ping?statistics?---
4?packets?transmitted,?4?received,?0%?packet?loss,?time?3000ms
rtt?min/avg/max/mdev?=?0.063/0.089/0.121/0.028?ms
這里我們使用了一條 ip netns exec 的命令,這個(gè)命令允許我們?cè)谥付ǖ木W(wǎng)絡(luò)命名空間中去執(zhí)行任意的命令,可以看到現(xiàn)在我們?cè)?ns1 網(wǎng)絡(luò)命名空中間去 ping 10.0.1.0 就可以通了。
配置第二個(gè)網(wǎng)絡(luò)命名空間
下面我們用上面的方式來創(chuàng)建第二個(gè)網(wǎng)絡(luò)命名空間 ns2,然后將 veth1 接口分配給這個(gè)網(wǎng)絡(luò)命名空間,并將 10.0.2.0/24 的 IP 地址范圍分配給這個(gè)接口。
#?創(chuàng)建名為?ns2?的網(wǎng)絡(luò)命名空間
$?ip?netns?add?ns2
#?分配?veth1?接口到?ns2?網(wǎng)絡(luò)命名空間
$?ip?link?set?veth1?netns?ns2
#?將?10.0.2.0/24?IP?地址范圍分配給?veth1?接口
$?ip?-n?ns2?addr?add?10.0.2.0/24?dev?veth1
#?將?veth1?接口?up?起來
$?ip?-n?ns2?link?set?veth1?up
#?將?lo?口?up?起來(這樣可以?ping?通自己)
$?ip?-n?ns2?link?set?lo?up?
$?ip?-n?ns2?addr?show
1:?lo:??mtu?65536?qdisc?noqueue?state?UNKNOWN?group?default?qlen?1000
????link/loopback?00:00:00:00:00:00?brd?00:00:00:00:00:00
????inet?127.0.0.1/8?scope?host?lo
???????valid_lft?forever?preferred_lft?forever
????inet6?::1/128?scope?host
???????valid_lft?forever?preferred_lft?forever
288:?veth1@if289:??mtu?1500?qdisc?noqueue?state?UP?group?default?qlen?1000
????link/ether?be:0d:a4:8c:9f:2a?brd?ff:ff:ff:ff:ff:ff?link-netnsid?0
????inet?10.0.2.0/24?scope?global?veth1
???????valid_lft?forever?preferred_lft?forever
????inet6?fe80::bc0d:a4ff:fe8c:9f2a/64?scope?link
???????valid_lft?forever?preferred_lft?forever
為方便后面設(shè)置路由,這里我們?yōu)?veth1 接口分配一個(gè)不同的子網(wǎng) IP 范圍。和 veth0 接口類似,veth1 接口也不能從主機(jī)網(wǎng)絡(luò)命名空間到達(dá),只能在 ns2 本身的網(wǎng)絡(luò)命名空間內(nèi)工作。
$?ip?link?show?veth1
Device?"veth1"?does?not?exist.
$?ping?-c10?10.0.2.0
PING?10.0.2.0?(10.0.2.0)?56(84)?bytes?of?data.
From?180.149.159.13?icmp_seq=2?Packet?filtered
^C
---?10.0.2.0?ping?statistics?---
2?packets?transmitted,?0?received,?+1?errors,?100%?packet?loss,?time?999
$?ip?netns?exec?ns2?ping?-c10?10.0.2.0
PING?10.0.2.0?(10.0.2.0)?56(84)?bytes?of?data.
64?bytes?from?10.0.2.0:?icmp_seq=1?ttl=64?time=0.100?ms
64?bytes?from?10.0.2.0:?icmp_seq=2?ttl=64?time=0.096?ms
64?bytes?from?10.0.2.0:?icmp_seq=3?ttl=64?time=0.068?ms
^C
---?10.0.2.0?ping?statistics?---
3?packets?transmitted,?3?received,?0%?packet?loss,?time?1999ms
rtt?min/avg/max/mdev?=?0.068/0.088/0.100/0.014?ms
配置子網(wǎng)路由
雖然在上面的兩個(gè)網(wǎng)絡(luò)空間內(nèi)可以各自訪問自己,但是他們互相之間是不能 ping 通的。
$?ip?netns?exec?ns1?ping?-c10?10.0.2.0
connect:?Network?is?unreachable
$?ip?netns?exec?ns2?ping?-c10?10.0.1.0
connect:?Network?is?unreachable
veth0 和 veth1 這兩個(gè)接口本身也都 up 起來了,而且在各種的網(wǎng)絡(luò)命名空間中 ping 也能正常工作,所以互相直接不通那很可能和路由有關(guān)。下面我們使用 ip 命令來調(diào)試下,我們可以通過 ip route get 命令來確定一個(gè)數(shù)據(jù)包所走的路由。
$?ip?-n?ns1?route?get?10.0.2.0
RTNETLINK?answers:?Network?is?unreachable
$?ip?-n?ns2?route?get?10.0.1.0
RTNETLINK?answers:?Network?is?unreachable
我們可以看到都是網(wǎng)絡(luò)不可達(dá),我們來檢查下兩個(gè)網(wǎng)絡(luò)命名空間中的路由表信息。
$?ip?-n?ns1?route
10.0.1.0/24?dev?veth0?proto?kernel?scope?link?src?10.0.1.0
$?ip?-n?ns2?route
10.0.2.0/24?dev?veth1?proto?kernel?scope?link?src?10.0.2.0
看到路由表是不是很清晰了,兩個(gè)網(wǎng)絡(luò)命名空間的路由表都只有各自 IP 范圍的路由條目,并沒有通往其他子網(wǎng)的路由,所以當(dāng)然不能互通了,要解決也很簡單,可以使用 ip route add 命令在路由表中插入新的路由條目是不是就可以了。
#?更新?veth0?路由表,添加一條通往?10.0.2.0/24?的路由
$?ip?-n?ns1?route?add?10.0.2.0/24?dev?veth0
#?確認(rèn)發(fā)往?10.0.2.0/24?的數(shù)據(jù)包被路由到?veth0
$?ip?-n?ns1?route?get?10.0.2.0
10.0.2.0?dev?veth0?src?10.0.1.0
????cache
#?同樣更新?veth1?路由表,添加一條通往?10.0.1.0/24?的路由
$?ip?-n?ns2?route?add?10.0.1.0/24?dev?veth1
#?確認(rèn)發(fā)往?10.0.1.0/24?的數(shù)據(jù)包被路由到?veth1
$?ip?-n?ns2?route?get?10.0.1.0
10.0.1.0?dev?veth1?src?10.0.2.0
????cache
上面我們?cè)诟髯缘木W(wǎng)絡(luò)命名空間中添加了對(duì)方的路由信息,現(xiàn)在我們來嘗試 ping 下對(duì)方的 veth 接口。
$?ip?netns?exec?ns1?ping?-c10?10.0.2.0
PING?10.0.2.0?(10.0.2.0)?56(84)?bytes?of?data.
64?bytes?from?10.0.2.0:?icmp_seq=1?ttl=64?time=0.140?ms
64?bytes?from?10.0.2.0:?icmp_seq=2?ttl=64?time=0.080?ms
64?bytes?from?10.0.2.0:?icmp_seq=3?ttl=64?time=0.091?ms
^C
---?10.0.2.0?ping?statistics?---
3?packets?transmitted,?3?received,?0%?packet?loss,?time?1999ms
rtt?min/avg/max/mdev?=?0.080/0.103/0.140/0.028?ms
$?ip?netns?exec?ns2?ping?-c10?10.0.1.0
PING?10.0.1.0?(10.0.1.0)?56(84)?bytes?of?data.
64?bytes?from?10.0.1.0:?icmp_seq=1?ttl=64?time=0.114?ms
64?bytes?from?10.0.1.0:?icmp_seq=2?ttl=64?time=0.084?ms
64?bytes?from?10.0.1.0:?icmp_seq=3?ttl=64?time=0.086?ms
^C
---?10.0.1.0?ping?statistics?---
3?packets?transmitted,?3?received,?0%?packet?loss,?time?2000ms
rtt?min/avg/max/mdev?=?0.084/0.094/0.114/0.017?ms
可以看到已經(jīng)通啦!!????此外我們還可以使用 tcpdump 來捕獲兩個(gè)網(wǎng)絡(luò)命名空間之間傳輸?shù)臄?shù)據(jù)包。
$?ip?netns?exec?ns1?tcpdump?-i?veth0?icmp?-l
tcpdump:?verbose?output?suppressed,?use?-v?or?-vv?for?full?protocol?decode
listening?on?veth0,?link-type?EN10MB?(Ethernet),?capture?size?262144?bytes
11:29:22.080392?IP?10.0.2.0?>?10.0.1.0:?ICMP?echo?request,?id?7253,?seq?1,?length?64
11:29:22.080464?IP?10.0.1.0?>?10.0.2.0:?ICMP?echo?reply,?id?7253,?seq?1,?length?64
11:29:23.080409?IP?10.0.2.0?>?10.0.1.0:?ICMP?echo?request,?id?7253,?seq?2,?length?64
11:29:23.080472?IP?10.0.1.0?>?10.0.2.0:?ICMP?echo?reply,?id?7253,?seq?2,?length?64
11:29:24.080357?IP?10.0.2.0?>?10.0.1.0:?ICMP?echo?request,?id?7253,?seq?3,?length?64
11:29:24.080418?IP?10.0.1.0?>?10.0.2.0:?ICMP?echo?reply,?id?7253,?seq?3,?length?64
11:29:25.080346?IP?10.0.2.0?>?10.0.1.0:?ICMP?echo?request,?id?7253,?seq?4,?length?64
11:29:25.080401?IP?10.0.1.0?>?10.0.2.0:?ICMP?echo?reply,?id?7253,?seq?4,?length?64
11:29:26.080417?IP?10.0.2.0?>?10.0.1.0:?ICMP?echo?request,?id?7253,?seq?5,?length?64
11:29:26.080496?IP?10.0.1.0?>?10.0.2.0:?ICMP?echo?reply,?id?7253,?seq?5,?length?64
11:29:27.080454?IP?10.0.2.0?>?10.0.1.0:?ICMP?echo?request,?id?7253,?seq?6,?length?64
11:29:27.080507?IP?10.0.1.0?>?10.0.2.0:?ICMP?echo?reply,?id?7253,?seq?6,?length?64
11:29:28.080398?IP?10.0.2.0?>?10.0.1.0:?ICMP?echo?request,?id?7253,?seq?7,?length?64
11:29:28.080456?IP?10.0.1.0?>?10.0.2.0:?ICMP?echo?reply,?id?7253,?seq?7,?length?64
11:29:29.080390?IP?10.0.2.0?>?10.0.1.0:?ICMP?echo?request,?id?7253,?seq?8,?length?64
11:29:29.080431?IP?10.0.1.0?>?10.0.2.0:?ICMP?echo?reply,?id?7253,?seq?8,?length?64
11:29:30.080524?IP?10.0.2.0?>?10.0.1.0:?ICMP?echo?request,?id?7253,?seq?9,?length?64
11:29:30.080576?IP?10.0.1.0?>?10.0.2.0:?ICMP?echo?reply,?id?7253,?seq?9,?length?64
11:29:31.081895?IP?10.0.2.0?>?10.0.1.0:?ICMP?echo?request,?id?7253,?seq?10,?length?64
11:29:31.081942?IP?10.0.1.0?>?10.0.2.0:?ICMP?echo?reply,?id?7253,?seq?10,?length?64
^C
20?packets?captured
20?packets?received?by?filter
0?packets?dropped?by?kernel
TCP 連接
最好我們來測(cè)試下 TCP 連接,使用 nc 命令在 ns1 命名空間的 7096 端口啟動(dòng)一個(gè) TCP 服務(wù)器,然后從 ns2 網(wǎng)絡(luò)命名空間發(fā)起一個(gè) TCP 握手連接。
$?ip?netns?exec?ns1?nc?-l?10.0.1.0?7096?-v
exec?of?"nc"?failed:?No?such?file?or?directory
上面命令報(bào)錯(cuò)是因?yàn)槲覀冞€沒有安裝 ns 這個(gè)工具,安裝完成后就正常了。
$?yum?install?-y?nc
$?ip?netns?exec?ns1?nc?-l?10.0.1.0?7096?-v
Ncat:?Version?7.50?(?https://nmap.org/ncat?)
Ncat:?Listening?on?10.0.1.0:7096
然后重新開一個(gè)終端進(jìn)行連接:
#?使用?nc?從?ns2?發(fā)起?TCP?握手
$?ip?netns?exec?ns2?nc?-4t?10.0.1.0?7096?-v
Ncat:?Version?7.50?(?https://nmap.org/ncat?)
Ncat:?Connected?to?10.0.1.0:7096.
#?這個(gè)時(shí)候正常會(huì)在前面的服務(wù)中看到連接狀態(tài)
$?ip?netns?exec?ns1?nc?-l?10.0.1.0?7096?-v
Ncat:?Version?7.50?(?https://nmap.org/ncat?)
Ncat:?Listening?on?10.0.1.0:7096
Ncat:?Connection?from?10.0.2.0.
Ncat:?Connection?from?10.0.2.0:34090.
一旦 TCP 連接建立,我們就可以從 ns2 向 ns1 發(fā)送測(cè)試消息了。
$?ip?netns?exec?ns2?nc?-4t?10.0.1.0?7096?-v
Ncat:?Version?7.50?(?https://nmap.org/ncat?)
Ncat:?Connected?to?10.0.1.0:7096.
this?is?a?test?message??#?在這里輸入一段信息
此時(shí)我們?cè)?ns1 這邊的服務(wù)器端也會(huì)收到發(fā)送的消息。
$?ip?netns?exec?ns1?nc?-l?10.0.1.0?7096?-v
Ncat:?Version?7.50?(?https://nmap.org/ncat?)
Ncat:?Listening?on?10.0.1.0:7096
Ncat:?Connection?from?10.0.2.0.
Ncat:?Connection?from?10.0.2.0:34090.
this?is?a?test?message
同樣我們也可以使用 tcpdump 來抓取所有在兩個(gè)網(wǎng)絡(luò)命名空間之間傳輸?shù)臄?shù)據(jù)包。
$?ip?netns?exec?ns1?tcpdump?-X?-i?veth0?-n?tcp?-l
tcpdump:?verbose?output?suppressed,?use?-v?or?-vv?for?full?protocol?decode
listening?on?veth0,?link-type?EN10MB?(Ethernet),?capture?size?262144?bytes
11:42:59.912176?IP?10.0.2.0.34090?>?10.0.1.0.7096:?Flags?[P.],?seq?118819706:118819735,?ack?1587208228,?win?229,?options?[nop,nop,TS?val?1970393377?ecr?1970365937],?length?29
?0x0000:??4500?0051?ad52?4000?4006?7655?0a00?0200??E..Q.R@[email protected]....
?0x0010:??0a00?0100?852a?1bb8?0715?0b7a?5e9a?e024??.....*.....z^..$
?0x0020:??8018?00e5?1743?0000?0101?080a?7571?d121??.....C......uq.!
?0x0030:??7571?65f1?7468?6973?2069?7320?616e?6f74??uqe.this.is.anot
?0x0040:??6865?7220?7465?7374?206d?6573?7361?6765??her.test.message
?0x0050:??0a???????????????????????????????????????.
11:42:59.912207?IP?10.0.1.0.7096?>?10.0.2.0.34090:?Flags?[.],?ack?29,?win?227,?options?[nop,nop,TS?val?1970393377?ecr?1970393377],?length?0
?0x0000:??4500?0034?4612?4000?4006?ddb2?0a00?0100??E..4F.@.@.......
?0x0010:??0a00?0200?1bb8?852a?5e9a?e024?0715?0b97??.......*^..$....
?0x0020:??8010?00e3?1726?0000?0101?080a?7571?d121??.....&......uq.!
?0x0030:??7571?d121????????????????????????????????uq.!
當(dāng)然也可以將這個(gè)抓包結(jié)果保存下來然后用其他工具比如大白鯊來進(jìn)行詳細(xì)的分析。
總結(jié)
本文我們使用 ip 子命令可以用來創(chuàng)建和配置網(wǎng)絡(luò)命名空間、接口和路由等,我們創(chuàng)建了一對(duì) veth 接口,這些接口被分配到兩個(gè)不同的網(wǎng)絡(luò)命名空間中,具有不同的子網(wǎng) IP 地址范圍,在網(wǎng)絡(luò)命名空間的路由表中配置了額外的路由,這可以實(shí)現(xiàn)兩個(gè)子網(wǎng)之間的通信。
兩個(gè) veth 接口都無法從主機(jī)網(wǎng)絡(luò)命名空間直接到達(dá),因?yàn)樗鼈兊?IP 地址范圍和路由表的變化也被隔離在自己的網(wǎng)絡(luò)命名空間中了。
我們可以使用 ip netns exec 命令運(yùn)行工具和 tcpdump 來調(diào)試網(wǎng)絡(luò)命名空間之間的連接問題。
對(duì) Kubernetes 網(wǎng)絡(luò)訓(xùn)練營感興趣的也可以點(diǎn)擊下面圖片了解更多信息~

?點(diǎn)擊屏末?|?閱讀原文?|?即刻學(xué)習(xí)
