Рубрики
Uncategorized

Самый простой способ отлаживать рабочие нагрузки Kubernetes

Отладка контейнерных рабочих нагрузок и стручков является ежедневная задача для каждого разработчика и инженера DEVOPS … Теги с DevOps, Kubernetes, Linux, отладки.

Отладка контейнерных рабочих нагрузок и Стручки Это ежедневная задача для каждого инженера-разработчика и разработчика, который работает с Куберовщиками. Часто простые kubectl logs или Kubectl Опишите стручок Достаточно найти виновник некоторых проблем, но некоторые проблемы сложнее охотиться. В этих случаях вы можете попытаться использовать kubectl Exec. Но даже это может быть недостаточно как некоторые контейнеры, такие как Отмерщика Даже не содержат оболочки, в которую вы могли бы SSH в. Так что мы оставили, если все вышеперечисленное не удается? …

Там может быть просто лучший способ …

Иногда вам нужно схватить больший молоток или просто использовать более подходящий инструмент для задачи под рукой. В случае отладки нагрузки на Kubernetes, этот подходящий инструмент будет Kubectl Debug , который является новой командой, добавленной не слишком давно (v1.18), что позволяет отлаживать работу подвода. Он впрыскивает специальный тип контейнера, называемый Эфемерконтайнер в проблемный стручок, позволяющий вам ткать и устранять неполадки. Это может быть очень полезно для случаев, описанных в вступлении или в любой другой ситуации, когда интерактивная отладка предпочтительна или более эффективна. Итак, Kubectl Debug Похоже, как путь, но использовать его, нам понадобится Эфемерные контейнеры Так что же именно это?

Эфемеральные контейнеры — это подзагодный ресурс в POD, аналогично нормальному Контейнеры Отказ В отличие от регулярных контейнеров, хотя эфемерные контейнеры не предназначены для строительных приложений, а скорее для их проверки. Мы не определяем их в момент создания POD, скорее вводим их с использованием специальных API в запущенное POD для запуска команд устранения неполадок и проверять среду POD. Помимо этих различий, эфемерные контейнеры также не хватает некоторых полей основных контейнеров, таких как Порты или Ресурсы Отказ

Почему мы нуждаются в них, хотя? Разве мы не можем просто использовать базовые контейнеры? Ну, вы не можете добавлять контейнеры для POD, поскольку они должны быть одноразовыми (или другими словами — удалены и воссозданы в любое время), что может затруднить устранение неполадок трудно воспроизвести ошибки, которые требуют проверки стручка. Вот почему эфемерные контейнеры были добавлены в API — они позволяют добавлять контейнер к существующему POD, что облегчает проверку работающих стручков.

Учитывая, что эфемерные контейнеры являются частью спецификации POD, который является ядром Kubernetes, как вы (возможно) еще не слышали об этом? Причина, по которой это в основном неизвестная особенность, потому что эфемерные контейнеры находятся в начале Альфа Этап, что означает, что они не включены по умолчанию. Ресурсы и особенности на этом этапе могут проходить большие изменения или быть полностью удалены в будущих версиях Кубератеса. Поэтому использовать их, вы должны явно включить их, используя Функция Гейтс в Кублет Отказ

Настройка объектных ворот

Мы уже установили, что мы хотим попробовать Kubectl Debug. Итак, как мы включаем в виду эфемерные контейнеры. Ну, это зависит от вашей кластеры. Например, если вы используете kubeadm Чтобы раскрутить создание кластеров, то вы можете использовать следующие Клостерконфигурация Чтобы включить эфемерные контейнеры:

apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.20.2
apiServer:
  extraArgs:
    feature-gates: ephemeral containers=true

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

# File: config.yaml
# Run:  kind create cluster --config ./config.yaml --name kind --image=kindest/node:v1.20.2
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
  ephemeral containers: true
nodes:
- role: control-plane

С кластером работает, мы должны убедиться, что это действительно сработало. Самый простой способ посмотреть, применяется ли эта конфигурация, заключается в проверке API POD, которая теперь должна включать в себя раздел эфемерных контейнеров рядом с обычными контейнерами:

~ $ kubectl explain pod.spec.ephemeralContainers
KIND:     Pod
VERSION:  v1

RESOURCE: ephemeralContainers <[]Object>

DESCRIPTION:
     List of ephemeral containers run in this pod....
...

Это подтверждает, что у нас есть и поэтому мы можем начать использовать Kubectl Debug. . Итак, давайте начнем с простого примера:

~ $ kubectl run some-app --image=k8s.gcr.io/pause:3.1 --restart=Never
~ $ kubectl debug -it some-app --image=busybox --target=some-app
Defaulting debug container name to debugger-tfqvh.
If you don't see a command prompt, try pressing enter.
/ #

