dron8s
dron8s copied to clipboard
Yet another Kubernetes plugin for Drone using dynamic Server Side Apply to achieve --server-side parity for your CI-CD pipelines
Dron8s
Yet another Kubernetes plugin for Drone using dynamic Server Side Apply to achieve kubectl apply --server-side
parity for your CI-CD pipelines.
Features
- Create resources if they do not exist/update if they do
- Can handle multiple yaml configs in one file
- Can handle most resource types1
- In-cluster/Out-of-cluster use
- Easy set up, simple usage, well documented
- Support variables
1Dron8s uses [email protected]. While most common Kubernetes API will work with your cluster's version, some features will not. For more information check the compatibility matrix.
in-cluster use
In-cluster use is intented to only work along Kubernetes Runner with in-cluster deployment scope. That is your pipelines can only apply
resources within the cluster Kubernetes Runner is running.
Prerequisites
You need to manually create a clusterrolebinding
resource to allow cluster edit access for Drone.
Assuming you installed Drone/Kubernetes Runner using Drone provided Helm charts run:
$ kubectl create clusterrolebinding dron8s --clusterrole=edit --serviceaccount=drone:default --namespace=drone
If you opted for manual installation you have to replace the --serviceaccount
and/or --namespace
flag with the correct service/namespace name you used (ie. --serviceaccount=drone-ci:default --namespace=default
).
In-cluster Pipe Example
kind: pipeline
type: kubernetes
name: dron8s-in-cluster-example
steps:
- name: dron8s
image: ghcr.io/bh90210/dron8s:latest
settings:
yaml: ./config.yaml
In-cluster Pipe Example With Variables
for a full example see the examples folder
kind: pipeline
type: kubernetes
name: dron8s-in-cluster-example
steps:
- name: dron8s
image: ghcr.io/bh90210/dron8s:latest
settings:
yaml: ./config.yaml
# variables. Must be lowercase, Usage: {{.service_name}}
service_name: myservice
And in your config:
apiVersion: v1
kind: Service
metadata:
name: {{.service_name}}
spec:
...
Uninstall
You need to manually delete the clusterrolebinding
created as prerequisite. Run:
$ kubectl delete clusterrolebinding dron8s --namespace=drone
out-of-cluster use
For out-of-cluster use you can choose whichever runner you prefer but you need to provide you cluster's kubeconfig
via a secret.
Prerequisites
Create a secret with the contents of kubeconfig.
NOTE: You can always use Vault or AWS Secrets etc. But for this example I only show Per Repository, Kubernetes Secrets & Encrypted.
1. Per Repository Secrets (GUI)
Copy the contents of your ~/.kube/config
in Drone's Secret Value field and name the secret kubeconfig
:
Per Repository Secrets - Docker Runner Pipe Example
kind: pipeline
type: docker
name: dron8s-out-of-cluster-example
steps:
- name: dron8s
image: ghcr.io/bh90210/dron8s:latest
settings:
yaml: ./config.yaml
kubeconfig:
from_secret: kubeconfig
Uninstall
Delete the secret
containing kubeconfig.
2. Kubernetes Secrets (Kubectl)
In order to use this type of secret you have to install Kubernetes Secrets
Helm Chart.
Furthermore the assumption is that you use Kubernetes Runner
with out-of-cluster scope.
That is a scenario where your CI/CD exists in cluster a and you apply configurations in cluster b. For in-cluster usage you do not need Kubernetes Secrets
or secrets at all. See in-cluster use.
Before using Kubernetes Secrets in your pipeline you first need to manually create your secrets via kubectl
. In this case you need to create a secret out of ~/.kube/config
. Run:
$ kubectl create secret generic dron8s --from-file=kubeconfig=$HOME/.kube/config
note that if you opted for different namespace than the default when installed drone-kubernetes-secret
chart (secretNamespace
& KUBERNETES_NAMESPACE
) you need to also pass the appropriate --namespace
flag to the above command
Kubernetes Secrets - Kubernetes Runner Pipe Example
kind: pipeline
type: kubernetes
name: dron8s-out-of-cluster-example
steps:
- name: dron8s
image: ghcr.io/bh90210/dron8s:latest
settings:
yaml: ./config.yaml
kubeconfig:
from_secret: kubeconfig
---
kind: secret
name: kubeconfig
get:
path: dron8s
name: kubeconfig
Uninstall
Delete the secret
containing kubeconfig. Run:
$ kubectl delete secret dron8s
3. Encrypted (Drone CLI)
In order to use this method you need to have Drone CLI installed and configured on your machine.
To generate the secret run:
$ drone encrypt user/repository @$HOME/.kube/config
where user
is your real username and repository
the name of the repository that you are creating the secret for.
Copy the output of your terminal to data
field inside kubeconfig secret.
Encrypted Secret - Exec Runner Pipe Example
kind: pipeline
type: exec
name: dron8s-out-of-cluster-example
platform:
os: linux
arch: amd64
steps:
- name: dron8s
image: ghcr.io/bh90210/dron8s:latest
settings:
yaml: ./config.yaml
kubeconfig:
from_secret: kubeconfig
---
kind: secret
name: kubeconfig
data: ZGDJTGfiy5vzdvvZWRSEdIRlloamRmaW9saGJkc0vsVSDVs[...]
Field Manager
When transferring ownership for server-side-apply
you will need to know the field manager of Dron8s (as described on the relevant issue).
The field manager is dron8s-plugin
and can be found in the source code too.
Known issues (and workarounds)
- If your resource contains
ports:
without specifically declaringprotocol: TCP
/protocol: UDP
you will probably get a similar error:
failed to create typed patch object: .spec.template.spec.containers[name=].ports: element 0: associative list with keys has an element that omits key field "protocol"
The workaround is to simply define a protocol like so where applicable:
ports:
- protocol: TCP
containerPort: 80
If it is not possible to alter the resource then maybe consider upgrading to Kubernetes v.0.20.0 where this bug is hopefully resolved.
Developing
You need to have Go and Docker installed on your system.
If you wish you may clone the repo and directly edit .drone.yaml
as everything you need for the build is right there.
Otherwise:
$ git clone github.com/bh90210/dron8s
$ docker build -t {yourusername}/dron8s .
$ docker push {yourusername}/dron8s
To use your own repo inside Drone pipelines just change the image
field to {yourusername}/dron8s
kind: pipeline
type: docker
name: default
steps:
- name: dron8s
image: {yourusername}/dron8s
settings:
yaml: ./config.yaml
Replace {yourusername}
with your actual Docker Hub (or other registry) username.
For more information see Drone's Go Plugin Documentation.
Contributing
Any code improvements, updates, documentation spelling corrections etc are always very welcome.
It is a very simple project so just clone the master branch, edit it and open a PR.