我一直在使用fabric8的Java Kubernetes Client API构建一个创建Kubernetes复制控制器的应用程序,如下所示。
import io.fabric8.kubernetes.api.KubernetesClient;
import io.fabric8.kubernetes.api.KubernetesFactory;
import io.fabric8.kubernetes.api.model.*;
import io.fabric8.kubernetes.api.model.resource.Quantity;
import io.fabric8.kubernetes.client.KubernetesClientException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.stratos.kubernetes.client.interfaces.ReplicationControllerClientAPIInterface;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ReplicationControllerClientAPI implements ReplicationControllerClientAPIInterface {
private final KubernetesClient kubernetesClient;
private static final Log LOG = LogFactory.getLog(ReplicationControllerClientAPI.class);
public ReplicationControllerClientAPI(String endpointURL) {
kubernetesClient = new KubernetesClient(new KubernetesFactory(endpointURL));
System.out.println(endpointURL);
}
public void createReplicationController(String replicationControllerID, String selectorLabel,
int replicas, String containerName, String dockerImage, int cpu, int memory,
List<ContainerPort> ports) throws KubernetesClientException {
try {
int memoryInMB = 1024 * 1024 * memory;
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("Creating kubernetes replication-controller: [rc-id] %s "
+ "[container-name] %s [docker-image] %s "
+ "[cpu] %d [memory] %d MB [ports] %s",
replicationControllerID, containerName, dockerImage, cpu, memoryInMB, ports));
}
// Create replication-controller definition
ReplicationController replicationController = new ReplicationController();
replicationController.setApiVersion(ReplicationController.ApiVersion.V_1);
replicationController.setKind(KubernetesConstantsExtended.KIND_REPLICATION_CONTROLLER);
ObjectMeta replicationControllerMetaData = new ObjectMeta();
replicationControllerMetaData.setName(replicationControllerID);
replicationController.setMetadata(replicationControllerMetaData);
ReplicationControllerSpec replicationControllerSpec = new ReplicationControllerSpec();
replicationControllerSpec.setReplicas(replicas);
// Setup label selectors for the replication controller
Map<String, String> selectors = new HashMap<String, String>();
selectors.put(KubernetesConstantsExtended.LABEL_NAME_REPLICATION_CONTROLLER, selectorLabel);
replicationControllerSpec.setSelector(selectors);
PodTemplateSpec podTemplateSpec = new PodTemplateSpec();
ObjectMeta podMetaData = new ObjectMeta();
podMetaData.setLabels(selectors);
podTemplateSpec.setMetadata(podMetaData);
PodSpec podSpec = new PodSpec();
List<Container> containers = new ArrayList<Container>();
// Create container definition
Container container = new Container();
container.setName(containerName);
container.setImage(dockerImage);
// Set resource limits
ResourceRequirements resources = new ResourceRequirements();
Map<String, Quantity> limits = new HashMap<String, Quantity>();
limits.put(KubernetesConstants.RESOURCE_CPU, new Quantity(String.valueOf(cpu)));
limits.put(KubernetesConstants.RESOURCE_MEMORY, new Quantity(String.valueOf(memoryInMB)));
resources.setLimits(limits);
container.setResources(resources);
// Add container definition to the list of containers
containers.add(container);
podSpec.setContainers(containers);
// Add Pod Spec to the Pod Template Spec
podTemplateSpec.setSpec(podSpec);
// Add Pod Template Spec to the ReplicationController Spec
replicationControllerSpec.setTemplate(podTemplateSpec);
// Add Replication Controller Spec to the Replication Controller instance
replicationController.setSpec(replicationControllerSpec);
// Create the replication-controller
kubernetesClient.createReplicationController(replicationController);
} catch (Exception e) {
String message = String.format("Could not create kubernetes replication-controller: "
+ "[rc-id] %s", replicationControllerID);
LOG.error(message, e);
throw new KubernetesClientException(message, e);
}
}
public ReplicationController getReplicationController(String replicationControllerID)
throws KubernetesClientException {
try {
return kubernetesClient.getReplicationController(replicationControllerID);
} catch (Exception e) {
String message = String.format("Could not retrieve kubernetes replication-controller"
+ ": [rc-id] %s", replicationControllerID);
LOG.error(message, e);
throw new KubernetesClientException(message, e);
}
}
public ReplicationControllerList getReplicationControllers()
throws KubernetesClientException {
try {
return kubernetesClient.getReplicationControllers();
} catch (Exception e) {
String message = String.format("Could not retrieve kubernetes replication-controllers");
LOG.error(message, e);
throw new KubernetesClientException(message, e);
}
}
public void deleteReplicationController(String replicationControllerID)
throws KubernetesClientException {
try {
kubernetesClient.deleteReplicationController(replicationControllerID);
} catch (Exception e) {
String message = String.format("Could not delete kubernetes replication-controller"
+ ": [rc-id] %s", replicationControllerID);
LOG.error(message, e);
throw new KubernetesClientException(message, e);
}
}
}
当我执行上面的代码时,我发现应用程序抛出了以下异常。
javax.ws.rs.WebApplicationException: HTTP 404 the server could not find the requested resource
at io.fabric8.kubernetes.api.ExceptionResponseMapper.fromResponse(ExceptionResponseMapper.java:44)
at io.fabric8.kubernetes.api.ExceptionResponseMapper.fromResponse(ExceptionResponseMapper.java:35)
at org.apache.cxf.jaxrs.client.ClientProxyImpl.checkResponse(ClientProxyImpl.java:302)
at org.apache.cxf.jaxrs.client.ClientProxyImpl.handleResponse(ClientProxyImpl.java:725)
at org.apache.cxf.jaxrs.client.ClientProxyImpl.doChainedInvocation(ClientProxyImpl.java:683)
at org.apache.cxf.jaxrs.client.ClientProxyImpl.invoke(ClientProxyImpl.java:224)
at com.sun.proxy.$Proxy18.createReplicationController(Unknown Source)
at io.fabric8.kubernetes.api.KubernetesClient.createReplicationController(KubernetesClient.java:460)
at io.fabric8.kubernetes.api.KubernetesClient.createReplicationController(KubernetesClient.java:450)
at org.apache.stratos.kubernetes.client.ReplicationControllerClientAPI.createReplicationController(ReplicationControllerClientAPI.java:108)
at org.apache.stratos.kubernetes.client.ReplicationControllerTestSuite.createReplicationController(ReplicationControllerTestSuite.java:44)
at org.apache.stratos.kubernetes.client.ReplicationControllerTestExecutor.main(ReplicationControllerTestExecutor.java:22)
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)
Exception in thread "main" io.fabric8.kubernetes.client.KubernetesClientException: Could not create kubernetes replication-controller: [rc-id] helloworldrc
at org.apache.stratos.kubernetes.client.ReplicationControllerClientAPI.createReplicationController(ReplicationControllerClientAPI.java:113)
at org.apache.stratos.kubernetes.client.ReplicationControllerTestSuite.createReplicationController(ReplicationControllerTestSuite.java:44)
at org.apache.stratos.kubernetes.client.ReplicationControllerTestExecutor.main(ReplicationControllerTestExecutor.java:22)
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: javax.ws.rs.WebApplicationException: HTTP 404 the server could not find the requested resource
at io.fabric8.kubernetes.api.ExceptionResponseMapper.fromResponse(ExceptionResponseMapper.java:44)
at io.fabric8.kubernetes.api.ExceptionResponseMapper.fromResponse(ExceptionResponseMapper.java:35)
at org.apache.cxf.jaxrs.client.ClientProxyImpl.checkResponse(ClientProxyImpl.java:302)
at org.apache.cxf.jaxrs.client.ClientProxyImpl.handleResponse(ClientProxyImpl.java:725)
at org.apache.cxf.jaxrs.client.ClientProxyImpl.doChainedInvocation(ClientProxyImpl.java:683)
at org.apache.cxf.jaxrs.client.ClientProxyImpl.invoke(ClientProxyImpl.java:224)
at com.sun.proxy.$Proxy18.createReplicationController(Unknown Source)
at io.fabric8.kubernetes.api.KubernetesClient.createReplicationController(KubernetesClient.java:460)
at io.fabric8.kubernetes.api.KubernetesClient.createReplicationController(KubernetesClient.java:450)
at org.apache.stratos.kubernetes.client.ReplicationControllerClientAPI.createReplicationController(ReplicationControllerClientAPI.java:108)
... 7 more
Process finished with exit code 1
我已将KubernetesClient的端点URL设置为http://127.0.0.1:8080,因为我在本地通过Docker运行Kubernetes用于测试目的。我之前发过几篇与类似问题有关的文章,但在这种情况下,似乎没有一篇文章可以帮助我。
我在.bashrc中设置了以下环境变量。
export KUBERNETES_SERVICE_HOST=127.0.0.1
export KUBERNETES_SERVICE_PORT=8080
以下代码示例用于在我的应用程序中设置KubernetesClient。
private final ReplicationControllerClientAPIInterface REPLICATION_CONTROLLER_CLIENT;
public ReplicationControllerTestSuite() {
REPLICATION_CONTROLLER_CLIENT = new ReplicationControllerClientAPI("http://"
+ ReplicationControllerTestConstants.KUBERNETES_SERVICE_HOST + ":"
+ ReplicationControllerTestConstants.KUBERNETES_SERVICE_PORT);
// REPLICATION_CONTROLLER_CLIENT = new ReplicationControllerClientAPI("http://localhost:8080");
}
public void createReplicationController(int replicas) {
List<ContainerPort> exposedPorts = new ArrayList<ContainerPort>();
ContainerPort port = new ContainerPort();
port.setContainerPort(ReplicationControllerTestConstants.EXPOSED_PORT);
exposedPorts.add(port);
REPLICATION_CONTROLLER_CLIENT.createReplicationController(
ReplicationControllerTestConstants.REPLICATION_CONTROLLER_ID, ReplicationControllerTestConstants.SELECTOR_LABEL,
replicas, ReplicationControllerTestConstants.CONTAINER_NAME, ReplicationControllerTestConstants.DEFAULT_DOCKER_IMAGE,
ReplicationControllerTestConstants.CPU_CORES, ReplicationControllerTestConstants.MEMORY_ALLOCATION, exposedPorts);
}
上述代码中的常量引用如下:
protected static final String KUBERNETES_SERVICE_HOST = "127.0.0.1";
protected static final String KUBERNETES_SERVICE_PORT = "8080";
protected static final String SELECTOR_LABEL = "helloworld";
protected static final String REPLICATION_CONTROLLER_ID = "helloworldrc";
// Container specific
protected static final String DEFAULT_DOCKER_IMAGE = "helloworld";
protected static final String CONTAINER_NAME = "helloworld";
protected static final int CPU_CORES = 1;
protected static final int MEMORY_ALLOCATION = 512;
protected static final int EXPOSED_PORT = 8080;
对于此问题的任何帮助都非常感谢,因为我对REST API和Kubernetes的了解有限。
答案 0 :(得分:0)
Fabric8 kubernetes客户端的重写版本具有较少的依赖关系,流畅的DSL&amp;改善手表支持。它位于https://github.com/fabric8io/kubernetes-client&amp;的单独回购中。 Maven Central中可用的工件使用以下依赖项:
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client</artifactId>
<version>1.3.6</version>
</dependency>
请注意,有频繁发布的更新,但截至目前,API是稳定的&amp;准备生产使用。
创建复制控制器的example如下所示:
Config config = new ConfigBuilder().withMasterUrl(master).build();
try (final KubernetesClient client = new DefaultKubernetesClient(config)) {
client.replicationControllers().inNamespace("thisisatest").createNew()
.withNewMetadata().withName("nginx2-controller").addToLabels("server", "nginx").endMetadata()
.withNewSpec().withReplicas(0)
.withNewTemplate()
.withNewMetadata().addToLabels("server", "nginx2").endMetadata()
.withNewSpec()
.addNewContainer().withName("nginx").withImage("nginx")
.addNewPort().withContainerPort(80).endPort()
.endContainer()
.endSpec()
.endTemplate()
.endSpec().done();
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage(), e);
}
客户端可通过配置构建器高度配置。涵盖所有核心Kubernetes类型,以及OpenShift 3扩展。
更新:根据您自己的回复,我已经与Stratos项目一起提出了一个JIRA迁移到新客户端 - 他们目前正在对旧客户端进行某种重新打包。这可能会导致您的问题。请参阅issues.apache.org/jira/browse/STRATOS-1524
答案 1 :(得分:0)
我设法通过避免使用https://github.com/apache/stratos来解决上述问题,这是我在代码中使用的一个依赖项。我打算在我的代码中使用它已经创建的功能,例如KubernetesClientException,但由于这种依赖性,上面的问题似乎会弹出。
但是,我并不完全确定特定问题背后的原因。