* fix(coredns): using patch for deployment and service reconciliation
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* feat(kubeproxy): using patch for daemonset reconciliation
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
---------
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
This commit extends CRD API: Added hostNetwork field to KonnectivityAgentSpec struct.
It's false by default so it's backwards compatible.
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* feat: pausing reconciliation of controlled objects
Objects such as TenantControlPlane and Secret can be annotated with
kamaji.clastix.io/paused to prevent controllers from processing them.
This will stop reconciling objects for debugging or other purposes.
Annotation value is irrelevant, just the key presence is evaluated.
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* docs: pausing reconciliation of controlled objects
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* chore(logs): typo for deleted resources
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
---------
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
This patch switches default kubelet-preferred-address-types to
"InternalIP,ExternalIP,Hostname" to avoid failures in kube-apiserver
connection to kubelet when node hostnames are not resolvable by the
external DNS server. This improves out-of-the-box reliability across
most environments by choosing node `InternalIP` as the preferred mode
to reach Kubelet.
Signed-off-by: Parth Yadav <parthyadav3105@gmail.com>
* feat(migration): customising timeout via tcp annotation
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* docs: customising migration timeout via tcp annotation
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* fix(migrate): delete job in case of timeout change
This will delete the failed job due to an incorrect timeout and performs
the creation of a new object rather than updating it, since its
immutability in the API specification.
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
---------
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* feat(migration): cleanup prior migration
When using the annotation `kamaji.clastix.io/cleanup-prior-migration`
with a true boolean value, Kamaji will perform a clean-up on the target
DataStore to avoid stale resources when back and forth migrations occur.
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* docs: cleanup prior migration
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
---------
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* feat: buffered channels for generic events
Channels used for GenericEvent feeding for cross controllers triggers
are now buffered according to the --max-concurrent-tcp-reconciles: this
is required to avoid channel full errors when dealing with large
management clusters serving a sizeable amount of Tenant Control Planes.
Increasing this value will put more pressure on memory (mostly for GC)
and CPU (provisioning multiple certificates at the same time).
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* refactor: retrying datastore status update
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* feat(performance): reducing memory consumption for channel triggers
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* feat(datastore): reconcile events only for root object changes
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* feat: waiting soot manager exit before termination
This change introduces a grace period of 10 seconds before abruptly
terminating the Tenant Control Plane deployment, allowing the soot
manager to complete its exit procedure and avoid false positive errors
due to API Server being unresponsive due to user deletion.
Aim of this change is reducing the amount of false positive errors upon
mass deletion of Tenant COntrol Plane objects.
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* refactor: unbuffered channel with timeout
WatchesRawSource is non blocking, no need to check if channel is full.
To prevent deadlocks a WithTimeout check has been introduced.
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
---------
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
This change is required for the enterprise offering where the Kamaji
stable image is hosted in a container registry with authentication and
can't be pulled with no credentials: when a migrate job is spun up it
resuses the same Kamaji controller ServiceAccount which will offer its
image pull credentials.
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* test: add scale to zero e2e test
Signed-off-by: Mario Valderrama <mario.valderrama@ionos.com>
* fix: retry create token command
* fix: use correct assertion
---------
Signed-off-by: Mario Valderrama <mario.valderrama@ionos.com>
* feat(api): introducing sleeping status
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* chore(helm)!: introducing sleeping status
Marking this commit as breaking since a CustomResourceDefinition update
is required for users dealing with scale to zero since the introduction
of the new enum for the status field.
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* docs: introducing sleeping status
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
---------
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* feat: Validate DataStores with CEL using the following rules
- certificateAuthority privateKey must have secretReference or content when driver is etcd
- clientCertificate must have secretReference or content when driver is etcd
- clientCertificate privateKey must have secretReference or content when driver is etcd
- When driver is not etcd and tlsConfig exists, certificateAuthority must be null or contain valid content
- When driver is not etcd and tlsConfig exists, clientCertificate must be null or contain valid content
- When driver is not etcd and basicAuth exists, username must have secretReference or content
- When driver is not etcd and basicAuth exists, password must have secretReference or content
- When driver is not etcd, either tlsConfig or basicAuth must be provided
Signed-off-by: aerosouund <aerosound161@gmail.com>
* fix: Add extra rule
Signed-off-by: aerosouund <aerosound161@gmail.com>
* fix: ginkgo flag ordering
Signed-off-by: aerosouund <aerosound161@gmail.com>
* fix: Fix syntax of tls or basic auth rule and remove the certificate authority rule
Signed-off-by: aerosouund <aerosound161@gmail.com>
* test: Add ginkgo tests for validations
Signed-off-by: aerosouund <aerosound161@gmail.com>
* fix(test): missing default values
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* chore(ci): running integration tests as gh job
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
---------
Signed-off-by: aerosouund <aerosound161@gmail.com>
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
Co-authored-by: Dario Tranchitella <dario@tranchitella.eu>
Addresses #688, this commit removes the deprecated `spec.loadBalancerIP`.
With the property being set in the service, the AWS cloud controller complained and caused issues.
This commit introduces a breaking change such as the removal of
the default bootstrap token created by kubeadm on an idempotent basis.
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
- Fixes a deployment issue with CD tools like ArgoCD.
- apiVersion and kind not set in source, causing drift.
- Ensures consistent state across deployments.
Signed-off-by: kahirokunn <okinakahiro@gmail.com>
* feat(webhook): validating api server cert sans
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* feat(controller): validating api server cert sans
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
---------
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* Update README.md
Minor changes to helm deployment instructions
* further changes to improve helm deployment instructions
* ran make -C charts/kamaji docs
* fixed helm deployment instructions
* chore(kubeadm): bumping up support to v1.31.3
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* chore(deps): bumping up support to v1.31.3
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
---------
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* fix: cel for load balancer class
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* fix(helm): cel for load balancer class
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
---------
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* feat: automatically set dns service address
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* feat(helm): automatically set dns service address
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* docs: automatically set dns service address
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
---------
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* feat(crd): add LoadBalancerSourceRanges field and integrate with service resource
* test(crd): add tests for CEL validation logic
* feat(webhook): implement LoadBalancerSourceRanges validation logic for CIDRs
* test(webhook): add tests for webhook validation logic
* test: modify Makefile for envtest setup
* docs: add LoadBalancerSourceRanges field to API reference
* fix(adopters): order alphabetically according to the header
Signed-off-by: Jan Schoone <jan@jass.es>
* feat(adopters): add Sovereign Cloud Stack
Signed-off-by: Jan Schoone <jan@jass.es>
---------
Signed-off-by: Jan Schoone <jan@jass.es>
* feat: Add DataStoreSchema field to TCP spec
* feat: Read DB_SCHEMA from TCP spec field
* feat: Default DataStoreSchema in webhook
* fix: Catch unsetting the dataStore via CEL
* fix: Apply all patches, not only the first
This also includes converting OnUpdate() to a no-op, as the
existence and immutability of the fields are already checked
by the API server, thanks to kubebuilder markers.
The webhook ensures that fields like dataStore, dataStoreSchema
are defaulted during creation (if unset), and the CEL expressions
prohibit unsetting them during update.
* test: Add tests for defaulting webhook
* fix: typo
* fix: Linter issues
* fix: make apidoc
* Update TCP CRD in charts folder
* fix: Don't run E2E tests during `make test`
* fix: Use proper `metav1` import name
* feat: Handle updates of TCPs without dataStoreSchema (+ tests)
* fix: Prioritize Status over Spec
Co-authored-by: Dario Tranchitella <dario@tranchitella.eu>
* Update goDoc on DataStore field
* make apidoc
---------
Co-authored-by: Dario Tranchitella <dario@tranchitella.eu>
A bug has been introduced with #527 which doesn't handle properly all the required business logic, such as the application of customised labels, as well as the handling of the controller Resource.
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* chore(makefile): installing cert-manager via helm
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* chore: removing need of kustomize in favor of yq
By removing kustomize generation files we can simply release, despite
the bundles must be removed since based on kustomize despite never being
used.
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* chore(ci): aligning to latest manifest generation strategy
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
---------
Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
* chore: improve error handling and logging for certificate operations
- Enhance error reporting in GenerateCertificatePrivateKeyPair function
- Add detailed error checks for CA certificate and private key parsing
- Implement check for expected number of certificate files
- Improve error logging in APIServerCertificate resource
This commit preserves more details about certificate-related issues,
aiding in debugging and troubleshooting.
* feat: support loadbalancer hostname resolution
Add functionality to resolve loadbalancer hostname to IP address in DeclaredControlPlaneAddress method.
This enhances the existing IP address handling by allowing the use of hostnames for loadbalancers.
- Add hostname check in addition to IP check
- Implement hostname resolution using net.LookupIP
- Return the first resolved IP address if available
* fix: Remove hostname support for LoadBalancer ingress
- Extract LoadBalancer address logic to separate function
- Remove hostname resolution for LoadBalancer ingress
- Add explanatory comments on reasons for not supporting hostnames
* fix: replace fmt and vet with golint
- Remove fmt and vet targets
- Update build target to use golint instead of fmt and vet
- Remove fmt and vet dependencies from run target
* fix: lint errors
During reconciliation, the bootstrap provider copies the content from the secret provided by Kamaji, named `<cluster>-admin-kubeconfig` into a `cluster-info` configmap of tenant cluster, which then used by kubeadm to join nodes.
This change introduces a new annotation, `kamaji.clastix.io/kubeconfig-secret-key`, for the TenantControlPlane resource. This annotation instructs kamaji to read the kubeconfig from a specific key (the default one is super-admin.conf).
Example:
```
kamaji.clastix.io/kubeconfig-secret-key: super-admin.svc
```
This will instruct the system to use `super-admin.svc` a kubeconfig with a local service FQDN (introduced by https://github.com/clastix/kamaji/pull/403).
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
The label kamaji.clastix.io/soot is deprecated in favour of
kamaji.clastix.io/name, every external resource referring to this must
be aligned prior to updating to this version.
The TCP Deployment container kube-apiserver is deeply hacked with extra
details for konnectivity: most of them weren't cleaned-up properly, and
the function wasn't entirely idempotent in toggling the feature.
This fix is addressing this situation, and rearranging the code
according to the latest polish.
Using the log facade and logging the error directly in the resource
handler we're getting a more detailed overview of the errors, along with
other metadata useful to understand quicker where the reconciliation
failed.
Starting from this change, all the nodes trying to join a Kamaji TCP
must be initiated with kubeadm >= 1.25. This is not a hard-prerequisite
since a previous Kubernetes version can be used by specifying it in the
ClusterConfiguration kubernetesVersion field.
A new CLI flag (`--kine-container`) has been introduced, with the
default value of `rancher/kine:v0.9.2-amd64`. It can be overridden also
using the kamaji configuration file (`kamaji.yaml`) using the key
`kine-image`.
For AddOns and KubeadmPhase the last revision reference has been removed
in favor of the md5 hash: this has been required since some information
required for the comparison is not persisted in the admin cluster.
With this change, the CRD definition has changed too, making this change
breaking, although still in v1alpha1.
Removing the field tcp.spec.networkProfile.domain in favor of the
tcp.spec.networkProfile.certSANs which allows specifying additional
extra domains that could be used to reach out to the tenant control
plane.
This is a list of companies that have adopted Kamaji.
Feel free to open a Pull-Request to get yours listed.
### Adopter list (alphabetically)
| Type | Name | Since | Website | Use-Case |
|:-|:-|:-|:-|:-|
| Vendor | Aknostic | 2023 | [link](https://aknostic.com) | Aknostic is a cloud-native consultancy company using Kamaji to build a Kubernetes based PaaS. |
| Vendor | Aruba | 2025 | [link](https://www.arubacloud.com/) | Aruba Cloud is an Italian Cloud Service Provider using Kamaji to build and offer [Managed Kubernetes Service](https://my.arubacloud.com). |
| Vendor | CBWS | 2025 | [link](https://cbws.nl) | CBWS is an European Cloud Provider using Kamaji to build and offer their [Managed Kubernetes Service](https://cbws.nl/cloud/kubernetes/). |
| Vendor | Coredge | 2025 | [link](https://coredge.io/) | Coredge uses Kamaji in its K8saaS offering to save infrastructure costs in its Sovereign Cloud & AI Infrastructure Platform for end-user organisations. |
| Vendor | DCloud | 2024 | [link](https://dcloud.co.id) | DCloud is an Indonesian Cloud Provider using Kamaji to build and offer [Managed Kubernetes Service](https://dcloud.co.id/dkubes.html). |
| Vendor | Dinova | 2025 | [link](https://dinova.one/) | Dinova is an Italian cloud services provider that integrates Kamaji in its datacenters to offer fully managed Kubernetes clusters. |
| End-user | KINX | 2024 | [link](https://kinx.net/?lang=en) | KINX is an Internet infrastructure service provider and will use kamaji for its new [Managed Kubernetes Service](https://kinx.net/service/cloud/kubernetes/intro/?lang=en). |
| Vendor | Netsons | 2023 | [link](https://www.netsons.com) | Netsons is an Italian hosting and cloud provider and uses Kamaji in its [Managed Kubernetes](https://www.netsons.com/kubernetes) offering. |
| Vendor | NVIDIA | 2024 | [link](https://github.com/NVIDIA/doca-platform) | DOCA Platform Framework manages provisioning and service orchestration for NVIDIA Bluefield DPUs. |
| R&D | Orange | 2024 | [link](https://gitlab.com/Orange-OpenSource/kanod) | Orange is a French telecommunications company using Kamaji for experimental research purpose, with Kanod research solution. |
| Vendor | Platform9 | 2024 | [link](https://elasticmachinepool.com) | Platform9 uses Kamaji in its offering - Elastic Machine Pool, which is a tool for optimizing the cost of running kubernetes clusters in EKS. |
| Vendor | Qumulus | 2024 | [link](https://www.qumulus.io) | Qumulus is a cloud provider and plans to use Kamaji for it's hosted Kubernetes service |
| End-user | sevensphere | 2023 | [link](https://www.sevensphere.io) | Sevensphere provides consulting services for end-user companies / cloud providers and uses Kamaji for designing cloud/on-premises Kubernetes-as-a-Service platform. |
| End-user | Sicuro Tech Lab | 2024 | [link](https://sicurotechlab.it/) | Sicuro Tech Lab offers cloud infrastructure for Web Agencies and uses kamaji to provide managed k8s services. |
| Vendor | Sovereign Cloud Stack | 2024 | [link](https://sovereigncloudstack.org) | Sovereign Cloud Stack develops a standardized cloud platform and uses Kamaji in there Kubernetes-as-a-Service reference implementation |
| R&D | TIM | 2024 | [link](https://www.gruppotim.it) | TIM is an Italian telecommunications company using Kamaji for experimental research and development purposes. |
| End-user | Tinext Cloud | 2025 | [link](https://cloud.tinext.com) | Tinex Cloud is a Swiss cloud service provider using Kamaji to build their Managed Kubernetes Services. |
| Vendor | Ænix | 2023 | [link](https://aenix.io/) | Ænix provides consulting services for cloud providers and uses Kamaji for running Kubernetes-as-a-Service in free PaaS platform [Cozystack](https://cozystack.io). |
| End-user | Rackspace | 2024 | [link](https://spot.rackspace.com/) | Rackspace Spot uses Kamaji to manage our instances, offering fully-managed kubernetes infrastructure, auctioned in an open market. |
| R&D | IONOS Cloud | 2024 | [link](https://cloud.ionos.com/) | IONOS Cloud is a German Cloud Provider evaluating Kamaji for its [Managed Kubernetes platform](https://cloud.ionos.com/managed/kubernetes). |
| Vendor | OVHCloud | 2025 | [link](https://www.ovhcloud.com/) | OVHCloud is a European Cloud Provider that will use Kamaji for its Managed Kubernetes Service offer. |
| Vendor | WOBCOM GmbH | 2024 | [link](https://www.wobcom.de/) | WOBCOM provides an [**Open Digital Platform**](https://www.wobcom.de/geschaeftskunden/odp/) solution for Smart Cities, which is provided for customers in a Managed Kubernetes provided by Kamaji. |
### Adopter Types
**End-user**: The organization runs Kamaji in production in some way.
**Integration**: The organization has a product that integrates with Kamaji, but does not contain Kamaji.
**Vendor**: The organization packages Kamaji in their product and sells it as part of their product.
**R&D**: Company that exploring innovative technologies and solutions for research and development purposes.
test -s $(LOCALBIN)/ko ||GOBIN=$(LOCALBIN)CGO_ENABLED=0 go install -ldflags="-s -w" github.com/google/ko@v0.14.1
.PHONY:yq
yq:$(YQ)## Download yq locally if necessary.
$(YQ):$(LOCALBIN)
test -s $(LOCALBIN)/yq ||GOBIN=$(LOCALBIN)CGO_ENABLED=0 go install -ldflags="-s -w" github.com/mikefarah/yq/v4@v4.44.2
.PHONY:helm
helm:$(HELM)## Download helm locally if necessary.
$(HELM):$(LOCALBIN)
test -s $(LOCALBIN)/helm ||GOBIN=$(LOCALBIN)CGO_ENABLED=0 go install -ldflags="-s -w" helm.sh/helm/v3/cmd/helm@v3.9.0
.PHONY:ginkgo
ginkgo:$(GINKGO)## Download ginkgo locally if necessary.
$(GINKGO):$(LOCALBIN)
test -s $(LOCALBIN)/ginkgo ||GOBIN=$(LOCALBIN)CGO_ENABLED=0 go install -ldflags="-s -w" github.com/onsi/ginkgo/v2/ginkgo
.PHONY:kind
kind:$(KIND)## Download kind locally if necessary.
$(KIND):$(LOCALBIN)
test -s $(LOCALBIN)/kind ||GOBIN=$(LOCALBIN)CGO_ENABLED=0 go install -ldflags="-s -w" sigs.k8s.io/kind/cmd/kind@v0.14.0
.PHONY:controller-gen
controller-gen:$(CONTROLLER_GEN)## Download controller-gen locally if necessary.
$(CONTROLLER_GEN):$(LOCALBIN)
test -s $(LOCALBIN)/controller-gen ||GOBIN=$(LOCALBIN)CGO_ENABLED=0 go install -ldflags="-s -w" sigs.k8s.io/controller-tools/cmd/controller-gen@v0.16.1
.PHONY:golangci-lint
golangci-lint:$(GOLANGCI_LINT)## Download golangci-lint locally if necessary.
$(GOLANGCI_LINT):$(LOCALBIN)
test -s $(LOCALBIN)/golangci-lint ||GOBIN=$(LOCALBIN)CGO_ENABLED=0 go install -ldflags="-s -w" github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.0.2
.PHONY:apidocs-gen
apidocs-gen:$(APIDOCS_GEN)## Download crdoc locally if necessary.
$(APIDOCS_GEN):$(LOCALBIN)
test -s $(LOCALBIN)/crdoc ||GOBIN=$(LOCALBIN)CGO_ENABLED=0 go install -ldflags="-s -w" fybrik.io/crdoc@latest
.PHONY:envtest
envtest:$(ENVTEST)## Download envtest-setup locally if necessary.
$(ENVTEST):$(LOCALBIN)
test -s $(LOCALBIN)/setup-envtest ||GOBIN=$(LOCALBIN)CGO_ENABLED=0 go install -ldflags="-s -w" sigs.k8s.io/controller-runtime/tools/setup-envtest@$(ENVTEST_VERSION)
##@ Development
manifests:controller-gen## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
<a href="https://kubernetes.slack.com/archives/C03GLTTMWNN"><img alt="#kamaji on Kubernetes Slack" src="https://img.shields.io/badge/slack-@kubernetes/kamaji-blue.svg?logo=slack"/></a>
</p>
**Kamaji** is a tool aimed to build and operate a **Managed Kubernetes Service** with a fraction of the operational burden. With **Kamaji**, you can deploy and operate hundreds of Kubernetes clusters as a hyper-scale cloud provider.


<p align="center" style="padding: 6px 6px">
<img src="assets/kamaji-logo.png" />
</p>
### 🤔 What is Kamaji?
> This project is still in the early development stage which means it's not ready for production as APIs, commands, flags, etc. are subject to change, but also that your feedback can still help to shape it. Please try it out and let us know what you like, dislike, what works, what doesn't, etc.
**Kamaji** is the **Kubernetes Control Plane Manager** leveraging on the concept of [**Hosted Control Plane**](https://clastix.io/post/the-raise-of-hosted-control-plane-in-kubernetes/).
## Why we are building it?
Global hyper-scalers are leading the Managed Kubernetes space, while regional cloud providers, as well as large corporations, are struggling to offer the same level of experience to their developers because of the lack of the right tools. Also, Kubernetes solutions for the on-premises are designed with an enterprise-first approach and they are too costly when deployed at scale. Project Kamaji aims to solve this pain by leveraging multi-tenancy and simplifying how to run Kubernetes clusters at scale with a fraction of the operational burden.
Kamaji's approach is based on running the Kubernetes Control Plane components in Pods instead of dedicated machines.
This allows operating Kubernetes clusters at scale, with a fraction of the operational burden.
Thanks to this approach, running multiple Control Planes can be cheaper and easier to deploy and operate.
## How it works
Kamaji turns any CNCF conformant Kubernetes cluster into an _“admin cluster”_ to orchestrate other Kubernetes clusters we're calling _“tenant clusters”_. As with every Kubernetes cluster, a tenant cluster has a set of nodes and a control plane, composed of several components: `APIs server`, `scheduler`, `controller manager`. What Kamaji does is deploy those components as a pod running in the admin cluster.
_Kamaji is like a fleet of Site Reliability Engineers with expertise codified into its logic, working 24/7 to keep up and running your Control Planes._
And what about the tenant worker nodes? They are just worker nodes: regular instances, e.g. virtual or bare metal, connecting to the APIs server of the tenant cluster. Kamaji's goal is to manage the lifecycle of hundreds of these clusters, not only one, so how can we add another tenant cluster? As you could expect, Kamaji just deploys a new tenant control plane as a new pod in the admin cluster, and then it joins the new tenant worker nodes.
### 📖 How it works
<p align="center">
<img src="assets/kamaji-light.png" />
</p>
Kamaji is extending the Kubernetes API capabilities thanks to [Custom Resource Definitions](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#customresourcedefinitions).
All the tenant clusters built with Kamaji are fully compliant CNCF Kubernetes clusters and are compatible with the standard Kubernetes toolchains everybody knows and loves.
By installing Kamaji, two pairs of new APIs will be available:
<p align="center">
<img src="assets/screenshot.png" />
</p>
-`TenantControlPlane`, the instance definition of your desired Kubernetes Control Plane
-`Datastore`, the backing store used by one (or more) `TenantControlPlane`
## Save the state
Putting the tenant cluster control plane in a pod is the easiest part. Also, we have to make sure each tenant cluster saves the state to be able to store and retrieve data.
The `TenantControlPlane` (short-named as `tcp`) objects are Namespace-scoped and allows configuring every aspect of your desired Control Plane.
Besides the Kubernetes configuration values, you can specify the Pod options such as limit, request, tolerations, node selector, etc.,
as well as how these should be exposed (e.g.: using a `ClusterIP`, a `LoadBalancer`, or a `NodePort`).
A dedicated `etcd` cluster for each tenant cluster doesn’t scale well for a managed service because `etcd` data persistence can be cumbersome at scale, rising the operational effort to mitigate it. So we have to find an alternative keeping in mind our goal for a resilient and cost-optimized solution at the same time. As we can deploy any Kubernetes cluster with an external `etcd` cluster, we explored this option for the tenant control planes. On the admin cluster, we deploy a multi-tenant `etcd` cluster storing the state of multiple tenant clusters.
The `TenantControlPlane` is the stateless definition of the Control Plane allowing to set up the required components for a full-fledged Kubernetest cluster.
The state is managed by the `Datastore` API, a cluster-scoped resource which can hold the data of one or more Kubernetes clusters.
With this solution, the resiliency is guaranteed by the usual `etcd` mechanism, and the pods' count remains under control, so it solves the main goal of resiliency and costs optimization. The trade-off here is that we have to operate an external `etcd` cluster and manage the access to be sure that each tenant cluster uses only its data. Also, there are limits in size in `etcd`, defaulted to 2GB and configurable to a maximum of 8GB. We’re solving this issue by pooling multiple `etcd` and sharding the tenant control planes.
> For further information about the API specifications and all the available options,
> refer to the official [API reference](https://kamaji.clastix.io/reference/api/#tenantcontrolplane).
## Use cases
Kamaji project has been initially started as a solution for actual and common problems such as minimizing the Total Cost of Ownership while running Kubernetes at scale. However, it can open a wider range of use cases. Here are a few:
### ⭐️ Main features
### Managed Kubernetes
Enabling companies to provide Cloud Native Infrastructure with ease by introducing a strong separation of concerns between management and workloads. Centralize clusters management, monitoring, and observability by leaving developers to focus on the applications, increase productivity and reduce operational costs.
- **Fast provisioning time**: depending on the infrastructure, Tenant Control Planes are up and ready to serve traffic in **16 seconds**.
- **Streamlined update**: the rollout to a new Kubernetes version for a given Tenant Control Plane takes just **10 seconds**, with a Blue/Green deployment to avoid serving mixed Kubernetes versions.
- **Resource optimization**: thanks to the Datastore decoupling, there's no need of odd number instances (e.g.: RAFT consensus) by allowing to save up to 60% of HW resources.
- **Scale from zero to the moon**: scale down the instance when there's no usage, or automatically scale to support the traffic spikes reusing the Kubernetes patterns.
- **Declarative approach, constant reconciliation**: thanks to the Operator pattern, drift detection happens in real-time, maintaining the desired state.
- **Automated certificates management**: Kamaji leverages on `kubeadm` and the certificates are automatically created and rotated for you.
- **Managing core addons**: Kamaji allows configuring automatically `kube-proxy`, `CoreDNS`, and `konnectivity`, with automatic remediation in case of user errors (e.g.: deleting the `CoreDNS` deployment).
- **Auto Healing**: the `TenantControlPlane` objects in the management cluster are tracked by Kamaji, in case of deletion of those, everything is created in an idempotent way.
- **Datastore multi-tenancy**: optionally, Kamaji allows running multiple Control Planes on the same _Datastore_ instance leveraging on the multi-tenancy of each driver, decreasing operations and optimizing costs.
- **Overcoming `etcd` limitations**: optionally, Kamaji allows using a different _Datastore_ thanks to [`kine`](https://github.com/k3s-io/kine) by supporting `MySQL`, `PostgreSQL`, or `NATS` as an alternative.
- **Simplifying mixed-networks setup**: thanks to [`Konnectivity`](https://kubernetes.io/docs/tasks/extend-kubernetes/setup-konnectivity/),
the Tenant Control Plane is connected to the worker nodes hosted in a different network, overcoming the no-NAT availability when dealing with nodes with a non routable IP address
(e.g.: worker nodes in a different infrastructure).
### Control Plane as a Service
Provide Kubernetes control plane in a self-service fashion by running management and workloads on different infrastructures and cost centers with the option of Bring Your Own Device - BYOD.
### 🚀 Use cases
### Edge Computing
Distribute Kubernetes workloads across edge computing locations without having to manage multiple clusters across various providers. Centralize management of hundreds of control planes while leaving workloads to run isolated on their own dedicated infrastructure.
- [**Creating a private Managed Kubernetes Service**](https://clastix.io/post/netsons-builds-a-managed-kubernetes-service-with-kamaji-and-open-stack/)
- [**Building a Platform as a Service**](https://aenix.io/cozystack/)
- [**Overcoming public Managed Kubernetes Services**](https://clastix.io/post/overcoming-eks-limitations-with-kamaji-on-aws/) such as EKS
host the Control Plane on the Cloud and worker nodes on prem or vice-versa, according to your needs.
- [**Kubernetes at the edge**](https://clastix.io/post/edgevolution-unleashing-the-power-of-kubernetes-clusters-for-a-revolutionary-edge-computing-experience/):
take full advantage of the _Kubernetes API Server as a service_ paradigm.
- **Kubernetes Control Plane as a Service:** centrally manage multiple Kubernetes clusters from a single management point (_Multi-Cluster management_).
- **High-density Control Plane:** place multiple control planes on the same infrastructure, instead of having dedicated machines for each control plane.
- **Strong Multi-tenancy:** leave users to access the control plane with admin permissions while keeping them isolated at the infrastructure level.
- **Kubernetes Inception:** use Kubernetes to manage Kubernetes with automation, high-availability, fault tolerance, and autoscaling out of the box.
- **Bring Your Own Device:** keep the control plane isolated from data plane. Worker nodes can join and run consistently from everywhere: cloud, edge, and data-center.
- **Full CNCF compliant:** all clusters are built with upstream Kubernetes binaries, resulting in full CNCF compliant Kubernetes clusters.
### Cluster Simulations
Test a new Kubernetes API or experimental flag or a new tool without impacting production operations. Kamaji will let you simulate such things in a safe and controlled environment.
> 🤔 You'd like to do the same but don't know how?
> 💡 [CLASTIX](https://clastix.io/) can help you with your needs!
## Features
### 🧑💻 Production grade
### Self Service Kubernetes
Leave users the freedom to self-provision their Kubernetes clusters according to the assigned boundaries.
Kamaji is empowering several businesses, and it counts public adopters.
Check out the [adopters](./ADOPTERS.md) file to learn more.
### Multi-cluster Management
Centrally manage multiple tenant clusters from a single admin cluster. Happy SREs.
> 🤗 If you're using Kamaji, share your love by opening a PR!
### Cheaper Control Planes
Place multiple tenant control planes on a single node, instead of having three nodes for a single control plane.
### 🍦 Vanilla Kubernetes clusters
### Stronger Multi-Tenancy
Leave tenants to access the control plane with admin permissions while keeping the tenant isolated at the infrastructure level.
Kamaji is **not** yet-another-Kubernetes distribution: you have full freedom on the technology stack to provide to end users.
Kamaji is a perfect fit for Platform Engineering, hiding the complexity of the Control Plane management to developers and DevOps engineers.
### Kubernetes Inception
Use Kubernetes to manage Kubernetes by re-using all the Kubernetes goodies you already know and love.
The provided Kubernetes Control Planes are [CNCF compliant clusters](https://kamaji.clastix.io/reference/conformance/).
### Full APIs compliant
Tenant clusters are fully CNCF compliant built with upstream Kubernetes binaries. A client does not see differences between a Kamaji provisioned cluster and a dedicated cluster.
- [x] Support for dynamic address allocation on native Load Balancer
Kamaji is **not** a [Cluster API](https://cluster-api.sigs.k8s.io/) replacement, rather, it plays very well with it.
Since Kamaji is just focusing on the Control Plane a [Kamaji's Cluster API Control Plane provider](https://github.com/clastix/cluster-api-control-plane-provider-kamaji) has been developed.
### 🛣️ Roadmap
- [x] Dynamic address on Load Balancer
- [x] Zero Downtime Tenant Control Plane upgrade
- []`konnectivity` integration
- []Provisioning of Tenant Control Plane through Cluster APIs
- []Prometheus metrics for monitoring and alerting
- []`kine` integration, i.e. use MySQL, SQLite, PostgreSQL as datastore
- [ ]Deeper `kubeadm` integration
- [ ]`etcd` pooling
- []Tenant Control Planes sharding
- [x][Join worker nodes from anywhere thanks to Konnectivity](https://kamaji.clastix.io/concepts/#konnectivity)
- [x][Pool of multiple datastores](https://kamaji.clastix.io/concepts/#datastores)
- [x][Seamless migration between datastores](https://kamaji.clastix.io/guides/datastore-migration/)
- [ ]Automatic assignment to a datastore
- [ ]Autoscaling of Tenant Control Plane
- [x][Provisioning through Cluster APIs](https://github.com/clastix/cluster-api-control-plane-provider-kamaji)
- [ ] Terraform provider
- [ ] Custom Prometheus metrics
## Documentation
Please, check the project's [documentation](./docs/) for getting started with Kamaji.
### 🎥 Multimedia
## Contributions
Kamaji is Open Source with Apache 2 license and any contribution is welcome.
- Playlist ▶️ [Tutorials and How-Tos by Dario Tranchitella, CLASTIX](https://www.youtube.com/playlist?list=PLjiUjoV4Ws_3pNsUpTXI-KKk731nD2MQY)
- YouTube ▶️ [Metal³ provisioning with Kamaji Hosted Control Planes by Huy Mai, Ericsson](https://youtu.be/u9sbURj6jXY?t=10536)
- YouTube ▶️ [Hands-on introduction to Kamaji](https://www.youtube.com/watch?v=HhevxwQWQ88)
- YouTube ▶️ [Scaling Kubernetes up to 1,000 Control Planes](https://www.youtube.com/watch?v=W_HXRXJh96U)
- YouTube ▶️ [Equinix, Kamaji, and Cluster API](https://www.youtube.com/watch?v=TLBTqROj_wA)
- YouTube ▶️ [Rancher & Kamaji: solving multitenancy challenges in the Kubernetes world](https://www.youtube.com/watch?v=VXHNrMmlF8U)
- YouTube ▶️ [Enabling Self-Service Kubernetes clusters with Kamaji and Paralus](https://www.youtube.com/watch?v=JWA2LwZazM0)
- YouTube ▶️ [Hosted Control Plane on Kubernetes (HPC) with Kamaji and K0mostron by Hervé Leclerc, ALTER WAY](https://www.youtube.com/watch?v=vmRdE2ngn78)
## FAQ
Q. What does Kamaji means?
### 🏷️ Versioning
A. Kamaji is named as the character _Kamaji_ from the Japanese movie [_Spirited Away_](https://en.wikipedia.org/wiki/Spirited_Away).
Versioning adheres to the [Semantic Versioning](http://semver.org/) principles.
A full list of the available releases is available in the GitHub repository's [**Release** section](https://github.com/clastix/kamaji/releases).
Q. Is Kamaji another Kubernetes distribution?
### 📄 Documentation
A. No, Kamaji is a tool you can install on top of any CNCF conformant Kubernetes to provide hundreds of managed Tenant clusters as a service. We tested Kamaji on vanilla Kubernetes 1.23+, KinD, and MS Azure AKS. We expect it to work smoothly on other Kubernetes distributions. The tenant clusters made with Kamaji are conformant CNCF Kubernetes vanilla clusters built with `kubeadm`.
Further documentation can be found on the official [Kamaji documentation website](https://kamaji.clastix.io/).
Q. Is it safe to run Kubernetes control plane components in a pod?
### 🤝 Contributions
A. Yes, the tenant control plane components are packaged in the same way they are running in bare metal or virtual nodes. We leverage the `kubeadm` code to set up the control plane components as they were running on a server. The same unchanged images of upstream `APIs server`, `scheduler`, `controller manager` are used.
Contributions are highly appreciated and very welcomed!
Q. And what about multi-tenant `etcd`? I never heard of it.
In case of bugs, please, check if the issue has been already opened by checking the [GitHub Issues](https://github.com/clastix/kamaji/issues) section.
In case it isn't, you can open a new one: a detailed report will help us to replicate it, assess it, and work on a fix.
A. Even if multi-tenant deployment for `etcd` is not a common practice, multi-tenancy, RBAC, and client authentication has been [supported](https://etcd.io/docs/v3.5/op-guide/authentication/) in `etcd` from a long time.
You can express your intention in working on the fix on your own.
The commit messages are checked according to the described [semantics](https://github.com/projectcapsule/capsule/blob/main/CONTRIBUTING.md#semantics).
Commits are used to generate the changelog, and their author will be referenced in it.
Q. You already provide a Kubernetes multi-tenancy solution with [Capsule](capsule.clastix.io). Why does Kamaji matter?
In case of **✨ Feature Requests** please use the [Discussion's Feature Request section](https://github.com/clastix/kamaji/discussions/categories/feature-requests).
A. Lighter Multi-Tenancy solutions, like Capsule shares the Kubernetes control plane among all tenants keeping tenant namespaces isolated by policies. While these solutions are the right choice by balancing between features and ease of usage, there are cases where a tenant user requires access to the control plane, for example, when a tenant requires to manage CRDs on his own. With Kamaji, you can provide admin permissions to the tenants.
### 📝 License
Q. So I need a costly cloud infrastructure to try Kamaji?
Kamaji is licensed under Apache 2.0.
The code is provided as-is with no warranties.
A. No, it is possible to try Kamaji on your laptop with [KinD](./deploy/kind/README.md).
### 🛟 Commercial Support
 [CLASTIX](https://clastix.io/) is the commercial company behind Kamaji and the Cluster API Control Plane provider.
If you're looking to run Kamaji in production and would like to learn more, **CLASTIX** can help by offering [Open Source support plans](https://clastix.io/support),
as well as providing a comprehensive Enterprise Platform named [CLASTIX Enterprise Platform](https://clastix.cloud/), built on top of the Kamaji and [Capsule](https://capsule.clastix.io/) project (now donated to CNCF as a Sandbox project).
Feel free to get in touch with the provided [Contact form](https://clastix.io/contact).
//+kubebuilder:validation:XValidation:rule="self == oldSelf",message="Datastore driver is immutable"
typeDriverstring
var(
EtcdDriverDriver="etcd"
KineMySQLDriverDriver="MySQL"
KinePostgreSQLDriverDriver="PostgreSQL"
KineNatsDriverDriver="NATS"
)
//+kubebuilder:validation:MinItems=1
typeEndpoints[]string
// DataStoreSpec defines the desired state of DataStore.
// +kubebuilder:validation:XValidation:rule="(self.driver == \"etcd\") ? (self.tlsConfig != null && (has(self.tlsConfig.certificateAuthority.privateKey.secretReference) || has(self.tlsConfig.certificateAuthority.privateKey.content))) : true", message="certificateAuthority privateKey must have secretReference or content when driver is etcd"
// +kubebuilder:validation:XValidation:rule="(self.driver == \"etcd\") ? (self.tlsConfig != null && (has(self.tlsConfig.clientCertificate.certificate.secretReference) || has(self.tlsConfig.clientCertificate.certificate.content))) : true", message="clientCertificate must have secretReference or content when driver is etcd"
// +kubebuilder:validation:XValidation:rule="(self.driver == \"etcd\") ? (self.tlsConfig != null && (has(self.tlsConfig.clientCertificate.privateKey.secretReference) || has(self.tlsConfig.clientCertificate.privateKey.content))) : true", message="clientCertificate privateKey must have secretReference or content when driver is etcd"
// +kubebuilder:validation:XValidation:rule="(self.driver != \"etcd\" && has(self.tlsConfig) && has(self.tlsConfig.clientCertificate)) ? (((has(self.tlsConfig.clientCertificate.certificate.secretReference) || has(self.tlsConfig.clientCertificate.certificate.content)))) : true", message="When driver is not etcd and tlsConfig exists, clientCertificate must be null or contain valid content"
// +kubebuilder:validation:XValidation:rule="(self.driver != \"etcd\" && has(self.basicAuth)) ? ((has(self.basicAuth.username.secretReference) || has(self.basicAuth.username.content))) : true", message="When driver is not etcd and basicAuth exists, username must have secretReference or content"
// +kubebuilder:validation:XValidation:rule="(self.driver != \"etcd\" && has(self.basicAuth)) ? ((has(self.basicAuth.password.secretReference) || has(self.basicAuth.password.content))) : true", message="When driver is not etcd and basicAuth exists, password must have secretReference or content"
// +kubebuilder:validation:XValidation:rule="(self.driver != \"etcd\") ? (has(self.tlsConfig) || has(self.basicAuth)) : true", message="When driver is not etcd, either tlsConfig or basicAuth must be provided"
typeDataStoreSpecstruct{
// The driver to use to connect to the shared datastore.
DriverDriver`json:"driver"`
// List of the endpoints to connect to the shared datastore.
// No need for protocol, just bare IP/FQDN and port.
EndpointsEndpoints`json:"endpoints"`
// In case of authentication enabled for the given data store, specifies the username and password pair.
// This value is optional.
BasicAuth*BasicAuth`json:"basicAuth,omitempty"`
// Defines the TLS/SSL configuration required to connect to the data store in a secure way.
// This value is optional.
TLSConfig*TLSConfig`json:"tlsConfig,omitempty"`
}
// TLSConfig contains the information used to connect to the data store using a secured connection.
typeTLSConfigstruct{
// Retrieve the Certificate Authority certificate and private key, such as bare content of the file, or a SecretReference.
// The key reference is required since etcd authentication is based on certificates, and Kamaji is responsible in creating this.
// Version is the running Kubernetes version of the Tenant Control Plane.
//+kubebuilder:validation:XValidation:rule="!(self.mode == 'DaemonSet' && has(self.replicas) && self.replicas != 0) && !(self.mode == 'Deployment' && self.replicas == 0)",message="replicas must be 0 when mode is DaemonSet, and greater than 0 when mode is Deployment"
typeKonnectivityAgentSpecstruct{
// AgentImage defines the container image for Konnectivity's agent.
// Enables the kube-proxy addon in the Tenant Cluster.
// The registry and the tag are configurable, the image is hard-coded to `kube-proxy`.
KubeProxy*AddonSpec`json:"kubeProxy,omitempty"`
}
// KubernetesIngressStatus defines the status for the TenantControlPlane Ingress in the management cluster.
typeKubernetesIngressStatusstruct{
networkingv1.IngressStatus`json:",inline"`
// The name of the Ingress for the given cluster.
Namestring`json:"name"`
// The namespace which the Ingress for the given cluster is deployed.
Namespacestring`json:"namespace"`
// TenantControlPlaneSpec defines the desired state of TenantControlPlane.
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.dataStore) || has(self.dataStore)", message="unsetting the dataStore is not supported"
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.dataStoreSchema) || has(self.dataStoreSchema)", message="unsetting the dataStoreSchema is not supported"
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.dataStoreUsername) || has(self.dataStoreUsername)", message="unsetting the dataStoreUsername is not supported"
// +kubebuilder:validation:XValidation:rule="!has(self.networkProfile.loadBalancerSourceRanges) || (size(self.networkProfile.loadBalancerSourceRanges) == 0 || self.controlPlane.service.serviceType == 'LoadBalancer')", message="LoadBalancer source ranges are supported only with LoadBalancer service type"
// +kubebuilder:validation:XValidation:rule="!has(self.networkProfile.loadBalancerClass) || self.controlPlane.service.serviceType == 'LoadBalancer'", message="LoadBalancerClass is supported only with LoadBalancer service type"
// +kubebuilder:validation:XValidation:rule="self.controlPlane.service.serviceType != 'LoadBalancer' || (oldSelf.controlPlane.service.serviceType != 'LoadBalancer' && self.controlPlane.service.serviceType == 'LoadBalancer') || has(self.networkProfile.loadBalancerClass) == has(oldSelf.networkProfile.loadBalancerClass)",message="LoadBalancerClass cannot be set or unset at runtime"
typeTenantControlPlaneSpecstruct{
// DataStore specifies the DataStore that should be used to store the Kubernetes data for the given Tenant Control Plane.
// When Kamaji runs with the default DataStore flag, all empty values will inherit the default value.
// By leaving it empty and running Kamaji with no default DataStore flag, it is possible to achieve automatic assignment to a specific DataStore object.
//
// Migration from one DataStore to another backed by the same Driver is possible. See: https://kamaji.clastix.io/guides/datastore-migration/
// Migration from one DataStore to another backed by a different Driver is not supported.
DataStorestring`json:"dataStore,omitempty"`
// DataStoreSchema allows to specify the name of the database (for relational DataStores) or the key prefix (for etcd). This
// value is optional and immutable. Note that Kamaji currently doesn't ensure that DataStoreSchema values are unique. It's up
// to the user to avoid clashes between different TenantControlPlanes. If not set upon creation, Kamaji will default the
// DataStoreSchema by concatenating the namespace and name of the TenantControlPlane.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="changing the dataStoreSchema is not supported"
//+kubebuilder:printcolumn:name="Control-Plane-Endpoint",type="string",JSONPath=".status.controlPlaneEndpoint",description="Tenant Control Plane Endpoint (API server)"
//+kubebuilder:printcolumn:name="Kubeconfig",type="string",JSONPath=".status.kubeconfig.admin.secretName",description="Secret which contains admin kubeconfig"
//+kubebuilder:printcolumn:name="Installed Version",type="string",JSONPath=".status.kubernetesResources.version.version",description="The actual installed Kubernetes version from status"
//+kubebuilder:printcolumn:name="Control-Plane endpoint",type="string",JSONPath=".status.controlPlaneEndpoint",description="Tenant Control Plane Endpoint (API server)"
//+kubebuilder:printcolumn:name="Kubeconfig",type="string",JSONPath=".status.kubeconfig.admin.secretName",description="Secret which contains admin kubeconfig"
There are two methods for specifying overrides of values during Chart installation: `--values` and `--set`.
The `--values` option is the preferred method because it allows you to keep your overrides in a YAML file, rather than specifying them all on the command line. Create a copy of the YAML file `values.yaml` and add your overrides to it.
Specify your overrides file when you install the Chart:
The values in your overrides file `myvalues.yaml` will override their counterparts in the Chart's values.yaml file. Any values in `values.yaml` that weren’t overridden will keep their defaults.
If you only need to make minor customizations, you can specify them on the command line by using the `--set` option. For example:
| fullnameOverride | string | `""` | Overrides the full name of the resources created by the chart. |
| kamajiCertificateName | string | `"kamaji-serving-cert"` | The cert-manager Certificate resource name, holding the Certificate Authority for webhooks. |
| kamajiNamespace | string | `"kamaji-system"` | The namespace where Kamaji has been installed: required to inject the Certificate Authority for cert-manager. |
| kamajiService | string | `"kamaji-webhook-service"` | The Kamaji webhook Service name. |
| nameOverride | string | `""` | Overrides the name of the chart for resource naming purposes. |
There are two methods for specifying overrides of values during Chart installation: `--values` and `--set`.
The `--values` option is the preferred method because it allows you to keep your overrides in a YAML file, rather than specifying them all on the command line. Create a copy of the YAML file `values.yaml` and add your overrides to it.
Specify your overrides file when you install the Chart:
The values in your overrides file `myvalues.yaml` will override their counterparts in the Chart's values.yaml file. Any values in `values.yaml` that weren’t overridden will keep their defaults.
If you only need to make minor customizations, you can specify them on the command line by using the `--set` option. For example:
{{-printf"%s/%s"(required"A valid .Values.kamajiNamespace is required".Values.kamajiNamespace)(required"A valid .Values.kamajiCertificateName is required".Values.kamajiCertificateName)}}
[Kamaji](https://github.com/clastix/kamaji) requires a [multi-tenant `etcd`](https://github.com/clastix/kamaji-internal/blob/master/deploy/getting-started-with-kamaji.md#setup-internal-multi-tenant-etcd) cluster.
This Helm Chart starting from v0.1.1 provides the installation of an internal `etcd` in order to streamline the local test. If you'd like to use an externally managed etcd instance, you can specify the overrides and by setting the value `etcd.deploy=false`.
> For production use an externally managed `etcd` is highly recommended, the `etcd` addon offered by this Chart is not considered production-grade.
There are two methods for specifying overrides of values during Chart installation: `--values` and `--set`.
The `--values` option is the preferred method because it allows you to keep your overrides in a YAML file, rather than specifying them all on the command line. Create a copy of the YAML file `values.yaml` and add your overrides to it.
Specify your overrides file when you install the Chart:
The values in your overrides file `myvalues.yaml` will override their counterparts in the Chart's values.yaml file. Any values in `values.yaml` that weren’t overridden will keep their defaults.
If you only need to make minor customizations, you can specify them on the command line by using the `--set` option. For example:
| livenessProbe | object | `{"httpGet":{"path":"/healthz","port":"healthcheck"},"initialDelaySeconds":15,"periodSeconds":20}` | The livenessProbe for the controller container |
| loggingDevel.enable | bool | `false` | Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn). Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error) (default false) |
| metricsBindAddress | string | `":8080"` | The address the metric endpoint binds to. (default ":8080") |
| podAnnotations | object | `{}` | The annotations to apply to the Kamaji controller pods. |
| podSecurityContext | object | `{"runAsNonRoot":true}` | The securityContext to apply to the Kamaji controller pods. |
| readinessProbe | object | `{"httpGet":{"path":"/readyz","port":"healthcheck"},"initialDelaySeconds":5,"periodSeconds":10}` | The readinessProbe for the controller container |
| replicaCount | int | `1` | The number of the pod replicas for the Kamaji controller. |
| securityContext | object | `{"allowPrivilegeEscalation":false}` | The securityContext to apply to the Kamaji controller container only. It does not apply to the Kamaji RBAC proxy container. |
| temporaryDirectoryPath | string | `"/tmp/kamaji"` | Directory which will be used to work with temporary files. (default "/tmp/kamaji") |
| tolerations | list | `[]` | Kubernetes node taints that the Kamaji controller pods would tolerate |
## Installing and managing etcd as DataStore
Kamaji supports multiple data store, although `etcd` is the default one: thus, an initial cluster will be created upon the Chart installation.
The `DataStore` resource can be configured with the proper values in case of overrides when using a different driver, otherwise all the required data will be inherited by the Chart values.
[Kamaji](https://github.com/clastix/kamaji) requires a [multi-tenant `etcd`](https://github.com/clastix/kamaji-internal/blob/master/deploy/getting-started-with-kamaji.md#setup-internal-multi-tenant-etcd) cluster.
This Helm Chart starting from v0.1.1 provides the installation of an internal `etcd` in order to streamline the local test. If you'd like to use an externally managed etcd instance, you can specify the overrides and by setting the value `etcd.deploy=false`.
> For production use an externally managed `etcd` is highly recommended, the `etcd` addon offered by this Chart is not considered production-grade.
There are two methods for specifying overrides of values during Chart installation: `--values` and `--set`.
The `--values` option is the preferred method because it allows you to keep your overrides in a YAML file, rather than specifying them all on the command line. Create a copy of the YAML file `values.yaml` and add your overrides to it.
Specify your overrides file when you install the Chart:
The values in your overrides file `myvalues.yaml` will override their counterparts in the Chart's values.yaml file. Any values in `values.yaml` that weren’t overridden will keep their defaults.
If you only need to make minor customizations, you can specify them on the command line by using the `--set` option. For example:
Kamaji supports multiple data store, although `etcd` is the default one: thus, an initial cluster will be created upon the Chart installation.
The `DataStore` resource can be configured with the proper values in case of overrides when using a different driver, otherwise all the required data will be inherited by the Chart values.
# -- Toggle the ServiceMonitor true if you have Prometheus Operator installed and configured
enabled:false
# -- The address the probe endpoint binds to. (default ":8081")
healthProbeBindAddress:":8081"
@@ -56,7 +38,7 @@ readinessProbe:
initialDelaySeconds:5
periodSeconds:10
# -- (string) The address the metric endpoint binds to. (default ":8080")
# -- The address the metric endpoint binds to. (default ":8080")
metricsBindAddress:":8080"
imagePullSecrets:[]
@@ -89,28 +71,6 @@ securityContext:
# runAsNonRoot: true
# runAsUser: 1000
service:
type:ClusterIP
port:8443
ingress:
# -- Whether to expose the Kamaji controller through an Ingress.
enabled:false
# -- Name of the ingress class to route through this controller.
className:""
annotations:{}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host:chart-example.local
paths:
- path:/
pathType:ImplementationSpecific
tls:[]
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources:
limits:
cpu:200m
@@ -132,5 +92,23 @@ affinity: {}
temporaryDirectoryPath:"/tmp/kamaji"
loggingDevel:
# -- (string) Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn). Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error) (default false)
# -- Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn). Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error) (default false)
enable:false
# -- If specified, all the Kamaji instances with an unassigned DataStore will inherit this default value.
defaultDatastoreName:default
# -- Subchart: See https://github.com/clastix/kamaji-etcd/blob/master/charts/kamaji-etcd/values.yaml
kamaji-etcd:
deploy:true
fullnameOverride:kamaji-etcd
## -- Important, this must match your management cluster's clusterDomain, otherwise the init jobs will fail
cmd.Flags().StringVar(&metricsBindAddress,"metrics-bind-address",":8080","The address the metric endpoint binds to.")
cmd.Flags().StringVar(&healthProbeBindAddress,"health-probe-bind-address",":8081","The address the probe endpoint binds to.")
cmd.Flags().BoolVar(&leaderElect,"leader-elect",true,"Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.")
cmd.Flags().StringVar(&tmpDirectory,"tmp-directory","/tmp/kamaji","Directory which will be used to work with temporary files.")
cmd.Flags().StringVar(&kineImage,"kine-image","rancher/kine:v0.11.10-amd64","Container image along with tag to use for the Kine sidecar container (used only if etcd-storage-type is set to one of kine strategies).")
cmd.Flags().StringVar(&datastore,"datastore","","Optional, the default DataStore that should be used by Kamaji to setup the required storage of Tenant Control Planes with undeclared DataStore.")
cmd.Flags().StringVar(&migrateJobImage,"migrate-image",fmt.Sprintf("%s/clastix/kamaji:%s",internal.ContainerRepository,internal.GitTag),"Specify the container image to launch when a TenantControlPlane is migrated to a new datastore.")
cmd.Flags().IntVar(&maxConcurrentReconciles,"max-concurrent-tcp-reconciles",1,"Specify the number of workers for the Tenant Control Plane controller (beware of CPU consumption)")
cmd.Flags().StringVar(&managerNamespace,"pod-namespace",os.Getenv("POD_NAMESPACE"),"The Kubernetes Namespace on which the Operator is running in, required for the TenantControlPlane migration jobs.")
cmd.Flags().StringVar(&managerServiceName,"webhook-service-name","kamaji-webhook-service","The Kamaji webhook server Service name which is used to get validation webhooks, required for the TenantControlPlane migration jobs.")
cmd.Flags().StringVar(&managerServiceAccountName,"serviceaccount-name",os.Getenv("SERVICE_ACCOUNT"),"The Kubernetes Namespace on which the Operator is running in, required for the TenantControlPlane migration jobs.")
cmd.Flags().StringVar(&webhookCAPath,"webhook-ca-path","/tmp/k8s-webhook-server/serving-certs/ca.crt","Path to the Manager webhook server CA, required for the TenantControlPlane migration jobs.")
cmd.Flags().DurationVar(&controllerReconcileTimeout,"controller-reconcile-timeout",30*time.Second,"The reconciliation request timeout before the controller withdraw the external resource calls, such as dealing with the Datastore, or the Tenant Control Plane API endpoint.")
cmd.Flags().BoolVar(&disableTelemetry,"disable-telemetry",false,"Disable the analytics traces collection.")
cmd.Flags().DurationVar(&certificateExpirationDeadline,"certificate-expiration-deadline",24*time.Hour,"Define the deadline upon certificate expiration to start the renewal process, cannot be less than a 24 hours.")
returnfmt.Errorf("unable to migrate data from %s to %s: %w",originDs.GetName(),targetDs.GetName(),err)
}
log.Info("migration completed")
returnnil
},
}
cmd.Flags().StringVar(&tenantControlPlane,"tenant-control-plane","","Namespaced-name of the TenantControlPlane that must be migrated (e.g.: default/test)")
cmd.Flags().StringVar(&targetDataStore,"target-datastore","","Name of the Datastore to which the TenantControlPlane will be migrated")
cmd.Flags().BoolVar(&cleanupPriorMigration,"cleanup-prior-migration",false,"When set to true, migration job will drop existing data in the target DataStore: useful to avoid stale data when migrating back and forth between DataStores.")
cmd.Flags().DurationVar(&timeout,"timeout",5*time.Minute,"Amount of time for the context timeout")
- description:Tenant Control Plane Endpoint (API server)
jsonPath:.status.controlPlaneEndpoint
name:Control-Plane-Endpoint
type:string
- description:Secret which contains admin kubeconfig
jsonPath:.status.kubeconfig.admin.secretName
name:Kubeconfig
type:string
- description:Age
jsonPath:.metadata.creationTimestamp
name:Age
type:date
name:v1alpha1
schema:
openAPIV3Schema:
description:TenantControlPlane is the Schema for the tenantcontrolplanes
API.
properties:
apiVersion:
description:'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type:string
kind:
description:'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type:string
metadata:
type:object
spec:
description:TenantControlPlaneSpec defines the desired state of TenantControlPlane.
properties:
controlPlane:
description:ControlPlane defines how the Tenant Control Plane Kubernetes
resources must be created in the Admin Cluster, such as the number
of Pod replicas, the Service resource, or the Ingress.
properties:
deployment:
description:Defining the options for the deployed Tenant Control
Plane as Deployment resource.
properties:
additionalMetadata:
description:AdditionalMetadata defines which additional metadata,
such as labels and annotations, must be attached to the
created resource.
properties:
annotations:
additionalProperties:
type:string
type:object
labels:
additionalProperties:
type:string
type:object
type:object
replicas:
default:2
format:int32
type:integer
type:object
ingress:
description:Defining the options for an Optional Ingress which
will expose API Server of the Tenant Control Plane
properties:
additionalMetadata:
description:AdditionalMetadata defines which additional metadata,
such as labels and annotations, must be attached to the
created resource.
properties:
annotations:
additionalProperties:
type:string
type:object
labels:
additionalProperties:
type:string
type:object
type:object
enabled:
type:boolean
hostname:
description:Hostname is an optional field which will be used
as Ingress's Host. If it is not defined, Ingress's host
will be "<tenant>.<namespace>.<domain>", where domain is
specified under NetworkProfileSpec
type:string
ingressClassName:
type:string
required:
- enabled
type:object
service:
description:Defining the options for the Tenant Control Plane
Service resource.
properties:
additionalMetadata:
description:AdditionalMetadata defines which additional metadata,
such as labels and annotations, must be attached to the
created resource.
properties:
annotations:
additionalProperties:
type:string
type:object
labels:
additionalProperties:
type:string
type:object
type:object
serviceType:
description:ServiceType allows specifying how to expose the
Tenant Control Plane.
enum:
- ClusterIP
- NodePort
- LoadBalancer
type:string
required:
- serviceType
type:object
required:
- service
type:object
kubernetes:
description:Kubernetes specification for tenant control plane
properties:
admissionControllers:
default:
- CertificateApproval
- CertificateSigning
- CertificateSubjectRestriction
- DefaultIngressClass
- DefaultStorageClass
- DefaultTolerationSeconds
- LimitRanger
- MutatingAdmissionWebhook
- NamespaceLifecycle
- PersistentVolumeClaimResize
- Priority
- ResourceQuota
- RuntimeClass
- ServiceAccount
- StorageObjectInUseProtection
- TaintNodesByCondition
- ValidatingAdmissionWebhook
description:'List of enabled Admission Controllers for the Tenant
cluster. Full reference available here: https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers'
items:
enum:
- AlwaysAdmit
- AlwaysDeny
- AlwaysPullImages
- CertificateApproval
- CertificateSigning
- CertificateSubjectRestriction
- DefaultIngressClass
- DefaultStorageClass
- DefaultTolerationSeconds
- DenyEscalatingExec
- DenyExecOnPrivileged
- DenyServiceExternalIPs
- EventRateLimit
- ExtendedResourceToleration
- ImagePolicyWebhook
- LimitPodHardAntiAffinityTopology
- LimitRanger
- MutatingAdmissionWebhook
- NamespaceAutoProvision
- NamespaceExists
- NamespaceLifecycle
- NodeRestriction
- OwnerReferencesPermissionEnforcement
- PersistentVolumeClaimResize
- PersistentVolumeLabel
- PodNodeSelector
- PodSecurity
- PodSecurityPolicy
- PodTolerationRestriction
- Priority
- ResourceQuota
- RuntimeClass
- SecurityContextDeny
- ServiceAccount
- StorageObjectInUseProtection
- TaintNodesByCondition
- ValidatingAdmissionWebhook
type:string
type:array
kubelet:
properties:
cgroupfs:
description:CGroupFS defines the cgroup driver for Kubelet
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.