# From other terminal...
~ $ kubectl describe pod some-app
...
Containers:
  some-app:
    Container ID:   containerd://60cc537eee843cb38a1ba295baaa172db8344eea59de4d75311400436d4a5083
    Image:          k8s.gcr.io/pause:3.1
    Image ID:       k8s.gcr.io/pause@sha256:f78411e19d84a252e53bff71a4407a5686c46983a2c2eeed83929b888179acea
...
Ephemeral Containers:
  debugger-tfqvh:
    Container ID:   containerd://12efbbf2e46bb523ae0546b2369801b51a61e1367dda839ce0e02f0e5c1a49d6
    Image:          busybox
    Image ID:       docker.io/library/busybox@sha256:ce2360d5189a033012fbad1635e037be86f23b65cfd676b436d0931af390a2ac
    Port:           
    Host Port:      
    State:          Running
      Started:      Mon, 15 Mar 2021 20:33:51 +0100
    Ready:          False
    Restart Count:  0
    Environment:    
    Mounts:         

Сначала начнем под названием какое-то приложение просто так у нас есть что-то до «Отладка» Отказ Затем мы бежим Kubectl Debug против этого стручка, указав Busybox Как изображение для эфемерального контейнера, а также цель, которая является оригинальным контейнером. Кроме того, мы также включаем -Питать Аргументы, так что мы немедленно прикрепите к контейнеру и получим сеанс оболочки.

В приведенном выше фрагменте вы также можете увидеть, что если мы опишем POD после запуска Kubectl Debug На нем тогда его описание будет включать Эфемерные контейнеры Раздел со значениями, которые мы указаны в качестве параметров команд ранее.

Процесс разделения пространства имен

Kubectl Debug Это довольно мощный инструмент, но иногда добавляя другой контейнер к струнию, может быть недостаточно, чтобы получить соответствующую информацию о приложении, работающем в другом контейнере POD. Это может быть случай, когда контейнер, не включающий необходимые инструменты отладки или даже оболочку. В такой ситуации мы можем использовать Обмен процессом Чтобы позволить нам проверить оригинальный контейнер POD с использованием нашего инъецированного эфемерального контейнера.

Одна проблема, хотя с использованием процессов состоит в том, что оно не может быть применено к существующим стручкам, поэтому мы должны создать новый с SPEC.ShareProcessnimespace Установить на правда и ввести в него эфемерный контейнер. Это было бы довольно громоздким, особенно если мы должны отлаживать несколько стручков/контейнеров или просто выполнять это несколько раз. К счастью, Kubectl Debug могу сделать это для нас, используя --Последимые процессы вариант:

~ $ kubectl run some-app --image=nginx --restart=Never
~ $ kubectl debug -it some-app --image=busybox --share-processes --copy-to=some-app-debug
Defaulting debug container name to debugger-tkwst.
If you don't see a command prompt, try pressing enter.
/ # ps ax
PID   USER     TIME  COMMAND
    1 root      0:00 /pause
    8 root      0:00 nginx: master process nginx -g daemon off;
   38 101       0:00 nginx: worker process
   39 root      0:00 sh
   46 root      0:00 ps ax

~ $ cat /proc/8/root/etc/nginx/conf.d/default.conf 
server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;
...

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

Как вы, вероятно, заметили, в дополнение к --Последимые процессы Мы также включали - kopy-to = new-pod-name Потому что — как было упомянуто — нам нужно создать новый POD, имя которого указывается этим флагом. Если мы тогда перечислите беговые стручки из другого терминала, мы увидим следующее:

# From other terminal:
~ $ kubectl get pods
NAME             READY   STATUS    RESTARTS   AGE
some-app         1/1     Running   0          23h
some-app-debug   2/2     Running   0          20s

И это наша новая отладка POD вдоль оригинального POD приложения. Он имеет 2 контейнера по сравнению с оригиналом, так как он также включает в себя эфемерную контейнер.

Кроме того, если вы хотите в любой момент подтвердить, разрешен ли совместное использование процессов в каком-то POD, то вы можете запустить:

~ $ kubectl get pod some-app-debug -o json  | jq .spec.shareProcessNamespace
true

Положить его в хорошее использование

Теперь, когда у нас есть функциональные ворота включены и знают, как работает команда, давайте попробуем поставить его хорошо использовать и отлаживать некоторое приложение. Представьте, что следующий сценарий — у нас есть приложение, которое плохо себя ведет, и нам нужно устранить неполадки, связанные с сетью, связанными с проблемами в своем контейнере. Приложение не имеет необходимых сетевых инструментов CLI, которые мы могли бы использовать. Чтобы решить это, мы можем использовать Kubectl Debug следующим образом:

~ $ kubectl run distroless-python --image=martinheinz/distroless-python --restart=Never
~ $ kubectl exec -it distroless-python -- /bin/sh
# id
/bin/sh: 1: id: not found
# ls
/bin/sh: 2: ls: not found
# env
/bin/sh: 3: env: not found
#
...

