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. Я бы разделил это на две задачи:
- Скопируйте указанный файл из вашего контейнера (
c1
) в вашу локальную систему - Скопируйте файл, сохраненный в вашей локальной системе, в другой контейнер (скажем,
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);
}
}