Привет! Я Саша Хренников, руководитель DevOps-юнита в KTS.

Новогоднее испытание для DevOps-инженеров подошло к концу, и сегодня я пошагово разберу решение задачи. Но сначала я сделаю два объявления.

Во-первых, с этого дня мы открываем доступ ко всем архивным челленджам. Если вы не успели поучаствовать, но хотите проверить свои силы и подготовиться к будущим испытаниям, вы можете перейти в нашего бота, и он расскажет, что делать. Главное — попробуйте разобраться самостоятельно, не спойлерите себе решение.

Почитать описания архивных челленджей можно здесь:

  1. DevOps-челлендж: решите задачку и выиграйте крутой мерч

  2. Назад в прошлое: запускаем k8s v.0.1 из 2014 и анонсируем челлендж

  3. DevOps Challenge: восстановите работу MySQL и выиграйте крутой мерч

Во-вторых, я с радостью поздравляю победителей текущего испытания — тринадцать участников, которые быстрее всех справились с заданием и уже освобождают место в шкафу для нашего мерча. Итак, поздравляем с победой:

  1. Konstantin aka @526***: 5 мин 42 сек

  2. Chatbot aka @mr_hightlook: 5 мин 51 сек

  3. ne0ba aka @ne0ba: 5 мин 53 сек

  4. Alexey AnyOps aka @mozgoo: 9 мин 1 сек

  5. ssch aka @ssch1337: 10 мин 22 сек

  6. Dmitry Tigrov aka @dmitrytiger: 15 мин 26 сек

  7. Alexandr Boltris aka @AlexandrBoltris: 17 мин 41 сек

  8. Alexander Evsikov aka @Evsikov: 18 мин 33 сек

  9. Igor Dronov aka @Benosa19: 19 мин 33 сек

  10. Кирилл aka @kirill_serguta: 20 мин 26 сек

  11. Azat aka @nevmetovazat: 22 мин 26 сек

  12. Sergei D aka @sergei0d: 26 мин 0 сек

  13. Vladimir Fedorov aka @FdrvVldmr: 26 мин 0 сек

Именно им, а не своим оленям, Деду Морозу стоило поручать развертывание приложения. А пока Дедушка развозит подарки, я предлагаю разобраться с тем, что натворили наши парнокопытные.

Оглавление

Диагностика

Сперва посмотрим, что запущено в кластере и какие ошибки мы видим при запуске. 

#kubectl get po
NAME                       READY   STATUS             RESTARTS      AGE
newyear-76ccb4dffd-kxtc5   0/1     CrashLoopBackOff   4 (49s ago)   2m32s
#kubectl logs newyear-76ccb4dffd-kxtc5
2024/12/31 23:59:59 err

Похоже, что для отладки придется погружаться в под. Для этого отредактируем deployment, предварительно сохранив его.

#kubectl get deploy
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
newyear   0/1     1            0           4m27s
#kubectl get deploy newyear -o yaml > ./deploy.yaml
#kubectl edit deploy newyear

Во время редактирования стоит удалить livenessProbe и заменить параметр command на что-то, что не будет падать при запуске. Например, так:

  • Исходный вариант:

   spec:
     containers:
     - command:
       - /build/newyaer
       image: cr.yandex/crpeghj733dngql9boeu/challenges-new-year-disk:0.0.1
       imagePullPolicy: IfNotPresent
       livenessProbe:
         failureThreshold: 3
         httpGet:
           path: /status
           port: 8080
           scheme: HTTP
         periodSeconds: 10
         successThreshold: 1
         timeoutSeconds: 1
  • Результат:

   spec:
     containers:
     - command:
       - tail
       - -f
       - /etc/hosts
       image: cr.yandex/crpeghj733dngql9boeu/challenges-new-year-disk:0.0.1
       imagePullPolicy: IfNotPresent

Теперь можно попасть в запущенный под через exec и сразу воспроизвести проблему.

#kubectl get po
NAME                       READY   STATUS    RESTARTS   AGE
newyear-559dd4766f-dcbtz   1/1     Running   0          26s
#kubectl exec -it newyear-559dd4766f-dcbtz -- /bin/bash
root@newyear-559dd4766f-dcbtz:/build# /build/newyaer
2024/12/31 23:59:59 err

Далее есть два способа разобраться, что же не так с приложением.

  • Первый — для староверов и любителей низкоуровневой отладки:

root@newyear-559dd4766f-dcbtz:/build# strace /build/newyaer
openat(AT_FDCWD, "/opt/storage/2024HNY.txt", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644) = -1 ENOSPC (No space left on device)
  • Второй для тех, кто верит, что даже олени способны на разумные действия:

root@newyear-559dd4766f-dcbtz:/build# /build/newyaer -h
You can add -v
2024/12/31 23:59:59 err
root@newyear-559dd4766f-dcbtz:/build# /build/newyaer -v
2024/12/31 23:59:59 open /opt/storage/2024HNY.txt: no space left on device

