K8s Q A Shell Operator: различия между версиями

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску
Строка 19: Строка 19:
   
 
=Как это сделать=
 
=Как это сделать=
  +
  +
  +
Для обработки событий использую вот такой скрипт, при запуске с параметром <code>--config</code>он должен выдать описания событий на которые нужно подписаться,
  +
при запуске без параметров ему передается (чеерз переменную окружения <code>${BINDING_CONTEXT_PATH}</code> путь к файлу который содержит данные события
  +
<PRE>
  +
#!/usr/bin/env bash
  +
  +
NAMESPACE="stacklight"
  +
POD_NAME="elasticsearch-curator"
  +
  +
# Эта часть кода запускается при старте оператора, и
  +
# определяет на какие именно события будет подписываться этот скрипт
  +
# В частности - в каком именно неймспейсе
  +
if [[ $1 == "--config" ]] ;
  +
then
  +
cat <<EOF
  +
{
  +
"configVersion":"v1",
  +
"kubernetes":[
  +
{
  +
"apiVersion": "events.k8s.io/v1",
  +
"kind": "Event",
  +
  +
"namespace": {
  +
"nameSelector": {
  +
"matchNames": ["${NAMESPACE}"]
  +
}
  +
},
  +
  +
"fieldSelector": {
  +
"matchExpressions": [
  +
{
  +
"field": "metadata.namespace",
  +
"operator": "Equals",
  +
"value": "${NAMESPACE}"
  +
}
  +
]
  +
}
  +
  +
}
  +
]
  +
}
  +
EOF
  +
else
  +
# Сохранить содержимое BINDING_CONTEXT (для последующего анализа)
  +
cat "${BINDING_CONTEXT_PATH}" >> /tmp/log2
  +
echo ""
  +
echo "[events-hook.sh] Starting HOOK"
  +
echo "[events-hook.sh] ------------------------------------------"
  +
# Вывести в лог (лог пода)
  +
cat "${BINDING_CONTEXT_PATH}"
  +
echo "[events-hook.sh] "
  +
type=$(jq -r '.[0].type' ${BINDING_CONTEXT_PATH})
  +
echo "[events-hook.sh] ------------------------------------------"
  +
echo "[events-hook.sh] TYPE=${type}"
  +
echo "------------------------------------------"
  +
if [[ $type == "Event" ]] ; then
  +
echo "[events-hook.sh] Got Event: "
  +
echo "[events-hook.sh] ------------------------------------------"
  +
jq '.[0].object' ${BINDING_CONTEXT_PATH}
  +
echo "[events-hook.sh] ------------------------------------------"
  +
podName=$(jq -r '.[0].object.metadata.name' $BINDING_CONTEXT_PATH)
  +
echo "[events-hook.sh] Pod Name: '${podName}'"
  +
echo "[events-hook.sh] ------------------------------------------"
  +
else
  +
echo "DATA: ${BINDING_CONTEXT_PATH}" >> /tmp/log
  +
fi
  +
  +
#jq -r '.[0].object.note' ${BINDING_CONTEXT_PATH} >> /tmp/note.log
  +
note=$(jq -r '.[0].object.note' ${BINDING_CONTEXT_PATH})
  +
echo "[events-hook.sh] ------------------------------------------"
  +
echo "[events-hook.sh] Got note: ${note}"
  +
echo "[events-hook.sh] ------------------------------------------"
  +
  +
# Возможно на первой иттерации под не успеет стартовать, но
  +
# если он упадет, то его логи будут получены при следующем запуске
  +
# Cron Job
  +
if [[ "${note}" == "Started container ${POD_NAME}" ]];
  +
then
  +
D=$(date +%Y%m%d-%H%M%S)
  +
kubectl get pod | grep "${POD_NAME}"| grep -vE "Completed|Running|Pending|ContainerCreating" >> /tmp/list_pods_${D}
  +
for failedPod in $(kubectl get pod | grep "${POD_NAME}" | grep -vE "Completed|Running|Pending|ContainerCreating" | awk '{ print $1 }' );
  +
do
  +
# Найти под и вывести в логи его описание, дескрайб и логи
  +
echo "[events-hook.sh] Found failed POD: ${failedPod}"
  +
  +
describeFailedPod=$(kubectl describe pod ${failedPod})
  +
echo "[events-hook.sh] POD Describe: ${describeFailedPod}"
  +
echo "${describeFailedPod}" > /tmp/${failedPod}_describe_${D}
  +
  +
getFailedPodYaml=$(kubectl get pod ${failedPod} -o yaml)
  +
echo "[events-hook.sh] POD Definition: ${getFailedPodYaml}"
  +
echo "${getFailedPodYaml}" > /tmp/${failedPod}_yaml_${D}
  +
  +
failedPodLogs=$(kubectl \
  +
logs -f ${failedPod} \
  +
--all-containers 2>&1)
  +
echo "${failedPodLogs}" > /tmp/${failedPod}_logs_${D}
  +
echo "[events-hook.sh] POD Logs: ${failedPodLogs}"
  +
done
  +
fi
  +
fi
  +
</PRE>

Версия 19:01, 11 января 2024


Shell Operator

https://habr.com/ru/companies/flant/articles/447442/


Что нужно сделать

Есть cron-job которая

  • Падает время от времени (но не всегда, а скорее редко)
  • Подчищает за собой POD
  • Хочется найти упавший под и собрать с него логи ДО того как под будет удален
  • Не хочется сидеть и ждать такой под
  • Доступа к централизованной системе логгирования нет (так бывает - логи пишутся централизованно в корпоративную систему)

Как это сделать

Для обработки событий использую вот такой скрипт, при запуске с параметром --configон должен выдать описания событий на которые нужно подписаться, при запуске без параметров ему передается (чеерз переменную окружения ${BINDING_CONTEXT_PATH} путь к файлу который содержит данные события

#!/usr/bin/env bash

NAMESPACE="stacklight"
POD_NAME="elasticsearch-curator"

# Эта часть кода запускается при старте оператора, и
# определяет на какие именно события будет подписываться этот скрипт
# В частности - в каком именно неймспейсе
if [[ $1 == "--config" ]] ;
then
  cat <<EOF
{
  "configVersion":"v1",
  "kubernetes":[
    {
      "apiVersion": "events.k8s.io/v1",
      "kind": "Event",

      "namespace": {
        "nameSelector": {
          "matchNames": ["${NAMESPACE}"]
        }
      },

      "fieldSelector": {
        "matchExpressions": [
          {
            "field": "metadata.namespace",
            "operator": "Equals",
            "value": "${NAMESPACE}"
          }
        ]
      }

    }
  ]
}
EOF
else
    # Сохранить содержимое BINDING_CONTEXT (для последующего анализа)
    cat "${BINDING_CONTEXT_PATH}" >> /tmp/log2
    echo ""
    echo "[events-hook.sh] Starting HOOK"
    echo "[events-hook.sh] ------------------------------------------"
    # Вывести в лог (лог пода)
    cat "${BINDING_CONTEXT_PATH}"
    echo "[events-hook.sh] "
    type=$(jq -r '.[0].type' ${BINDING_CONTEXT_PATH})
    echo "[events-hook.sh] ------------------------------------------"
    echo "[events-hook.sh] TYPE=${type}"
    echo "------------------------------------------"
    if [[ $type == "Event" ]] ; then
        echo "[events-hook.sh] Got Event: "
        echo "[events-hook.sh] ------------------------------------------"
        jq '.[0].object' ${BINDING_CONTEXT_PATH}
        echo "[events-hook.sh] ------------------------------------------"
        podName=$(jq -r '.[0].object.metadata.name' $BINDING_CONTEXT_PATH)
        echo "[events-hook.sh] Pod Name: '${podName}'"
        echo "[events-hook.sh] ------------------------------------------"
    else
        echo "DATA: ${BINDING_CONTEXT_PATH}" >> /tmp/log
    fi

    #jq -r '.[0].object.note'  ${BINDING_CONTEXT_PATH} >> /tmp/note.log
    note=$(jq -r '.[0].object.note'  ${BINDING_CONTEXT_PATH})
    echo "[events-hook.sh] ------------------------------------------"
    echo "[events-hook.sh] Got note: ${note}"
    echo "[events-hook.sh] ------------------------------------------"

    # Возможно на первой иттерации под не успеет стартовать, но
    # если он упадет, то его логи будут получены при следующем запуске
    # Cron Job
    if [[ "${note}" == "Started container ${POD_NAME}" ]];
    then
        D=$(date +%Y%m%d-%H%M%S)
        kubectl get pod | grep "${POD_NAME}"| grep -vE "Completed|Running|Pending|ContainerCreating"  >> /tmp/list_pods_${D}
        for failedPod in $(kubectl get pod | grep "${POD_NAME}" | grep -vE "Completed|Running|Pending|ContainerCreating" | awk '{ print $1 }' );
        do
            # Найти под и вывести в логи его описание, дескрайб и логи
            echo "[events-hook.sh] Found failed POD: ${failedPod}"

            describeFailedPod=$(kubectl describe pod ${failedPod})
            echo "[events-hook.sh] POD Describe: ${describeFailedPod}"
            echo  "${describeFailedPod}" > /tmp/${failedPod}_describe_${D}

            getFailedPodYaml=$(kubectl get  pod ${failedPod} -o yaml)
            echo "[events-hook.sh] POD Definition: ${getFailedPodYaml}"
            echo  "${getFailedPodYaml}" > /tmp/${failedPod}_yaml_${D}

            failedPodLogs=$(kubectl \
                logs -f  ${failedPod} \
                 --all-containers 2>&1)
            echo  "${failedPodLogs}" > /tmp/${failedPod}_logs_${D}
            echo  "[events-hook.sh] POD Logs: ${failedPodLogs}"
        done
    fi
fi