com.spotify.docker.client.DockerRequestException:请求错误:DELETE unix:// localhost:80 / v1.12 / containers / …:409

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

在这个应用程序中,我添加了一个function,使用户能够移除用户部署的Web工件。

删除I时,

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

  2. 分别删除副本窗格(因为在Java API的相应方法中删除复制控制器时,不会自动删除窗格)

  3. 删除掉相应的服务创build

  4. 删除对应于已删除的窗格的Docker容器

  5. 最后,删除用于部署的Docker镜像

以下代码显示了已执行的删除function:

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容器删除function的实现如下:

 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); } } 

在上述情况下,虽然执行期望的function没有任何问题发生,但在某些情况下,我倾向于得到以下例外。

 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) 

我search了大量的消息来源,但仍然无法避免它,我执行这个function。

在开始的时候,我倾向于比现在更频繁地得到这个问题,但是允许执行的线程在删除每个Docker容器的末尾睡眠,在删除任何Docker容器之前,逐渐减less了我遇到这个问题的实例的数量。

睡觉的线程是这个问题的最终解决scheme还是有任何其他原因,这个问题popup和解决scheme,可以帮助我避免这种exception? 任何帮助是极大的赞赏。

不幸的是,我不熟悉Java客户端库。

我的build议是尝试使用常规的命令行客户端(kubectl)。 如果这有效,那么你知道问题出在Java客户端库或者你的使用情况。 如果使用命令行客户端不起作用,那么会有更多的人可以帮助你(因为很多人熟悉命令行客户端而不是Java客户端库)。

换句话说,%kubectl删除豆荚…#–cascade = true默认情况下%kubectl删除服务…

我很好奇你为什么需要步骤(4)和(5)。 步骤(4)应该在删除吊舱时自动发生,并且步骤(5)应该在后台自动发生。

如果两行“kubectl delete”工作,那么问题出在Java客户端库或者你的使用情况。 作为一个起点,我build议从Java代码中删除调用deleteContainers()和removeImage(),看看是否有帮助。 我认为这些步骤是不必要的。