In this tutorial, you will start a local Kubernetes cluster using
minikube. You will then deploy Consul with the official Helm chart or the Consul K8S CLI. After deploying Consul, you will learn how to access the agents. You will then deploy two services that use Consul to discover each other.
Security Warning This tutorial is not for production use. By default, the chart will install an insecure configuration of Consul. Please refer to the Kubernetes deployment guide to determine how you can secure Consul on Kubernetes in production. Additionally, it is highly recommended to use a properly secured Kubernetes cluster or make sure that you understand and enable the recommended security features.
First, you will need to follow the directions for installing Minikube.
You'll also need to install
kubectl with Homebrew.
$ brew install kubernetes-cli
helm with Homebrew.
$ brew install helm
Start Minikube with the optional
--memory flag specifying the equivalent of 4-8GB of memory, so your pods will have plenty of resources to use. Starting Minikube may take several minutes. It will download a 100-300MB of dependencies and container images.
$ minikube start --memory 4096
The output will be similar to the following.
😄 minikube v1.16.0 on Darwin 10.15.7 🎉 minikube 1.25.1 is available! Download it: https://github.com/kubernetes/minikube/releases/tag/v1.25.1 💡 To disable this notice, run: 'minikube config set WantUpdateNotification false' ✨ Automatically selected the docker driver. Other choices: hyperkit, virtualbox 👍 Starting control plane node minikube in cluster minikube 🔥 Creating docker container (CPUs=2, Memory=4096MB) ... 🐳 Preparing Kubernetes v1.20.0 on Docker 20.10.0 ... ▪ Generating certificates and keys ... ▪ Booting up control plane ... ▪ Configuring RBAC rules ... 🔎 Verifying Kubernetes components... 🌟 Enabled addons: storage-provisioner, default-storageclass 🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
minikube does not ship with the kubernetes dashboard by default. If, you wish to install the Kubernetes Dashboard, refer to the Kubernetes Dashboard project for instructions on how to install and view it.
»Install Consul with the official Helm chart
Tip: You can deploy a complete Consul datacenter using the official Helm chart. You can review the official Helm chart values to learn more about the default settings.
You can deploy a complete Consul datacenter using the official Consul Helm chart or the Consul K8S CLI. You can review the Consul Kubernetes installation documentation to learn more about these installation options.
»Create a values file
To customize your deployment, you can pass a yaml file to be used during the deployment;
it will override the Helm chart's default values. The chart comes with reasonable defaults, however, you will override a few values to integrate more easily with
minikube and enable useful features.
Create a custom values file called
helm-consul-values.yaml with the
following contents. This configuration will:
- Set the prefix used for all resources in the Helm chart to
- Name the Consul datacenter
- Configure the datacenter to run only 1 server
- Configure the server to use the
- Enable the Consul UI and expose it via a
- Enable Consul service mesh features by setting
- Enable Consul service mesh CRDs by setting
- With Transparent Proxy
- Without Transparent Proxy
$ cat > helm-consul-values.yaml <<EOF global: name: consul datacenter: dc1 server: replicas: 1 securityContext: runAsNonRoot: false runAsGroup: 0 runAsUser: 0 fsGroup: 0 ui: enabled: true service: type: 'NodePort' connectInject: enabled: true controller: enabled: true EOF
Note Transparent proxy is the default method for service to service communication within the service mesh since Consul 1.10. Check out the transparent proxy documentation to learn more.
»Install Consul in your cluster
You can now deploy a complete Consul datacenter in your Kubernetes cluster using the official Consul Helm chart or the Consul K8S CLI.
$ helm repo add hashicorp https://helm.releases.hashicorp.com "hashicorp" has been added to your repositories
$ helm install --values helm-consul-values.yaml consul hashicorp/consul --create-namespace --namespace consul --version "0.43.0"
Note: You can review the official Helm chart values to learn more about the default settings.
»Access the Consul UI
Verify Consul was deployed properly by accessing the Consul UI. Run
minikube service list to list your services. Find the one with
consul-ui in the name.
$ minikube service list |-------------|---------------------------|--------------|-----| | NAMESPACE | NAME | TARGET PORT | URL | |-------------|---------------------------|--------------|-----| | consul | consul-connect-injector | No node port | | consul | consul-controller-webhook | No node port | | consul | consul-dns | No node port | | consul | consul-server | No node port | | consul | consul-ui | http/80 | | | default | kubernetes | No node port | | kube-system | kube-dns | No node port | |-------------|---------------------------|--------------|-----|
minikube service with the
consul-ui service name as the argument. It will open the service in your web browser.
$ minikube service consul-ui --namespace consul
You can now visit the Consul UI with a list of Consul's services, nodes, and other resources. Currently, you should only find the
consul service listed.
»Access Consul with kubectl and the HTTP API
In addition to accessing Consul with the UI, you can manage Consul with the
HTTP API or by directly connecting to the pod with
To access the pod and data directory, you can remote execute into the pod with the command
kubectl to start a shell session.
$ kubectl exec --stdin --tty consul-server-0 --namespace consul -- /bin/sh
This will allow you to navigate the file system and run Consul CLI commands on the pod. For example you can view the Consul members.
$ consul members Node Address Status Type Build Protocol DC Partition Segment consul-server-0 172.17.0.8:8301 alive server 1.11.2 2 dc1 default <all> minikube 172.17.0.4:8301 alive client 1.11.2 2 dc1 default <default>
When you have finished interacting with the pod, exit the shell.
»Consul HTTP API
You can use the Consul HTTP API by communicating with the local agent running on the Kubernetes node. Read the documentation to learn more about using the Consul HTTP API with Kubernetes.
»Deploy services with Kubernetes
Now that you have a running Consul service mesh, you can deploy services to it.
»Deploy two services
You will now deploy a two-tier application made of a backend data service that
returns a number (the
counting service), and a frontend
dashboard that pulls
counting service over HTTP and displays the number.
Create a deployment definition, service, and service account for the
- With Transparent Proxy
- Without Transparent Proxy
$ cat > counting.yaml <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: counting --- apiVersion: v1 kind: Service metadata: name: counting spec: selector: app: counting ports: - port: 9001 targetPort: 9001 --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: counting name: counting spec: replicas: 1 selector: matchLabels: app: counting template: metadata: annotations: 'consul.hashicorp.com/connect-inject': 'true' labels: app: counting spec: containers: - name: counting image: hashicorp/counting-service:0.0.2 ports: - containerPort: 9001 EOF
Create a deployment definition, service, and service account for
dashboard service named
- With Transparent Proxy
- Without Transparent Proxy
$ cat > dashboard.yaml <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: dashboard --- apiVersion: v1 kind: Service metadata: name: dashboard spec: selector: app: dashboard ports: - port: 9002 targetPort: 9002 --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: dashboard name: dashboard spec: replicas: 1 selector: matchLabels: app: dashboard template: metadata: annotations: 'consul.hashicorp.com/connect-inject': 'true' labels: app: dashboard spec: containers: - name: dashboard image: hashicorp/dashboard-service:0.0.4 ports: - containerPort: 9002 env: - name: COUNTING_SERVICE_URL value: 'http://counting:9001' EOF
kubectl to deploy the counting service.
$ kubectl apply -f counting.yaml serviceaccount/counting created service/counting created deployment.apps/counting created
kubectl to deploy the dashboard service.
$ kubectl apply -f dashboard.yaml serviceaccount/dashboard created service/dashboard created deployment.apps/dashboard created
To verify the services were deployed, refresh the Consul UI until you observe
dashboard services are running.
»Visit the dashboard
To visit the dashboard, forward the pod's port where the dashboard
service is running to your local machine on the same port by providing
the pod name (
dashboard), which you specified in the service definition YAML file.
$ kubectl port-forward deploy/dashboard 9002:9002 Forwarding from 127.0.0.1:9002 -> 9002 Forwarding from [::1]:9002 -> 9002
Visit localhost:9002 in your web browser. It will display
dashboard UI with a number retrieved from the
counting service using
Consul service discovery.
»Secure service communication with intentions
Consul intentions provide you the ability to control which services are allowed
to communicate. Next, you will use intentions to test the communication between
»Create an intention that denies communication
You can use a Consul
CRD to create an intention that prevents the
dashboard service from reaching
Create a file named
deny.yaml that denies communication between the two services.
$ cat > deny.yaml <<EOF apiVersion: consul.hashicorp.com/v1alpha1 kind: ServiceIntentions metadata: name: dashboard-to-counting spec: destination: name: counting sources: - name: dashboard action: deny EOF
kubectl to apply the intention.
$ kubectl apply -f deny.yaml serviceintentions.consul.hashicorp.com/dashboard-to-counting created
Verify the services are no longer allowed to communicate by returning to the dashboard UI. The service will display a message that the "Counting Service is Unreachable", and the count will display as "-1".
»Allow the application dashboard to communicate with the Counting service
Finally, remove the intention so that the services can communicate again.
$ kubectl delete -f deny.yaml serviceintentions.consul.hashicorp.com "dashboard-to-counting" deleted
Intentions take effect rather quickly. The next time you visit the
you'll notice that it's successfully communicating with the backend
To learn more about Consul service mesh on Kubernetes, review the service mesh tutorials. To learn how to deploy Consul on a Kubernetes cluster, review the production deployment tutorial. To learn how to secure Consul and services for production, read the Secure Consul and Registered Services on Kubernetes tutorial.