用于Kubectl复制命令的Kubernetes Java API

时间:2018-03-22 05:43:47

标签: kubernetes kubectl google-kubernetes-engine

我有一个容器在Kubernetes集群内部(在POD内)和许多其他容器(在他们自己的POD中)一起运行,我的容器是一个普通的容器。现在,我想将文件从其他容器拉(复制)到我的公共容器。我调查了一些选项,发现可以使用kubectl拷贝。但是,为此,我需要在我的公共容器中包含kubectl命令行工具。我不确定这是否正确。所以,我想到使用Java Kubernetes API来做同样的事情。 Kubectl复制命令是否有等效的Kubernetes REST API?我经历了kubernetes API,找不到任何这样的API ..

由于

2 个答案:

答案 0 :(得分:4)

那是因为kubectl cp is implemented via tar,所以实际正在发生的是kubectl exec $pod -- tar -cf - /the/container/file | tar -xf -,这也是我期望你的Java API需要做的事情,以及

但是,您可以 - 根据您的需要 - 在kubectl cp到达之前能够躲过我以前的工作方式:kubectl exec $pod -- /bin/cat /the/container/file > local-file在您的情况下可能会更容易我希望API会将这些字节实现为InputStream,从而节省了进入tar格式解析业务的需要

答案 1 :(得分:0)

我认为您应该可以使用Fabric8 Kubernetes Java Client来做到这一点。我将其分为两个任务:

  1. 将指定文件从容器(c1)复制到本地系统
  2. 将保存到本地系统的文件复制到其他容器(例如c2

假设您有一个在Kubernetes中运行的吊舱,其中有两个容器c1c2。让我们以这个为例:

apiVersion: v1
kind: Pod
metadata:
  name: multi-container-pod
spec:
  containers:
  - name: c1
    image: nginx:1.19.2
    ports:
    - containerPort: 80  
  - name: c2
    image: alpine:3.12
    command: ["watch", "wget", "-qO-", "localhost"]

现在,我要将/docker-entrypoint.sh中的文件c1传输到/tmp/docker-entrypoint.sh中的c2Fabric8 Kubernetes Client为从Kubernetes Pods上传/下载文件提供了流畅的DSL。正如@mndanial在其答案中指出的那样,复制操作涉及编码/解码,Fabric8依赖于commons-codeccommons-compress。这些是可选的依赖项,需要将其包含在类路径中才能使用复制操作。对于maven,它将像这样将其添加到pom.xml中:

        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>${commons-codec.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-compress</artifactId>
            <version>${commons-compress.version}</version>
        </dependency>

将文件从容器c1复制到本地系统: 为了进行复制,您可以使用KubernetesClient的流畅DSL指定要复制的文件以及在本地系统中复制的位置。这是示例代码:

try (KubernetesClient client = new DefaultKubernetesClient()) {
    // Path Where to copy file to local storage
    Path downloadToPath = new File("/home/rohaan/Downloads/docker-entrypoint.sh").toPath();
    // Using Kubernetes Client to copy file from pod
    client.pods()
            .inNamespace("default")             // <- Namespace of pod
            .withName("multi-container-pod")    // <- Name of pod
            .inContainer("c1")                  // <- Container from which file has to be downloaded
            .file("/docker-entrypoint.sh")      // <- Path of file inside pod
            .copy(downloadToPath);              // <- Local path where to copy downloaded file
}

将文件从本地系统复制到其他容器(c2): 现在我们需要执行第一步的相反操作,类似于copy() KubernetesClient提供了upload()方法,该方法允许您将文件或目录上载到目标Pod。这是您的操作方式:

try (KubernetesClient client = new DefaultKubernetesClient()) {
    // File which was downloaded in Step 1
    File fileToUpload = new File("/home/rohaan/Downloads/docker-entrypoint.sh");
    client.pods().inNamespace("default")
            .withName("multi-container-pod")
            .inContainer("c2")
            .file("/tmp/docker-entrypoint.sh")  // <- Target location in other container
            .upload(fileToUpload.toPath());     // <- Local path of downloaded file
}

执行此操作后,我可以看到文件被复制到所需位置:

~ : $ kubectl exec multi-container-pod -c c2 ls /tmp
docker-entrypoint.sh

Fabric8 Kubernetes Client还允许您直接将文件读取为InputStream而不是将其存储。这是一个示例:

try (KubernetesClient client = new DefaultKubernetesClient()) {
    try (InputStream is = client.pods()
            .inNamespace("default")
            .withName("quarkus-84dc4885b-tsck6")
            .inContainer("quarkus")
            .file("/tmp/jobExample.yml").read())  {
        String result = new BufferedReader(new InputStreamReader(is)).lines().collect(Collectors.joining("\n"));
        System.out.println(result);
    }
}