Недавно мы начали сталкиваться с проблемами при развертывании нашего приложения .NET Core в k8s в Azure, когда приложение не могло найти имена хостов, такие как имя нашей базы данных Azure.
Проблема кажется прерывистой, так как наши старые модули все еще работают нормально, даже когда мы их отбрасываем, они возвращаются в порядке.
Проблема, описанная ниже, выглядит как проблема с Hangfire, но на самом деле это ошибка разрешения доменного имени.
Hangfire.SqlServer.SqlServerObjectsInstaller - An exception occurred while trying to perform the migration. Retrying...
System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 35 - An internal exception was caught)
---> System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (00000001, 11): Resource temporarily unavailable
at System.Net.Dns.InternalGetHostByName(String hostName)
at System.Net.Dns.GetHostAddresses(String hostNameOrAddress)
at System.Data.SqlClient.SNI.SNITCPHandle.Connect(String serverName, Int32 port, TimeSpan timeout)
at System.Data.SqlClient.SNI.SNITCPHandle..ctor(String serverName, Int32 port, Int64 timerExpire, Object callbackObject, Boolean parallel)
at System.Data.ProviderBase.DbConnectionPool.CheckPoolBlockingPeriod(Exception e)
at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.Open()
at Hangfire.SqlServer.SqlServerStorage.CreateAndOpenConnection()
at Hangfire.SqlServer.SqlServerStorage.UseConnection[T](DbConnection dedicatedConnection, Func`2 func)
at Hangfire.SqlServer.SqlServerStorage.UseConnection(DbConnection dedicatedConnection, Action`1 action)
at Hangfire.SqlServer.SqlServerStorage.Initialize()
ClientConnectionId:00000000-0000-0000-0000-000000000000
Выяснилось, что проблема была связана с истекшим сроком действия учетных данных участника-службы, что происходит ежегодно. В этой статье объясняется, как обновить субъект-службу.
TL;DR
Запустите этот bash-скрипт. (Если вы работаете в Windows, это будет работать в Git Bash. Просто не забудьте установить Azure CLI. Он не будет работать в PowerShell.)
RESOURCE=<your resource>
NAME=<cluster name>
SP_ID=$(az aks show --resource-group $RESOURCE --name $NAME --query servicePrincipalProfile.clientId -o tsv)
SP_SECRET=$(az ad sp credential reset --name $SP_ID --query password -o tsv)
az aks update-credentials --resource-group $RESOURCE --name $NAME --reset-service-principal --service-principal $SP_ID --client-secret $SP_SECRET
Примечание. Последняя команда будет выполняться более 5 минут. Я убил свой процесс, но он все равно завершился успешно.