【问题标题】:API Management Self Hosted Gateway when restarting Docker Container重启 Docker 容器时的 API 管理自托管网关
【发布时间】:2021-08-19 17:39:24
【问题描述】:

APIM 自托管网关已在本地使用 Docker 容器设置。当互联网断开时,通过 SHG(自托管网关)的 API 调用继续工作(使用“内存中”配置)。此外,在断开连接时,用于检索配置的 API 管理调用停止工作,这也是意料之中的。

不起作用的是,当仍然断开连接运行时,Docker 容器重新启动,获取配置的调用不起作用,并且 Docker 不使用 Docker 卷中本地保存的配置。当互联网离线时,Docker 容器如何知道使用本地配置文件而不是依赖内存中的配置或必须与 APIM 建立良好的连接?

【问题讨论】:

    标签: azure azure-api-management


    【解决方案1】:

    当您使用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 stopdocker restart 命令时,容器内的主进程将收到SIGTERM,并在宽限期后收到SIGKILL

    docker kill 子命令会杀死一个或多个容器。容器内的主进程发送SIGKILL信号(默认),或--signal选项指定的信号。

    在这些情况下,进程退出并且相应的容器文件系统被删除。所以在docker startdocker 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 stopdocker killdocker pause 命令之间的区别。

    【讨论】:

    • @Srijit_Bose_MSFT - 谢谢你提供的信息。 MSFT 文章:docs.microsoft.com/en-us/azure/api-management/… 声明如下:当配置备份打开并且与 Azure 的连接中断时:-运行自托管网关将继续使用配置的内存副本运行-停止的自托管网关将能够开始使用配置的备份副本所以问题是......当docker重新启动时,为什么它不使用保存在本地卷/存储中的配置?根据 MSFT 文章中的观点。
    【解决方案2】:

    此问题是由 Microsoft 提出的。 APIM 团队确认只有错误代码 401 触发容器从配置启动。错误代码 502/503 被认为是暂时的。 APIM 团队计划尽快解决此问题。 v1.2.4 中的目标修复。 APIM 发行说明 github repo:https://github.com/Azure/API-Management

    【讨论】:

      猜你喜欢
      • 2021-12-17
      • 1970-01-01
      • 1970-01-01
      • 2019-05-25
      • 2020-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多