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, but how can I instruct gsutil to use the credentials in /var/run/secrets/kubernetes.io/serviceaccount?
lrwxrwxrwx 1 root root 12 Oct 8 20:56 token -> ..data/token
lrwxrwxrwx 1 root root 16 Oct 8 20:56 namespace -> ..data/namespace
lrwxrwxrwx 1 root root 13 Oct 8 20:56 ca.crt -> ..data/ca.crt
lrwxrwxrwx 1 root root 31 Oct 8 20:56 ..data -> ..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 ..
Note that your Kubernetes Service Account is different from your Google Cloud Storage service account.
gsutil
uses the boto config so you can mount a Kubernetes secret under /etc/boto.cfg
or ~/.boto
You can authenticate with GCP using a token or a service account. You can generate a token using gsutil config -f
you can generate service account credentials using gsutil config -e
. It will generate a ~/.boto
file and then you can mount that as Kubernetes secret on your pods.
More information here.
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 GOOGLE_APPLICATION_CREDENTIALS
environment variable):
https://cloud.google.com/kubernetes-engine/docs/tutorials/authenticating-to-cloud-platform
Rather than reading from the GOOGLE_APPLICATION_CREDENTIALS
environment variable, Gsutil uses Boto configuration files to load credentials. The common places that it knows to look for these Boto config files are /etc/boto.cfg
and $HOME/.boto
. Note that the latter value changes depending on the user running the command ($HOME
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.
So, on your pod, you'll need to first create a Boto config file that references the keyfile:
# 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'
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 BOTO_CONFIG
environment variable in the commands you supply for your cron job:
export BOTO_CONFIG=/path/to/my/boto.cfg; /path/to/gsutil cp <src> <dst>
Edit:
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 default
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 default
service account, this solution should work out-of-the-box.