How to contain your love for OpenVPN and Kubernetes

Introduction

Does your developer team make you want to drop all internet traffic to dev and head to the bar? Is your security team pestering you to put a VPN endpoint into your cloud network to encrypt your network traffic? For those less familiar, VPNs are virtual private networks which work by providing two functions, tun and tap. Tun is short for tunnel, and provides a layer 3 (of the OSI Model) virtual network interface that can route IP packets. Tap (Test access point) provides low level kernel support that can be used to create a network bridge and can be used to monitor frames at layer 2. VPNs have been a part of network security efforts for years. If you find the need to add a VPN to your Kubernetes infrastructure, we’re going to show you how to setup OpenVPN on Kubernetes.

Brief intro to helm

Note: If you are familiar with helm, skip this section.


Helm is a great tool for scaffolding reusable Kubernetes templates. It’s particularly great because of the large community behind it that also contribute their templates to charts.

Helm works in two parts, your local client and a server, called a tiller. The tiller runs in your cluster and manages and versions your helm chart deployments.

Locally, your chart holds a values.yml file that has configurable options and their default values. When you deploy a chart, the client uses golang’s text/template package to put the variables in your values file into kubernetes manifests, and then pushes those to the server, which deploys them by sending them to the kubernetes api.

To get going with helm, you first have to get the tiller running on your cluster. This is done with

helm init

This will take a variable amount of time to pull the tiller image and get started.
You can confirm that the tiller is or isn’t running with:

kubectl get pods -n kube-system|grep tiller

Welcome to life at the helm. Now let’s deploy OpenVPN.


OpenVPN Chart Smarts

Let’s take a look at the community openVPN chart, available at:
https://github.com/kubernetes/charts/blob/master/stable/openvpn/

There are a few things to note in this chart. First, this chart deploys a
loadbalancer type service. If you launch this in GCP or on AWS, it is going to
create a loadbalancer from that provider. Secondly, this chart by default will setup
a persistent volume claim, in order to preserve your disk should you pod be
rescheduled, but this will create a disk and delete it per whatever persistent
volume policy is configured.

If the defaults look good to you, deploy the chart with:
helm install stable/openvpn

Otherwise, make a copy of values.yml in your current working directory and run:
helm install stable/openvpn -f values.yml

You’ll notice a bit of output once you run this command. These are notes that
pertain to the chart you’ve deployed, so they are worth reading through. But,
if you want the tl;dr here it is:


Once the external IP is available and all the server certificates are generated create client key .ovpn files by pasting the following into a shell:

POD_NAME=$(kubectl get pods --namespace default -l type=openvpn -o jsonpath='{ .items[0].metadata.name }')
SERVICE_NAME=$(kubectl get svc --namespace default -l type=openvpn -o jsonpath='{ .items[0].metadata.name }')
SERVICE_IP=$(kubectl get svc --namespace default $SERVICE_NAME -o go-template='{{ range $k, $v := (index .status.loadBalancer.ingress 0)}}{{ $v }}{{end}}')
KEY_NAME=kubeVPN
kubectl --namespace default exec -it $POD_NAME /etc/openvpn/setup/newClientCert.sh $KEY_NAME $SERVICE_IP
kubectl --namespace default exec -it $POD_NAME cat /etc/openvpn/certs/pki/$KEY_NAME.ovpn > $KEY_NAME.ovpn

You can update the KEY_NAME variable and repeat these steps for as many clients as you need.

What’s next?

If you run the steps in the notes, you’ll end up with an openvpn configuration file in your working directory called kubeVPN.ovpn. If you have a VPN client installed, such as TunnelBlick for MacOs (brew install caskroom/cask/tunnelblick), you can
run open kubeVPN.ovpn on mac or double click the file, which should start your vpn client and load the configuration.

At this stage, you should be all set to connect to the VPN. Welcome to the big leagues.


Did you have trouble launching openVPN in Kubernetes? Have any questions or concerns?
Leave them in the comments below.

If you or your organization needs help with technologies like Kubernetes and OpenVPN,
we might be able to help. Get in touch to learn more.