DEV Community

Ajinkya Ingole
Ajinkya Ingole

Posted on • Updated on

How to connect to your Kubernetes services using internal DNS

Introduction

Kubernetes DNS schedules a DNS Pod and Service on the cluster, and configures the kubelets to tell individual containers to use the DNS Service’s IP to resolve DNS names.

What things get DNS names?

Every Service defined in the cluster (including the DNS server itself) is assigned a DNS name. By default, a client Pod’s DNS search list will include the Pod’s own namespace and the cluster’s default domain. This is best illustrated by example:

Assume a Service named foo in the Kubernetes namespace bar. A Pod running in namespace bar can look up this service by simply doing a DNS query for foo. A Pod running in namespace quux can look up this service by doing a DNS query for foo.bar.

To make these names resolvable you need a tool that watches the Kubernetes API so as to allow you to know your container IPs, and then answer your DNS requests with the correct IP. At present the most common tool to achieve this is Kube-DNS. I believe this is the first tool you should deploy in Kubernetes cluster.

alt text

This is what a basic Kubernetes Service for a HTTP server looks like:

kind: Service
apiVersion: v1
metadata:
  name: http-server
spec:
  selector:
    app: http-server
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

Once this object is deployed in your cluster you should be able to contact the name http-server (from the same namespace), and Kube-DNS will answer with the correct ClusterIP to speak to your final pods. ClusterIPs are governed by IPTables rules created by kube-proxy on Workers that NAT your request to the final container’s IP.

The Kube-DNS naming convention is service.namespace.svc.cluster-domain.tld and the default cluster domain is cluster.local.
For example, if you want to contact a service called mysql in the db namespace from any namespace, you can simply speak to mysql.db.svc.cluster.local.

To practice what we have discussed we will see how to deploy a simple two service application, and how to connect them. In this case a Wordpress and a mysql application.

So let’s start by creating basic Kubernetes Service for a HTTP server

$ git clone https://github.com/ajinkyaingole30/kube-pod-connect-of-diff-namespace.git
$ cd kube-pod-connect-of-diff-namespace
$ kubectl create -f kube-dns.yml

To check service

$ kubectl get svc

NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
http-server   ClusterIP   10.102.105.197   <none>        80/TCP    11s

Now let's create namespace:

$ kubectl create ns mysql-example
$ kubectl create ns wordpress-example

Create mysql deployment resource

$ kubectl create -f mysql-deployment.yml

To allow any other container to speak to database pod we need to expose it to a service resource

$ kubectl create -f mysql-service.yml

Create Wordpress container and configure it to talk to Mysql pod

$ kubectl create -f wordpress-deployment.yml

Check if pods are runing or not

$ kubectl get pod -n mysql-example

NAME                     READY   STATUS    RESTARTS   AGE
mysql-58c8f46579-whxz6   1/1     Running   0          31s
$ kubectl get pod -n wordpress-example

NAME                         READY   STATUS              RESTARTS   AGE
wordpress-856b4c866f-4xfpz   1/1     ContainerCreating   0          20s

To reach the Wordpress website you need to expose the Wordpress service. In this instance a ClusterIP isn’t sufficient because you need to be able to contact it from the exterior of the cluster.
To Expose Wordpress service

$ kubectl create -f wordpress-nodeport.yml
$ kubectl get svc -n wordpress-example

NAME        TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
wordpress   NodePort   10.98.102.140   <none>        80:31343/TCP   30s

You can now see that Wordpress service is exposed on port 31499/TCP on workers. To configure our website let’s open browser and enter url
http://worker-IP:31343

alt text

Now you can finish the installation of your Wordpress application using the following details :

Database name : wordpress

User name : root

Password : redhat

Database host : mysql.mysql-example.svc.cluster.local

alt text

I hope that you have understood the significant role of Kube-DNS and Kubernetes Services.

Discussion (0)