You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将kubectl cp转换为Kubernetes Python客户端代码时遇类型错误求助

Fixing TypeError: must be str, not bytes in Kubernetes Python Client for kubectl cp Equivalent

Let's break down the issue and fix it step by step:

The Root Cause

In Python 3, tar_buffer.read() returns a binary bytes object, but the older version of Kubernetes Python Client (matching your Kubernetes 1.13 cluster) uses a websocket client that tries to concatenate a string (the channel identifier) with your binary data when writing to stdin. This causes the TypeError you're seeing.

We'll modify the command running in the Pod to decode base64 input, then encode our tar data as base64 strings before sending. This avoids type mismatches while preserving the binary tar content.

Here's the updated code:

from kubernetes import client, config
from kubernetes.stream import stream
import tarfile
from tempfile import TemporaryFile
import base64
import os  # Add this to handle file names

# Load config and initialize API
config.load_kube_config()
api_instance = client.CoreV1Api()

# Modified command: decode base64 input before passing to tar
exec_command = ['sh', '-c', 'base64 -d | tar xvf - -C /']
resp = stream(api_instance.connect_get_namespaced_pod_exec, 
              "nginx-deployment-6bb6554bf-9sdtr", 
              'default',
              command=exec_command, 
              stderr=True, stdin=True, stdout=True, tty=False, 
              _preload_content=False)

source_file = '/tmp/abc.txt'
with TemporaryFile() as tar_buffer:
    with tarfile.open(fileobj=tar_buffer, mode='w') as tar:
        # Use arcname to avoid creating /tmp/ in the Pod (optional but recommended)
        tar.add(source_file, arcname=os.path.basename(source_file))
    tar_buffer.seek(0)

    # Encode binary tar data to base64 string
    tar_data = base64.b64encode(tar_buffer.read()).decode('utf-8')
    commands = [tar_data]

    while resp.is_open():
        resp.update(timeout=1)
        if resp.peek_stdout():
            print("STDOUT: %s" % resp.read_stdout())
        if resp.peek_stderr():
            print("STDERR: %s" % resp.read_stderr())
        if commands:
            c = commands.pop(0)
            resp.write_stdin(c)
        else:
            break
resp.close()

Key Changes:

  1. Updated Exec Command: We wrap the tar command in a shell pipeline that decodes base64 input first.
  2. Base64 Encoding: Convert the binary tar data to a UTF-8 encoded base64 string before sending to stdin.
  3. Arcname Fix: Added arcname=os.path.basename(source_file) to ensure the file is placed directly in / of the Pod, instead of recreating the /tmp/ directory structure from your local machine (adjust this if you want to preserve the original path).

Why This Works

By encoding the binary tar data as a base64 string, we're passing a valid UTF-8 string to write_stdin, which plays nicely with the client's websocket code that concatenates it with the channel identifier string. The Pod then decodes the string back to binary before passing it to tar.

内容的提问来源于stack exchange,提问作者Prafull Ladha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:49:43