Search code examples
postgresqlkuberneteskeycloakvmware

Connect to Postgresql from inside kubernetes cluster


I setup a series of VM 192.168.2.(100,105,101,104) where kubernetes master is on 100 and two workers on 101,104. Also setup the postgres on 192.168.2.105, followed this tutorial but it is still unreachable from within. Tried it in minikube inside a test VM where minikube and postgres were installed in the same VM, worked just fine.

Changed the postgers config file from localhost to *, changed listen at pg_hba.conf to 0.0.0.0/0

Installed postgesql-12 and postgresql-client-12 in the VM 192.168.2.105:5432, now i added headless service to kubernetes which is as follows

apiVersion: v1
kind: Service
metadata:
    name: my-service
spec:
    ports:
        - protocol: TCP
          port: 5432
          targetPort: 5432
------
apiVersion: v1
kind: Endpoints
metadata:
    name: my-service
subsets:
    - addresses:
        - ip: 192.168.2.105
      ports:
        - port: 5432

in my deployment I am defining this to access database

apiVersion: v1
kind: Service
metadata:
  name: keycloak
  labels:
    app: keycloak
spec:
  ports:
  - name: http
    port: 8080
    targetPort: 8080
  selector:
    app: keycloak
  type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keycloak
  namespace: default
  labels:
    app: keycloak
spec:
  replicas: 1
  selector:
    matchLabels:
      app: keycloak
  template:
    metadata:
      labels:
        app: keycloak
    spec:
      containers:
      - name: keycloak
        image: quay.io/keycloak/keycloak:11.0.0
        env:
        - name: KEYCLOAK_USER
          value: "admin"
        - name: KEYCLOAK_PASSWORD
          value: "admin"
        - name: PROXY_ADDRESS_FORWARDING
          value: "true"
        - name: DB_ADDR
          value: 'my-service:5432'
        - name: DB_DATABASE
          value: postgres
        - name: DB_PASSWORD
          value: admin
        - name: DB_SCHEMA
          value: public
        - name: DB_USER
          value: postgres
        - name: DB_VENDOR
          value: POSTGRES
        ports:
        - name: http
          containerPort: 8080
        - name: https
          containerPort: 8443
        readinessProbe:
          httpGet:
            path: /auth/realms/master
            port: 8080

Also the VMs are bridged, not on NAT.

What i am doing wrong here ?


Solution

  • The first thing we have to do is create the headless service with custom endpoint. The IP in my solution is only specific for my machine.

    Endpoint with service:

    apiVersion: v1
    kind: Service
    metadata:
      name: postgres-service
    spec:
      ports:
        - protocol: TCP
          port: 5432
          targetPort: 5432
    ---
    apiVersion: v1
    kind: Endpoints
    metadata:
      name: postgres-service
    subsets:
      - addresses:
          - ip: 192.168.2.105
        ports:
          - port: 5432
    

    As for my particular specs, I haven't defined any ingress or loadbalancer so i'll change the selector type from LoadBalancer to NodePort in the service after its deployed.

    Now i deployed the keycloak with the the mentioned .yaml file

    apiVersion: v1
    kind: Service
    metadata:
      name: keycloak
      labels:
        app: keycloak
    spec:
      ports:
        - name: http
          port: 8080
          targetPort: 8080
        - name: https
          port: 8443
          targetPort: 8443
      selector:
        app: keycloak
      type: NodePort
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: keycloak
      namespace: default
      labels:
        app: keycloak
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: keycloak
      template:
        metadata:
          labels:
            app: keycloak
        spec:
          containers:
            - name: keycloak
              image: quay.io/keycloak/keycloak:11.0.0
              env:
                - name: KEYCLOAK_USER
                  value: "admin" # TODO give username for master realm
                - name: KEYCLOAK_PASSWORD
                  value: "admin" # TODO give password for master realm
                - name: PROXY_ADDRESS_FORWARDING
                  value: "true"
                - name: DB_ADDR
                  value: # <Node-IP>:<LoadBalancer-Port/ NodePort>
                - name: DB_DATABASE
                  value: "keycloak" # Database to use
                - name: DB_PASSWORD
                  value: "admin" # Database password
                - name: DB_SCHEMA
                  value: public
                - name: DB_USER
                  value: "postgres" # Database user
                - name: DB_VENDOR
                  value: POSTGRES
              ports:
                - name: http
                  containerPort: 8080
                - name: https
                  containerPort: 8443
              readinessProbe:
                httpGet:
                  path: /auth/realms/master
                  port: 8080
    

    After mentioning all the possible values, it connects successfully to the postgres server that is hosted on another server away from kubernetes master and workers node !