Kubernetes deployment straight outta your comfy terminal.
I freaking love Kubernetes! But I freaking hate Continuous Delivery tools during the development process!
Don't get me wrong, CD tools are crucial nowadays. Deployments became much more stable and, therefore, more painless - in production.
But is it for the day-to-day development process? Of course, yes - the answer of any sane developer.
And I agree. But still, how many buttons on shiny UI need to be pressed to do deployment? Open the CD site in the browser, login or SSO, 2FA via an app, find a suitable pipeline, recall and enter the right environment, microservice, proper infra definitions, and required Docker image.
Wow, wait a minute... and repeat that over again every time?
So, why not automate it?
The motto of any self-respecting developer.
With each filthy CD cycle, when I was forced to quit my code editor or terminal, my mind started to become poisoned with this paranoic question. Poisoning grew alongside anger, irritation, and annoyance.
Hence, on the third day, I started writing a Bash script. The initial version, which can be found in the legacy folder. Doing its job, but clumsy, unmaintainable, and slow (still cool 😎 , check it out if you're a Bash guy). However, the demand for new features, and its challenges when writing them in Bash, paved my path to Golang and the current contents of this brilliant repository.
>_ kdeploy [microservice]
Deploy specific microservice.Initiates K8S REST clients based on local .kube configuration. Searches for images of requested microservice in Google Artifact Registry, prompts you to interactively select an image for deployment (arrows navigation, search features), and sets the selected image in the workload. Kubernetes will handle deployment afterwards.
kdeploy ms-training
>_ kdeploy
If microservice was not specified - it obtains possible repositories from the configured registry and prompts you to select it first. Then proceeds to the original flow.kdeploy
>_ kdeploy --previous [microservice]
kdeploy remembers every deployment you made and allows you to redeploy previous images from history.kdeploy --previous ms-training
Running deploy-previous mode without specifying microservice results in prompting microservice first from your previous deployments.
kdeploy requires two configuration blocks to run:
gar- how to read images from Google Artifact Registry:project,location,repository, and optionalpackagePrefix.k8s- how image paths should be written back to Kubernetes:registryandrepository.
If they are not set you will be prompted to enter them on startup. You can define them interactively:
kdeploy config define gar
kdeploy config define k8s
Example values:
gar:
project: company-infra
location: us
repository: docker-images
packagePrefix: company-
k8s:
registry: us-docker.pkg.dev
repository: company-infra/docker-images/Or edit configuration file manually:
kdeploy config edit
Assumed that all Kubernetes workloads are of Deployment type. If some are Stateful Sets, set them in configurations (comma separated):
kdeploy config set statefulsets ms-events,ms-core
kdeploy allows you to define mappings for your microservices in the configuration file. This is useful when a microservice has different names in GAR and Kubernetes.
To define a mapping, use the following command:
kdeploy config define mappings
Then you will be prompted to provide microservice name (required) and names for GAR and Kubernetes (optional).
You can define mappings for multiple microservices by running the command multiple times with different microservice names.
The resulting configuration looks like this:
mappings:
api-events:
gar: events
k8s: cmpn-eventsTo view the current configuration, use the following command:
kdeploy config view
Run go build command in the root directory to build the binary file.
Then place it on at /usr/local/bin for convenient access anywhere on your system.
Minimal setup requirements:
- A working Kubernetes context in your local
~/.kube/config. - Google credentials that can read Artifact Registry packages and versions.
- A populated kdeploy config file at
~/.config/kdeploy/.kdeploy.yaml.
Recommended first-run flow:
go build -o kdeploy
mv ./kdeploy /usr/local/bin/kdeploy
kdeploy config define gar
kdeploy config define k8s
kdeploy config define mappings # optional
kdeploy config view
kdeploy <microservice>Google authentication:
- kdeploy uses Application Default Credentials for Google Artifact Registry access.
- In local development, the usual setup is:
gcloud auth application-default login- You can also use a service account through standard ADC mechanisms if that is how your environment is configured.
Kubernetes access:
- kdeploy reads your current kube context from
~/.kube/config. - Before using kdeploy, make sure the selected context points to the target cluster and namespace flow you expect.
Configuration file:
- Path:
~/.config/kdeploy/.kdeploy.yaml - The file is created automatically if it does not exist.
kdeploy config editopens that file directly.
How image names are composed:
- GAR package lookup uses:
projects/{gar.project}/locations/{gar.location}/repositories/{gar.repository}/packages/{gar.packagePrefix}{microservice} - Kubernetes image patching uses:
{k8s.registry}/{k8s.repository}{gar-package}:{tag}@sha256:{digest} - If
mappings.<service>.garis set, that mapped GAR package name is used instead of{gar.packagePrefix}{microservice}.
Example:
gar:
project: company-infra
location: us
repository: docker-images
packagePrefix: company-
k8s:
registry: us-docker.pkg.dev
repository: company-infra/docker-images/
mappings:
api-events:
gar: events
k8s: cmpn-eventsWith this config:
kdeploy api-userslooks up GAR packagecompany-api-userskdeploy api-eventslooks up GAR packageevents- deploying
api-eventspatches the Kubernetes image for container/resource namecmpn-events
Troubleshooting:
- If GAR listing fails with a Google auth error, verify ADC is configured with
gcloud auth application-default login. - If Kubernetes requests fail, verify your current kube context and cluster access before running kdeploy.
- If a service uses different names in GAR and Kubernetes, add a
mappingsentry instead of relying on--k8s-nameevery time.


