Контейнерное приложение .NET обновлено с версии 6 до 8, и проба запуска начинает давать сбой в службах Azure Kubernetes

Недавно мы обновили все наши службы с .NET 6 до .NET 8, и все они полностью перестали работать в нашем кластере Azure Kubernetes. Все наши службы терпят неудачу из-за того, что проверка работоспособности в AKS не позволяет достичь контейнера. Следовательно, AKS перезапускает контейнер снова и снова.

Startup probe failed: Get "http://x.x.x.x:80/health/startup": dial tcp x.x.x.x:80: connect: connection refused

Моим первым подозрением было критическое изменение, которое произошло с портами по умолчанию в контейнерных приложениях .NET 8, которое изменило порт по умолчанию с 80 на 8080, указанный в документации, в нем говорится, что переменные среды ASPNETCORE_URLS, ASPNETCORE_HTTP_PORTS, ASPNETCORE_HTTPS_PORTS должны быть установлены для портов, которые вы хотите, чтобы приложение использовало.

Оказывается, что все наши сервисы уже указали ASPNETCORE_URLS в переменных среды контейнера И в файле appsettings.json до того, как мы выполнили обновление, а это означает, что приложение должно все еще использовать эти порты. Я также изменил Dockerfile, включив на всякий случай эти переменные среды, но все равно не повезло.

Я попытался увеличить тайм-аут запуска зонда, но тоже ничего не произошло.

startupProbe:
 httpGet:
   path: /health/startup
   port: http
 timeoutSeconds: 30

Примечания:

  • Я не менял НИ ОДИН файл развертывания.yaml, service.yaml или ingress.yaml для этого приложения, поскольку ранее они прослушивали и полностью работали на ПОРТ 80.
  • Когда приложение понижено до .NET 6, оно работает безупречно без каких-либо других изменений.

Докерфайл:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
ENV ASPNETCORE_URLS=http://+:80
ENV ASPNETCORE_HTTP_PORTS=80
ENV ASPNETCORE_HTTPS_PORTS=443

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["nuget.config", "."]
COPY ["NID.Support.API/NID.Support.API.csproj", "NID.Support.API/"]
RUN dotnet restore "NID.Support.API/NID.Support.API.csproj"
COPY . .
WORKDIR "/src/NID.Support.API"
RUN dotnet build "NID.Support.API.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "NID.Support.API.csproj" -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "NID.Support.API.dll"]

Обновлено:

Кажется, что служба Kestrel пытается запуститься ПОСЛЕ закрытия приложения, а не раньше. Не могу сказать, почему это так.

Логи из kubectl

[15:34:51 DBG] Registered model binder providers, in the following order: ["Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BinderTypeModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ServicesModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.HeaderModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FloatingPointTypeModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.EnumTypeModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.DateTimeModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.SimpleTypeModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.TryParseModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.CancellationTokenModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ByteArrayModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FormFileModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FormCollectionModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.KeyValuePairModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.DictionaryModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ArrayModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.CollectionModelBinderProvider", "Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexObjectModelBinderProvider"]
[15:34:53 DBG] Hosting starting
[15:34:53 WRN] Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed. For more information go to https://aka.ms/aspnet/dataprotectionwarning
[15:34:53 INF] User profile is available. Using '/root/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
[15:34:53 DBG] Repository contains no viable default key. Caller should generate a key with immediate activation.
[15:34:53 DBG] Policy resolution states that a new key should be added to the key ring.
[15:34:53 INF] Creating key {xxxx} with creation date 2024-06-12 15:34:53Z, activation date 2024-06-12 15:34:53Z, and expiration date 2024-09-10 15:34:53Z.
[15:34:53 DBG] Descriptor deserializer type for key {xxxx} is 'Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=9.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
[15:34:53 DBG] No key escrow sink found. Not writing key {xxxx} to escrow.
[15:34:53 WRN] No XML encryptor configured. Key {xxxx} may be persisted to storage in unencrypted form.
[15:34:53 INF] Writing data to file '/root/.aspnet/DataProtection-Keys/key-xxxx.xml'.
[15:34:53 DBG] Key cache expiration token triggered by 'CreateNewKey' operation.
[15:34:53 DBG] Reading data from file '/root/.aspnet/DataProtection-Keys/key-xxxx.xml'.
[15:34:53 DBG] Found key {xxxx}.
[15:34:53 DBG] Considering key {xxxx} with expiration date 2024-09-10 15:34:53Z as default key.
[15:34:53 DBG] Using managed symmetric algorithm 'System.Security.Cryptography.Aes'.
[15:34:53 DBG] Using managed keyed hash algorithm 'System.Security.Cryptography.HMACSHA256'.
[15:34:53 DBG] Using key {xxxx} as the default key.
[15:34:53 DBG] Key ring with default key {xxxx} was loaded during application startup.
[15:36:05 INF] Application is shutting down...
[15:36:05 WRN] Overriding HTTP_PORTS '80' and HTTPS_PORTS '443'. Binding to values defined by URLS instead 'http://*:80;'.
[15:36:06 DBG] Middleware configuration started with options: {AllowedHosts = *, AllowEmptyHosts = True, IncludeFailureMessage = True}
[15:36:06 DBG] Wildcard detected, all requests with hosts will be allowed.
[15:36:06 ERR] Hosting failed to start
System.Threading.Tasks.TaskCanceledException: A task was canceled.
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.BindAsync(CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__14_1(IHostedService service, CancellationToken token)
   at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)

