我有一个容器在Kubernetes集群内部(在POD内)和许多其他容器(在他们自己的POD中)一起运行,我的容器是一个普通的容器。现在,我想将文件从其他容器拉(复制)到我的公共容器。我调查了一些选项,发现可以使用kubectl拷贝。但是,为此,我需要在我的公共容器中包含kubectl命令行工具。我不确定这是否正确。所以,我想到使用Java Kubernetes API来做同样的事情。 Kubectl复制命令是否有等效的Kubernetes REST API?我经历了kubernetes API,找不到任何这样的API ..
由于
答案 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来做到这一点。我将其分为两个任务:
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 Client为从Kubernetes Pods上传/下载文件提供了流畅的DSL。正如@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 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);
}
}