27

I need to rsync a file tree to a specific pod in a kubernetes cluster. It seems it should be possible if only one can convince rsync that kubectl acts sort of like rsh. Something like:

rsync --rsh='kubectl exec -i podname -- ' -r foo x:/tmp

... except that this runs into problems with x since rsync assumes a hostname is needed:

exec: "x": executable file not found in $PATH

I can not seem to find a method to help rsync construct the rsh command. Is there a way to do this? Or some other method by which relatively efficient file transfer can be achieved over a pipe?

(I am aware of gcloud compute copy-files, but it can only be used onto the node?)

7 Answers 7

55

To rsync to a Pod I use the following helper.

pod=$1;shift;kubectl exec -i $pod -- "$@"

I put this in a file called "rsync-helper.sh" and then run the rsync like so.

rsync -av --progress --stats -e './rsync-helper.sh' source-dir/ thePodName:/tmp/dest-dir

If you'd like a simple script that wraps this all up, save this as krsync.

#!/bin/bash

if [ -z "$KRSYNC_STARTED" ]; then
    export KRSYNC_STARTED=true
    exec rsync --blocking-io --rsh "$0" $@
fi

# Running as --rsh
namespace=''
pod=$1
shift

# If user uses pod@namespace, rsync passes args as: {us} -l pod namespace ...
if [ "X$pod" = "X-l" ]; then
    pod=$1
    shift
    namespace="-n $1"
    shift
fi

exec kubectl $namespace exec -i $pod -- "$@"

Then you can use krsync where you would normally rsync.

krsync -av --progress --stats src-dir/ pod:/dest-dir

You can also set the namespace.

krsync -av --progress --stats src-dir/ pod@namespace:/dest-dir

NOTE: The Pod must have the rsync executable installed for this to work.

10
  • 1
    This script works perfectly!
    – omikron
    Feb 16, 2019 at 15:23
  • 3
    Works perfectly indeed, the --rsh part is not trivial at all to understand. Downside is not using tar
    – Mugen
    Mar 26, 2019 at 13:47
  • hats off to you, sir. This is a very elegant script. Mar 23, 2020 at 20:45
  • 1
    Thank you for the script. I am new to k8s and was trying to migrate my old server. Saved me a lot of time. Feb 12, 2021 at 12:33
  • 1
    Thanks so much for the script which works very well. Could you please provide some explanation about how it works? It is not trivial to understand. Apr 20, 2022 at 20:59
3

In the end, I wrote a Python script to act as a receiver of tar files. You can do thus:

tar cf - . | kubectl exec shinken -i catcher -v /etc/shinken/custom_configs

Note that this only works if you cluster nodes are kubernetes 1.1 or later.

2

A one-liner, just edit to you names and paths:

p_user=$USER;p_name=$POD_NAME; rsync -avurP --blocking-io --rsync-path= --rsh="$(which kubectl) exec $p_name -i -- " /home/$USER/target_dir rsync:/home/$p_user/
2

If the tar binary is available on the container, you can transfer files using the new cp command.

Though possibly not as efficient as rsync.

0
2

The answer from @karl-bunch was perfect. For those who prefer using tar this is how I use it:

tar -cvz -C /orig-dir . | kubectl exec -ti podname -- sh -c 'cd /var/www && tar -xzv'
1

I ran into the same problem today. I had to sync files from the pod to my local machine.

My solution for this was this rsync command

rsync -aOv --blocking-io --rsync-path="/some/path/on/pod" --rsh="kubectl exec somePod -c someContainer -i -- " rsync:"/some/path/on/pod /some/local/path
1
  • the double-quotes are unbalanced: should I add one? of remove the rsync:" quote?
    – codesmith
    Nov 18, 2022 at 7:33
0

It is not supported, but there is an issue for adding support which you can +1 or even contribute to: https://github.com/kubernetes/kubernetes/issues/18007#issuecomment-164797262

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.