<p>I have a kubernetes Cronjob that performs some backup jobs, and the backup files needs to be uploaded to a bucket. The pod have the service account credentials mounted inside the pod at /var/run/secrets/kubernetes.io/serviceaccount, <strong>but how can I instruct gsutil to use the credentials in /var/run/secrets/kubernetes.io/serviceaccount?</strong></p>

<pre><code>lrwxrwxrwx 1 root root   12 Oct  8 20:56 token -&gt; ..data/token
lrwxrwxrwx 1 root root   16 Oct  8 20:56 namespace -&gt; ..data/namespace
lrwxrwxrwx 1 root root   13 Oct  8 20:56 ca.crt -&gt; ..data/ca.crt
lrwxrwxrwx 1 root root   31 Oct  8 20:56 ..data -&gt; ..2018_10_08_20_56_04.686748281
drwxr-xr-x 2 root root  100 Oct  8 20:56 ..2018_10_08_20_56_04.686748281
drwxrwxrwt 3 root root  140 Oct  8 20:56 .
drwxr-xr-x 3 root root 4096 Oct  8 20:57 ..
</code></pre>

<p>The short answer is that the token there is not in a format that gsutil knows how to use, so you can't use it. You'll need a JSON keyfile, as mentioned in the tutorial here (except that you won't be able to use the <code>GOOGLE_APPLICATION_CREDENTIALS</code> environment variable):</p>

<p><a href="https://cloud.google.com/kubernetes-engine/docs/tutorials/authenticating-to-cloud-platform" rel="nofollow noreferrer">https://cloud.google.com/kubernetes-engine/docs/tutorials/authenticating-to-cloud-platform</a></p>

<p>Rather than reading from the <code>GOOGLE_APPLICATION_CREDENTIALS</code> environment variable, Gsutil uses Boto configuration files to load credentials. The common places that it knows to look for these Boto config files are <code>/etc/boto.cfg</code> and <code>$HOME/.boto</code>.  Note that the latter value changes depending on the user running the command (<code>$HOME</code> expands to different values for different users); since cron jobs usually run as a different user than the one who set up the config file, I wouldn't recommend relying on this path.</p>

<p>So, on your pod, you'll need to first create a Boto config file that references the keyfile:</p>

<pre><code># This option is only necessary if you're running an installation of
# gsutil that came bundled with gcloud. It tells gcloud that you'll be
# managing credentials manually via your own Boto config files.

$ gcloud config set pass_credentials_to_gsutil False


# Set up your boto file at /path/to/my/boto.cfg - the setup will prompt
# you to supply the /path/to/your/keyfile.json.  Alternatively, to avoid
# interactive setup prompts, you could set up this config file beforehand
# and copy it to the pod.

$ gsutil config -e -o '/path/to/my/boto.cfg'
</code></pre>

<p>And finally, whenever you run gsutil, you need to tell it where to find that Boto config file which references your JSON keyfile (and also make sure that the user running the command has permission to read both the Boto config file and the JSON keyfile). If you wrote your Boto config file to one of the well-known paths I mentioned above, gsutil will attempt to find it automatically; if not, you can tell gsutil where to find the Boto config file by exporting the <code>BOTO_CONFIG</code> environment variable in the commands you supply for your cron job:</p>

<pre><code>export BOTO_CONFIG=/path/to/my/boto.cfg; /path/to/gsutil cp &lt;src&gt; &lt;dst&gt;
</code></pre>

<p><strong>Edit</strong>:</p>

<p>Note that GCE VM images come with a pre-populated file at /etc/boto.cfg.  This config file tells gsutil to load a plugin that allows gsutil to contact the GCE metadata server and fetch auth tokens (corresponding to the <code>default</code> robot service account for that VM) that way.  If your pod is able to read the host VM's /etc/boto.cfg file, you're able to contact the GCE metadata server, and you're fine with operations being performed by the VM's <code>default</code> service account, this solution should work out-of-the-box.</p>