kubectl debug -it distroless-python --image=praqma/network-multitool --target=distroless-python -- sh
Defaulting debug container name to debugger-rvtd4.
If you don't see a command prompt, try pressing enter.
/ # ping localhost
PING localhost(localhost (::1)) 56 data bytes
64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.025 ms
64 bytes from localhost (::1): icmp_seq=2 ttl=64 time=0.044 ms
64 bytes from localhost (::1): icmp_seq=3 ttl=64 time=0.027 ms

После запуска POD мы впервые попытаемся получить сеанс оболочки в свой контейнер, что может показаться, что она сработала, но когда мы стараемся запустить некоторые основные команды, мы можем видеть, что там буквально ничего нет. Итак, вместо этого мы вводим эфемерную контейнер в POD, используя Praqma/Network-multitool Изображение, которое содержит инструменты, такие как Curl , пинг , Telnet , так далее. И теперь мы можем выполнять все необходимое устранение неполадок.

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

~ $ kubectl run distroless-python --image=martinheinz/distroless-python --restart=Never
~ $ kubectl debug -it distroless-python --image=busybox --share-processes --copy-to=distroless-python-debug
Defaulting debug container name to debugger-l692h.
If you don't see a command prompt, try pressing enter.
/ # ps ax
PID   USER     TIME  COMMAND
    1 root      0:00 /pause
    8 root      0:00 /usr/bin/python3.5 sleep.py  # Original container is just sleeping forever
   14 root      0:00 sh
   20 root      0:00 ps ax
/ # cat /proc/8/root/app/sleep.py 
import time
print("sleeping for 1 hour")
time.sleep(3600)

Здесь мы еще раз проработали контейнер, который использует imveroless Image. Зная, что мы не сможем ничего делать в своей оболочке, мы побежали Kubectl Debug с --share-процессы - acopy-to = ... , который создает новый POD с дополнительным эфемеральным контейнером, который имеет доступ ко всем процессам. Когда мы затем перечислим эксплуатацию процессов, мы видим, что наш процесс контейнера приложений имеет PID 8, что мы можем использовать для изучения его файлов и окружающей среды. Сделать это, мы должны пройти через /proc//... каталог — который в этом случае будет — /proc/8/root/app/... .

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

~ $ kubectl get pods
NAME                READY   STATUS             RESTARTS   AGE
crashing-app        0/1     CrashLoopBackOff   1          8s

~ $ kubectl debug crashing-app -it --copy-to=crashing-app-debug --container=crashing-app -- sh
If you don't see a command prompt, try pressing enter.
# id
uid=0(root) gid=0(root) groups=0(root)
#
...

# From another terminal
~ $ kubectl get pods
NAME                READY   STATUS             RESTARTS   AGE
crashing-app        0/1     CrashLoopBackOff   3          2m7s
crashing-app-debug  1/1     Running            0          16s

Бонус: Отладка кластерных узлов

Эта статья была в основном сосредоточена на отладке стручков и их контейнеров — но, поскольку любой кластер Admin знает — часто это узлы, которые нуждаются в отладке, а не стручки. К счастью для нас, Kubectl Debug Также позволяет отладить узлы, создавая POD, который будет работать на указанном узле с помощью корневой файловой системы узла, установленной в /root каталог. Это по существу действует как соединение SSH в узле, учитывая, что мы можем даже использовать Chroot Чтобы получить доступ к хост-бинарии:

~ $ kubectl get nodes
NAME                 STATUS   ROLES                  AGE   VERSION
kind-control-plane   Ready    control-plane,master   25h   v1.20.2

~ $ kubectl debug node/kind-control-plane -it --image=ubuntu
Creating debugging pod node-debugger-kind-control-plane-hvljt with container debugger on node kind-control-plane.
If you don't see a command prompt, try pressing enter.
root@kind-control-plane:/# chroot /host

# head kind/kubeadm.conf
apiServer:
  certSANs:
  - localhost
  - 127.0.0.1
  extraArgs:
    feature-gates: EphemeralContainers=true
    runtime-config: ""
apiVersion: kubeadm.k8s.io/v1beta2
clusterName: kind
controlPlaneEndpoint: kind-control-plane:6443

В приведенном выше фрагменте мы впервые опознали узел, который мы хотим отлавить, то мы побежали Kubectl Debug явно использую Узел/... в качестве параметра, чтобы получить доступ к узлу нашего кластера. После этого, когда мы привязываемся к POD, мы используем Chroot/host. вырваться из Chroot тюрьма и получить полный доступ к хозяину. Наконец, чтобы убедиться, что мы действительно можем видеть все на хосте, мы рассматриваем часть kubeadm.conf в котором мы можем увидеть Функциональные ворота: который мы настроили в начале статьи.

Заключение

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

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

С этим сказанным, Kubectl Debug И эфемеральные контейнеры являются лишь одним из многих полезных — но едва известных — Cubernetes Feated Gates, поэтому следить за последующей статье (ы), которые будут погружаться в некоторые другие скрытые особенности Кубератеса.

Оригинал: «https://dev.to/martinheinz/the-easiest-way-to-debug-kubernetes-workloads-1njg»