Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用kubernetes python客户端将文件从pod复制到主机_Python_Kubernetes_Kubernetes Python Client - Fatal编程技术网

使用kubernetes python客户端将文件从pod复制到主机

使用kubernetes python客户端将文件从pod复制到主机,python,kubernetes,kubernetes-python-client,Python,Kubernetes,Kubernetes Python Client,我需要使用kubernetes python客户端将文件从pod复制到主机。它类似于kubectl-cp-pod:file-file 我正在测试以下代码: 具体而言,该代码: command_copy=['tar','cf','-',source_path] 使用临时文件()作为tar_缓冲区: exec\u stream=stream(self.coreClient.connect\u get\u namespaced\u pod\u exec、pod\u name、name\u space、

我需要使用kubernetes python客户端将文件从pod复制到主机。它类似于
kubectl-cp-pod:file-file

我正在测试以下代码:

具体而言,该代码:

command_copy=['tar','cf','-',source_path]
使用临时文件()作为tar_缓冲区:
exec\u stream=stream(self.coreClient.connect\u get\u namespaced\u pod\u exec、pod\u name、name\u space、,
command=command\u copy,stderr=True,stdin=True,stdout=True,tty=False,
_预加载(内容=假)
#将文件复制到流
尝试:
而exec\u stream.is\u open():
exec_stream.update(超时=1)
如果exec_stream.peek_stdout():
out=exec\u stream.read\u stdout()
tar_缓冲区写入(out.encode('utf-8'))
如果exec_stream.peek_stderr():
logger.debug(“STDERR:%s”%exec\u stream.read\u STDERR())
exec_stream.close()
tar_buffer.flush()
tar_缓冲区寻道(0)
以tarfile.open(fileobj=tar_buffer,mode='r:')作为tar:
member=tar.getmember(源路径)
tar.makefile(成员,目标路径)
返回真值
例外情况除外,如e:
提出管理库伯内特斯例外(e)
我使用的是官方的Kubernetes Python库版本10.0.1稳定版和Python 3.6.8

但它不能正常工作:

  • 当我复制小文本文件时,它正在工作
  • 但它不适用于其他文件,如tar或zip文件。它复制一个与原始文件大小相同的损坏文件
代码中有错误吗?通过使用kubernetes python客户机,您还有其他方法可以做到这一点吗

祝你一切顺利

谢谢

通过使用kubernetes python客户机,您还有其他方法可以做到这一点吗


如果您只需要Pod中的一个文件,那么不要使用
tar
,而是使用
/bin/cat
,这样做的额外好处是您可以直接写入本地文件,而不必处理tar文件格式。这种方法的缺点是,您将负责设置本地文件的权限,使其与您期望的权限相匹配,这是
tar-xf
为您所做的事情。但是,如果您复制的是远程tar文件或zip文件,则该限制无论如何都不适用,并且可能会使代码更易于推理。

我使用了以下代码:

def stream_copy_from_pod(self, pod_name, name_space, source_path, destination_path):
    """
    Copy file from pod to the host.

    :param pod_name: String. Pod name
    :param name_space: String. Namespace
    :param source_path: String. Pod destination file path
    :param destination_path: Host destination file path
    :return: bool
    """
    command_copy = ['tar', 'cf', '-', source_path]
    with TemporaryFile() as tar_buffer:
        exec_stream = stream(self.coreClient.connect_get_namespaced_pod_exec, pod_name, name_space,
                             command=command_copy, stderr=True, stdin=True, stdout=True, tty=False,
                             _preload_content=False)
        # Copy file to stream
        try:
            reader = WSFileManager(exec_stream)
            while True:
                out, err, closed = reader.read_bytes()
                if out:
                    tar_buffer.write(out)
                elif err:
                    logger.debug("Error copying file {0}".format(err.decode("utf-8", "replace")))
                if closed:
                    break
            exec_stream.close()
            tar_buffer.flush()
            tar_buffer.seek(0)
            with tarfile.open(fileobj=tar_buffer, mode='r:') as tar:
                member = tar.getmember(source_path)
                tar.makefile(member, destination_path)
                return True
        except Exception as e:
            raise manage_kubernetes_exception(e)
使用此web套接字文件管理器进行读取

class WSFileManager:
"""
WS wrapper to manage read and write bytes in K8s WSClient
"""

def __init__(self, ws_client):
    """

    :param wsclient: Kubernetes WSClient
    """
    self.ws_client = ws_client

def read_bytes(self, timeout=0):
    """
    Read slice of bytes from stream

    :param timeout: read timeout
    :return: stdout, stderr and closed stream flag
    """
    stdout_bytes = None
    stderr_bytes = None

    if self.ws_client.is_open():
        if not self.ws_client.sock.connected:
            self.ws_client._connected = False
        else:
            r, _, _ = select.select(
                (self.ws_client.sock.sock, ), (), (), timeout)
            if r:
                op_code, frame = self.ws_client.sock.recv_data_frame(True)
                if op_code == ABNF.OPCODE_CLOSE:
                    self.ws_client._connected = False
                elif op_code == ABNF.OPCODE_BINARY or op_code == ABNF.OPCODE_TEXT:
                    data = frame.data
                    if len(data) > 1:
                        channel = data[0]
                        data = data[1:]
                        if data:
                            if channel == STDOUT_CHANNEL:
                                stdout_bytes = data
                            elif channel == STDERR_CHANNEL:
                                stderr_bytes = data
    return stdout_bytes, stderr_bytes, not self.ws_client._connected

tar\u buffer.write(out.encode('utf-8'))
几乎肯定是不正确的,因为tar文件不是utf-8,我很惊讶当它遇到空字节(tar文件肯定包含空字节)时,它没有爆炸成
unicodencodeerror
,我已经通过在WSClient和out.encode(“CP437”)中使用data.decode(“CP437”)解决了这个问题在我的复制方法中。您是如何在WSClient中设置data.decode的?是的,cat适用于常规文件。但它不适用于zip文件。有没有将zip文件从pod复制到本地的想法?
/bin/cat
是二进制安全的,尽管正如页面顶部的评论所提到的:以二进制格式打开流是程序员的责任,否则将面临编码地狱的愤怒