0
votes

I'm trying to configure my Kubernetes application so that my frontend application can speak to my backend, which is running on another deployment and is exposed via a ClusterIP service.

Currently, the frontend application is serving up some static content through Nginx. The configuration for that server is located inside a mounted configuration. I've got the / route serving up my static content to users, and I'd like to configure another route in the server block to point to my backend, at /api but I'm not sure how to direct that at the ClusterIP service for my other deployment.

The full frontend deployment file looks like this:

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-conf
data:
  nginx.conf: |

    ## To make changes to the configuration
    ## You use the kubectl rollout restart nginx command.

    events {}
    http {

      include /etc/nginx/mime.types;
      include /etc/nginx/conf.d/*.conf;
      include /etc/nginx/extra-conf.d/*.conf;

      server {

        listen 80;

        location / {
          root /usr/share/nginx/html;
          index index.html index.htm;
          try_files $uri $uri/ /index.html =404;
        }

        #location /api {
        ##
        ## Send traffic to my API, running on another Kubernetes deployment, here...
        ## }

        }
      }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: mydockerusername/ts-react
        imagePullPolicy: Always 
        ports:
          - containerPort: 80
        volumeMounts:
          - name: nginx-conf
            mountPath: /etc/nginx/nginx.conf
            subPath: nginx.conf
            readOnly: true
      volumes:
        - name: nginx-conf
          configMap:
            name: nginx-conf

My backend API is exposed via a ClusterIP Service on PORT 1234, and looks like this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: typeorm
spec:
  selector:
    matchLabels:
      app: typeorm # Find and manage all the apps with this label
  replicas: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:
    metadata:
      labels:
        app: typeorm # Create apps with this label
    spec:
      containers:
        - image: mydockerusername/typeorm
          imagePullPolicy: Always
          name: typeorm
          ports:
            - containerPort: 1234
          env:
            - name: ENV
              value: "production"
          envFrom:
            - secretRef:
                name: typeorm-config
--- 
apiVersion: v1
kind: Service
metadata:
  name: typeorm 
  labels:
    app: typeorm
spec:
  type: ClusterIP
  ports:
  - port: 1234
    targetPort: 1234
  selector:
    app: typeorm
1

1 Answers

3
votes

You can't expose your ClusterIP service through nginx config file here as ClusterIP service is only available inside kubernetes. You need an nginx ingress controller and ingress component to expose your ClusterIP service to outside world.

You can use ingress component to expose your ClusterIP service to /api path. Your ingress manifest file will look like below.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-ingress
spec:
  rules:
  - host: foo.bar.com #your server address here
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: typeorm
            port:
              number: 1234

Even you can use just one ingress component to expose your both frontend and backend. But for that you need another Service pointing to that frontend deployment.Then your manifest file you look like something like below:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-fanout-example
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: backend-service
            port:
              number: 1234