In this 2 part series I will go into detail about how a DNS service is provided by Kubernetes. The DNS service is one of a number of standard Kubernetes cluster services. Currently, the other services are a Docker registry, a simple Kubernetes UI, a logging capability and a monitoring dashboard.
The main reason for writing this series was to flesh out my visual vocabulary and writing style for documenting the k8sdc project. The Kubernetes DNS service is reasonably complex so it seemed like a good candidate to stretch myself on.
As with other cluster services the Service, Replication Controller and Pod resources are created within the kube-system namespace.
The DNS service watches the Kubernetes API for Service resources in all Namespaces and creates a DNS entry for each one found.
The DNS entries that are created are based on the Service name and the Namespace. The rule below shows the format for each DNS entry.
<domain> is the Kubernetes DNS domain (as defined by the Kubernetes configuration).
Using a Service called nginx that is created in the default Namespace and with a DNS domain of kube.local we can expect the following DNS names to be resolveable.
nginx nginx.default nginx.default.svc nginx.default.svc.kube.local
Each of these DNS names will point to the IP address of the nginx Service within the default Namespace.
When a client uses the short name of a Service then the Service is resolved relative to the Namespace of the client. So if a client in the default Namespace resolves a DNS entry using the short name nginx then it will receive the IP address of a Service called nginx that is created within the default Namespace.
However, if a client uses any of the longer forms of DNS name then the Service will be resolved relative to the defined Namespace. The following is an example of how a shared message queue Service could be resolved to the shared Namespace.
queue.shared queue.shared.svc queue.shared.svc.kube.local
This ability to resolve a Service that is relative to the local Namespace or within a specific Namespace is very powerful. It makes it easy to create numerous isolated environments (Namespaces) where the individual components of an application can find each other. It also allows for applications to be shared across multiple environments (Namespaces), such as for a centralised logging capability.
The following diagram demonstrates how Pods can find Services both within their own Namespace and within other Namespaces.
- The frontend Pod resolves the name cache. The DNS service returns the IP address for the cache Service in the same Namespace as the frontend Pod. The frontend Pod communicates with the cache Service.
- The cache Service (implemented by the kube-proxy daemon) proxies the request to one of the available cache Pods.
- The frontend, cache and database Pods resolve the name queue.shared. The DNS service returns the IP address for the queue Service in the shared Namespace. The frontend, cache and database Pods each send their logs to the queue Service.
- The queue Service proxies the request to one of the available queue Pods.
The Kubernetes team have made a lot of very sensible design choices when it comes to naming and service discovery. Combined with the speed of containers it is now possible to launch a new environment full of application components within seconds to minutes. Clearly this will be a game changer for development and operations and allow for incredible flexibilty of delivery.