A new adventure…

As the title says, I’ll soon be starting off on a new adventure.  After almost 6 years working in various networking roles at United Health Group I’ve decided to move on.  The decision to leave wasn’t an easy one for me to make.  I’ve built lots of great relationships and had the opportunity to work with some truly gifted individuals.  Many of the people I worked with have had a profound impact on my development as a network engineer and architect.  While I can’t possibly list all of the names, I want to sincerely thank all the people that have motivated and supported me during my tenure with UHG.  There are countless people that gave me opportunities I couldn’t have had anywhere else and for that I am truly grateful. 

So while it’s hard for me to close out this chapter of my career, I’m anxiously looking forward to starting the next one.  In late August I’ll be starting in my new role as a network engineer at IBM within the Watson business unit.  I’m excited about the opportunity and literally can’t wait to dig in!

In other news, some of you may have noticed that there hasn’t been a lot of new blog content lately.  The reasons for that mostly fall under the ‘usual suspect’ category.  Work has been extremely busy and the bulk of my free time has been dedicated to a new project I’m working on (more to come on that soon!).  Needless to say, once that project is completed, and I’ve settled into my new role, I look forward to getting back to a more normal cadence of content creation here on the blog.

Thanks for hanging in there with me, it’s been a busy summer!

Redefining the WAN

One of the more interesting recent trends in the network space has been around software defined WAN (SDWAN).  While I’ll admit I first didn’t give it much attention, I’ve since given it a harder look and see quite a bit of promise in the technology.  The WAN is a part of the network that, until recently, hasn’t received much attention particularly as it relates to SDN.  SDN in the enterprise space seems mostly focused on the data center since that’s where the network always seems to be the most complicated.  The unfortunate outcome of that mindset is that while we focus on the data center network, technologies like SDWAN appear and don’t always get the attention they deserve.  I think the primary reason for this is that many of us have WANs that we think are ‘working just fine’.  And while that may be the case, I think SDWAN has the potential to significantly reduce costs, improve WAN performance, and increase network agility.

One of the vendors in this market that I’ve recently had the chance to hear about is Silver Peak.  Silver Peak has been around for quite some time and is well known in the WAN optimization space.  In the past year Silver Peak has released it’s SDWAN product called Unity EdgeConnect.  The solution also includes Unity Orchestrator to manage your SDWAN endpoints and Unity Boost which adds WAN optimization to the endpoints.  Let’s talk a little bit about each piece of the solution.

The heart and soul of the solution lives in the EdgeConnect appliances.  These are your SDWAN endpoints and terminate all of the overlay network tunnels on either side of your WAN.  What I found the most interesting about EdgeConnect was the pricing model.  While traditionally we’re used to spending a lot upfront for remote site hardware, Silver Peak obviously isn’t looking to make a lot of money on hardware margin with the appliances being very reasonably priced.  There’s also a virtual edition allowing you to use your own hardware if you prefer.  The licensing model is simple at $199 per site regardless of bandwidth and what size hardware appliance you deploy.  And while not unique in this space, the EdgeConnect appliances support zero touch provisioning and are managed centrally from the Unity Orchestrator. 

The central point of control for Silver Peak’s SDWAN is the Unity Orchestrator.  In another interesting move, Silver Peak makes this software free with any Unity deployment.  The controller allows for single screen administration of your entire SDWAN and offers visibility into key metrics for monitoring and troubleshooting.  This also includes heat map like functionality to give a high level overview of how certain pieces of the WAN are performing.  This allows you to quickly isolate issues based on sites and regions which is key when considering that a major use case for SDWAN is using internet based circuits.  The orchestrator is also where you define what Silver Peak calls ‘business intent policies’ that define how certain application traffic is handled as it traverses the WAN.

The last optional component of the solution is Unity Boost.  Boost adds Silver Peak’s well known WAN optimization features to the solution.  And just like the two other components, the pricing on this piece is also innovative.  Boost is purchased ‘by the bit’.  That is, you can buy a pool of WAN optimization capacity and allocate it as you see fit across your SDWAN.  This opens up some interesting uses cases given that WAN optimization is usually an all or nothing proposition.  Traditional WAN optimization was either at the site or not at the site.  Many times it wasn’t always needed and was typically an expensive solution to have if not required.  In this model you can dole it out as needed. One of your WAN sites starts having connectivity issues?  Do you have a large migration to handle that could benefit from one of the many WAN optimization features?  Now you can allocate it as you see fit. 

