
От
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>
Я получаю прошедшее время для модулей в формате: 4д3ч15м3с (похоже, что чаще всего это две последовательные единицы: дни и часы, часы минуты, минуты и секунды, но я не могу этого гарантировать).
Мне нужно проверить, существует ли модуль дольше некоторого порогового значения 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 под названиемОкруг Колумбияили настольный калькулятор вРПН(Обратная польская запись).
решение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}'
До сих пор я наблюдал только использование единиц измерения в этой области, даже для стручков, которым более 100 дней.
Команда 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 и status, которые могут присутствовать.
решение4
Для команды, которая их понимает 4d3h15m3s
, см. dateutils dadd
:
$ TZ=UTC0 dateutils.dadd -f%s 1970-01-01T00:00:00 4d3h15m3s
357303
Здесь эта длительность добавляется к началу времени эпохи Unix и результат выводится как время эпохи Unix в часовом поясе с нулевым смещением относительно UTC.