如何將 kubernetes 風格的時間轉換為秒,以便我可以進行一些比較

如何將 kubernetes 風格的時間轉換為秒,以便我可以進行一些比較

kubectl get pods -o wide

輸出看起來類似

some-pod-name-with-numbers-123             1/1     Running   0          6d4h      192.168.0.23   node-name-abcdeft-host.domain   <none>           <none>
some-pod-name-with-numbers-1234            1/1     Running   0          4h38m      192.168.0.24   node-name-abcdeft-host.domain   <none>           <none>
some-pod-name-with-numbers-1235            1/1     Running   0          2m38s      192.168.0.25   node-name-abcdeft-host.domain   <none>           <none>

我得到 Pod 的經過時間,格式如下:4d3h15m3s(看起來最多是兩個連續的單位,天和小時,小時分鐘,分鐘和秒,但我不能保證這一點。

我需要檢查 pod 的存在時間是否超過某個閾值 X。

我試圖找到某種方法透過 kubectl 將該欄位提取為秒,但沒有運氣。我在網路上搜尋了一種預先安裝解決方案,但找不到。

我想我可以使用 awk 將字串轉換為數字秒,這樣我就可以比較它是否 > $X,這個值是可配置的。

答案1

您不需要僅為了取得 kubernetes 運行時間(以秒為單位)而派生外部程序。下面的 GNU awk 程式碼有一個使用者定義的函數fx(),該函數將執行該轉換,從那裡您可以將其用於比較目的。

kubectl get pods -o wide |
awk '
BEGIN {
    a["d"] = 24*(\
    a["h"] = 60*(\
    a["m"] = 60*(\
    a["s"] = 1)));
  }
  {
    print fx($5); # kubernetes time elapsed in seconds 
  }
  function fx(ktym,    f,u,n,t,i) {
    n = split(ktym, f, /[dhms]/, u)
    t = 0
    for (i=1; i<n; i++) {
      t += f[i] * a[u[i]] 
    }
    return t
  }
'

如果您想在 bash 中使用使用者定義的函數,那麼我們可以執行以下操作。我們有一個函數 fx() ,它需要一個參數,它是 kubernetes 格式的經過時間,它會輸出以秒為單位的時間。

fx() {
echo "$1" |
sed -Ee '
  s/[1-9][0-9]*[dhms]/&+ /g
  :a;s/[+]([^+].*)/\1+/;ta
  s/.$//
  :loop
    s/d/ 24h*/
    s/h/ 60m*/
    s/m/ 60s*/
    s/s//
  t loop
  s/.*/echo "&" | dc -e "?p"/e
'
}

我們正在為名為的 Linux 實用程式動態產生程式碼直流電或桌面計算器RPN(逆波蘭表示法)。

答案2

如果有人像我一樣在尋找 python 函數,這裡是:

def kubctle_dur_to_secs(kubectl_time:str) -> int:
    total_time = 0
    for t_char, sec_in_t in zip( ('d', 'h', 'm', 's'), (86400, 3600, 60, 1) ):
        if t_char in kubectl_time:
            t_index = kubectl_time.find(t_char)
            total_time += int(kubectl_time[:t_index])*sec_in_t
            kubectl_time = kubectl_time[t_index+1:]
    return total_time

答案3

花了一些時間,發現最快的方法是用 sed 替換來標記時間。

sed -e 's/\([smhd]\)/\1 /g' | awk '{ b=0; for(i=1; i<=NF; ++i) { s=substr($i,1,length($i)-1); u=substr($i,length($i)); if (u=="s") b+=s; else if (u=="m") b+=s*60; else if (u=="h") b+=s*60*60; else if (u=="d") b+=s*60*60*24; else u=""; } if (b>1) printf "%d", b}'

到目前為止,我只觀察到該領域使用了 d、h、m、s 單位,即使對於超過 100 天的 pod 也是如此。

sed 指令基本上用空格分隔每個單元。
然後 awk 循環遍歷欄位並將字串拆分為單位 (u) 和數字字串 (s)。
連結的 if-elseif-else 語句只是根據單位將值轉換為秒,並將其加到保留的總時間(以秒為單位)中。

我已將此命令放在腳本“kube_elapsed_to_seconds”中,並計劃在外部使用另一個 awk 和系統命令在此欄位上運行此腳本。

kubectl get pods -o wide | awk '{ system("echo " $5 " | kube_elapased_to_seconds"); print $0 }'

我願意接受有關如何使此命令更易於閱讀或與其他非時間相關欄位(例如可能存在的 podname 和狀態)更好地互動的建議。

答案4

關於理解這些的命令4d3h15m3s,請參閱 dateutils 的dadd

$ TZ=UTC0 dateutils.dadd -f%s 1970-01-01T00:00:00 4d3h15m3s
357303

這裡將該持續時間加入到 Unix 紀元時間的開頭,並將結果輸出為 Unix 紀元時間(在與 UTC 偏移量為 0 的時區中)。

相關內容