몇 가지 비교를 할 수 있도록 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>

4d3h15m3s와 같은 형식으로 포드에 대한 경과 시간을 얻습니다. (가장 큰 것은 두 개의 연속 단위인 일과 시간, 시 분, 분과 초인 것처럼 보이지만 이를 보장할 수는 없습니다.

포드가 일부 임계값 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}'

지금까지 나는 100일이 넘는 포드에 대해서도 이 분야에서 d,h,m,s 단위가 사용되는 것을 관찰했습니다.

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

나는 이 명령을 더 쉽게 읽을 수 있도록 하거나 존재할 수 있는 포드 이름 및 상태와 같은 시간과 관련되지 않은 다른 필드와 더 잘 상호 작용하는 방법에 대한 제안을 환영합니다.

답변4

이를 이해하는 명령은 4d3h15m3sdateutils의 다음을 참조하세요 dadd.

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

여기서 해당 기간을 Unix epoch 시간의 시작 부분에 추가하고 그 결과를 UTC에 대한 오프셋이 0인 시간대에서 Unix epoch 시간으로 출력합니다.

관련 정보