Having an internal network + DNS service is a common practice in a corporate network. It serves to completely separate internal and external network traffic, and provide the convenience of using domain names for internal services.
With a kubernetes cluster at home, it is pretty simple to replicate the setup at home. In my case, it provided the following benefits:
- Use of domain names for internal services
- HTTPS traffic between internal services
- Easy to add new services
- No need to worry about IP address depletion (by using reverse proxy)
Prerequisites
- A Kubernetes cluster
- A domain name pointing to your cluster ingress controller
- traefik installed in your cluster
Configure traefik
If you installed your traefik using helm chart, you can simply apply the following HelmChartConfig
to your cluster:
|
|
This will create the following endpoints that we can later refer to in ingress
resources:
- internal: for HTTP traffic
- internalsecure: for HTTPS traffic
They will be separate from the default traefik endpoints web
and websecure
, which are typically used for external traffic.
We also need to add a service to expose the internal traefik endpoints:
|
|
The loadBalancerIP
will later be referenced in the DNS configuration.
Configure bind9
For internal DNS service, I chose bind9, which can easily be deployed on Kubernetes.
Sample configuration:
|
|
Since I already own the domain name junyi.me
which points to my cluster’s ingress controller (traefik) on Cloudflare’s DNS server, I just reused it for internal domain names as well. This has several benefits:
- I can use the same SSL certificates for my services, so same services/ingresses can be used internally and externally with HTTPS
- Same domain names can be used from inside and outside my home network, so I (my browser) don’t have to remember different domain names for the same services
This will tell bind9 to resolve *.i.junyi.me
to the internal IP, and *.junyi.me
to the external IP.
“external IP” here does not mean the publically accessible IP address. It is the service IP address (like loadBalancerIP) of traefik that is accessible in the private network.
Deploy the bind9 service:
|
|
<dns-ip>
will be the IP address of DNS service, which can be used like a normal DNS server in your network.
Test it by running something like this:
|
|
I have configured my router to give out this IP address as the default DNS server in DHCP.
Deploy a service
To deploy something into the internal network, just take any existing deployment and change its ingress resource to use the internal traefik endpoints. For example, this is my staging deployment of this blog service.
|
|
This will make the staging blog service accessible at blog.i.junyi.me
from inside the network.
But not accessible from outside the network.
The ingress resources without the traefik.ingress.kubernetes.io/router.entrypoints
annotation will still be accessible from outside the network. This blog is an example.
Conclusion
I tried several ways to make this setup happen, but this approach seems to be the most straightforward and maintainable.
Looking into the values.yml
on the traefik helm chart repo helped a lot.