Setup SkyDNS on a Kubernetes Cluster

1 comment


SkyDNS

Today we’re releasing SkyDNS as an open source project on github. SkyDNS is our attempt to solve the problem of finding the services that are running in a large environment. SkyDNS acts as a DNS service that only returns SRV records. Services announce their availability by sending a POST with a small JSON payload. Each service has a Time to Live that allows SkyDNS to expire records for services that haven’t updated their availability within the TTL window. Services can send a periodic POST to SkyDNS updating their TTL to keep them in the pool.
Now when services die, hosts die, datacenters die, or meteors fall, your clients won’t be wasting valuable time making requests to services that aren’t running or aren’t reachable.
When a client is looking for a particular service, it issues a DNS request to SkyDNS with the particulars of the service needed. SkyDNS supports several interesting parameters in the SRV record to facilitate returning the service that is best situated to serve the client.

Environment

SkyDNS understands the last parameter in the DNS query as an Environment. You can put any value here, but for our purpose, words like developmentstagingqaproduction, and integration make the most sense. The environment parameter allows you to segregate your services so that you can run a single SkyDNS service cluster but serve your entire development environment.

Service

The Service parameter is the name of the service that is running. Yours might be called addressvalid if you’re running an address validation service, or it could be called indexentries if you’re running a service that indexes documents in the background. The service name is the unique name that identifies WHAT your service does.

Version

Services can be versioned to allow for variations in the request/response data without breaking backwards compatibility. The version parameter allows you to request a specific version of a service.

Region

We run services in multiple data centers, so SkyDNS understands locality of a service. Services register themselves as running in a specific region, which allows clients to request a service running in the same region. If you’re running the same service in multiple regions, SkyDNS will use the priority field in the SRV record to return services in the requested region first, with the same priority. Services running in different regions are returned at a lower priority so that the client can use them in case they’re needed but prefer the local services first.

Host

SkyDNS understands the host that a service is running on so that if a client prefers it, the client can request a service on the same host.

UUID

Services are required to have a unique identifier, which allows multiple services at the same version to be running on the same host. If you really wanted to request a specific instance of a service you can specify the UUID in the request and you’ll only receive that specific instance.

Wildcards

The only field that is required in the DNS request is the “Environment” field. Any missing fields are interpreted as “any”, and you can specify “any” at any point along the parameter list.

Introduction

Other tutorials on DevOps Central describe how to manually deploy a Kubernetes cluster on various platforms.
By default, the containers allows for service discovery through the use of dynamic environment variables that are similar to the Docker syntax. For example:
APP_SERVICE_HOST=<app host>
APP_SERVICE_PORT=<app port>
Kubernetes also provides support for a cluster DNS add-on. When this add-on is enabled, Kubernetes Services will automatically create associated DNS records that are resolvable within the containers.
The format of the DNS record is service_name.namespace.cluster_domain. Based on this tutorial, for example, a redis-master Service may use the following domain (assuming the default namespace is being used):
redis-master.default.kubernetes.local

Requirements

  • Functional Kubernetes cluster
  • Kubernetes container subnet: 10.254.0.0/16
  • Kubernetes DNS IP address: 10.254.0.10
  • Kubernetes domain name: kubernetes.local
NoteIf you chose another container subnet in your existing Kubernetes cluster, then the skydns PortalIP must reside in that subnet and the Kubelet startup parameter --cluster_dns must match that IP address.

Create Replication Controller Manifest

The Replication Controller manifest will describe the state of the containers within the Pod as well as the number of replicas. The skydns Pod will consist of three containers:
  • etcd - Stores the SkyDNS configuration and DNS records.
  • skydns - The DNS server responding to requests.
  • kube2sky - A bridge between Kubernetes and SkyDNS.
Create a file called skydns-rc.yaml and paste in the following YAML text:
kind: ReplicationController
apiVersion: v1beta1
id: skydns
namespace: default
labels:
  k8s-app: skydns
desiredState:
  replicas: 1
  replicaSelector:
    k8s-app: skydns
  podTemplate:
    labels:
      k8s-app: skydns
    desiredState:
      manifest:
        version: v1beta2
        id: skydns
        dnsPolicy: "Default"
        containers:
          - name: etcd
            image: quay.io/coreos/etcd:latest
            command: [
              "/etcd",
              "-bind-addr=127.0.0.1",
              "-peer-bind-addr=127.0.0.1",
            ]
          - name: kube2sky
            image: kubernetes/kube2sky:1.0
            command: [
              # entrypoint = \"/kube2sky\",
              "-domain=kubernetes.local",
            ]
          - name: skydns
            image: kubernetes/skydns:2014-12-23-001
            command: [
              # entrypoint = \"/skydns\",
              "-machines=http://localhost:4001",
              "-addr=0.0.0.0:53",
              "-domain=kubernetes.local.",
            ]
            ports:
              - name: dns
                containerPort: 53
                protocol: UDP

Create Service Manifest

The Service manifest will expose the DNS service IP address and port to other containers within the cluster.
Create a new service file called skydns-svc.yaml and paste in the following YAML text.
kind: Service
apiVersion: v1beta1
id: skydns
namespace: default
protocol: UDP
port: 53
portalIP: 10.254.0.10
containerPort: 53
labels:
  k8s-app: skydns
selector:
  k8s-app: skydns

Load the Manifests

The manifest files are now ready to be loaded into Kubernetes using the kubectl command.
kubectl create -f ./skydns-rc.yaml
kubectl create -f ./skydns-svc.yaml
The kubectl command can also be used to confirm the state of the new skydns Replication Controller, Pod, and Service.
kubectl get rc
kubectl get pods
kubectl get service

Configure the Kubelet Services

Cluster DNS must now be enabled on all the container nodes. This is done by adding two startup parameters to the Kubelet service. Open the kubelet configuration file on each host and add the following two parameters:
  • --cluster_dns=10.254.0.10
  • --cluster_domain=kubernetes.local
The location of the kubelet configuration file may vary along with the parameter syntax depending on the Linux distribution. For example:

Kubelet on CentOS 7

The /etc/kubernetes/kubelet file should contain the following:
KUBELET_ARGS="--cluster_dns=10.254.0.10 --cluster_domain=kubernetes.local"

Kubelet on Ubuntu

The /etc/default/kubelet may appear similar to this example:
KUBELET_OPTS="--address=0.0.0.0 \
--port=10250 \
--hostname_override=kube-minion \
--etcd_servers=http://kube-master:4001 \
--enable_server=true \
--cluster_dns=10.254.0.10 \
--cluster_domain=kubernetes.local \
--v=0"

Restart the Kubelet

Finally, restart the Kubelet to enable cluster DNS. To restart the service on CentOS:
systemctl restart kubelet
And to restart the service on Ubuntu:
service docker restart
SOURCE

1 comment :