Kubernetes Service Discovery

I am helping my client transition from a few large monoliths hosted on AWS to micro-services hosted on Kubernetes. It is my first experience with Kubernetes and I must say that I am impressed so far.

Of course, micro-services work best when it is easy to find a service’s dependencies. This is one area where Kubernetes shines as it has a well designed service abstraction.

You can find services through two approaches:

  1. Using the environment variables that use the same conventions as those created by Docker links.
  2. Using DNS to resolve the service names to the service’s IP address.

Environment Variables

Kubernetes injects environment variables for each service and each port exposed by the service. This makes it easy to deploy containers that use Docker links to find their dependencies. For example, if we are exposing a RabbitMQ service, we can locate it using the RABBITMQ_SERVICE_SERVICE_HOST and RABBIT_MP_SERVICE_SERVICE_PORT variables. Other environment variables are also exposed to support this.

The easiest way to find out what environment variables are exposed are to exec the env command within a pod:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
kubectl exec memcached-rm58b env | grep RABBITMQ
RABBITMQ_SERVICE_SERVICE_HOST=10.0.143.172
RABBITMQ_SERVICE_SERVICE_PORT_A=5672
RABBITMQ_SERVICE_PORT_5672_TCP_ADDR=10.0.143.172
RABBITMQ_SERVICE_PORT_15672_TCP_ADDR=10.0.143.172
RABBITMQ_SERVICE_PORT_15672_TCP_PORT=15672
RABBITMQ_SERVICE_PORT_15672_TCP=tcp://10.0.143.172:15672
RABBITMQ_SERVICE_PORT_5672_TCP_PORT=5672
RABBITMQ_SERVICE_SERVICE_PORT_B=15672
RABBITMQ_SERVICE_PORT_5672_TCP_PROTO=tcp
RABBITMQ_SERVICE_PORT=tcp://10.0.143.172:5672
RABBITMQ_SERVICE_PORT_5672_TCP=tcp://10.0.143.172:5672
RABBITMQ_SERVICE_PORT_15672_TCP_PROTO=tcp
RABBITMQ_SERVICE_SERVICE_PORT=5672

DNS Resolution

Kubernetes has a kube-dns addon that exposes the service’s name as a DNS entry. As a result, you can tell your application to connect to a host name. The advantage of this approach is that you do not need to do anything different than you would otherwise.

The service names are scoped within namespaces. This allows you to run different deployment of a service for each namespace (for example, one per developer or one per environments) without having to edit configuration files.

Benefits

You can use either approach to write services that adapt to the environment in which they are deployed without having to change it’s configuration.

But What About the API?

Kubernetes provides a powerful API that allows you to inspect and discover services, replication controllers, pods and other component of a cluster. This would allow you to build deeper service discovery mechanisms where appropriate. But they are generally overkill for the needs of an application that needs to connect to it’s dependencies. I’ll discuss a few scenarios where this can be useful in a future post.

OpenID Connect and ID Tokens

OAuth2 is fundamentally an authorization protocol. It is not meant to be used for authentication. In general, OAuth2 based authorization services provide an end point that can be used to retrieve user profiles and identifiers. In some cases, they use...

Read More...

Signed JSON Web Tokens

Let’s continue using the analogies used in my last post and explore the JSON Web Tokens (JWT).

You hand over both your boarding pass and an identity document. The agent scans the boarding pass and examines the identity document to check it’s authenticity...

Read More...

Identity and Flying

Airport Security. Public Domain, https://www.flickr.com/photos/sixmilliondollardan/3382932556/in/photolist-69WpZo-6ovssq-4Pud5x-3yTksP-BMEB-6jdHz1-4vGox9-e8WbBd-Eq1JM-4u6cXw-f49kST-9yMyqh-2mPphB-7tQfFt-7zd55c-a6UnD2-4MZHTA-8G8fAm-8iDGiZ-b2hbhp-b636x-661hXd-459nE-acE949-kQFt6-53B2Fg-EMBoQ-b5awD-8SNYPd-8U8gQ7-6EsPiP-5YKWV9-nXRXdD-5NpqpQ-6jq1w-4FZCDR-b5axC-8UYf8L-AHptGi-5MF1mL-vBhvH-e3zcE-eNmLN9-58Vjve-96E2cA-6unyV7-7qNu4W-5588mk-bXavMg-ggg1g

Authentication and authorization are two concepts that are often mingled together. In a lot of Rails app, there is little thought given to it beyond adding devise to an app and running the generator to build the User model. In Spring based app, including...

Read More...

PhantomJS, Capybaras, and Poodles

Poodle source: https://secure.flickr.com/photos/imagesbywestfall/3452788638/in/photolist-6g7rLA-5Ly2TJ-dhgp22-7Eq65g-4L9Gkr-4L9Gkv-5MgFuL-86RKEk-a2Vhpv-54pS7t-uKNEz-2yMbx-7KkzPK-7BizcU-6fJFni-38DoTP-8smzb-rQXyi-fcDEVr-7b85h1-7Y7hwQ-dKEkPA-7AtcjM-keJ7tm-7NDCUj-dGSKFe-7kYDHP-8cXRa5-bKAgZ-5McrAk-6eCU2x-ijPiDn-9ycYtL-2rSBGq-7DRCHb-7Aniiq-7BiAts-dTdnGK-9wm9XC-dKEkb7-7tzuvX-7pSYi1-7uyoDN-dKyToP-7yA4oj-6x661Y-7nXHTq-7B9BnA-7zfV92-kSpeT/

The client that I am working with runs a web store and needed some changes made to the Spree/Paypal Express Checkout gateway to support receiving addresses from Paypal. This involves a fair amount of coordination between Paypal and Spree. It’s also...

Read More...

Implicit vs Explicit Testing

A developer pulls a copy of the staging database and runs a migration to make sure that it will work against the existing data and structure.

A developer writes specs around a new feature that he is building.

Both acts imply testing. One is explicit...

Read More...

PGP Public Key

It’s not a surprise that governments in general want to monitor what happens on the Internet. I always took the stance that anything that goes over unproctected and unencrypted channel was basically public. Private things need to be encrypted. This is...

Read More...

Page 1 of 7

Next page