Cómo convertir el tiempo transcurrido de un estilo de Kubernetes en segundos para poder hacer algunas comparaciones

Cómo convertir el tiempo transcurrido de un estilo de Kubernetes en segundos para poder hacer algunas comparaciones

De

kubectl get pods -o wide

La salida es similar a

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>

Obtengo el tiempo transcurrido para los pods en un formato como: 4d3h15m3s (parece que lo máximo son dos unidades consecutivas, días y horas, horas, minutos, minutos y segundos, pero no puedo garantizarlo.

Necesito verificar si un pod ha existido por más tiempo que cierto umbral X.

Intenté encontrar alguna forma de extraer este campo como segundos a través de kubectl, pero no tuve suerte. Busqué en Internet una solución prefabricada y no pude encontrarla.

Estoy pensando que puedo usar awk para convertir la cadena en segundos numéricos para luego poder comparar si es > $X, este valor es configurable.

Respuesta1

No es necesario bifurcar un proceso externo solo para obtener el tiempo transcurrido de Kubernetes en segundos. El siguiente código GNU awk tiene una función definida por el usuario fx()que realizará esa conversión y, a partir de ahí, podrá utilizarla para fines de comparación.

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
  }
'

En caso de que desee utilizar una función definida por el usuario en bash, podemos hacer lo siguiente. Tenemos una función fx() que necesita un argumento, que es el tiempo transcurrido en formato kubernetes y generará un tiempo en segundos.

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
'
}

Estamos generando dinámicamente un código para la utilidad de Linux llamadacorriente continuao la calculadora de escritorio en elRPN(Notación polaca inversa).

Respuesta2

En caso de que alguien estuviera buscando una función de Python como yo, aquí está:

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

Respuesta3

Dediqué algún tiempo a esto y descubrí que la forma más rápida de lograrlo era tokenizar el tiempo con un reemplazo de 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}'

Hasta ahora solo he observado el uso de unidades d,h,m,s en este campo, incluso para módulos que tienen más de 100 días.

El comando sed básicamente divide cada unidad con un espacio.
Awk luego recorre los campos y divide la cadena en la unidad (u) y la cadena numérica (s).
Las declaraciones encadenadas if-elseif-else simplemente convierten los valores en segundos según la unidad y los agregan a un total acumulado del tiempo en segundos que se mantiene.

Coloqué este comando en un script "kube_elapsed_to_segundos" y planeo usar otro awk en el exterior y el comando del sistema para ejecutar este script en este campo.

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

Estoy abierto a sugerencias sobre cómo hacer que este comando sea más fácil de leer o interactuar mejor con otros campos no relacionados con el tiempo, como el nombre del pod y el estado, que puedan estar presentes.

Respuesta4

Para obtener un comando que los comprenda 4d3h15m3s, consulte dateutils dadd:

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

Aquí se agrega esa duración al inicio de la época de Unix y se genera el resultado como hora de la época de Unix, en una zona horaria con 0 desplazamiento a UTC.

información relacionada