Отладка в контейнерной среде – дело не самое простое, поэтому разработчики зачастую прибегают к неэффективным методам локализации ошибок на этапе развертывания. Допустим, вам надо отладить Kubernetes-оператор, потому что согласование кластера (reconciliation process) выполняется как-то не так или сам оператор работает неправильно. Чтобы понять, что происходит в продакшен-кластере, можно развернуть этот оператор на локальном Kubernetes-кластере, который крутится на вашем ноутбуке. Затем надо будет написать соответствующий код для отладки оператора, собрать новый отладочный образ, развернуть его на локальном кластере, и, наконец, отследить вывод и журналы на предмет информации, которая поможет исправить ошибку. Долго? Да, долго. Так что быстрее и красивее будет использовать отладчик на удаленном сервере, задав точки останова для поиска причин неполадок. Именно этот, второй и красивый, вариант мы рассмотрим сегодня и покажем, как запускать отладчик на кластере Kubernetes через IDE-среду Visual Studio Code (VS Code). В качестве приложения у нас будет программа на Go, но всё изложенное вполне применимо и к другим языкам программирования и отладчикам. Для начала разберем упомянутые выше методы отладки, чтобы понять, в чем красота второго варианта.  Контроль вывода – это самый простой способ развертывания и отладки приложений и операторов. Вам просто нужно продумать, где в коде расставить контрольные точки и добавить в них команды вывода отладочной информации. Проблема в том, что каждый раз, когда вы захотите добавить, убрать или изменить такой вывод, придется заново пересобирать образ – а на это требуется время. Плюс, добавьте время на то, чтобы развернуть оператор на кластере, прежде чем выполнять тестирование. Кроме того, в циклах согласования для комплексных операторов (тысячи и более строк на цикл) трудно бывает сразу определиться, какая именно информация понадобится для отладки. В результате, вам понадобится несколько попыток на то, чтобы локализовать проблему, и лишь потом уже приступить к отладке. Кроме того, при таком способе легко упустить из виду важные (с отладочной точки зрения) места в коде и не вставить туда команды вывода отладочной информации. В общем, при таком варианте отладки можно потерять массу времени, особенно, если вы не очень хорошо разбираетесь в отлаживаемом коде. Суть этого метода в том, чтобы использовать классический отладчик для получения информации, помогающей быстро понять причину проблемы. Процесс, который мы рассматриваем в этой статье, выполняется на удаленном сервере в среде Kubernetes, допустим, в промежуточной (staging) среде, которая эмулирует продакшен. Более того, вы создаете образы одновременно с тем, как вносите исправления в код, раз за разом развертывая оператор, и тем самым сокращаете время получения отладочной информации. Итак, ключевые особенности метода удаленной отладки: Выполняется удаленно, в тестовой, промежуточно или продакшен-среде. Используется интерактивный отладчик (в нашем случае, это Delve для программ на Go). Автоматическая сборка и развертывание образов при запуске отладчика. А теперь подробно рассмотрим, как организовать удаленную отладку. Расскажем, как настроить среду и инструменты для нашего приложения-примера. Мы будем использовать кластер Kubernetes на удаленном сервере и с помощью одного расширения для VS Code будем удаленной запускать там отладчик и наше приложение. Для этого мы будем использовать следующую среду: Ноутбук разработчика:  ОС: macOS Big Sur 11.6 VS Code IDE и расширения На ноутбуке установлена VS Code, но без инструментов развёртывания, вроде Docker, kubectl, и т. п. Сервер (hostname alkmini):  Linux (Fedora 5.11.8-200.fc33.x86_64) SSH-server Работающий Docker daemon kubectl и oc (интерфейс командной строки для Red Hat OpenShift) Delve (отладчик для Go) Кластер Kubernetes (в нашем примере, с использованием minikube) Для удаленного сервера также можно использовать промежуточный кластер, локальный кластер или какую-то другую конфигурацию. Здесь важно вот что: На локальной машине вам нужна только среда разработки. На удаленном сервер среда разработки не нужна. Первым делом установим расширения VS Code, чтобы потом запускать всё удаленно. Это расширение позволяет использовать VS Code на вашем ноутбуке для работы на удаленном сервере так, как будто вы работаете на своей локальной машине. Расширение использует SSH для подключения к удаленному серверу и выполнения команд на нем, а также для использования других расширений VS Code. Расширение Remote - SSH устанавливается из магазина приложений Visual Studio. Добавим в него наш сервер и откроем папку как рабочую область, чтобы начать работать удаленно. Добавим информацию о хосте и проверим, что у нас есть SSH-доступ к нему (через ранее добавленный SSH ключ). Затем переходим к папке, которую хотим добавить, как показано на Рис.1. О том, что вы работает удаленно, информирует зеленый индикатор SSH-соединения в левом нижнем углу, как показано на Рис. 2. Теперь всё, что вы делаете на своем ноутбуке в редакторе VS Code, выполняется на удаленном сервере. Продумайте, какие расширения нужны вам на удаленном сервере. Скорее всего, это лишь часть тех расширений, которые установлены на локальной системе. Это расширение обеспечивает непрерывную локальную обратную связь с вашим проектом в процессе редактирования, сборки, развертывания и запуска приложений локально или в облаке. Расширение взаимодействует с контейнерными инструментами командной строки Google, такими как Skaffold, minikube и kubectl. Cloud Code изначально был разработан для использования с Google Cloud Platform, но теперь работает на любых кластерах Kubernetes, в частности здесь мы используем на Kubernetes-кластере minikube. Расширение Cloud Code устанавливается из магазина приложений Visual Studio. Примечание. На момент написания этой статьи в последней версии Cloud Code была обнаружена ошибка, поэтому надо устанавливать предыдущую версию Cloud Code 1.14.1. Delve (dlv) –это официальный отладчик для языка программирования Go. Он удобен как в плане вызова, так и плане использования, и предоставляет простой и вместе с тем полнофункциональный инструмент отладки для Go. Если вы используете отладчик, то, скорее всего, дела идут не очень хорошо. Поэтому Delve, насколько это возможно, постарается не мешать вам. Delve устанавливается из репозитория GitHub следующим образом: Чтобы отлаживать приложение на удаленном сервере с локальной машины, используя редактор VS Code и расширение Remote – SSH, на удаленном сервере должен быть запущен отладчик Delve. В этом разделе мы в пошагового режиме разберем удаленную отладку. А также рассмотрим репозиторий и конфигурации, необходимые для интерактивной отладки приложения в кластере Kubernetes. Загрузить пример приложения Go можно из репозитория GitHub. Содержимое этого репозитория следующее: Ключевые элементы здесь следующие: Папка docker – содержит Dockerfile для генерации образа, который мы затем отправим в реестр Quay.io. Папка k8s – содержит манифест, описывающий развертывание приложения. Main.go – основной файл кода приложения. Skaffold.yaml – конфигурационный файл, используемый для сборки и развертывания приложения. .vscode/launch.json – конфигурация для расширения Cloud Code. Откроем файл .vscode/launch.json и добавим параметры конфигурации, отмеченные стрелками на Рис. 3 (мы опишем эти параметры ниже). Мы используем эту опцию, чтобы подключаться к запущенному pod’у в кластере Kubernetes для отладки. Если образ был собран с установленным отладчиком Delve, то в коде можно задать точку останова. Отладка приложения выполняется путем подключения к его podselector’у и порту, как показано в следующей конфигурации: При этом надо обязательно настроить свойства remotePath и remoteRoot. Иначе, к pod’у можно будет подключаться, но не отлаживаться, поскольку точка останова окажется «неверифицированной». Конфигурация для этой опции выглядит следующим образом: Поясним некоторые моменты: autoStop: – если задано true, сеанс отладки автоматически прекращается при завершении работы приложения. SkaffoldConfig: – это конфигурационный файл, с помощью которого происходит непрерывная сборка и развертывание приложения. watch: – это самая важная опция для интерактивной отладки. Она уведомляет Skaffold об изменениях в коде, чтобы Skaffold мог выполнять пересборку и повторно развёртывание образа, когда мы отлаживаем и меняем код. Кроме того, если включена опция auto-save, этот процесс будет работать постоянно. cleanUp: – это опция возврата сервера в чистое состоянии по завершении сеанса. Иначе говоря, уничтожения контейнеров и образов, созданных Skaffold’ом после того, как вы останавливаете отладчик. portForward: – эта опция позволяет запускать отладчик удаленно, перенаправляя порт в локальную среду. debug/image: – это образ, который будет собираться с уже установленным в него отладчиком Delve и нашим приложением. Если вкратце, то для отладки работающего pod’а можно использовать расширение Cloud Code вместе с опцией Attach (Go) to k8s Pod. Когда вы что-то меняете в своем коде, Skaffold выполняет пересборку и повторное развертывание образа, чтобы вы тут же венмогли продолжить отладку. Сочетание двух этих опций и обеспечивает волшебство удаленной отладки приложений и операторов Kubernetes. Skaffold – это очень интересный инструмент для создания и развертывания приложений непосредственно с помощью уже рассмотренного расширения Cloud Code. Вам достаточно лишь скопировать манифест, чтобы создать конвейера для своего приложения и запустить расширение Cloud Code, чтобы использовать этот манифеста. У Skaffold тоже есть ряд важных опций, которые мы рассмотрим чуть ниже. На Рис. 4 показана схема работы Skaffoldпри сборке и развертывании приложений. Этот процесс не происходит мгновенно, поскольку сборка занимает некоторое ненулевое время, но тем менее он обеспечивает итеративную отладку и пересборку, не заставляя останавливать отладчик. При этом мы используем следующий конфигурационный файл: На этапе сборки Skaffold можно использовать различные builder’ы, включая такие широко распространенные инструменты, как Dockerfile, Maven и Buildpacks, а также настраиваемые пользовательские скрипты. В нашем примере используется Buildpacks, который автоматически детектирует ваш Dockerfile и использует его для сборки: В больших проектах, где есть несколько этапов сборки со сложными Makefiles, можно использовать конфигурацию вроде такой: Также сборку можно выполнить, используя свою спецификацию Dockerfile, например, так: Для этапе развертывания Skaffold также можно использовать разные deployer’ы: Kubernetes, Helm, Kustomize и Docker. Для отладки приложения, его образ надо собирать вместе с Delve, чтобы иметь возможность запускать приложение через точку входа (entry point) команды dlv: Точка входа запускает приложение с помощью команды dlv, что позволяет отлаживать его на удаленном сервере. В нашем примере используется базовое развертывание приложения Kubernetes. Это простое развертывание с одним контейнером с использованием образа, который мы только что создали: Как только вся конфигурация будет готова, откроем расширение Cloud Code и выполним следующие шаги. Сначала проверим, что кластер готов, и мы можем обращаться к нему из VS Code и расширения Cloud Code, как показано на Рис. 5. Затем зададим в коде точку останова в коде, как показано на Рис. 6. А теперь щелкаем мышкой кнопку Debug on Kubernetes, чтобы запустить процесс, как показано на Рис. 7. Теперь, когда наше приложение запускается, оно работает через отладчик, как показано в этом видео: Чтобы воспроизвести описанный выше процесс у себя, надо скопировать проект внутрь Dockerfile, поскольку отладчику нужен доступ к стеку, чтобы знать, какая трасса является трассой для отладки. Делается это так: Основные инструменты, упоминавшиеся в этой статье: VScode Remote Explorer CРасширение Cloud Code Go-отладчик Delve Билдеры Skaffold Видео отладочного сеанса Программные решения с открытым исходным кодом