System.Threading.Tasks.TaskCanceledException: A task was canceled.
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.BindAsync(CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__14_1(IHostedService service, CancellationToken token)
   at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)
   at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at Program.<Main>$(String[] args) in /src/NID.Support.API/Program.cs:line 182
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
193
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Похоже, проблема связана с несоответствием конфигурации между ожидаемым портом приложения и портом, проверенным проверкой работоспособности Kubernetes.

Вот несколько вещей, которые вы можете попробовать, чтобы устранить проблему:

Проверьте конфигурацию стартового зонда:

  1. Дважды проверьте конфигурацию startProbe в YAML-файле развертывания. файл. Убедитесь, что указанный порт соответствует порту вашего приложения. прослушивает (вероятно, 80 на основе ASPNETCORE_URLS).

Проверьте приложение переменной среды:

  1. Убедитесь, что переменные среды (ASPNETCORE_URLS, ASPNETCORE_HTTP_PORTS) фактически устанавливаются внутри контейнера. Вы можете использовать такие инструменты, как kubectl exec, чтобы войти в контейнер и проверить переменные среды.

Устраните потенциальные конфликты:

  1. Если другие процессы прослушивают порт 80 внутри контейнера, они могут конфликтовать с приложением. Рассмотрите возможность использования другого порт для проверки работоспособности или остановки любых конфликтующих процессов.

Просмотрите журналы Kubelet:

  1. Проверьте журналы Kubelet на наличие дополнительной информации о отказ датчика запуска. Эти журналы могут дать подсказку о попытка подключения.

Рассмотрим изменения кода:

  1. Хотя это и менее вероятно, в .NET 8 могут быть изменения кода, которые повлияют на поведение по умолчанию или конечная точка работоспособности. Проверьте официальный .NET 8 документацию по любым известным проблемам или критическим изменениям, связанным с проверки здоровья.

Если описанные выше способы не помогли, попробуйте выполнить следующие действия:

Тестируйте локально:

  1. Попробуйте развернуть контейнерное приложение локально (например, с помощью Docker). Напишите), чтобы проверить, сохраняется ли проблема за пределами AKS. Это может помогите изолировать проблему в конфигурации Kubernetes или само приложение.

Упрощение развертывания YAML:

  1. Если возможно, рассмотрите возможность удаления ненужной переменной среды. настройки из развертывания YAML и полагаясь исключительно на Настройки докерфайла. Это может помочь снизить сложность конфигурации.

Обновление документации:

  1. Если решение предполагает изменение кода или корректировку конфигурации специально для .NET 8, попробуйте обновить документацию чтобы отразить изменения, необходимые для плавного обновления.

На данный момент попробовал следующее, и вот результаты: 1. Проверено, и они совпадают. 2. Проверено, и вы можете видеть, что приложение .NET идентифицирует переменную среды. Также это установлено в yaml для развертывания модуля, а также в appsettings.json 3. Я мог видеть что-то подобное, но очень странно, что при понижении версии приложения до NET 6 это работает 4. Хорошее предложение, проверю подробнее 5. Проверено, но попробую просто пропинговать приложение без фактической проверки работоспособности 6. Локально все работает отлично и использует указанные порты 7. Проверю Спасибо за помощь

Juan P. Garces 12.06.2024 15:11

4. Проверил, вроде все нормально. Запрос никогда не достигает контейнера 5. Пробовал просто пинговать, все равно безуспешно.

Juan P. Garces 12.06.2024 15:29

3. попробовал использовать другой порт, в данном случае 5000, результат тот же.

Juan P. Garces 12.06.2024 16:25

если ничего не помогло, попробуйте изучить журналы Kubernetes и посмотреть, сможете ли вы решить проблему оттуда.

A.Haque 12.06.2024 16:42

Я добавил дополнительную информацию в пост. Кажется, что служба Kestrel запускается ПОСЛЕ того, как считается, что приложение перезапускается/завершает работу, поскольку запрос HealthCheck не может быть выполнен.

Juan P. Garces 12.06.2024 17:43
Ответ принят как подходящий

Для тех, кто столкнулся с такой же ситуацией. Вот и решение моих проблем. Проблемы вызывал пакет NuGet, на их странице GitHub в то время не было примечаний к выпуску новой версии, поэтому было почти невозможно узнать, кроме простого обновления всего, что мы могли для нашего проекта.

Мы обновили веб-API, и он снова начал работать без каких-либо проблем.

<PackageReference Include = "Microsoft.ApplicationInsights.Kubernetes" Version = "6.1.2" />

к

<PackageReference Include = "Microsoft.ApplicationInsights.Kubernetes" Version = "7.0.0" />

Другие вопросы по теме

Удаление назначения роли az: в запросе не было подписки или допустимого поставщика ресурсов уровня клиента
Проблема с веб-приложением или Azure?: в этом регионе для вашей подписки предусмотрена квота в 0 ядер PremiumV2. Попробуйте выбрать другой регион или артикул
Получить все типы ресурсов в группе ресурсов
Как подключить модуль в AKS к Центру событий Azure с помощью интерфейса Kafka?
Перемещение электронных писем в удаленные элементы с помощью Microsoft Graph API
Предоставление согласия администратора на разрешение API регистрации приложения
Периодические проблемы с триггерами в сетке событий для загрузки и удаления больших двоичных объектов в функции Azure
Ошибка выдачи конвейера Azure Devops при запуске сценария PowerShell. В строке отсутствует терминатор: "
Azure b2c все еще проходит проверку подлинности после выхода из системы
Как условно ограничить доступ к конечной точке API на основе идентификатора аудитории?