com.spotify.docker.client.DockerRequestException:请求错误:删除 unix://localhost:80/v1.12/containers/...:40

Posted

技术标签:

【中文标题】com.spotify.docker.client.DockerRequestException:请求错误:删除 unix://localhost:80/v1.12/containers/...:409【英文标题】:com.spotify.docker.client.DockerRequestException: Request error: DELETE unix://localhost:80/v1.12/containers/...: 409 【发布时间】:2015-12-07 23:21:49 【问题描述】:

我正在开发一个 Java 应用程序,该应用程序使用 Google Kubernetes 在 Apache Tomcat Docker 容器中部署 Web 工件。我使用https://github.com/spotify/docker-client 来执行 Docker 映像和容器处理活动,使用https://github.com/fabric8io/fabric8/tree/master/components/kubernetes-api 来执行 Kubernetes 相关功能。

在此应用程序中,我添加了一项功能,使用户能够删除用户部署的 Web 工件。

当移除 I 时,

    删除我用来生成所需数量的 pod 副本的 Kubernetes 复制控制器

    单独删除replica pods(因为在Java API的相应方法中删除replication controller时不会自动删除pods)

    删除已创建的对应服务

    delete off 删除的 pod 对应的 Docker Containers

    最后,移除用于部署的 Docker 镜像

以下代码显示了实现的删除功能:

public boolean remove(String tenant, String appName) throws WebArtifactHandlerException 
        String componentName = generateKubernetesComponentName(tenant, appName);
        final int singleImageIndex = 0;
        try 
            if (replicationControllerHandler.getReplicationController(componentName) != null) 
                String dockerImage = replicationControllerHandler.getReplicationController(componentName).getSpec()
                        .getTemplate().getSpec().getContainers().get(singleImageIndex).getImage();
                List<String> containerIds = containerHandler.getRunningContainerIdsByImage(dockerImage);
                replicationControllerHandler.deleteReplicationController(componentName);
                podHandler.deleteReplicaPods(tenant, appName);
                serviceHandler.deleteService(componentName);
                Thread.sleep(OPERATION_DELAY_IN_MILLISECONDS);
                containerHandler.deleteContainers(containerIds);
                imageBuilder.removeImage(tenant, appName, getDockerImageVersion(dockerImage));
                return true;
             else 
                return false;
            
         catch (Exception exception) 
            String message = String.format("Failed to remove web artifact[artifact]: %s",
                    generateKubernetesComponentName(tenant, appName));
            LOG.error(message, exception);
            throw new WebArtifactHandlerException(message, exception);
        
     

Docker Container删除功能的实现如下:

public void deleteContainers(List<String> containerIds) throws WebArtifactHandlerException 
        try 
            for (String containerId : containerIds) 
                dockerClient.removeContainer(containerId);
                Thread.sleep(OPERATION_DELAY_IN_MILLISECONDS);
            
         catch (Exception exception) 
            String message = "Could not delete the Docker Containers.";
            LOG.error(message, exception);
            throw new WebArtifactHandlerException(message, exception);
        
    

在上述情况下,尽管执行所需的功能没有任何问题,但在某些情况下,我倾向于得到以下异常。

Sep 11, 2015 3:57:28 PM org.apache.poc.webartifact.WebArtifactHandler remove
SEVERE: Failed to remove web artifact[artifact]: app-wso2-com
org.apache.poc.miscellaneous.exceptions.WebArtifactHandlerException: Could not delete the Docker Containers.
    at org.apache.poc.docker.JavaWebArtifactContainerHandler.deleteContainers(JavaWebArtifactContainerHandler.java:80)
    at org.apache.poc.webartifact.WebArtifactHandler.remove(WebArtifactHandler.java:206)
    at org.apache.poc.Executor.process(Executor.java:222)
    at org.apache.poc.Executor.main(Executor.java:46)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: com.spotify.docker.client.DockerRequestException: Request error: DELETE unix://localhost:80/v1.12/containers/af05916d2bddf73dcf8bf41c6ea7f5f3b859c90b97447a8248ffa7b5b3968691: 409
    at com.spotify.docker.client.DefaultDockerClient.propagate(DefaultDockerClient.java:1061)
    at com.spotify.docker.client.DefaultDockerClient.request(DefaultDockerClient.java:1021)
    at com.spotify.docker.client.DefaultDockerClient.removeContainer(DefaultDockerClient.java:544)
    at com.spotify.docker.client.DefaultDockerClient.removeContainer(DefaultDockerClient.java:535)
    at org.wso2.carbon6.poc.docker.JavaWebArtifactContainerHandler.deleteContainers(JavaWebArtifactContainerHandler.java:74)
    ... 8 more