While you can use SDWAN over any type of circuit, I believe the real gain with SDWAN is had when using it in conjunction with internet based circuits.  That being said, the focus of any SDWAN solution should be around making non-SLA driven circuit types (the internet) act more like a dedicated private link.  Silver Peak has a variety of features that all fall into the category of path conditioning…

Adaptive forward error correction (FEC) – FEC is a means to rebuild lost packets on the far side of a link which helps with the delay induced by having to resend lost packets.  The solution uses parity packets sent along with the real data that can be used to rebuild any packets that get lost in transit.  The feature scales dynamically minimizing parity packet overhead when it’s not required. 

Real-time Packet Order Correction – Ensures that packets are delivered in order on either side of the link by resequencing packets that arrive out of order.  This can be a two way street as waiting for out of order packets can often cause other problems.  However, as with all of these features, timeout settings can be configured to meet your needs. 

Tunnel bonding and failover – This is what allows you to combine multiple physical circuits into one or many logical circuits.  Having the ability to abstract the physical network is one of the main features that allows you to implement business intent policies across the WAN. 

Silver Peak is not alone in the SDWAN space, but I believe they are unique in many of their features and their pricing model.  If you’re interested in hearing more about their products and SDWAN solutions I’d suggest you check out these videos…

Introduction to Silver Peak with David Hughes

Silver Peak Unity EdgeConnect SD-WAN Overview

Silver Peak Creating Business Intent Policies with Silver Peak’s EdgeConnect SD-WAN Solution Demo

Silver Peak Delivering Broadband QoS with Silver Peak’s EdgeConnect SD-WAN Solution Demo

Silver Peak Zscaler Security Demo and Discussion

Kubernetes offers several different authentication mechanisms or plugins.  The goal of this post is to review each of them and provide a brief example of how they work.  In addition, we’ll talk about the ‘kubeconfig’ file and how it’s used in association with authentication plugins.

Note: In theory there’s no requirement to use any of these authentication plugins.  With the proper configuration, the API server can accept requests over HTTP on any given insecure port you like.  However – doing so is insecure and somewhat limiting because some features of Kubernetes rely on using authentication so it’s recommended to use one or more of the following plugins.

Kubernetes offers 3 default authentication plugins as of version 1.0.  These plugins are used to authenticate requests against the API server.  Since they’re used for communication to the API, that means that they apply to both the Kubelet and Kube-Proxy running on your server nodes as well as any requests or commands you issue through the kubectl CLI tool.  Let’s take a look at each option…

Client Certificate Authentication
This is the most common method of authentication and is widely used to authentication node back to the master.  This configuration option relies on valid certificates from the client being presented to the API server which has a defined CA certificate.  The most common method for achieving this is to generate certificates using the ‘make-ca-cert’ shell script from the Kubernetes Github page located here…

https://github.com/kubernetes/kubernetes/blob/master/cluster/saltbase/salt/generate-cert/make-ca-cert.sh

To use this I run something that looks like this…

In my case, running the script looks like this…

After running the script, head on over to the ‘/srv/kubernetes’ directory and you should see all of the certs required…

image

These will be the certificates we use on the API server and on any remote client (Kubelet or kubectl) that need to authenticate against the API server.  To tell the API server to use certificate authentication, we need to pass the process (or hyperkube container in my case) these options…

Note: In addition, since I run the API server using the hyperkube container image, I also need to make sure that the correct volumes are mounted to this container so it can consume these certificates.

HTTP Basic Authentication
Another option for authentication is to use HTTP basic authentication.  In this mode, you provide the API server a CSV file containing the account information you wish for it to use.  In it’s current implementation these credentials last forever and can not be modified without restarting the API server instance.  This mode is really intended for convenience during testing.  An example CSV file would look something like this…

Telling the API server to us HTTP basic authentication is as simple as passing this single flag to the API server…

Token Authentication
The last option for authentication is to use Tokens.  Much like the basic authentication option, these tokens are provided to the API server in a CSV file.  The same limitations apply in regards to them being valid forever and requiring a restart of the API server to load new tokens.  These types of authentication tokens are referred to as ‘bearer tokens’ and allow requests to be authenticated by passing a token rather than a standard username/password combination.  An example CSV token file looks like this…

Token authentication is enabled on the API server by passing this single flag to the API server…

Consuming the authentication plugins
Now that we’ve covered the different configuration options on the master, we need to know how to consume these plugins from a client perspective.  From a node (minion) side of things both the Kubelet and Kube-Proxy service need to be able to talk to the API server.  From a management perspective kubectl also needs to talk to the API server.  Luckily for us, Kubernetes has the ‘kubeconfig’ construct that can be used for both the node services as well as the command line tools.  Let’s take a quick look at a sample Kubeconfig file…

