使用 client-go 可以在 Kubernetes 集群中的 pod 中复制文件。具体步骤如下:
- 导入 client-go 包:
import (
"context"
"fmt"
"os"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
- 建立 Kubernetes 集群客户端:
config, err := rest.InClusterConfig()
if err != nil {
panic(err.Error())
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
- 获取需要复制的 pod 和容器名称:
podName := "my-pod"
containerName := "my-container"
namespace := "default"
pod, err := clientset.CoreV1().Pods(namespace).Get(context.Background(), podName, metav1.GetOptions{})
if err != nil {
panic(err.Error())
}
- 复制文件到本地 pod:
copyFromPath := "/var/log/myapp.log"
copyToPath := "/tmp/myapp.log"
err = copyFile(clientset, namespace, podName, containerName, copyFromPath, copyToPath)
if err != nil {
panic(err.Error())
}
- 实现 copyFile 函数:
func copyFile(clientset *kubernetes.Clientset, namespace, podName, containerName, copyFromPath, copyToPath string) error {
req := clientset.CoreV1().RESTClient().
Post().
Resource("pods").
Name(podName).
Namespace(namespace).
SubResource("exec").
VersionedParams(&corev1.PodExecOptions{
Container: containerName,
Command: []string{"sh", "-c", fmt.Sprintf("cat %s", copyFromPath)},
Stdout: true,
Stderr: true,
}, metav1.ParameterCodec)
exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
if err != nil {
return err
}
file, err := os.Create(copyToPath)
if err != nil {
return err
}
defer file.Close()
err = exec.Stream(remotecommand.StreamOptions{
Stdout: file,
Stderr: os.Stderr,
})
if err != nil {
return err
}
return nil
}
需要注意的是,执行此操作需要具有相应的 RBAC 权限,可以在 Kubernetes 集群中创建一个新的 ServiceAccount,并将其绑定到具有访问源和目标 pod 的角色上。