Exposing Postgres Services¶
This section explains how to expose a PostgreSQL service externally, allowing accessto your PostgreSQL database fromoutsideyourKubernetescluster usingNGINX Ingress Controller.
If you followed the Quickstart , you should have by nowa database
that can be accessed inside the cluster via the cluster-example-rw
(primary) and cluster-example-r (read-only)services in the
default namespace. Both services use port 5432 .
Let’s assume that you want to make the primary instance accessible from
externalaccesses on port 5432 . A typical use case, when moving to a
Kubernetesinfrastructure, is indeed the one represented by
legacyapplications that cannot be easily or sustainably
“containerized”. A sensible workaroundis to allow those applications
that most likely reside in a virtual machineor a physical server, to
access a PostgreSQL database inside a Kubernetes clusterin the same
network.
Warning
Allowing access to a database from the public network could expose your database to potential attacks from malicious users. Ensure you secure your database before granting external access or that your Kubernetes cluster is only reachable from a private network.
For this example, you will use NGINX Ingress Controller ,since it is maintained directly by the Kubernetes project and can be set upon every Kubernetes cluster. Many other controllers are available (see the Kubernetes documentation for a comprehensive list).
We assume that:
the NGINX Ingress controller has been deployed and works correctly
it is possible to create a service of type
LoadBalancerin your cluster
Important
Ingresses are only required to expose HTTP and HTTPS traffic. While the NGINX Ingress controller can, not all Ingress objects can expose arbitrary ports or protocols.
The first step is to create a tcp-services ConfigMap whose data
fieldcontains info on the externally exposed port and the namespace,
service andport to point to internally.
apiVersion: v1
kind: ConfigMap
metadata:
name: tcp-services
namespace: ingress-nginx
data:
5432: default/cluster-example-rw:5432
Then, if you’ve installed NGINX Ingress Controller as suggested in
theirdocumentation, you should have an ingress-nginx service. You’ll
have to addthe 5432 port to the ingress-nginx service to expose
it.The ingress will redirect incoming connections on port 5432 to your
database.
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
type: LoadBalancer
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
- name: https
port: 443
targetPort: 443
protocol: TCP
- name: postgres
port: 5432
targetPort: 5432
protocol: TCP
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
You can use cluster-expose-service.yaml and apply itusing kubectl .
Warning
If you apply this file directly, you will overwrite any previous change in your ConfigMap and Service of the Ingress
Now you will be able to reach the PostgreSQL Cluster from outside your Kubernetes cluster.
Important
Make sure you configure pg_hba to allow connections from the Ingress.
Testing on Minikube¶
On Minikube you can setup the ingress controller running:
minikube addons enable ingress
Then, patch the tcp-service ConfigMap to redirect to the primary
theconnections on port 5432 of the Ingress:
kubectl patch configmap tcp-services -n kube-system \
--patch {"data":{"5432":"default/cluster-example-rw:5432"}}
You can then patch the deployment to allow access on port 5432.Create a
file called patch.yaml with the following content:
spec:
template:
spec:
containers:
- name: nginx-ingress-controller
ports:
- containerPort: 5432
hostPort: 5432
and apply it to the nginx-ingress-controller deployment :
kubectl patch deployment nginx-ingress-controller --patch "$(cat patch.yaml)" -n kube-system
You can access the primary from your machine running:
psql -h $(minikube ip) -p 5432 -U postgres