Skip to main content
This guide walks you through setting up a local cluster (or using an existing one) to mesh a microservices-based application with Linkerd and use the ngrok Kubernetes Operator to route public traffic through an encrypted tunnel to your cluster. The ngrok Kubernetes Operator is the official controller for adding secure public ingress and middleware execution to your Kubernetes applications with ngrok’s cloud service. Linkerd is an open source service mesh: a set of network proxies that handle communications between microservices and add observability, security, and reliability at the platform level. Linkerd enables mutual TLS (mTLS) between microservices for confidentiality and authenticity. When integrated, the ngrok Kubernetes Operator and Linkerd simplify your networking stack (internal and external traffic) and give you additional monitoring and resiliency.

What you’ll need

  • An existing remote or local Kubernetes cluster or the minikube CLI installed locally to create a new testing cluster.
  • The Linkerd 2.x CLI installed locally (helper script, Homebrew, or binary in your $PATH).
  • An ngrok account.
  • kubectl and Helm 3.0.0+ installed on your local workstation.
  • The ngrok Kubernetes Operator installed on your cluster.
  • A reserved domain from the ngrok dashboard or API; this guide refers to it as <NGROK_DOMAIN>.

Set up a local development cluster

  • Create a local Kubernetes cluster with minikube. You will assign it a profile named ngrok-linkerd with -p, and for the best compatibility with Linkerd, use the containerd container runtime.
    minikube start -p ngrok-linkerd --container-runtime=containerd
    
    If your OS does not support containerd, you can run minikube without specifying the container runtime.
    minikube start -p ngrok-linkerd
    
    If minikube defaults to using the docker runtime, you will likely see an error related to root privileges when installing Linkerd to your cluster. The error includes a workaround to let you install Linkerd despite using the docker runtime.
  • Use kubectl to verify your local cluster is running properly.
    kubectl get namespaces
    
    NAME              STATUS   AGE
    default           Active   72s
    kube-node-lease   Active   72s
    kube-public       Active   72s
    kube-system       Active   72s
    

Deploy Linkerd’s service mesh to your cluster

  • Verify your Linkerd CLI is working correctly with linkerd version, which should display the same output as below. The Server version: unavailable is expected at this point.
    linkerd version
    Client version: stable-2.14.2
    Server version: unavailable
    
  • Validate that your Kubernetes cluster is ready to deploy Linkerd with linkerd check --pre. You should see the following output at the end:
    linkerd check --pre
    ...
    Status check results are
    
  • Generate and deploy the Kubernetes manifests required to run Linkerd on your cluster, starting with the CRDs.
    linkerd install --crds | kubectl apply -f -
    
    Followed by the core resources.
    linkerd install | kubectl apply -f -
    
  • Check that Linkerd installed correctly with linkerd check. You should see a number of successful checks in your terminal output, with a final verification at the end.
    linkerd check
    ...
    Status check results are
    
These steps follow the Linkerd getting-started documentation for installing the service mesh.

Deploy an example microservices-based application

