Skip to content
/ dron8s Public
forked from bh90210/dron8s

Yet another Kubernetes plugin for Drone using dynamic Server Side Apply to achieve kubectl apply -f parity for your CI-CD pipelines

License

Notifications You must be signed in to change notification settings

jeessy2/dron8s

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

71 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dron8s

Yet another Kubernetes plugin for Drone using dynamic Server Side Apply to achieve kubectl apply -f 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 client-go@v0.19.2. 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 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: bh90210/dron8s:latest
  settings:
    yaml: ./config.yaml
    # variables. Must be lowercase, Usage: {{.service_name}}
    service_name: myservice
    image_version: 1.8

Uninstall

You need to manually delete the clusterrolebinding created as prerequisite. Run:

$ kubectl delete clusterrolebinding dron8s --namespace=drone

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:

Imgur

Per Repository Secrets - Docker Runner Pipe Example

kind: pipeline
type: docker
name: dron8s-out-of-cluster-example

steps:
- name: dron8s
  image: bh90210/dron8s:latest
  settings:
    yaml: ./config.yaml
    kubeconfig:
        from_secret: kubeconfig
    # variables. Must be lowercase, Usage: {{.service_name}}
    service_name: myservice
    image_version: 1.8

Uninstall

Delete the secret containing kubeconfig.

Imgur

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: 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: bh90210/dron8s:latest
  settings:
    yaml: ./config.yaml
    kubeconfig:
        from_secret: kubeconfig
---
kind: secret
name: kubeconfig
data: ZGDJTGfiy5vzdvvZWRSEdIRlloamRmaW9saGJkc0vsVSDVs[...]

Known issues (and workarounds)

  • If your resource contains ports: without specifically declaring protocol: 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.

  • If you get an error (we know this to be true for at least configMap resource - see #11) the server could not find the requested resource the solution is to include a namespace field in your config, which is recomended as best practice for k8s anyway.
apiVersion: v1
kind: ConfigMap
metadata:
  name: demo
  namespace: default
data:
  key: "value"

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
$ GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o 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.

About

Yet another Kubernetes plugin for Drone using dynamic Server Side Apply to achieve kubectl apply -f parity for your CI-CD pipelines

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Go 98.3%
  • Dockerfile 1.7%