Here’s the kubeconfig I use in my SaltStack Kubernetes build for authentication on the nodes.  Let’s break this down a little bit…

image

It’s easiest in my mind to look at this from the bottom up.  The current context is what specifies the context we’re using.  As we can see in red, the current context is ‘kubelet-context’.  Under contexts we have a matching ‘kubelet-context’ that specifies a cluster (green) and a user (blue).  Both of those have matching definitions under those the users and clusters definitions of the file.  So what we really end up with here is something like this…

image
So let’s make this a little more interesting and define some more options…

Now let’s look at that with the color coding again so we can see what’s associated with what more easily…

image

This file defines 3 different authentication contexts. 

Context-certauth uses certificates for authentication and accesses the master through the secure URL of https://192.168.127.100:6443

Context-tokenauth uses a token for authentication and accesses the master through the insecure URL of http://192.168.127.100:8080

Context-basicauth uses basic authentication (username/password) and accesses the master through the secure URL of https://k8stest1:6443.

You likely noticed that I have two different clusters defined that both use HTTPS (cluster-ssl and cluster-sslskip).  The difference between the two is solely around the certificates being used.  In the case of cluster-ssl I need to use the IP address in the URL since the cert was built using the IP rather than the name.  In the case of cluster-sslskip, I use the DNS name but tell the system to ignore cert warnings since I may or may not have defined certs to do a proper TLS handshake with. 

So let’s see this in action.  Let’s move to a new workstation that has never talked to me lab Kubernetes cluster.  Let’s download kubectl and try to talk to the cluster…

image 
So we can see that by default kubectl attempts to connect to an API server that’s running locally on HTTP over port 8080.  This is why in all of our previous examples kubectl has just worked since we’ve always run it on the master.  So while we can pass kubectl a lot of flags on the CLI, that’s not terribly useful. Rather, we can define the kubeconfig file shown above locally and then use it for connectivity information.  By default, kubectl will look in the path ‘~/.kube/config’ for a config file so let’s create it there and try again…

image 
Awesome!  It works!  Note that our file above lists a ‘current-context’.  Since we didn’t tell kubectl what context to use, the current-context from kubeconfig is used.  So let’s remove that line and then try again…

image 
Here we can see that we can pass kubectl a ‘context’ through the CLI.  In this case, we use the basic auth context, but we can use any of the other ones as well…

image
We can tell it’s using different contexts because it complains about not having the certs when attempting to do certificate authentication.  This can be remedied by placing the certs on this machine locally.

Kubectl vs Kube-Proxy and Kube-Kubelet
The previous example shows how to use kubeconfig with the kubectl CLI tool.  However, the same kubeconfig file is also used for the Kubelet and Kube-Proxy services when defining the authentication for talking to the API server.  However, in that instance it appears to only be used for defining authentication.  In other words – you still need to pass the API server to the service directly through the ‘master’ or ‘api_servers’ flag.  Based on my testing – you can define the server in kubeconfig on the nodes, that information is not used when the Kube-Proxy and Kubelet processes attempt to talk to the API server.  Bottom line being that the kubeconfig file is only used for defining authentication parameters for Kubernetes services.  It is not used to define the API server as it is when using kubectl. 

SSL Transport requirement
I want to point out that the authentication plugins only work when you are talking to the API server over HTTPS transport.  If you were watching closely, you might have noticed that I had a typo in the above configuration.  My token was defined as ‘TokenofTheJon’ but in the kubeconfig it was configured as ‘tokenoftheJ0n’ with a zero instead of the letter ‘o’.  You’ll also notice that when I used the ‘tokenauth’ context that the request did not fail.  The only reason this worked was because that particular context was accessing the API through it’s insecure port of 8080 over HTTP.  From the Kubernetes documentation here

“Localhost Port – serves HTTP – default is port 8080, change with –insecure-port flag. – defaults IP is localhost, change with –insecure-bind-address flag. – no authentication or authorization checks in HTTP – protected by need to have host access”

My above example worked because my API server is using an insecure bind address of 0.0.0.0 which means anyone can access the API without authentication.  That’s certainly not a great idea and I only have it on in my lab for testing and troubleshooting.  Not passing authentication across HTTP saves you from accidentally transmitting tokens or credentials in clear text.  However – you likely shouldn’t have your API server answering requests on 8080 for anything besides localhost to start with. 

I hope you see the value and uses of kubeconfig files.  Used appropriately they can certainly make your life easier.  In the next post we’ll talk more about tokens as we discuss Kubernetes secrets and service accounts.

Tags:

« Older entries