Недавно мы обновили все наши службы с .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
Примечания:
Докерфайл:
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
Похоже, проблема связана с несоответствием конфигурации между ожидаемым портом приложения и портом, проверенным проверкой работоспособности Kubernetes.
Вот несколько вещей, которые вы можете попробовать, чтобы устранить проблему:
Проверьте конфигурацию стартового зонда:
Проверьте приложение переменной среды:
Устраните потенциальные конфликты:
Просмотрите журналы Kubelet:
Рассмотрим изменения кода:
Если описанные выше способы не помогли, попробуйте выполнить следующие действия:
Тестируйте локально:
Упрощение развертывания YAML:
Обновление документации:
4. Проверил, вроде все нормально. Запрос никогда не достигает контейнера 5. Пробовал просто пинговать, все равно безуспешно.
3. попробовал использовать другой порт, в данном случае 5000, результат тот же.
если ничего не помогло, попробуйте изучить журналы Kubernetes и посмотреть, сможете ли вы решить проблему оттуда.
Я добавил дополнительную информацию в пост. Кажется, что служба Kestrel запускается ПОСЛЕ того, как считается, что приложение перезапускается/завершает работу, поскольку запрос HealthCheck не может быть выполнен.
Для тех, кто столкнулся с такой же ситуацией. Вот и решение моих проблем. Проблемы вызывал пакет NuGet, на их странице GitHub в то время не было примечаний к выпуску новой версии, поэтому было почти невозможно узнать, кроме простого обновления всего, что мы могли для нашего проекта.
Мы обновили веб-API, и он снова начал работать без каких-либо проблем.
<PackageReference Include = "Microsoft.ApplicationInsights.Kubernetes" Version = "6.1.2" />
к
<PackageReference Include = "Microsoft.ApplicationInsights.Kubernetes" Version = "7.0.0" />
На данный момент попробовал следующее, и вот результаты: 1. Проверено, и они совпадают. 2. Проверено, и вы можете видеть, что приложение .NET идентифицирует переменную среды. Также это установлено в yaml для развертывания модуля, а также в appsettings.json 3. Я мог видеть что-то подобное, но очень странно, что при понижении версии приложения до NET 6 это работает 4. Хорошее предложение, проверю подробнее 5. Проверено, но попробую просто пропинговать приложение без фактической проверки работоспособности 6. Локально все работает отлично и использует указанные порты 7. Проверю Спасибо за помощь