DEV Community

Cover image for Expose a Kubernetes service on your own custom domain
Peter Jausovec
Peter Jausovec

Posted on

Expose a Kubernetes service on your own custom domain

You have finally deployed your app to Kubernetes and you bought a cool domain name — ever wondered how to point your cool domain like, but cooler, to an app running inside Kubernetes? Well, read on and I’ll try to explain how to do just that!

What do you need?

Before we get started, make sure you have the following:

  • Kubernetes cluster and access to it (i.e. you can deploy stuff)
  • Your app* running in the Kubernetes cluster
  • Registered domain name (I am using for my domains, but any other registrar works as well)
  • Helm

Note: I am using the word app to represent your code that runs in your cluster and you want to access it through the domain name. Your code is running inside of a Docker image and a Kubernetes pod that’s part of a deployment and is exposed through a Kubernetes service. But app is what I’ll use to refer to all this.

Here are the rough steps to follow to hook up the domain with your service:

  • Create an Ingress resource
  • Deploy the Ingress controller
  • Update the domain records to point to the cluster

Accessing Kubernetes from the outside

A Kubernetes resource called Ingress is what manages external access to the apps running inside the cluster. With ingress, you can define rules that tell Kubernetes how to route external traffic to your app. Here’s how an example Ingress resource looks like:

apiVersion: extensions/v1beta1
kind: Ingress
  name: my-ingress
  annotations: nginx
  - host:
      - path: /
          serviceName: mycoolapp
          servicePort: 80
Enter fullscreen mode Exit fullscreen mode

However, this resource alone is not enough — you also need a controller that knows how to direct the traffic. I will be using the NGINX Ingress Controller, but there are others you could use as well (check out more docs here). We will be using Helm to deploy the nginx-ingress chart like this:

helm install stable/nginx-ingress
Enter fullscreen mode Exit fullscreen mode

The above command takes care of installing the NGINX controller and a default backend. Default backend is an ‘app’ that the ingress will point to by default or in case there are no services defined. As part of the NGINX controller you will also get a service with type LoadBalancer — this is where we you point your domain to.

Note that there are a plethora of buttons and knobs you can adjust and twist when deploying the controller — there’s a whole list of them here.

With the NGINX ingress controller deployed, let’s figure out what the IP address of the cluster is by running this command:

kubectl get services --all-namespaces
Enter fullscreen mode Exit fullscreen mode

Above command will list out all Kubernetes services running in all namespaces. What you are interested in is any service of type LoadBalancer and any service that has an external IP set (it’s usually the same service). Here’s how a sample output of the command would look like:

virtuous-gopher is the name Helm picked for the NGINX controller

The value that’s grayed out next to the *nginx-ingress-controller service in the image above is what you need. This is the IP address you will point your domain to.

Or, if you want to be more fancy, you can also run the command below that will filter all services by their type (LoadBalancer) and return you the name and the IP address:

kubectl get svc --all-namespaces -o jsonpath='{range .items[?(@.spec.type=="LoadBalancer")]}{}:{.status.loadBalancer.ingress[0].ip}{"\n"}{end}'
Enter fullscreen mode Exit fullscreen mode

Pointing your domain to the cluster

Depending on where you registered your domain, the steps might be a bit different, but the gist is the same — you need to create an A and CNAME DNS records to point your domain (host) to the cluster.

My registrar is, but I am pretty sure other registrars have some good docs on how to do this as well.

Heavily redacted view of the DNS records for my domain

Here’s what I did: on I went to my domain and opened the DNS records tab. From there, I was able to add an A record with the host called and as an answer, I entered my clusters IP address.

Similarly, I created a CNAME record and pointed to the cluster host name (usually, you can find this in your cloud providers settings). You don’t have to provide a CNAME, an A record is enough. Note that if you don’t provide the CNAME, then will not resolve to your app!

Test it out!

Fire up your favorite terminal or browser and navigate to Tadaaa — you should be able to get a response back (in my case, the app I deployed was a simple NGINX container, thus the default NGINX page)

Yes, I own domain… and bunch more that I’ll never use

Top comments (9)

nsanjay profile image
Sanjay Narayana


Thanks for the tutorial. Is there a way to set a static IP to the nginx-controller, so that we can configure the mapping between our domain and IP only once. From what I can tell, a new IP is created every time the cluster is freshly deployed.

peterj profile image
Peter Jausovec

Hi Sanjay!

Assuming you have an existing static IP, you can edit the ingress service in Kubernetes and use loadBalancerIP: field to set a static IP address. For example:

kind: Service
   type: LoadBalancer
ben profile image
Ben Halpern

Since this post is currently featured, I’ll drop this here to help anyone who is lost. 😊

joehobot profile image
Joe Hobot • Edited

I see you are doing http, to go bit more into it, you can get letsencrypt(free ssl) helm chart, edit your ingress and go with https :)

peterj profile image
Peter Jausovec

Yes! That's a good point - might need to write another post that explains that :). On the other hand, I sometimes use Cloudflare as well as they do the SSL termination for you (if you're just hosting a static site and don't necessarily have Kubernetes or a VM behind it).

joehobot profile image
Joe Hobot

That works too, I just use aws elb :)

kunle profile image

Kube-lego or cert-manager for that.

hakeemoriola profile image
Hakeem Oriola

Please how do i get the cluster host name for my application deployed on kubernetes on google cloud

peterj profile image
Peter Jausovec

You will need to get an external IP first:

kubectl get svc --all-namespaces -o jsonpath='{range .items[?(@.spec.type=="LoadBalancer")]}{}:{.status.loadBalancer.ingress[0].ip}{"\n"}{end}'

Once you have the IP, you can go to the website where you registered your domain and create an A record to point to that external IP.