Definitive guide to using Weave Net CNI on AWS EKS

Looking to install the Weave Net CNI on AWS EKS / Kubernetes and remove the AWS CNI? Look no further. This guide will detail and demonstrate the process.

What this guide will cover

  • Removing AWS CNI plugin
  • Installing the Weave Net CNI on AWS EKS
  • Making sure your EC2 instances will work with Weave
  • Customising Weave Net CNI including custom pod overlay network ranges
  • Removing max-pods limit on your EKS worker nodes
  • Reconfiguring pods that don’t work after switching to Weave. (E.g. those that need to talk back to the EKS master nodes that do not get the Weave overlay network)

Want the Terraform source and test scripts to jump right in?

GitHub Terraform and test environment source

Otherwise, read on for step-by-step and more information…

There are a few guides floating around that detail how to install the Weave Net CNI plugin for Amazon Kubernetes clusters (EKS), however I’ve not seen them go into much detail.

Most tend to skip over some important steps and details when it comes to configuring weave and getting the pod networking functioning correctly.

There are also some important caveats that you should be aware of when replacing the AWS CNI Plugin with a different CNI, whether it be Weave, Calico, or any other.

Replacing CNI functionality

You should be 100% happy with what you’ll lose if completely replace the AWS CNI with another CNI. The AWS CNI has some very useful functionality such as:

  • Assigning IP addresses (via ENIs) to place pods directly into your VPC network
  • VPC flow logs that make sense

However, depending on your architecture and design decisions, as well as potential VPC network limitations, you may wish to opt out of the CNI that Amazon provides and instead use a different CNI that provides an overlay network with other functionality.

AWS CNI Limitations

One of the problems I have seen in VPCs is limited CIDR ranges, and therefore subnets that are carved up into smaller numbers of IP addresses.

The Amazon AWS CNI plugin is very IP address hungry and attaches multiple Secondary Private IP addresses to EKS worker nodes (EC2 instances) to provide pods in your cluster with directly assigned IPs.

This means that you can easily exhaust subnet IP addresses with just a few EKS worker nodes running.

This limitation also means that those who want high densities of pods running on worker nodes are in for a surprise. The IP address limit becomes an issue for maximum number of pods in these scenarios way before compute capacity becomes a problem.

This page shows the maximum number of ENI’s and Secondary IP addresses that can be used per EC2 instance: https://github.com/awslabs/amazon-eks-ami/blob/master/files/eni-max-pods.txt

Removing the AWS CNI plugin

Note: This process will involve you needing to replace your existing EKS worker nodes (if any) in the cluster after installing the Weave Net CNI.

Assuming you have a connection to your cluster already, the first thing to do is to remove the AWS CNI.

kubectl -n=kube-system delete daemonset aws-node

With that gone, your future EKS workers will no longer assign multiple Secondary IP addresses from your VPC subnets.

Installing CNI Genie

With the AWS CNI plugin removed, your pods won’t be able to get a network connection when starting up from this point onward.

Installing a basic deployment of CNI Genie is a quick way to get automatic CNI selection working for containers that start from this point on.

CNI genie has tons of other great features like allowing you to customise which CNI containers use when starting up and more.

For now, you’re just using it to allow containers to start-up and use the Weave Net overlay network by default.

Install CNI Genie. This manifest works with Kubernetes 1.12, 1.13, and 1.14 on EKS.

kubectl apply -f https://raw.githubusercontent.com/Shogan/terraform-eks-with-weave/master/src/weave/genie-plugin.yaml

Installing Weave

Before continuing, you should ensure your EC2 machines disable source/destination network checking.

Make this change in the userdata script that your instances run when starting from their autoscale groups.

REGION_ID=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | grep -Po "(us|ca|ap|eu|sa)-(north|south)?(east|west|central)-[0-9]+")
aws ec2 modify-instance-attribute --instance-id $INSTANCE_ID --no-source-dest-check --region $REGION_ID

On to installing Weave Net CNI on AWS EKS…

Next, get a Weave Net CNI yaml manifest file. Decide what overlay network IP Range you are going to be using and fill it in for the env.IPALLOC_RANGE query string parameter value in the code block below before making the curl request.

curl --location -o ./weave-cni.yaml "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')&env.IPALLOC_RANGE=192.168.0.0/16"

Note: the env.IPALLOC_RANGE query string param added is to specify you want a config with a custom CIDR range. This should be chosen specifically not to overlap with any network ranges shared with the VPC you’ll be deploying into.

In the example above I had a VPC and VPC peers that shared the CIDR block 10.0.0.0/8). Therefore I chose to use 192.168.0.0/16 for the Weave overlay network.

You should be aware of the network ranges you’re using and plan this out appropriately.

The config you now have as weave-cni.yaml will contain the environment variable IPALLOC_RANGE with the correct value that the weave pods will use to setup networking on the EKS Worker nodes.

Apply the weave Net CNI resources:

Note: This manifest is pre-created to use an overlay network range of 192.168.0.0/16

kubectl apply -f https://raw.githubusercontent.com/Shogan/terraform-eks-with-weave/master/src/weave/weave-cni.yaml

