consul-k8s: running Consul Service Mesh inside a Kubernetes cluster
First-class support for Consul Service Mesh on Kubernetes
At a glance
- What is it?
- consul-k8s is HashiCorp's control plane that gives Consul first-class Kubernetes integrations, injecting Envoy sidecars, running API Gateway and syncing the Consul catalog with Kubernetes Services, installed through a Helm chart or a CLI. It suits a cluster that wants Consul as the service mesh, and it does not suit a team that already runs a different mesh.
- Who is it for?
- consul-k8s is worth adopting for a team that has chosen Consul as its service mesh and wants Kubernetes-native behaviour rather than a bolt-on, because the sidecar injection, the gateway and the catalog sync are first-class features of the same control plane rather than separate add-ons, and because the project is versioned independently of Consul so the Kubernetes side can move faster than the agents.
- Can I use it commercially?
- Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A separate control plane, versioned on its own schedule
The consul-k8s-control-plane binary carries the integrations between Consul and Kubernetes, and the project bundles several use cases into it: syncing services, injecting Consul sidecars, and more.
The versioning decision is stated early and explained, and it is the first thing to understand. This project is versioned separately from Consul, and the supported Consul version for each feature is noted in the documentation. The reason given is practical: by versioning the Kubernetes integrations separately, the team can iterate on them more quickly and release new versions without forcing Consul users to do a full Consul upgrade.
That is a meaningful operational property. A mesh agent upgrade and a control plane upgrade are different risk profiles, and coupling them means every cluster operation waits for the slowest-moving component. The cost of the split is that you now track two version lines and a compatibility table between them, and the release list in the repository shows both shapes at once: v1.8.18 on 2026-10-20 and v2.1.0-rc2 on 2026-10-15, with v2.1.0-rc1 before that. A v2 line at release candidate while a v1 patch is current means the project is mid-transition, and the documentation notes the supported Consul version per feature so you can tell which line applies to you.
The primary language is Go, the licence is MPL-2.0, and the repository is not archived, with the last push on 2026-10-20.
Three features, and only one of them is about traffic
The feature list has three entries, and the third is the one people miss.
Consul Service Mesh is the first. It injects Envoy sidecars and registers your Pods with Consul, which is the standard Consul mesh deployment on Kubernetes.
Consul API Gateway is the second. It runs the gateway so that north/south traffic, meaning traffic entering and leaving the mesh, can get into the service mesh.
Catalog Sync is the third, and it is the one with a different purpose from the other two. It syncs Consul services into first-class Kubernetes services and vice versa. The stated effect is that Kubernetes can easily access external services, and that non-Kubernetes nodes can easily discover and access Kubernetes services.
That last one is worth pausing on, because it is not about the mesh at all. It is about making Consul and Kubernetes two views of the same set of services, so that a workload in either place can find the other. For an organisation that runs some workloads on Kubernetes and some on VMs or bare metal, that is often the reason to adopt Consul in the first place, and the mesh is the part you get along with it.
The repository layout backs the same picture. There is a control-plane/ directory for the binary, a cli/ directory for the CLI, charts/ for the Helm chart, acceptance/ for the end-to-end tests, a version/ directory, and a hack/ directory of small Go programs used by the build, each with its own directory and a go run invocation in the Makefile.
Installing with the CLI takes three commands and a tap
The documentation calls the CLI the easiest way to get up and running, and the sequence is short.
First, the HashiCorp tap, which is a repository of all the Homebrew packages for HashiCorp:
``` bash brew tap hashicorp/tap
Then the CLI itself from that tap:
bash brew install hashicorp/tap/consul-k8s
And then the install subcommand:
bash consul-k8s install ```
The CLI reference on the Consul website documents the subcommands and the available flags for each one, and the full documentation for the install path is on the same site.
The prerequisites for that route are specific. You need kubectl configured to authenticate to a cluster with a valid kubeconfig file, and you need brew, yum or apt on the local machine. In other words, the CLI is a machine-local tool that talks to the cluster through your existing kubeconfig, and it expects the usual package managers to be present.
The project is also distributed as a Docker image, hashicorp/consul-k8s-control-plane, which the documentation says can be used to manually run consul-k8s-control-plane within a scheduled environment. That route is the one to reach for when the install is driven by something other than a person at a terminal.
The Helm route is the recommended one, and it has its own prerequisites
The Helm chart is described as the recommended installation method, because it automatically configures the Consul and Kubernetes integration to run within an existing cluster, and it is the right choice for automation whether for install or for upgrade. The chart supports multiple use cases depending on the values provided.
The steps are the standard Helm repository dance. Add the HashiCorp repository:
``` bash helm repo add hashicorp https://helm.releases.hashicorp.com
Then check that you can see the chart, updating first if you have added the repository before:
bash helm search repo hashicorp/consul
And install, with the note that this creates a consul namespace if it is not already present and installs Consul onto that dedicated namespace:
bash helm install consul hashicorp/consul --set global.name=consul --create-namespace -n consul ```
The options are in the values.yaml file, and the documentation notes they are also fully documented on the Consul website.
The version requirements are worth noting because they are narrow. Kubernetes 1.27.x to 1.30.x is the earliest and latest tested range, and the documentation is candid that it is possible the chart works with earlier versions but that it is untested. Helm 3.6 or later is needed for Helm based installs.
The chart also has a documentation pipeline in the build. The gen-helm-docs target generates the Helm reference docs from values.yaml and updates the Consul website, taking a path to the Consul repository as an argument, and there are separate targets to copy generated CRD YAML into charts/consul and to generate CRDs for externally defined CRDs, plus a target that converts snake_case keys in YAML to camelCase. That last one tells you the CRD layer is generated rather than hand written, which matters when you are reading a CRD schema and wondering where it came from.
The build reads its versions out of the chart and the toolchain file
The Makefile is unusual enough to be worth reading, because it shows how the pieces stay in step.
The project version comes from a shell script reading version/version.go, and the Go version comes from the first line of a .go-version file. Then the Consul image versions are read out of the chart's values.yaml by three separate scripts, one for the standard Consul image, one for the enterprise image and one for the dataplane image. So the chart is the single source of truth for which Consul image the control plane will run against, and the Makefile reads it rather than repeating the value.
The acceptance test versions are read the same way, out of a YAML file in the acceptance directory: the kind version, the kind node image and the kubectl version. A kind cluster is what the end to end tests run against, and pinning the cluster version, the node image and the kubectl client in one config file is how those three stay compatible with each other.
The Go modules are discovered rather than listed, with a find over go.mod files, which is what allows the hack/ helper programs, the control plane and the CLI to each be their own module. The build tag is hashicorpmetrics by default, and the test runner is gotestsum if it is on the path.
The repository also carries a .golangci.yml for the Go linter, a codecov.yml, a .copywrite.hcl file for the licence header tooling, a scan.hcl, and a THIRD_PARTY_LICENSES.md. The copywrite configuration and the third party licence file are the visible part of how a project with a large dependency tree keeps its licence attribution straight.
Where consul-k8s is the wrong tool
The first limit is that it presumes Consul is the mesh. Sidecar injection, the API gateway and the catalog sync are all pieces of Consul's own architecture, and the gateway in particular is Consul API Gateway rather than the Gateway API implementation in other meshes. A team already running Istio, Linkerd or an Envoy-based mesh has the sidecar injection problem solved, and adding a second mesh to the same cluster is a way to end up with two control planes making contradictory decisions about the same pod.
The second limit is the Kubernetes version window. The tested range is 1.27.x to 1.30.x, and the documentation is explicit that earlier versions are untested rather than confirmed working. Kubernetes moves its support windows, and a chart that lags the cluster's version is a chart that gets upgraded under pressure.
The third is the branching release line. v1.8.18 is the current patch and v2.1.0 is at release candidates, and the documentation says the supported Consul version is noted per feature, which means picking a branch is a decision about which features you can use rather than a mechanical version bump. The project is explicit that it is versioned separately from Consul so the Kubernetes side can move faster, and the cost of that is exactly this kind of compatibility bookkeeping.
The fourth is that the README is an overview, not the reference. It says so itself: the Kubernetes integrations are documented directly on the Consul website, and the full documentation is there. So the repository is a starting point, and an evaluation of the actual behaviour means reading the HashiCorp documentation and the chart's values.yaml, not this file.
The fifth is licensing and the fork. The project is MPL-2.0, and it includes a modified fork of the Kubernetes Gateway API, which is licensed under Apache License 2.0. A modified fork of a widely used API specification is worth a look for an organisation with an open source review process, and the additional licences are tracked in the THIRD_PARTY_LICENSES.md file at the root of the repository.
Editorial conclusion
consul-k8s is worth adopting for a team that has chosen Consul as its service mesh and wants Kubernetes-native behaviour rather than a bolt-on, because the sidecar injection, the gateway and the catalog sync are first-class features of the same control plane rather than separate add-ons, and because the project is versioned independently of Consul so the Kubernetes side can move faster than the agents. It is the wrong choice if your mesh is Istio or Linkerd, and the wrong choice if you want a shared catalogue across clusters rather than a per-cluster deployment. Before you commit, check the three things the documentation is specific about: the supported Kubernetes window of 1.27.x to 1.30.x, since earlier versions are untested rather than known broken; the Helm requirement of 3.6 or later, with the CLI route needing a working kubeconfig and a local package manager; and the version line itself, with v1.8.18 released on 2026-10-20 while v2.1.0 sits at release candidates, so pick the branch that matches your Consul version rather than the newest tag.
Frequently asked questions
How do I install consul-k8s on a Kubernetes cluster?
The recommended method is the official Consul Helm chart, which automatically configures the Consul and Kubernetes integration within an existing cluster. You add the repository with helm repo add hashicorp https://helm.releases.hashicorp.com, check it with helm search repo hashicorp/consul, then install with helm install consul hashicorp/consul --set global.name=consul --create-namespace -n consul.
What are the prerequisites for installing Consul on Kubernetes with consul-k8s?
Kubernetes 1.27.x to 1.30.x, which is the tested range, and Helm 3.6 or later for Helm based installs. The CLI based route additionally needs kubectl configured with a valid kubeconfig file and a local package manager, brew, yum or apt.
What does the Catalog Sync feature in consul-k8s do?
It syncs Consul services into first-class Kubernetes services and vice versa, so that Kubernetes can easily access external services and non-Kubernetes nodes can easily discover and access Kubernetes services. It is a catalogue bridge rather than part of the mesh traffic path.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/hashicorp-consul-k8s)Was this useful?