I need advice in managing deployments in K8S. I need to have blue/green deployment, using gitops, and this leave me basically two options:
This will necessitate using helm to manage removing resources and whatnot, and by proxy managing blue/green through helm, and this in turn will necessitate creating duplicate deployment templates (for green and blue).
Pros: managed by helm, will delete removed resources; seems to be general practice.
Cons: managed by helm, can mess up something, especially in multiple failed deployments; can create snowflake namespace if someone quickly fix/add some resource and will not commit to repo;
Just deploy each revision to it's namespace like web-front-2142, check, promote to ingress, then delete all other web-front-[\d] I can still use helm template engine, but without tiller. No need to rely on tiller managing resources - namespace will be deleted after production namespace promotion.
I will need to create separate namespace for ingress, because it is singular resource, but this will be a really simple namespace, something like web-front-ingress.
Pros: no snowflakes, every deployment has been created fully from repo; if it works - it works; no dependency on previous deployments in any way, if previous deployment was totally foobar-ed, it doesn't matter.
Cons: separate namespace for singular resources like ingress; seems to be not how k8s was designed and can lead to unforeseen consequences; all deployments tools including spinnaker revolves around single namespace deployment.
Need some advice and best practices! :)
So, basically i've since settled on an answer - singular namespaces is a way to go. Mainly because of singular resources, like PVC, that can't be shared between namespaces.
But main epiphany is that you don't have to use tiller! You can still use helm templates, and K8S labels is all you need! For example i use jenkins as a builder AND versioner. It set labels like managed_by: jenkins
, and version: <build_number>
, so all i have to do on deploy is to find all resources with same name
and version lower than current and patch them, and then add new resources, and remove all resources managed_by: jenkins
that are no longer present (by their name
). I've build simple case of this and it seems to work just fine.
The official documentation mentions the following:
Namespaces are intended for use in environments with many users spread across multiple teams, or projects. For clusters with a few to tens of users, you should not need to create or think about namespaces at all. Start using namespaces when you need the features they provide.
It is not necessary to use multiple namespaces just to separate slightly different resources, such as different versions of the same software: use labels to distinguish resources within the same namespace.
The Kubernetes Namespaces: use cases and insights" article tells us more about best approaches using namespaces. It is not recommended to use different namespaces for versioning software:
An easy to grasp anti-pattern for Kubernetes namespaces is versioning. You should not use Namespaces as a way to disambiguate versions of your Kubernetes resources. Support for versioning is present in the containers and container registries as well as in Kubernetes Deployment resource. Multiple versions should coexist by utilizing the Kubernetes container model which also provides for auto migration between versions with deployments. Furthermore versions scope namespaces will cause massive proliferation of namespaces within a cluster making it hard to manage.
Other resources (e.g. GCPB) describe namespaces usage mostly for separating Kubernetes objects for various stages, teams, projects, clients.
So you can assume that using separate namespaces for blue-green deployments or canary deployment is not a very common approach.