Если вы использовали Kubernetes (K8s), вы, вероятно, наткнулись на страшный Crashloopbackoff. CrashloopbackOff возможен для нескольких типов неправильных конфигураций K8s (не способных подключиться к постоянным объемам, неправильной конфигурации инициаторов и т. Д.). Мы не собираемся охватывать, как правильно настроить K8s в этой статье, но вместо этого сосредоточимся на более сложной проблеме отладки вашего кода или, что еще хуже, чужой код 😱
Вот выход из Kubectl Опишите POD для Crashloopbackoff:
Name: frontend-5c49b595fc-sjzkg Namespace: tedbf02-ac-david-nginx-golang-tmcclung-nginx-golang Priority: 0 Start Time: Wed, 23 Dec 2020 14:55:49 -0500 Labels: app=frontend pod-template-hash=5c49b595fc tier=frontend Status: Running IP: 10.1.31.0 IPs:Controlled By: ReplicaSet/frontend-5c49b595fc Containers: frontend: Container ID: docker://a4ed7efcaaa87fe36342cf7532ff1de5cd51b62d3d681dfb9857999300f6c587 Image: .amazonaws.com/tommyrelease/awesome-compose/frontend@sha256:dfd762c Image ID: docker-pullable://.amazonaws.com/tommyrelease/awesome-compose/frontend@sha256:dfd762c Port: 80/TCP Host Port: 0/TCP State: Waiting Reason: CrashLoopBackOff Last State: Terminated Reason: Error Exit Code: 1 Started: Sun, 24 Jan 2021 20:25:26 -0500 Finished: Sun, 24 Jan 2021 20:25:26 -0500 Ready: False Restart Count: 9043
Две общие проблемы при запуске контейнера — это время выполнения OCI, создать сбой (что означает, что вы ссылаетесь на двоичный или скрипт, который не существует в контейнере) и контейнер «заполнен» или «ошибка», что означает, что код, выполняемый в контейнере Не удалось запустить сервис и остаться в запуске.
Вот пример ошибки времени выполнения OCI, пытаясь выполнить: «Hello Crashloop»:
Port: 80/TCP Host Port: 0/TCP Command: hello crashloop State: Waiting Reason: CrashLoopBackOff Last State: Terminated Reason: ContainerCannotRun Message: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "hello": executable file not found in $PATH: unknown Exit Code: 127 Started: Mon, 25 Jan 2021 22:20:04 -0500 Finished: Mon, 25 Jan 2021 22:20:04 -0500
K8s дает вам состояние выхода процесса в контейнере, когда вы смотрите на стручок, используя kubectl или K9S Анкет Общие статусы выхода из процессов UNIX включают 1-125. Каждая команда Unix обычно имеет страницу человека, которая предоставляет более подробную информацию о различных кодах выхода. Выход кода (128 + Sigkill 9) 137 означает, что K8s достигают предела памяти для вашего стручка и убили ваш контейнер для вас.
Вот вывод из Kubectl описать POD, показывающий код выхода контейнера:
Last State: Terminated Reason: Error Exit Code: 1 Started: Sun, 24 Jan 2021 20:25:26 -0500 Finished: Sun, 24 Jan 2021 20:25:26 -0500 Ready: False Restart Count: 9043
Все контейнеры не создаются одинаково.
Docker позволяет вам определить Intrypoint
а также CMD
который вы можете смешивать и сочетать в Dockerfile. Intrypoint
исполняется и CMD
Аргументы переданы в Intrypoint
Анкет Схема Dockerfile довольно мягкая и позволяет пользователям устанавливать CMD
без Intrypoint
, что означает, что первый аргумент в CMD
будет исполняемым, чтобы запустить.
Примечание: K8S использует другое соглашение об именах для Docker Intrypoint
а также CMD
Анкет В Kubernetes Команда
это Docker Intrypoint
и kubernetes args
это докер CMD
Анкет
Команда, выполняемая контейнером | Точка входа | командование |
Аргументы, переданные команде | CMD | Аргс |
Есть несколько трюков, чтобы понять, как начинается контейнер, с которым вы работаете. Чтобы получить команду запуска, когда вы имеете дело с чужой контейнером, нам нужно знать предполагаемый Docker Intrypoint
а также CMD
изображения Docker. Если у вас есть Dockerfile, который создал изображение Docker, то вы, вероятно, уже знаете Intrypoint
а также CMD
, если вы не определяете их и не унаследоваете от базового изображения, которое их устанавливает.
При работе с контейнерами на полке, используя чужой контейнер, и у вас нет Dockerfile, или вы унаследоваете от базового изображения, на которого нет Dockerfile, вы можете использовать следующие шаги, чтобы получить ценности, которые вам нужны. Сначала мы тянем контейнер локально, используя Docker Pull
, затем мы осматриваем изображение контейнера, чтобы получить Intrypoint
а также CMD
:
Docker Pull <Идентификатор изображения>
Docker осмотреть
Здесь мы используем JQ
Чтобы отфильтровать ответ JSON от Docker осмотреть
:
david@sega:~: docker pull docker.elastic.co/elasticsearch/elasticsearch:7.10.2 7.10.2: Pulling from elasticsearch/elasticsearch ddf49b9115d7: Pull complete e736878e27ad: Pull complete 7487c9dcefbe: Pull complete 9ccb7e6e1f0c: Pull complete dcec6dec98db: Pull complete 8a10b4854661: Pull complete 1e595aee1b7d: Pull complete 06cc198dbf22: Pull complete 55b9b1b50ed8: Pull complete Digest: sha256:d528cec81720266974fdfe7a0f12fee928dc02e5a2c754b45b9a84c84695bfd9 Status: Downloaded newer image for docker.elastic.co/elasticsearch/elasticsearch:7.10.2 docker.elastic.co/elasticsearch/elasticsearch:7.10.2 david@sega:~: docker inspect docker.elastic.co/elasticsearch/elasticsearch:7.10.2 | jq '.[0] .ContainerConfig .Entrypoint' [ "/tini", "--", "/usr/local/bin/docker-entrypoint.sh" ] david@sega:~: docker inspect docker.elastic.co/elasticsearch/elasticsearch:7.10.2 | jq '.[0] .ContainerConfig .Cmd' [ "/bin/sh", "-c", "#(nop) ", "CMD [\"eswrapper\"]" ]
Страшный Crashloopbackoff
Теперь, когда у вас есть весь этот фон, давайте доберемся до отладки Crashloopbackoff.
Чтобы понять, что происходит, важно иметь возможность осмотреть контейнер внутри K8s, чтобы в приложении были все переменные среды и зависимые службы. Обновление развертывания и настройка контейнера Intrypoint
или k8s Команда
временно до хвост -f/dev/null
или Бесконечность сна
Даст вам возможность отладить, почему сервис не останется.
Вот как настроить K8s для переопределения контейнера Intrypoint
:
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: elasticsearch namespace: elasticsearch spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 3 selector: matchLabels: app: backend tier: backend strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: creationTimestamp: null labels: app: backend tier: backend spec: containers: - command: - tail - "-f" - /dev/null
Вот конфигурация в Выпуск :
services: - name: elasticsearch image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2 command: - tail - "-f" - /dev/null
Теперь вы можете использовать kubectl
или K9S
Чтобы вывести в контейнер и осмотреть. Используя Intrypoint
а также CMD
Вы обнаружили ранее, вы можете выполнить предполагаемую команду запуска и посмотреть, как сбои приложение.
В зависимости от контейнера, в котором вы запускаете, он может не хватать во многих инструментах, необходимых для отладки вашей проблемы, таких как: curl, lsof, vim; И если это чужой код, вы, вероятно, не знаете, какая версия Linux использовалась для создания изображения. Обычно мы пробуем всех общих менеджеров пакетов, пока не найдем правильный. Большинство контейнеров в наши дни используют Alpine Linux (Manager Package Package) или Debian, Ubuntu (Apt-Get Package Manager). В некоторых случаях мы видели Centos и Fedora, которые используют менеджер пакетов YUM.
Одна из следующих команд должна работать в зависимости от операционной системы:
апк
apt-get
мрачный
Сопровождающие Dockerfile часто удаляют кэш из менеджера пакетов, чтобы сократить размер изображения, поэтому вам также может потребоваться запустить одно из следующих действий:
обновление APK
apt-get обновление
Yum Makecache
Теперь вам нужно добавить необходимые инструменты, чтобы помочь в отладке. В зависимости от того, что вы нашли менеджер пакетов, используйте одну из следующих команд для добавления полезных инструментов отладки:
— apt-get install -y curl vim procps inetutils-tools net-tools lsof
— APK добавить Curl Vim Procps Net-Tools LSOF
— YUM Установка Curl Vim Procps lsof
На данный момент вам решать, чтобы выяснить проблему. Вы можете редактировать файлы, используя Vim, чтобы настроить контейнер, пока не поймете, что происходит. Если вы забудете все файлы, которые вы коснулись в контейнере, вы можете всегда убить стручку, и контейнер перезагрузится без ваших изменений. Всегда не забудьте записать шаги, предпринятые для работы контейнера. Вы захотите использовать свои заметки, чтобы изменить DockerFile или добавить команды в сценарии запуска контейнеров.
Отладка ваших контейнеров
Мы создали простой сценарий, чтобы получить все инструменты отладки, если вы работаете с контейнером, который предварительно установил скручивание:
# install debugging tools on a container with curl pre-installed /bin/sh -c "$(curl -fsSL https://raw.githubusercontent.com/releasehub-com/container-debug/main/install.sh)"
Оригинал: «https://dev.to/tmcclung/kubernetes-how-to-debug-crashloopbackoff-in-a-container-18mn»