I think you should be able to do this using Fabric8 Kubernetes Java Client. I would divide this into two tasks:
- Copy specified file from your container(
c1
) to your local system
- Copy file saved to your local system to your other container (say
c2
)
Let's say your have a pod running inside Kubernetes with two containers c1
and c2
. Let's take this as an example:
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"]
Now I want to transfer a file /docker-entrypoint.sh
in c1
to /tmp/docker-entrypoint.sh
in c2
. Fabric8 Kubernetes Client provides fluent DSL to uploading/downloading files from Kubernetes Pods. As @mndanial already pointed out in his answer, copy operation involves encoding/decoding, Fabric8 relies on commons-codec
and commons-compress
. These are optional dependencies and need to be included in your classpath in order to use copy operations. For maven, it would be adding it to pom.xml
like this:
<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>
Copying File from Container c1
to your local system:
In order to copy you can use KubernetesClient
's fluent DSL to specify which file to copy and where to copy in your local system. Here is example code:
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
}
Copying File from your local system to other Container (c2
):
Now we have to do the opposite of first step, similar to copy()
KubernetesClient
offers upload()
method which allows you to upload file or directories to your target Pod. Here is how you would do it:
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
}
When I executed this, I was able to see my file being copied in desired location:
~ : $ kubectl exec multi-container-pod -c c2 ls /tmp
docker-entrypoint.sh
Fabric8 Kubernetes Client also allows you to read a file as InputStream
directly rather than storing it. Here is an example:
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);
}
}