Caused by: com.spotify.docker.client.shaded.javax.ws.rs.ClientErrorException: HTTP 409 Conflict
    at org.glassfish.jersey.client.JerseyInvocation.createExceptionForFamily(JerseyInvocation.java:991)
    at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:975)
    at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:795)
    at org.glassfish.jersey.client.JerseyInvocation.access$500(JerseyInvocation.java:91)
    at org.glassfish.jersey.client.JerseyInvocation$5.completed(JerseyInvocation.java:756)
    at org.glassfish.jersey.client.ClientRuntime.processResponse(ClientRuntime.java:189)
    at org.glassfish.jersey.client.ClientRuntime.access$300(ClientRuntime.java:74)
    at org.glassfish.jersey.client.ClientRuntime$1.run(ClientRuntime.java:171)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:320)
    at org.glassfish.jersey.client.ClientRuntime$2.run(ClientRuntime.java:201)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

我搜索了大量资源以寻求任何帮助,但我仍然无法在所有情况下避免它,我执行了这个功能。

一开始我往往比现在更频繁地遇到这个问题,但是在删除每个 Docker 容器结束时以及在删除任何 Docker 容器之前允许执行线程休眠,逐渐减少了我遇到这个问题的实例数量.

休眠线程是此问题的最终解决方案,还是有任何其他原因导致此问题弹出以及可以帮助我避免此异常的解决方案?任何帮助是极大的赞赏。

【问题讨论】:

【参考方案1】:

很遗憾,我不熟悉 Java 客户端库。

我的建议是尝试使用常规命令行客户端 (kubectl)。如果可行,那么您就知道问题出在 Java 客户端库或您对它的使用上。如果使用命令行客户端不起作用,那么会有更多的人可以帮助您(因为熟悉命令行客户端的人比熟悉 Java 客户端库的人多得多)。

换句话说 % kubectl delete pods ... # --cascade=true 默认 % kubectl 删除服务 ...

我很好奇为什么需要步骤 (4) 和 (5)。第 (4) 步应该在您删除 pod 时自动执行,第 (5) 步应该在后台自动执行。

如果“kubectl delete”的两行有效,那么问题出在 Java 客户端库或您对它的使用上。作为起点,我建议从您的 Java 代码中删除调用 deleteContainers() 和 removeImage() 并查看是否有帮助。我认为这些步骤是不必要的。

【讨论】:

是的,DavidO,就是这样。这些步骤适用于命令行客户端 (kubectl)。删除 pod 时无法删除相应的容器是由于 Java 客户端库而弹出的一些问题。当我删除复制控制器时也是如此,其中关联的 pod 没有被删除。这就是我手动删除它们的原因。另外,如果没有 deleteContainers() 和 removeImage() 方法,代码确实可以很好地工作,但我将它们包括在内,因为提供给我的规范要求我这样做。 另外,我没有使用命令行客户端 (kubectl),因为我被要求使用 Java 程序代码执行这些任务。 当然,我明白你为什么要使用 Java 客户端库;我只是建议尝试使用命令行客户端来帮助您缩小问题范围。 抱歉,发送太快了:当然,我明白你为什么要使用 Java 客户端库;我只是建议尝试使用命令行客户端来帮助您缩小问题范围。无论如何,更仔细地查看您收到的错误消息,这可能是因为在您运行 deleteContainers() 时容器已经被删除。我建议当您收到该错误消息时,检查容器是否已被删除。我怀疑你会发现它们已经被删除了。如果您发现它们尚未删除,请告诉我,我们可以寻找其他原因。 嗨 DavidO,是的,我尝试了你问我的方式,但是当应用 docker ps -a 时,异常指定的 Docker 容器仍然可以被视为已停止的容器,异常仍然发生。我现在觉得这是否与我的机器性能有关.

以上是关于com.spotify.docker.client.DockerRequestException:请求错误:删除 unix://localhost:80/v1.12/containers/...:40的主要内容,如果未能解决你的问题,请参考以下文章

Docker在本地打包maven程序为docker镜像报错: Connect to localhost:2375 [localhost/127.0.0.1, localhost/0:0:0:0:(代