当您使用ENTRYPOINT 和/bin/sh -c dotnet exec Gateway.Host.AspNetCore.dll $commit_env 中的/bin/sh -c dotnet exec Gateway.Host.AspNetCore.dll $commit_env 启动容器时(每个this section),主机上有或没有互联网连接我们看到:
[Info] 2021-08-25T08:33:43.357 [LoadingConfiguration], message: https://srbose-test-apim.management.azure-api.net/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xxxxxxx/providers/Microsoft.ApiManagement/service/srbose-test-apim/gateways/getConfiguration?api-version=2018-06-01-preview, source: ServiceConfigurationSource
当主机有互联网连接时,我们可以在docker logs看到前进:
[Info] 2021-08-25T08:33:46.297 [ConfigInitialSyncStarted], source: ConfigurationRepositoryProvider
[Info] 2021-08-25T08:33:49.059 [EventSnapshotElected], message: provider: storage, uri: https://apimxxxxxxxxxxxxxxxxxxxx.blob.core.windows.net/gatewaysnapshotsxxxxxxxxxxxxxx/snapshot-2019-10-11.gwhost_1.json.gzip, rev: 2, source: events.snapshot
[Info] 2021-08-25T08:33:49.074 [ConfigurationRetrieving], message: https://apimxxxxxxxxxxxxxxxxxxxx.blob.core.windows.net/gatewaysnapshotsxxxxxxxxxxxxxx/snapshot-2019-10-11.gwhost_1.json.gzip, source: events.snapshot.storage.private
[Info] 2021-08-25T08:33:49.649 [ConfigurationLoaded], message: https://apimxxxxxxxxxxxxxxxxxxxx.blob.core.windows.net/gatewaysnapshotsxxxxxxxxxxxxxxx/snapshot-2019-10-11.gwhost_1.json.gzip, source: events.snapshot.storage.private
[Info] 2021-08-25T08:33:49.798 [ConfigurationRetrieved], message: https://apimxxxxxxxxxxxxxxxxxxxx.blob.core.windows.net/gatewaysnapshotsxxxxxxxxxxxxxxx/snapshot-2019-10-11.gwhost_1.json.gzip, source: events.snapshot.storage.private
[Info] 2021-08-25T08:33:49.801 [LocalLoggerAddedToTenant], message: srbose-test-apim.azure-api.net, source: DefaultLocalLoggerConfigurationFilter
[Info] 2021-08-25T08:33:49.802 [LocalDiagnosticAddedtoTenant], message: srbose-test-apim.azure-api.net, source: DefaultTenantDiagnosticConfigurationFilter
[Info] 2021-08-25T08:33:49.853 [OperationRouteTableRebuildStarted], message: echo-api;rev=1, source: ApiRouter
[Info] 2021-08-25T08:33:49.884 [OperationRouteTableRebuildCompleted], message: echo-api;rev=1, source: ApiRouter
[Info] 2021-08-25T08:33:49.897 [LegacyBackendUpdated], source: BackendService
[Info] 2021-08-25T08:33:49.898 [EventSnapshotRestored], message: revision: 00000002, datasetId: xxxxxxxxxxxx, source: ConfigurationRepositoryProvider
[Info] 2021-08-25T08:33:49.902 [WaitingForRemainingEvents], message: snapshot-rev: 00000002, source: ConfigurationRepositoryProvider
[Info] 2021-08-25T08:33:49.904 [EventLoopStopped], source: TableStorageEventLoopFactory
[Info] 2021-08-25T08:33:49.904 [EventLoopStarted], source: TableStorageEventLoopFactory
[Info] 2021-08-25T08:33:51.539 [EventsSuccessfullyRestored], source: ConfigurationRepositoryProvider
[Info] 2021-08-25T08:33:51.541 [ConfigInitialSyncCompleted], source: ConfigurationRepositoryProvider
因此,自托管网关应用程序旨在在入口处启动初始配置同步。
如果在初始配置同步后容器主机上的互联网连接丢失,正在运行的容器仍然会同步配置。
当您运行docker stop 或docker restart 命令时,容器内的主进程将收到SIGTERM,并在宽限期后收到SIGKILL。
docker kill 子命令会杀死一个或多个容器。容器内的主进程发送SIGKILL信号(默认),或--signal选项指定的信号。
在这些情况下,进程退出并且相应的容器文件系统被删除。所以在docker start 或docker restart 上,进程再次从ENTRYPOINT 开始,容器文件系统是根据容器镜像构建的。这意味着它会在从ENTRYPOINT 执行时再次尝试同步配置。但是这一次,如果主机上的互联网连接以及容器上的扩展不可用,它就无法解析config.service.endpoint中提到的端点。
因此导致:
[Info] 2021-08-25T08:32:15.895 [LoadingConfiguration], message: https://srbose-test-apim.management.azure-api.net/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xxxxxxx/providers/Microsoft.ApiManagement/service/srbose-test-apim/gateways/getConfiguration?api-version=2018-06-01-preview, source: ServiceConfigurationSource
[Error]2021-08-25T08:32:16.063 [Error], exception: System.Net.Http.HttpRequestException: Name does not resolve
---> System.Net.Sockets.SocketException (0xFFFDFFFF): Name does not resolve
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at Gateway.Host.AspNetCore.ExternalConfiguration.ServiceConfigurationSource.<>c__DisplayClass17_0.<<UpdateConfiguration>b__1>d.MoveNext() in C:\azp\agent\_work\2\s\Proxy\Gateway.Host.AspNetCore\ExternalConfiguration\ServiceConfigurationSource.cs:line 156
--- End of stack trace from previous location where exception was thrown ---
at Polly.Retry.AsyncRetryEngine.ImplementationAsync[TResult](Func`3 action, Context context, CancellationToken cancellationToken, ExceptionPredicates shouldRetryExceptionPredicates, ResultPredicates`1 shouldRetryResultPredicates, Func`5 onRetryAsync, Int32 permittedRetryCount, IEnumerable`1 sleepDurationsEnumerable, Func`4 sleepDurationProvider, Boolean continueOnCapturedContext), source: ServiceConfigurationSource
相反,我建议您docker pause 容器,然后在您想恢复时使用docker unpause。这样,进程和相应的容器文件系统将保持在暂停状态,而不必从 ENTRYPOINT 重新开始。
docker pause 命令挂起指定容器中的所有进程。在 Linux 上,这使用了 freezer cgroup。传统上,当挂起一个进程时,会使用SIGSTOP 信号,这可以通过被挂起的进程观察到。使用 freezer cgroup,该进程不知道也无法捕获它正在暂停并随后恢复。在 Windows 上,只能暂停 Hyper-V 容器。
有关详细信息,请参阅freezer cgroup documentation。
以下是docker stop、docker kill 和docker pause 命令之间的区别。