<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Dev Infra]]></title><description><![CDATA[Dev Infra]]></description><link>https://devinfra.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6a789a8ddafa1c79f987abc7/6756a00a-f8ff-423a-b9f7-a156c4ea82c4.png</url><title>Dev Infra</title><link>https://devinfra.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Fri, 23 Oct 2026 09:13:53 GMT</lastBuildDate><atom:link href="https://devinfra.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[I Brought rsync to kubectl]]></title><description><![CDATA[Over the last few months, I've been working with Kubernetes pods in my development environment. One thing I frequently need to do is transfer files from my…]]></description><link>https://devinfra.hashnode.dev/kubectl-rsync</link><guid isPermaLink="true">https://devinfra.hashnode.dev/kubectl-rsync</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[kubectl]]></category><category><![CDATA[Devops]]></category><category><![CDATA[rsync]]></category><dc:creator><![CDATA[major1201]]></dc:creator><pubDate>Sun, 09 Aug 2026 17:11:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a789a8ddafa1c79f987abc7/501769b1-b389-483f-bfb1-85be018c9775.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Over the last few months, I've been working with Kubernetes pods in my development environment. One thing I frequently need to do is transfer files from my local machine into a development pod.</p>
<p>The usual choice is <code>kubectl cp</code>:</p>
<pre><code class="language-bash">kubectl cp ./local-dir my-dev-pod:/tmp/remote-dir
</code></pre>
<p>It works, but I wanted something better for a development workflow.</p>
<p>When I'm making changes locally and syncing them to a pod repeatedly, I don't want to transfer everything every time. I want <strong>rsync's incremental synchronization</strong> that is only the files that have changed should be transferred.</p>
<p>So I started wondering:</p>
<blockquote>
<p><strong>Could I make rsync work with kubectl?</strong></p>
</blockquote>
<h2>The rsync <code>-e</code> option</h2>
<p>It turns out that rsync has exactly the mechanism I needed: the <code>-e</code> option.</p>
<p>The <code>-e</code> option allows rsync to specify the remote shell command it should use for connecting to the remote machine.</p>
<p>For example, I created a small <code>rsh.sh</code> script:</p>
<pre><code class="language-shell">#!/bin/bash

POD="$1"
shift

kubectl exec -i "$POD" -- "$@"
</code></pre>
<p>Then I could tell rsync to use this script as its remote shell:</p>
<pre><code class="language-shell">rsync -avzP -e ./rsh.sh \
  ~/major1201/local-dir/ \
  my-dev-pod:/tmp/remote-dir/
</code></pre>
<p>And it worked.</p>
<pre><code class="language-text">sending incremental file list
./
1.txt
              4 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=2/4)
b/
b/2.txt
              4 100%    3.91kB/s    0:00:00 (xfr#2, to-chk=0/4)

sent 233 bytes  received 65 bytes  198.67 bytes/sec
total size is 8  speedup is 0.03
</code></pre>
<p>The important part wasn't the transfer itself. It was that <strong>rsync was doing the synchronization while</strong> <code>kubectl exec</code> <strong>provided the connection to the pod</strong>.</p>
<p>The flow looked like this: rsync -&gt; rsh.sh -&gt; kubectl exec -&gt; kubernetes Pod</p>
<h2>And that's the idea behind kubectl-rsync</h2>
<p>Once I had the proof of concept working, I packaged the idea into a <code>kubectl</code> plugin.</p>
<p>Now the same operation can be written as:</p>
<pre><code class="language-shell">kubectl rsync \
  ~/major1201/local-dir/ \
  my-dev-pod:/tmp/remote-dir/
</code></pre>
<p>Under the hood, <code>kubectl-rsync</code> acts as an rsync transport shim. It connects rsync to the pod through <code>kubectl exec</code>, allowing rsync to handle the file synchronization.</p>
<p>This means I can use rsync features such as incremental transfers, compression, progress reporting, and partial transfers while still using my existing Kubernetes authentication and <code>kubectl</code> workflow.</p>
<h2>kubectl cp vs kubectl-rsync</h2>
<p><code>kubectl cp</code> is great for simple, one-time file copies. But when you repeatedly synchronize a directory between your local machine and a pod, <code>kubectl-rsync</code> provides the rsync workflow you may already be familiar with.</p>
<table>
<thead>
<tr>
<th>Features</th>
<th><code>kubectl cp</code></th>
<th><code>kubectl-rsync</code></th>
</tr>
</thead>
<tbody><tr>
<td>Copy files to/from pods</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<td>Incremental synchronization</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Transfers only changed files</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Compression</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Progress reporting</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Archive mode</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Exclude files/directories</td>
<td>Limited</td>
<td>Yes, with rsync options</td>
</tr>
<tr>
<td>Delete files removed from source</td>
<td>No</td>
<td>Yes, with <code>--delete</code></td>
</tr>
</tbody></table>
<h2>Install it with Krew</h2>
<p>If you already have <a href="https://krew.sigs.k8s.io/">Krew</a> installed, you can install the plugin with:</p>
<pre><code class="language-shell">kubectl krew install rsync
</code></pre>
<h2>Try it out</h2>
<p>The project is open source:</p>
<p><a href="https://github.com/major1201/kubectl-rsync">https://github.com/major1201/kubectl-rsync</a></p>
<p>If you work with Kubernetes pods and frequently move files between your local machine and development environments, I'd love to hear what you think.</p>
<p>If you find it useful, consider giving the project a star on GitHub.</p>
]]></content:encoded></item></channel></rss>