To demonstrate how Linkerd and the ngrok Kubernetes Operator integrate to add additional observability, security, and reliability into your cluster, you’ll deploy the Emojivoto demo application, which was developed by Buoyant, the company that originally developed Linkerd.
  • Create an ngrok static subdomain for ingress if you don’t have one already. Go to the Domains section of the ngrok dashboard and click Create Domain or New Domain. This static subdomain will be your NGROK_DOMAIN for the remainder of this guide. Creating a subdomain on the ngrok Edge provides a public route for HTTP, HTTPS, and TLS traffic.
  • Deploy Emojivoto to the emojivoto namespace.
    curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/emojivoto.yml \
      | kubectl apply -f -
    
  • Add meshing by injecting Linkerd’s data plane proxies into each pod with a rolling deploy. The following command retrieves all deployments from the previous step, injects the Linkerd proxy, and redeploys each pod.
    kubectl get -n emojivoto deploy -o yaml \
      | linkerd inject - \
      | kubectl apply -f -
    
  • Verify your data plane with linkerd -n emojivoto check --proxy; it should end with a healthy status check.
    linkerd -n emojivoto check --proxy
    ...
    Status check results are
    
  • Create a new emojivoto-ingress.yaml file and add the following YAML content (see Linkerd’s ingress task documentation for the ngrok example). It defines the ngrok Kubernetes Operator for routing traffic on your NGROK_DOMAIN to the web-svc deployment you created when deploying Emojivoto.
    Edit line 9 of the manifest below (the NGROK_DOMAIN variable) with your ngrok subdomain (for example, one-two-three.ngrok.app).
    showLineNumbers
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: emojivoto-ingress
      namespace: emojivoto
    spec:
      ingressClassName: ngrok
      rules:
        - host: <NGROK_DOMAIN>
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: web-svc
                    port:
                      number: 80
    
  • Apply the emojivoto-ingress.yaml manifest you just created.
    kubectl apply -f emojivoto-ingress.yaml
    
    Give your cluster a few moments to launch the necessary resources and for ngrok’s cloud service to pick up the new tunnel.
    Troubleshooting: If you see an error when applying the manifest, double-check that you’ve updated the NGROK_DOMAIN value and try again.
  • Access your Emojivoto application by navigating to your ngrok domain (for example, https://one-two-three.ngrok.app) in your browser.

Add Linkerd’s dashboard to verify meshing and mTLS

Given that one of the key benefits of a service mesh is increased observability, and the inherent security enhancements that come from mTLS connections between your microservices, you’ll want to double-check that your deployments and pods are properly meshed.
  • Install the Linkerd dashboard.
    linkerd viz install | kubectl apply -f -
    
  • To verify mTLS, restart all pods in the emojivoto namespace to enable tapping.
    kubectl -n emojivoto rollout restart deploy
    
  • Use Linkerd’s tap feature: run linkerd viz -n emojivoto tap deploy to stream traffic from all pods in the emojivoto namespace to your terminal. The Emojivoto app generates traffic automatically, so you’ll see a consistent stream of requests.
    linkerd viz -n emojivoto tap deploy
    ...
    req id=0:11 proxy=out src=10.244.0.15:43706 dst=10.244.0.2:8080 tls=true :method=POST :authority=emoji-svc.emojivoto:8080 :path=/emojivoto.v1.EmojiService/ListAll
    
    You should see tls=true in all of these requests between these pods. You can also use kubectl get pods -o wide to see the IP address of each pod, which lets you verify the source and destination of each request. For example, the request shown above is the web-svc service sending a POST request, with mTLS enabled, to the emoji-svc service, which maintains and stores the votes database.
  • Run linkerd viz dashboard & to open the Linkerd dashboard in your browser. The default dashboard shows golden metrics (success rates, traffic, latencies per namespace) and the number of meshed pods per namespace. Some of the auto-generated traffic is designed to fail, which shows how to use the dashboard to debug pod-to-pod issues.

What’s next?

You’ve now integrated a demo microservices application with Linkerd’s service mesh and ngrok’s Kubernetes Operator to add multiple new layers of security and reliability without having to worry about configuring middleware, network interfaces, mTLS, or deploying new monitoring services for observing the external behavior of your code. After deploying this local demo, you have a few options for moving forward.

Clean up

To clean up from the work you’ve done for this local demo, you can stop and delete your minikube cluster with the minikube CLI:
minikube stop -p ngrok-linkerd
minikube delete -p ngrok-linkerd
Then remove the Linkerd CLI from your local workstation:
rm -rf $HOME/.linkerd2

Extend your ngrok Kubernetes Operator and Linkerd integration

For production and real-world applications, explore installing Linkerd with Helm and production runbooks. In more complex scenarios, you can follow the same steps to install the ngrok Kubernetes Operator and configure an Ingress so ngrok’s cloud service handles routing and middleware for simplicity, global load balancing, and automatic encryption. See the ngrok Kubernetes Operator GitHub repository and project documentation for more details.