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

如何将已修改的Kubernetes Linux Pod保存为Docker镜像?

在无节点SSH权限的DigitalOcean Kubernetes中保存Pod容器为镜像

DigitalOcean Kubernetes默认使用containerd作为容器运行时,而非Docker,这也是你之前挂载docker.sock无效的核心原因。以下是几种可行的解决方案:

方案1:导出容器修改文件,基于原镜像构建新镜像(适合修改量小的场景)

无需操作节点运行时,仅通过kubectl工具即可完成:

    1. 获取目标Pod名称:
    kubectl get pods
    
    1. 将容器内修改的文件/目录导出到本地:
      导出整个目录示例:
    kubectl cp <目标Pod名称>:/app ./local-app-directory
    
    导出单个文件示例:
    kubectl cp <目标Pod名称>:/etc/nginx/nginx.conf ./nginx.conf
    
    1. 编写Dockerfile,基于原镜像叠加修改内容:
    # 替换为原Pod使用的镜像及标签
    FROM original-image:tag
    # 复制导出的文件到镜像对应路径
    COPY ./local-app-directory /app
    
    1. 构建新镜像并推送到DigitalOcean容器注册表:
    docker build -t registry.digitalocean.com/your-registry/new-image:v1 .
    docker push registry.digitalocean.com/your-registry/new-image:v1
    
    1. 更新Deployment使用新镜像重新部署Pod。

方案2:通过特权Pod使用containerd的ctr工具导出镜像

利用containerd的命令行工具直接导出容器为镜像包:

    1. 部署特权Pod,挂载containerd的socket和节点镜像存储:
      创建containerd-tool-pod.yaml:
    kind: Pod
    apiVersion: v1
    metadata:
      name: containerd-tool
      namespace: default
    spec:
      # 指定目标Pod所在的节点名称(从kubectl get nodes获取)
      nodeSelector:
        kubernetes.io/hostname: pool-58i9au7bq-mgs6d
      hostNetwork: true
      privileged: true
      containers:
      - name: ctr
        image: alpine:latest
        command: ["sleep", "infinity"]
        volumeMounts:
        - name: containerd-socket
          mountPath: /run/containerd/containerd.sock
        - name: containerd-images
          mountPath: /var/lib/containerd
      volumes:
      - name: containerd-socket
        hostPath:
          path: /run/containerd/containerd.sock
          type: Socket
      - name: containerd-images
        hostPath:
          path: /var/lib/containerd
          type: Directory
    

    部署Pod:

    kubectl apply -f containerd-tool-pod.yaml
    
    1. 进入特权Pod并安装ctr工具:
    kubectl exec -it containerd-tool -- sh
    apk add containerd
    
    1. 获取目标容器的ID:
      方式一:本地执行命令查看:
    kubectl describe pod <目标Pod名称> | grep "Container ID"
    

    输出格式为containerd://<容器ID>,取后面的ID部分即可。

    方式二:在特权Pod内直接列出所有容器:

    ctr containers list
    
    1. 将容器导出为镜像tar包:
    ctr export container-image.tar <容器ID>
    
    1. 将tar包复制到本地:
    # 在本地执行
    kubectl cp containerd-tool:/container-image.tar ./container-image.tar
    
    1. 导入tar包为Docker镜像并推送:
    docker load -i container-image.tar
    # 替换为你的注册表地址和镜像标签
    docker tag <加载后的镜像ID> registry.digitalocean.com/your-registry/new-image:v1
    docker push registry.digitalocean.com/your-registry/new-image:v1
    
    1. 完成后删除特权Pod:
    kubectl delete pod containerd-tool
    

方案3:利用kubectl debug的--copy-to参数(Kubernetes 1.25+支持)

通过复制目标Pod的进程空间,挂载容器文件系统并导出内容:

    1. 创建复制目标Pod状态的debug Pod:
    kubectl debug <目标Pod名称> -it --copy-to=debug-pod --image=busybox --share-processes
    
    1. 在debug Pod内找到目标容器的进程ID并挂载文件系统:
    # 找到目标容器的主进程ID(比如nginx、python等)
    PID=$(ps aux | grep <容器进程名> | awk '{print $1}')
    mkdir /target-fs
    mount -o bind /proc/$PID/root /target-fs
    
    1. 打包容器文件系统内容:
    tar -czf /container-content.tar.gz -C /target-fs .
    
    1. 将压缩包复制到本地:
    # 在本地执行
    kubectl cp debug-pod:/container-content.tar.gz ./container-content.tar.gz
    
    1. 解压压缩包,编写Dockerfile基于原镜像构建新镜像,步骤同方案1。

内容的提问来源于stack exchange,提问作者Anil Kumar H P

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 16:35:14