Java API Kubernetes для команды копирования Kubectl

У меня есть контейнер, работающий внутри кластера Kubernetes (в POD) вдоль многих других контейнеров (в их собственных POD), и мой контейнер является общим контейнером. Теперь я хочу вытащить (скопировать) файлы из других контейнеров в мой общий контейнер. Я исследовал некоторые варианты и обнаружил, что копия kubectl может быть использована. Но для этого мне нужно включить инструмент командной строки kubectl внутри моего общего контейнера. Я не уверен, что это правильный подход. Итак, я подумал об использовании API Java Kubernetes, чтобы сделать то же самое. Существует ли эквивалентный REST API Kubernetes для команды копирования Kubectl? Я прошел через API kubernetes и не смог найти ни одного такого API ..

Спасибо

1 ответ

Это потому что kubectl cp реализуется через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

Я думаю, вы сможете сделать это с помощью Fabric8 Kubernetes Java Client. Я бы разделил это на две задачи:

  1. Скопируйте указанный файл из вашего контейнера (c1) в вашу локальную систему
  2. Скопируйте файл, сохраненный в вашей локальной системе, в другой контейнер (скажем, c2)

Допустим, у вас есть под, запущенный внутри Kubernetes с двумя контейнерами. c1 и c2. Возьмем это для примера:

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 в c2. Клиент Fabric8 Kubernetes обеспечивает плавный DSL для загрузки / скачивания файлов из модулей Kubernetes. Как уже отмечал @mndanial в своем ответе, операция копирования включает в себя кодирование / декодирование, Fabric8 полагается на commons-codec и commons-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 также позволяет читать файл как 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);
    }
}
Другие вопросы по тегам