I am trying to access a Postgresql database from within a Kubernets cluster with the following configuration (inspired by the documentation from /).
The database that I am trying to use runs on my localhost at address 192.168.1.177 port 54322, outside the cluster (Minikube).
---
# Source: external-postgresql/templates/service-entry.yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: sample-external-postgresql
namespace: sample
labels:
helm.sh/chart: external-postgresql-0.1.0
app.kubernetes.io/name: external-postgresql
app.kubernetes.io/instance: sample
app.kubernetes.io/version: "0.0.1"
app.kubernetes.io/managed-by: Helm
spec:
hosts:
- postgres
addresses:
- 192.168.1.177/16
ports:
- number: 54322
name: postgresql
protocol: TCP
location: MESH_EXTERNAL
resolution: STATIC
---
# Source: external-postgresql/templates/virtual-service.yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: sample-external-postgresql
namespace: sample
labels:
helm.sh/chart: external-postgresql-0.1.0
app.kubernetes.io/name: external-postgresql
app.kubernetes.io/instance: sample
app.kubernetes.io/version: "0.0.1"
app.kubernetes.io/managed-by: Helm
spec:
hosts:
- postgres
http:
- name: "external-postgresql"
match:
- uri:
prefix: "/"
route:
- destination:
host: postgres
The consuming Java (minimalistic SpringBoot) based Restful application gets configured to open the database connection with 'jdbc:postgresql://postgres:54322/postgres'. I am deploying that container with the following object
# Source: training-restful/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-training-restful
namespace: sample
labels:
helm.sh/chart: training-restful-0.0.2
app.kubernetes.io/name: training-restful
app.kubernetes.io/instance: sample
app.kubernetes.io/namespace: sample
app.kubernetes.io/version: "0.3"
app.kubernetes.io/managed-by: Helm
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: training-restful
app.kubernetes.io/instance: sample
app.kubernetes.io/namespace: sample
template:
metadata:
labels:
helm.sh/chart: training-restful-0.0.2
app.kubernetes.io/name: training-restful
app.kubernetes.io/instance: sample
app.kubernetes.io/namespace: sample
app.kubernetes.io/version: "0.3"
app.kubernetes.io/managed-by: Helm
spec:
serviceAccountName: sample-training-restful
securityContext:
{}
restartPolicy: Always
containers:
- name: training-restful
securityContext:
{}
image: "training-app:0.3"
imagePullPolicy: IfNotPresent
env:
- name: DATABASE_USER
value: postgres
- name: DATABASE_PASSWORD
value: ChangeMe$191
- name: DATABASE_URL
value: jdbc:postgresql://postgres:54322/postgres
ports:
- name: http
containerPort: 8080
protocol: TCP
livenessProbe:
initialDelaySeconds: 1000
failureThreshold: 1
periodSeconds: 60
terminationGracePeriodSeconds: 60
httpGet:
host: 127.0.0.1
path: /v1/api/index
port: 8080
When the pod starts-up, it writes the following traces in the log file
2025-02-06 17:53:36,670 INFO o.s.b.StartupInfoLogger [main] Starting SampleApplication v0.0.2-SNAPSHOT using Java 21.0.6 with PID 1 (/opt/app/Sample.jar started by root in /opt/app)
2025-02-06 17:53:36,674 DEBUG o.s.b.StartupInfoLogger [main] Running with Spring Boot v3.4.1, Spring v6.2.1
2025-02-06 17:53:36,674 INFO o.s.b.SpringApplication [main] The following 1 profile is active: "dev"
2025-02-06 17:53:40,975 ERROR o.h.e.j.s.SqlExceptionHelper [main] The connection attempt failed.
2025-02-06 17:53:42,506 DEBUG c.m.w.s.c.SecurityConfiguration [main] Configure the security platform
2025-02-06 17:53:42,866 INFO o.s.b.StartupInfoLogger [main] Started SampleApplication in 6.84 seconds (process running for 7.61)
After deploying the SE and VS, running 'istioctl analyze -n sample' yields no validation issues in the log.
>istioctl analyze -n sample
✔ No validation issues found when analyzing namespace: sample.
However, the Restful application cannot connect to the external database.
I have an extra hint from Kiali, which analyzing the Virtual Service, it tells me that the host (spec.http.route.destination.host) cannot be resolved.
To test that the actual Postgres database is connectable from the Kubernetes cluster, if I hardcode its IP directly into the environment variable DATABASE_URL (as shown in the code snippet below), the connection is established right, and my sample Restful app can do all needed operation (SELECT, INSERT, UPDATE ...) without restriction
# Source: training-restful/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-training-restful
namespace: sample
labels:
helm.sh/chart: training-restful-0.0.2
app.kubernetes.io/name: training-restful
app.kubernetes.io/instance: sample
app.kubernetes.io/namespace: sample
app.kubernetes.io/version: "0.3"
app.kubernetes.io/managed-by: Helm
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: training-restful
app.kubernetes.io/instance: sample
app.kubernetes.io/namespace: sample
template:
metadata:
labels:
helm.sh/chart: training-restful-0.0.2
app.kubernetes.io/name: training-restful
app.kubernetes.io/instance: sample
app.kubernetes.io/namespace: sample
app.kubernetes.io/version: "0.3"
app.kubernetes.io/managed-by: Helm
spec:
serviceAccountName: sample-training-restful
securityContext:
{}
restartPolicy: Always
containers:
- name: training-restful
securityContext:
{}
image: "training-app:0.3"
imagePullPolicy: IfNotPresent
env:
- name: DATABASE_USER
value: postgres
- name: DATABASE_PASSWORD
value: ChangeMe$191
- name: DATABASE_URL
value: jdbc:postgresql://192.168.1.177:54322/postgres
ports:
- name: http
containerPort: 8080
protocol: TCP
livenessProbe:
initialDelaySeconds: 1000
failureThreshold: 1
periodSeconds: 60
terminationGracePeriodSeconds: 60
httpGet:
host: 127.0.0.1
path: /v1/api/index
port: 8080
How can I configure the external database to access so that I can late make use of the goodies from Istio?
Thank you for any useful hit