Cloud Native Intranet with Kubernetes, CoreDNS and OpenVPN

Let me introduce you to what I am going to speak with you here with better
worlds: VPN, private, DNS, kubernetes, security.

I hope we all agree that VPN should be a must-have when you set up an
infrastructure. It doesn’t matter what you are doing, how many people are
working with you.

When you design a new system usually you need to expose to the public only some
service over HTTP and HTTPS all the rest: Jenkins, monitoring tools,
dashboards, log management should be locked-down and accessible just in a
private network. An intranet.

An intranet is a private network accessible only to an organization’s staff.
Often, a wide range of information and services are available on an
organization’s internal intranet that is unavailable to the public, unlike the
Internet.

All these concepts apply to “Cloud Native” ecosystem as well.

Kubernetes has a powerful dashboard and CTL that you can use to interact with
the API. That API doesn’t need to be publicly exposed, and to use the CLI from
your laptop, you should set up a VPN.

OpenVPN

Usually, I configure an OpenVPN using the image
kylemanna/openvpn available on
Docker Hub. It is straightforward to apply, and it offers a set of utilities
around user creation and certification management.

I don’t know if you realized that, but this VPN runs inside a Kubernetes
Cluster, so well configurated allow us to reach pods via a private network and
a bonus point also via kubedns to ping services, pods and all the other
resources registered to it.

To do that OpenVPN server can be configured to push kubedns to the client:

dhcp-option DNS <kube-dns-ip>

Something with learned is that if you are using Linux the
NetworkManager-OpenVPN plugin pushes the DNS correctly, but the OpenVPN cli
tool doesn’t if you are using the last one you need to set it up in another
way.

Tips: You can take the <kube-dns-ip> doing cat /etc/resolv.conf from inside a pod.

DNS

Push the KubeDNS or the DNS used by kubernetes is not enough to have a complete
intranet. You should be able to set up a custom domain to have friendly or
short URL.

You can take two different directions. KubeDNS can have static
record configured, but some person is not happy to touch or customize too much
the KubeDNS because Kubernetes itself use it and if you mess it up all it can
be a problem.

A possible solution is to deploy another DNS like CoreDNS and
configures it to resolve KubeDNS as a fallback. In this way, you will be free
to register custom LTDs and records. Kubernetes is going to use KubeDNS as
usual, and if you mess up CoreDNS, only a fraction of your system will blow
out.

Naturally to resolve your custom domains from the VPN you need to push
the CoreDNS ip and not the one used by Kubernetes.

If two DNSs are too much take the option one or from Kubernetes 1.10 you can
use CoreDNS as kubernetes DNS so it is a bit more flexible and you can use only
that one if you are brave enough.

I suggested CoreDNS because it supports records configuration via
etcd. Here an
example of Corefile:

Running this configuration inside a pod automatically fallback to kubedns (that
automatically fallback to the one configured to reach internet). Because of
upstream point to resolv.conf that inside a pod contains kubedns.

Benefits

Resolve Kubernetes DNS record from your local environment is very comfortable
to build a shared or dynamic development environment for you and your
colleagues.

You can set up per-developer namespaces that they can use to
deploy services reachable from the program that they are writing. Or you can
deploy your application, and another person connected to the VPN will be able
to use it.