The Drone Kubernetes plugin doesn’t actually deploy to Kubernetes; it uses Kubernetes to run your build steps.
Let’s see it in action. Imagine you have a Dockerfile and a deployment manifest. You want Drone to build your Docker image and then update your Kubernetes deployment with that new image.
Here’s a snippet from a .drone.yml file that accomplishes this:
kind: pipeline
type: kubernetes
name: default
steps:
- name: build-and-deploy
image: plugins/docker
settings:
repo: your-dockerhub-username/your-app
username:
from_secret: docker_username
password:
from_secret: docker_password
when:
branch: main
- name: kubernetes-deploy
image: plugins/kubernetes
settings:
kubeconfig:
from_secret: kubeconfig
namespace: default
template:
type: yaml
data: |
apiVersion: apps/v1
kind: Deployment
metadata:
name: your-app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: your-app
template:
metadata:
labels:
app: your-app
spec:
containers:
- name: your-app
image: your-dockerhub-username/your-app:${DRONE_COMMIT_SHA}
ports:
- containerPort: 80
In this pipeline:
- The
build-and-deploystep uses theplugins/dockerimage. It builds your Docker image and pushes it to Docker Hub. Notice how it tags the image with${DRONE_COMMIT_SHA}. This is Drone’s way of injecting environment variables related to the current commit. - The
kubernetes-deploystep uses theplugins/kubernetesimage. It takes your Kubernetes deployment manifest and applies it to your cluster. Crucially, it substitutes theimagefield in the deployment to use the newly built image tagged with the commit SHA.
The problem this solves is bridging the gap between your CI/CD system (Drone) and your container orchestration platform (Kubernetes). Instead of Drone needing direct access to kubectl or complex RBAC configurations, it leverages its own plugin infrastructure. The plugin runs as a pod within your Kubernetes cluster, and Drone orchestrates this pod’s execution.
Internally, when the kubernetes-deploy step runs, the plugins/kubernetes image starts up. It reads your kubeconfig (provided as a secret) and establishes a connection to your Kubernetes API server. It then takes the provided template data, performs variable substitution (like injecting the image tag), and uses the Kubernetes client library to apply this manifest to your cluster. This is essentially what kubectl apply -f - would do, but managed by Drone.
The namespace setting tells the plugin which Kubernetes namespace to target. The template section is where you define your Kubernetes resources. You can use standard Kubernetes YAML here, and the plugin will apply it.
A common point of confusion is that the plugins/kubernetes image itself is not running your application. It’s a temporary build container that interacts with your Kubernetes cluster. Once the step is complete, this pod is terminated. Your actual application pods are, of course, managed by Kubernetes itself.
The most surprising aspect for many is how the plugin handles authentication. While you can provide a raw kubeconfig file, it’s far more common and secure to use Kubernetes Service Accounts. If Drone is running within the same Kubernetes cluster where you want to deploy, you can often omit the kubeconfig entirely. The plugin will then automatically attempt to use the Service Account token mounted into the plugin pod by Kubernetes. This is a much cleaner and more secure approach, as it avoids exposing cluster credentials outside the cluster.
After successfully deploying a new image, the next logical step is to verify that the deployment is healthy, which often leads to exploring readiness and liveness probes within your Kubernetes manifests.