SANDEEP DINESH: If you're like most people,
chances are you're using sources that
live outside of your cluster.
For example, maybe you're using the Taleo API
to send text messages, or maybe the Google Cloud Vision API
to do image analysis.
If you use the same endpoint in all of your environments
and have no plans to bring the servers into your Kubernetes
cluster, it's perfectly fine to use the service endpoint
directly in your code.
However, there are many scenarios
where this is not the case.
In this episode of "Kubernetes Best Practices,"
let's learn how to leverage the built-in service discovery
mechanisms inside Kubernetes for services outside the cluster,
just like you can for services inside the cluster.
One common service that's a good example of an external service
is a database running outside of your Kubernetes cluster.
While some cloud-native databases, such as Google Cloud
Data Store or Google Cloud Spanner,
use a single endpoint for all access,
most databases have separate endpoints
for different instances.
However, best practices for traditional databases,
like MySQL and MongoDB, usually prescribe
that you connect to the different instances
for different environments.
So you might have a big machine for production data
and maybe a little one for the test environment.
But each of these will have a different IP address or domain
name, and you don't want to change
your code from environment to environment.
So instead of hard-coding these addresses,
you can actually use the built-in Kubernetes
DNS-based service discovery for these external services
just like you can for native Kubernetes services.
OK, so let's say you're running a MongoDB database on Google
Compute Engine.
So hopefully at some point you can
bring a database inside the cluster,
but until then, you're stuck in this hybrid world.
Thankfully, you can use static Kubernetes services
to ease some of the pain.
So in this example, I created a MongoDB server
using Google Cloud Launcher.
So because it's created in the same network, or VPC,
as the Kubernetes cluster, it can
be accessed using the high-performance internal IP
address.
In Google Cloud, this is the default setup,
so there's nothing special you need to configure.
So now we have the IP address.
The first step is to create a service.
You may notice that there's no pod selectors for this service.
So this will create a service, but it really
won't know where to send the traffic.
This allows you to manually create
the endpoints object that'll receive traffic
from the service.
You can see that the endpoints manually
defines the IP address for the database,
and it uses the same name as a service.
Kubernetes will use all the IP addresses
to find the endpoints as if they were regular Kubernetes pods.
So now you can access the database
with a simple connection string.
No need to use IP addresses in your code at all.
If the IP addresses change in the future,
you can just update the endpoints with the new IP
addresses, and your applications won't need to make any changes.
If you're using a hosted database from a third party,
chances are they give you a URI that you can connect to.
If they give you an IP address, you can just
use the previous method.
So in this example, I have two MongoDB databases
hosted on mLab.
One of them is by dev database, and the other is production.
The connection strings for these databases are as follows.
Now, mLab gives you a dynamic URI and dynamic port.
And so you can see that they're both different.
Let's use Kubernetes to abstract over this.
So let's connect to the dev database.
You can create an external name Kubernetes service
which will give you a static Kubernetes
service that redirects traffic to the external service.
This service will do a simple CNAME redirect
at the kernel level so there's very minimal impact
on your performance.
So now you can use a much more simplified connection string.
But because external name uses a CNAME redirection,
it can't do port remapping.
So this may be OK with services with static ports,
but unfortunately it falls short in this example
where the port is dynamic.
mLab's free tier gives you a dynamic port number,
and you can't change it.
This means you need a different connection
string for development and production,
and you need to hard-code values for the port, which is bad.
So how can we get port remapping to work?
The first step is to get the IP address from the URI.
If you run nslookup, hostname, or the ping command
against the URI, you can get the IP address of the database.
Now you have the IP address.
If the service gives you back multiple IP addresses,
you can actually use all of them in the endpoints object.
The key thing to remember is that IP addresses
behind the URI can change without notice.
This method is kind of risky to use in production
if you aren't sure the IP address won't change.
With this, you can connect to the remote database
without needing to specify the port.
Kubernetes service transparently does the port remapping.
So mapping external sources to internal ones
gives you the flexibility to bring these services
into the cluster in the future while minimizing
refactoring efforts.
Even if you don't plan on bringing them in today,
you never know what tomorrow brings.
It also makes it easier to manage and understand
what external services your organization is using.
I'll see you on the next episode of "Kubernetes Best Practices."
[MUSIC PLAYING]