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:

  1. The build-and-deploy step uses the plugins/docker image. 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.
  2. The kubernetes-deploy step uses the plugins/kubernetes image. It takes your Kubernetes deployment manifest and applies it to your cluster. Crucially, it substitutes the image field 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.

Want structured learning?

Take the full Drone course →