Introduction
Vault clusters on K8s generally expose Vault UI by its service, however, the 'serviceTypes' are by default 'ClusterIP' which we can modify by changing 'serviceType' to 'NodePort' or 'LoadBalancer' as per our requirements.
These changes would help us to access Vault UI by hitting these service endpoints, for 'LoadBalancer' we need to hit its FQDN, while for 'NodePort' type we need to pass <IP>:<NodePort>
In addition, we can use DNS to create a 'CNAME' record to point the LB URL to a simplified domain name (let’s say, vault-ui.example.com).
Besides, some more advanced requirements would be:-
-
We need multiple Vault services to be exposed to different hostnames. For eg., in the dev environment we would need the domain name vault-ui-dev.example.com but for the test environment, the hostname would be different like vault-ui-test.example.com.
-
We need to redirect incoming traffic to different services depending on the URI. For eg., any web application request will be redirected using vault-ui.example.com/web, similarly, backend application service request will be redirected as vault-ui.example.com/backend.
Such requirements are configurable by using 'Ingress' and 'IngressController' in K8s. In this guide, we will be covering such setup for hostname requirements.
Lab Setup:-
Requirements:-
-
Minikube cluster
-
kubectl installed locally
Following our reference learn guide to create a vault cluster on minikube.
Once the above setup is running we could see the following K8s services are created.
% kubectl get services -n vault
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
vault ClusterIP 10.111.29.187 <none> 8200/TCP,8201/TCP 5h42m
vault-active ClusterIP 10.111.244.212 <none> 8200/TCP,8201/TCP 5h42m
vault-agent-injector-svc ClusterIP 10.108.160.86 <none> 443/TCP 5h42m
vault-internal ClusterIP None <none> 8200/TCP,8201/TCP 5h42m
vault-standby ClusterIP 10.104.116.134 <none> 8200/TCP,8201/TCP 5h42m
Now to enable ingress resources on minikube, we need to first enable the IngressController addons on it.
Ref. https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/
$ minikube addons enable ingress
We can verify that its ingress-controller is running fine using the below command.
% kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-dlmmg 0/1 Completed 0 5h13m
ingress-nginx-admission-patch-4qpfx 0/1 Completed 1 5h13m
ingress-nginx-controller-9669b89f9-57x79 1/1 Running 0 5h13m
We can create an Ingress object now to configure hostname-based routing so that any request hitting URL "dns.kubernetes-demo.com" will be redirected in the backend to service vault-active over port 8200.
More than one URL can also be implemented just by introducing an another rule with a second URL.
% cat ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: vault-test-ingress
namespace: vault
annotations:
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
rules:
- host: dns.kubernetes-demo.com
http:
paths:
- backend:
service:
name: vault-active
port:
number: 8200
path: /
pathType: Prefix
- host: dns-2.kubernetes-demo.com
http:
paths:
- backend:
service:
name: vault
port:
number: 8200
path: /
pathType: Prefix
% kubectl apply -f ingress.yaml
ingress.networking.k8s.io/vault-test-ingress created
Ingress object will be create and we can see that it gets an Address through the ingress-controller network CIDR.
himanshusharma@himanshusharma-GJ9F6YC4M5 ~ % k get ing -n vault -w
NAME CLASS HOSTS ADDRESS PORTS AGE
vault-test-ingress nginx dns.kubernetes-demo.com,dns-2.kubernetes-demo.com 192.168.49.2 80 5h11m
From below output, we could see that ingress is pointing to the correct pod vault-0 pod (active one) having IP 10.244.0.11 over port 8200.
himanshusharma@himanshusharma-GJ9F6YC4M5 ~ % kubectl describe ingress -n vault vault-test-ingress
Name: vault-test-ingress
Labels: <none>
Namespace: vault
Address: 192.168.49.2
Ingress Class: nginx
Default backend: <default>
Rules:
Host Path Backends
---- ---- --------
dns.kubernetes-demo.com
/ vault-active:8200 (10.244.0.13:8200)
dns-2.kubernetes-demo.com
/ vault:8200 (10.244.0.11:8200,10.244.0.12:8200,10.244.0.13:8200)
Annotations: nginx.ingress.kubernetes.io/backend-protocol: HTTPS
nginx.ingress.kubernetes.io/force-ssl-redirect: true
nginx.ingress.kubernetes.io/ssl-passthrough: true
Events: <none>
himanshusharma@himanshusharma-GJ9F6YC4M5 ~ %
We need to verify that the Ingress controller is directing traffic, by following the instructions for your platform:
For Linux OS
$ curl --resolve "dns.kubernetes-demo.com:80:$( minikube ip )" -i http://dns.kubernetes-demo.com
Note:- You may determine Minikube IP using following commands:-
$ minikube ssh
$ dig +short host.docker.internal
For MacOS, keep running following command in one separate session:-
$ minikube tunnel
In other session, run following command to check the redirect output to vault UI.
himanshusharma@himanshusharma-GJ9F6YC4M5 ~ % curl --resolve "dns.kubernetes-demo.com:80:127.0.0.1" -i http://dns.kubernetes-demo.com
HTTP/1.1 308 Permanent Redirect
Date: Wed, 28 Aug 2024 10:59:10 GMT
Content-Type: text/html
Content-Length: 164
Connection: keep-alive
Location: https://dns.kubernetes-demo.com
<html>
<head><title>308 Permanent Redirect</title></head>
<body>
<center><h1>308 Permanent Redirect</h1></center>
<hr><center>nginx</center>
</body>
</html>
himanshusharma@himanshusharma-GJ9F6YC4M5 ~ % curl --resolve "dns-2.kubernetes-demo.com:80:127.0.0.1" -i http://dns-2.kubernetes-demo.com
HTTP/1.1 308 Permanent Redirect
Date: Fri, 30 Aug 2024 08:09:18 GMT
Content-Type: text/html
Content-Length: 164
Connection: keep-alive
Location: https://dns-2.kubernetes-demo.com
<html>
<head><title>308 Permanent Redirect</title></head>
<body>
<center><h1>308 Permanent Redirect</h1></center>
<hr><center>nginx</center>
</body>
</html>
In order to access this hostname for Vault UI from browser, we need to add a line to the bottom of the /etc/hosts file on your computer (you will need administrator access).
% cat /etc/hosts
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
127.0.0.1 dns.kubernetes-demo.com
127.0.0.1 dns-2.kubernetes-demo.com
References:-
https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/
https://kubernetes.io/docs/concepts/services-networking/ingress/