如何在 GKE Autopilot 上的 Pod 中使用 ping?

Ping 是一個在確認網路連結狀態的一個非常常用的工具,應該有很多人在遇到連線不通的時候就會下意識的直接跑 ping 試試看吧!最近在使用 GKE Autopilot 模式的時候就因為遇到一些網路怪怪的狀況而嘗試想跑個 ping 測測看網路通不通,但是一跑下去就發現 Autopilot 模式下的 Pod 竟然無法執行 ping 😱!這下該怎麼辦才好呢… 🤔

在 Autopilot 模式下的 Pod 執行 ping

GKE Autopilot 的限制

GKE 是 Google Cloud 提供的 managed Kubernetes 服務。不過雖然說是 managed,其實使用者還是需要處理跟 Kubernetes cluster 相關的 operations,要不然用起來還是會卡卡的。所以自從 GKE 推出了之後就一直有人在期待 Google Cloud 能夠出真的 fully managed 的 Kubernetes solution。終於在 2021 年,Google Cloud 推出了 GKE 的 Autopilot 模式讓使用者可以完全只需要負責 workload 的部分。

不過要讓 GKE 能夠把很多 operations 自動化的代價就是 Autopilot 模式的 cluster 有更多的限制。GKE 官方的說法是 Autopilot 將直接套用了維運 Kubernetes cluster 的 best practice,其實這個說法也沒有錯,但是如果你今天的需求剛好跟這些所謂的 best practice 衝突的話就會蠻麻煩的。所以仍然有不少的團隊因為 Autopilot 模式的這些「限制」而不敢進一步嘗試。本文介紹的問題就是其中一個 Autopilot 的限制所造成的結果。

關於 GKE Autopilot cluster 的所有限制,可以參考官方文件的說明(這裡這裡),本文就不再多做介紹。

為什麼不能用 ping?

這個的確跟 Autopilot 自動套用的 best practice 有關。事實上 GKE 的官方文件也確實有提到可能會有這個問題。以下節錄文件上關於可能無法使用 ping 的說明:

The CAP_NET_RAW container permission is dropped for all containers. The CAP_NET_RAW permission is not typically used and was the subject of multiple container escape vulnerabilities. The lack of CAP_NET_RAW might cause the use of ping to fail inside your container.

網路上很多人其實也都有分享了 Autopilot cluster 的 Pod 無法用 ping 的問題,然後這個設定跟 GKE Autopilot 眾多的其他預設行為一樣都是無法調整的。難道在 Autopilot cluster 上我們就真的不能使用網路工程師的最好的朋友了嗎?這也難怪很多人都覺得 Autopilot 的種種限制跟預設行為其實讓 GKE 變得更難用?🤔🤔🤔

解決方式

還好!這個問題其實是可以簡單的解決的。使用 ping 跟 CAP_NET_RAW 當作關鍵字 Google 了一下發現其實 Linux 為了解決 ping 可以不需要有 root 跟 CAP_NAT_RAW 的權限而 implement 的 ICMP socket 功能,並且透過一個可以使用 sysctl 調整的參數 net.ipv4.ping_group_range 來控制可以使用這個功能的 GID 範圍。參數的預設值是 "1 0" 也就是停用這個功能。這裡我們可以把這個參數調整成 "0 2147483647" 就可以讓所有 GID 都可以使用 ping 囉(建議還是根據實際情形設定本參數)!

GKE Autopilot 支援透過 Pod spec 修改某些特定的 sysctl 參數,而 net.ipv4.ping_group_range 也在支援的參數清單中!這樣要在我們的 cluster 中使用 ping 就只要在 Pod spec 中加入下面這段就可以囉!

securityContext:
  sysctls:
  - name: net.ipv4.ping_group_range
    value: "0 2147483647"

下面提供一個完整的 Pod resource demo 一下怎麼使用:

apiVersion: v1
kind: Pod
metadata:
  name: pinger
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - tail
    - -f
    - /dev/null
  securityContext:
    sysctls:
    - name: net.ipv4.ping_group_range
      value: "0 2147483647"

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *