Рубрики
Uncategorized

Kubernetes — Как отладить Crashloopbackoff в контейнере

Kubernetes — Как отлаживать Crashloopbackoff в контейнере, если вы использовали Kubernetes (K8S), … с меткой Kubernetes, DevOps, Debuging, Crashloopbackoff.

Если вы использовали 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»