Note: Don’t expect things to change suddenly. The current EKS worker nodes will need to be rotated out (e.g. drain, terminate, wait for new to appear) in order for the IP addresses that the AWS CNI has kept warm/allocated to be released.

If you have any existing EKS workers running, drain them now and terminate/replace them with new workers. This includes the source/destination check change made previously.

kubectl get nodes
kubectl drain nodename --ignore-daemonsets

Remove max pod limits on nodes:

Your worker nodes by default have a limit set on how many pods they can schedule. The EKS AMI sets this based on EC2 type (and the max pods due to the usual ENI limitations / IP address limitations with the AWS CNI).

Check your max pod limits with:

kubectl get nodes -o yaml | grep pods

If you’re using the standard EKS optimized AMI (or a derivative of it) then you can simply pass an option to the bootstrap.sh script located in the image that setup the kubelet and joins the cluster. Set –use-max-pods false as an argument to the script.

For example, your autoscale group launch configuration might get the EC2 worker nodes to join the cluster using the bootstrap.sh script. You can update it like so:

/etc/eks/bootstrap.sh --b64-cluster-ca 'YOUR_BASE64_CLUSTER_CA_DATA_HERE' --apiserver-endpoint 'https://YOUR_EKS_CLUSTER_ENDPOINT_HERE' --use-max-pods false --kubelet-extra-args '' 'YOUR_CLUSTER_NAME_HERE'

If you’re using the EKS Terraform module you can simply pass in bootstrap-extra-args – this will automatically setup your worker node userdata templates with extra bootstrap arguments for the kubelet. See example here

Checking max-pods limit again after applying this change, you should see the previous pod limit (based on prior AWS CNI max pods for your instance type) removed now.

You’re almost running Weave Net CNI on AWS EKS, but first you need to roll out new worker nodes.

With the Weave Net CNI installed, the kubelet service updated and your EC2 source/destination checks disabled, you can rotate out your old EKS worker nodes, replacing them with the new nodes.

kubectl drain node --ignore-daemonsets

Once the new nodes come up and start scheduling pods, if everything went to plan you should see that new pods are using the Weave overlay network. E.g. 192.168.0.0/16.

A quick run-down on weave IP addresses and routes

If you get a shell to a worker node running the weave overlay network and do a listing of routes, you might see something like the following:

# ip route show
default via 10.254.109.129 dev eth0
10.254.109.128/26 dev eth0 proto kernel scope link src 10.254.109.133
169.254.169.254 dev eth0
192.168.0.0/16 dev weave proto kernel scope link src 192.168.192.0 

This routing table shows two main interfaces in use. One from the host (EC2) instance network interfaces itself, eth0, and one from weave called weave.

When network packets are destined for the 10.254.109.128/26 address space, then traffic is routed down eth0.

If traffic on the host is destined for any address on 192.168.0.0/16, it will instead route via the weave interface ‘weave’ and the weave system will handle routing that traffic appropriately.

Otherwise if the traffic is destined for some public IP address out on the wider internet, it’ll go down the default route which is down the interface, eth0. This is a default gateway in the VPC subnet in this case – 10.254.109.129.

Finally, metadata URL traffic for 169.254.169.254 goes down the main host eth0 interface of course.

Caveats

For the most part everything should work great. Weave will route traffic between it’s overlay network and your worker node’s host network just fine.

However, some of your custom workloads or kubernetes tools might not like being on the new overlay network. For example they might need to talk to other Kubernetes nodes that do not run weave net.

This is now where the limitation of using a managed Kubernetes offering like EKS becomes a bit of a problem.

You can’t run weave on the Kubernetes master / API servers that are effectively the ‘managed’ control plane that AWS EKS hosts for you.

This means that your weave overlay network does not span the Kubernetes master nodes where the Kubernetes API runs.

If you have an application or container in the weave overlay network and the Kubernetes master node / API needs to talk to it, this won’t work.

One potential solution though is to use hostNetwork: true in your pod specification. However you should of course be aware of how this would affect your application and application security.

In my case, I was running metrics-server and it stopped working after it started using Weave. I found out that the Kubernetes API needs to talk to the metrics-server service and of course this won’t work in the overlay network.

Example EKS with Weave Net CNI cluster

You can use the source code I’ve uploaded here.

There are five simple steps to deploy this example EKS cluster in your own account.

  • Modify the example.tfvars file to fit your own parameters.
  • terraform plan -var-file="example.tfvars" -out="example.tfplan"
  • terraform apply "example.tfplan"
  • ./setup-weave.sh
  • ./test-weave.sh

Warning: This will create a new VPC, subnets, NAT Gateway instance, Internet Gateway, EKS Cluster, and set of worker node autoscale groups. So be sure Terraform Destroy this if you’re just testing things out.

– Your wallet

After terraform creates all the resources, you can run the two included shell scripts. setup-weave.sh will remove the AWS CNI, install CNI genie, Weave, and deploy two simple example pods and services.

At this point you should terminate your existing worker nodes (that still use the AWS CNI) and wait for your new worker nodes to join the cluster.

test-weave.sh will wait for the hello-node test pods to become ready, and then execute a curl command inside one, talking to the other via the the service and vice versa. If successful, you’ll see a HTTP 200 OK response from each service.

