Chris Sainty

A technical blog covering full-stack web development.

twitter | github | stackoverflow

in , ,

Bootstrapping Spring Cloud Netflix Eureka using DNS

Spring Cloud Netflix is a spring wrapper around many of the core components of the Netflix OSS stack.

It makes running some of these components very simple, but the devil is usually in the configuration. Let's take a look at how to configure your Eureka server instances to discover each other via DNS when running in your own datacenter.

Spring Cloud Netflix != Netflix OSS

First a word of warning. Part of the Spring Cloud Netflix wrapper around the Netflix components is a separate configuration system. The configuration options I use in this post do not match exactly to what you will find if you are using the Netflix libraries directly.

Creating a Eureka Server with Spring Cloud Netflix

You only need a tiny piece of java code to bring up a Eureka server using the Spring libraries.

package com.storytel.eureka;

import org.springframework.boot.Banner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
@EnableEurekaClient
public class Application {

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class)
                .bannerMode(Banner.Mode.CONSOLE)
                .registerShutdownHook(true)
                .web(true)
                .run(args);
    }

}

Configuring a Spring Cloud Netflix Eureka server for DNS

There are two ways to link eureka servers to each other. You can either provide static configuration or you can utilize well defined DNS records. Here I show how to do the latter via application.yml.

spring:
  application:
    name: eureka

server:
  port: 8761

eureka:
  instance:
    healthCheckUrlPath: /health
  client:
    region: global
    eurekaServerPort: 8761
    useDnsForFetchingServiceUrls: true
    eurekaServerDNSName: eureka.storytel
    eurekaServerURLContext: eureka
    registerWithEureka: true
    fetchRegistry: true

endpoints:
  enabled: false
  health:
    enabled: true

Here are the important parts :-

  1. useDnsForFetchingServiceUrls This must be true for DNS based configuration
  2. eurekaServerDNSName This is the suffix added to the DNS requests, so must match the records you create
  3. eurekaServerURLContext This is the url added to the servers returned from DNS. e.g. eureka01.storytel.local will become http://eureka01.storytel.local/eureka
  4. eurekaServerPort This is the port added to the servers returned from DNS. Important if you run a non-standard port.

In addition to these values you bake in to your config, there are some additional properties you should set. We do that via environment variables which can be used to add/override any value in application.yml

  1. EUREKA_INSTANCE_HOSTNAME The hostname for this instance
  2. EUREKA_INSTANCE_IP_ADDRESS The ip address for this instance
  3. EUREKA_CLIENT_REGION The region this instance is running in

What's the deal with regions

A Eureka topology is modeled as Region > Datacenter > Instance on amazon this might be us-east > us-east-1 > eurkeka01 on digital ocean this may be ams > ams2 > eureka01

This is important to understand as it is used when the Eureka client queries DNS.

DNS TXT records

Eureka will start by querying the TXT records for your region txt.<region>.<eurekaServerDNSName> eg txt.us-east.eureka.storytel where it will expect to find one value for each datacenter in the region us-east-1.eureka.storytel.
It will then make another TXT lookup this time for txt.<datacenter> e.g. txt.us-east-1.eureka.storytel where it will expect to find one value for each instance in the datacenter eureka01.us-east-1.eureka.storytel, eureka02.us-east-1.eureka.storytel.

How to add the TXT records

This will depend heavily on your environment. We use dnsmasq which you can also read about on my blog here.

in ,

Running dnsmasq in Docker

Today we take a quick look at running dnsmasq as a docker container.

dnsmasq is a simple lightweight DNS (amongst other features) that can be used to easily set up various DNS records within your infrastructure. Our particular usecase is to set the TXT records Eureka requires for DNS based bootstrapping.

Read More

in ,

Useful Docker Commands

Today I'll share some quick, helpful, docker commands I use in my workflow. These help keep my development and production machines clean of old and unused images.

I'm no bash expert, so tweet me or make a PR if you have any suggestions.

Read More

in , ,

Running jekyll with docker

Previously I moved my jekyll installation inside a Vagrant image. At the time this was a big improvement over installing and maintaining ruby/jekyll locally on my machines.

For a while now I have wanted to move this installation inside Docker instead. I actually use Docker daily in my work and am very comfortable in that environment.
It wasn't until the recent release of Docker for Mac beta that this became practical though with the improvements to volume mapping.

So this morning I finally made the switch.

Read More

in

Connecting docker containers

Twice recently I have seen people ask on twitter about how to link docker containers. In both instances they were given overly-complex answers that are out of date with the current state of docker.

So today I will show you how to do it correctly for docker v1.10.0+

Read More