В обоих случаях мы узнаем, что приложение не может создать файл /opt/storage/2024HNY.txt из-за нехватки места на диске. Видимо, стоит посмотреть, что происходит со свободным местом.

root@newyear-559dd4766f-dcbtz:/build# df -h
Filesystem      Size  Used Avail Use% Mounted on
…
/dev/vdb        488M  129M  349M  28% /opt/storage
…

Странная ситуация. Непохоже, что места недостаточно. Но и в этом случае стоит проверить еще один вариант — индексные дескрипторы, они же inode.

root@newyear-559dd4766f-dcbtz:/build# df -i
Filesystem      Inodes  IUsed   IFree IUse% Mounted on
…
/dev/vdb         32768  32768       0  100% /opt/storage
…

Вот и наша проблема. Все дескрипторы загружены, и приложение не может запуститься.

Фикс

Сначала нужно посмотреть, чем же заняты все дескрипторы.

ls -lah /opt/storage/ | head -n 10
total 129M
drwxr-xr-x 3 root root 928K Dec 16 20:56 .
drwxr-xr-x 1 root root 4.0K Dec 16 21:05 ..
-rw-r--r-- 1 root root    2 Dec 16 20:56 0.txt
-rw-r--r-- 1 root root    2 Dec 16 20:56 1.txt
-rw-r--r-- 1 root root    3 Dec 16 20:56 10.txt
-rw-r--r-- 1 root root    4 Dec 16 20:56 100.txt
-rw-r--r-- 1 root root    5 Dec 16 20:56 1000.txt
-rw-r--r-- 1 root root    6 Dec 16 20:56 10000.txt
-rw-r--r-- 1 root root    6 Dec 16 20:56 10001.txt

Большое количество мусорных файлов. Скорее всего, чистить все и сразу не стоит. В качестве эксперимента попробуем удалить один и запустить приложение:

root@newyear-559dd4766f-dcbtz:/build# cd /opt/storage/
root@newyear-559dd4766f-dcbtz:/opt/storage# rm ./1.txt
root@newyear-559dd4766f-dcbtz:/opt/storage# /build/newyaer -v
2024/12/31 23:59:59 open /opt/storage/2025HNY.txt: no space left on device

Любопытно, ошибка сохраняется, но имя файла поменялось. Похоже, что приложение хочет создать больше одного файла. Что ж, давайте попробуем удалить весь мусор.

root@newyear-559dd4766f-dcbtz:/opt/storage# rm ./*.txt
root@newyear-559dd4766f-dcbtz:/opt/storage# ls -lah
total 952K
drwxr-xr-x 3 root root 928K Dec 16 21:12 .
drwxr-xr-x 1 root root 4.0K Dec 16 21:05 ..
-rw-r--r-- 1 root root   69 Dec 16 20:56 2025conf.yaml

Увлекательно. Оказывается, у приложения был еще и конфиг. Кстати, если его удалить, то с ключом -v вы получите подсказки по его восстановлению.

root@newyear-559dd4766f-dcbtz:/opt/storage# rm ./2025conf.yaml
root@newyear-559dd4766f-dcbtz:/opt/storage# /build/newyaer -v
2024/12/31 23:59:59 open /opt/storage/2025conf.yaml: no such file or directory
root@newyear-559dd4766f-dcbtz:/opt/storage# > ./2025conf.yaml
root@newyear-559dd4766f-dcbtz:/opt/storage# /build/newyaer
2024/12/31 23:59:59 config error
/build/newyaer -v
2024/12/31 23:59:59 Please fill out the configuration in the following format:
    config:
      timeout: 5
      year: 2025
      greeting: "Happy New Year"

Наконец, когда проблема с файлами решена, мы можем проверить, что приложение перестало падать. Для этого запустим и прервем оригинальный бинарник /build/newyear.

И теперь, когда мы убедились, что приложение не падает, можно вернуть исходную конфигурацию deployment и проверить его работоспособность.

#kubectl edit deploy newyear
#kubectl get po
NAME                       READY   STATUS        RESTARTS   AGE
newyear-559dd4766f-dcbtz   1/1     Terminating   0          12m
newyear-76ccb4dffd-zgg28   1/1     Running       0          3s
#kubectl exec -it newyear-76ccb4dffd-zgg28 -- /bin/bash
root@newyear-76ccb4dffd-zgg28:/build# curl 127.0.0.1:8080/status
Happy New Year

Заключение

Вот, собственно, и все решение. На этот раз мы постарались не перегибать со сложностью, но все же оставить простор для гипотез и рассуждений. Будем благодарны, если вы поделитесь впечатлениями в комментариях и расскажете, что стоит улучшить к следующему разу.

Если же вам не хватает задач, вы уже прорешали все архивные челленджи и хотите окончательно преисполниться в своем познании перед новогодними праздниками, рекомендую почитать наши статьи для DevOps-инженеров. Там мы с коллегами делимся опытом и описываем технологии, которыми сами пользуемся в работе:

И желаем вам удачи с любыми испытаниями в наступающем году!

Комментарии (0)