vMetrics for WordPress blogs updated to version 1.1

I spent a little bit of time updating my vMetrics plugin for WordPress blogs. To give you a brief run-down, vMetrics allows you to display information from your VMware vCenter Cluster or ESX hosts / lab on your WordPress blog. It works with vSphere 4, 5 and 5.1.

 

 

In version 1.1 I have made the following changes:

Change log for version 1.1:

  • Added new metrics section for hardware information (Model and Vendor of first host in cluster – this is editable in the PowerCLI script)
  • Added configurable widget title section for Hardware
  • Updated PowerCLI updater script to have a DO WHILE loop (allowing you to run the script once on a management machine and it will keep updating your blog vMetrics every 30 minutes. (The script is called once every half hour). Thanks @dawoo for the idea 🙂
  • Added PowerCLI section to send the vendor and model type of the first ESX host it finds back to vMetrics so that you can display this information in the widget too
  • Cleaned up PHP in main plugin code

You can take a look at the main plugin page here or use the links below to download the latest version right away. Installation and configuration steps can be found on the main plugin page.

Latest version downloads (get the plugin and updater script):

[download id=”22″]
[download id=”23″]

Announcing vMetrics for WordPress

vMetrics is a small plugin for WordPress that works in conjunction with a PowerCLI Updater Script. You install the plugin, add the Widget to your sidebar in WordPress, configure which stats you would like to show, then run, or schedule the PowerCLI script against a standalong ESX/ESXi host, or vCenter server.

 

 

I have been working on this in my evenings whenever I find spare time over the last couple of weeks. It is based off Nicholas Weaver’s excellent WP-vSpherestats plugin, but has been re-worked to be more customisable, offer more metrics and statistics about your vSphere environment, and offers a PowerCLI Updater script, meaning you can easily change or customise the information that is brought back into the plugin.

You can find out more, or download the plugin over here.

 

An update on what I have been busy with lately…

Thought I would do a quick blog post on what I have been busy with lately.

1. My first iPhone / iPod Touch game (released on Cydia for Jailbroken devices)

So this is something I have been busy with over the last few months – coding bits and pieces here and there whenever I get a bit of spare time on my hands. Its nothing special – just a simple Maze game. You use your device’s accelerometer to navigate your character through 5 maze levels. If you touch the walls you lose health. The longer you take to complete the maze, the more score you lose too. So the point is to get through in the quickest possible time without touching walls. I learnt the basics of how to work with the accelerometer, game loops, twitter integration, a little bit of PHP and mySQL for the Highscore system and a fair amount of general objectiveC code. There are a couple of bugs in the game at the moment (like the way you get a little stuck on walls – issue with my game loop) that I don’t really have time to sort out at the moment. But hopefully I’ll get more time in the near future to figure out my mistakes and fix these. You can check the game out in more detail here or you can download it for Jailbroken Apple devices on Cydia. Search for “Speed Maze”.

2. Moving

Well we’re moving house in the next month or so. We have found a place a little closer in to London that is going to offer far more room, an awesome garden, park across the road, and to top it all off, its in a nice quiet cal-de-sac. As such, I have been taking the opportunity to eBay some surpluss hardware and gadgets I have had lying around for a while. This includes various PCs and bits of hardware I have had lying around, plus around 20U worth of Dell PowerEdge servers! (See image above).

3. Other

My home VMware lab – I have also been building various ESX and vCenter labs here at home to play with in a non-production environment. This is great as it allows me to test all kinds of crazy things I really don’t want to try out at work! I have chopped and changed the hardware, but finally have two different labs going. One is a nested set up of virtualized ESX 4.0 hosts, running under a main ESX 4.0 host if you see what I mean.  The other is running on a PowerEdge 6850 server at the moment – 4 x Xeon 3.16GHz CPUs and 4GB RAM. The issue I have here is that there is no Intel VT (hardware virtualization) support on these processors. So although ESX 4.0 runs OK, I can only run 32-bit VMs for now. Exchange 2010 and other 64-bit VMs will have to stay on my main gaming PC for now then. I also found this great WordPress plugin by lynxbat on Twitter. Once set up, it displays statistics from your VMware ESX host or vCenter Server. You can take a look at my current lab stats on the right in the sidebar. Get the plugin over here: WP-vSphereStats. Apart from that, we have also been planning one or two soon to be taken, well deserved holidays. We’ll be off to France soon, after which we’ll be taking a nice long holiday in South Africa. Excited to see friends and family again soon!

Winter is here! Testing the picture gallery plugin.

We went down to the local commons today, to see if the lakes would be frozen. We got there in the early afternoon, and my car temperature was already reading -2 degrees Celsius! I managed to get some decent photos taken, and so did the girlfriend. Today was the first time I had to fully kit myself out in my winter attire. Once at the lake, we were able to walk across the entire expanse of frozen water, and spent a few minutes hitting ice blocks around with sticks on the ice.

Anyway, the main reason for this post was to test my new plugin for uploading mini picture galleries to blog posts. I got it from here.

[PSGallery=1p4cio7rrq]