I run drone on GKE on a cluster with Workload Identity enabled: it’s a very neat way to avoid having to handle service account keys and would make drone just work without configuring secrets (at least from the gcloud side of things)
So far however, I have not been successful in configuring it, so I wonder if you intend to support it.
What I have done:
Enabled Workload Identity as in the documentation
Assign my GKE service account to the K8S “default” service account in the default namespace (used by the drone jobs) (and test it works)
As you can see, already at this step I am able to configure docker with no need to share any secret.
However, when I try to build and push an image, the job fails. I have tried with both docker and gcr plugins.
unauthorized: You don’t have the needed permissions to perform this operation, and you may have invalid credentials. To authenticate your request, follow the steps in: https://cloud.google.com/container-registry/docs/advanced-authentication
224 time=“2020-06-10T15:46:20Z” level=fatal msg=“exit status 1”
Just to confirm, if I run the exact same command with a traditional secret, it works:
Hi Allessandro,
I am not familiar with Workload Identity and I don’t personally use Kubernetes, so I cannot really answer specific questions. But I can probably provide some details that might explain why pulling an image vs pushing and image works differently.
When your pipeline step uses a private image, Drone creates a Kubernetes Pod where your pipeline step is represented as a container in the Pod. Kubernetes is therefore responsible for pulling all images.
When you use the Docker plugin to push an image, it is important to remember that this particular step is a container running inside a Pod, and this particular step plugin uses docker-in-docker. This means the docker commands are running inside a Pod using a docker-in-docker daemon, which are isolated from the host machine configuration.
Which I think means that it could easily be supported even in the case of docker-in-docker as long as you have connectivity.
I was hoping that the libraries you use would support fetching this service account transparently, which would have been neat. Do you mind if I open a feature request for it on the project Github?
I was hoping that the libraries you use would support fetching this service account transparently, which would have been neat.
In this case we do not really use any libraries. A pipeline step is just a container that runs inside a Pod. A plugin is just a container that runs a pre-defined script. And the Docker plugin is really just running plain old docker commands against a docker-in-docker daemon. Drone does not have any special knowledge of what a plugin is or does, so it would not know that the Docker plugin publishes Docker images or might require some special authentication.
Do you mind if I open a feature request for it on the project Github?
I would recommend starting out by creating an extension to inject custom secrets or tokens into your pipeline steps: Overview | Drone
In general we prefer implementing these features as third party extensions (we have done similar for Vault secrets, for example). Once the feature is implemented as an extension it gives us the opportunity to gauge community demand to determine whether or not it should remain a third party extension, or integrated in Drone core.
Hi @ademaria, did you ever get this working or created that feature request?
We’re faced with exactly the same problem, which is super annoying since we’ve managed to avoid the whole hassle of service accounts tokens this far by relying on workload identity.
Unfortunately not, especially because I moved to use “docker” nodes instead of kubernetes ones (using drone-autoscaler). But I believe it should be pretty straightforward to adapt the plugin/gcr to use workload identity if you fancy a bit of golang.
That was my conclusion as well, unfortunately golang isn’t my language of choice. I’m guessing/hoping this will eventually get picked up anyhow, because who would be using grc.io if not running on google cloud, and if running on google cloud these days workload identify is the way to go.
So for now we’ll probably have to pause our evaluation of drone.io and stick to our old system
unfortunately golang isn’t my language of choice. I’m guessing/hoping this will eventually get picked up anyhow
Plugins are just docker container that invoke a script (or program), and the plugin parameters in the yaml are passed in a plugin-agnostic manner (environment variables). This means a plugin can be written in any programming language, including bash. Remember that you are never required to use a plugin, since they are just wrappers around scripts, and they exist for convenience and re-use. You can opt to write shell commands directly, or even create your own plugin in your language of choice.
I am not familiar with workload identity, but if you cannot use the gcr plugin as-is, you can definitely build and publish images by defining shell commands [1][2]. You would just need to figure out how the shell commands use workload identity.
workload identity basically is an association between a kubernets service account and a gcloud service account, so all the google command line utilities will automatically be authenticated as the correct service account, and publishing to gcr.io is as easy as first doing gcloud auth configure-docker as I understand it. (it works outside the docker in docker as expected for me)
But figuring out where to inject that extra line in the existing gcr plugin is a major undertaking when not accustomed to the codebase nor language, otherwise I would have tried it already
It should be possible to get the needed tokens directly as well, but piggy backing on the gcloud cli tools seems like a much simpler approach. https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity#using_from_your_code