Search code examples
kuberneteskubernetes-ingresstraefik-ingressk3sk3d

Bad Gateway in Rails app with Kubernetes setup


I try to setup a Rails app within a Kubernetes Cluster (which is created with k3d on my local machine.

k3d cluster create --api-port 6550 -p "8081:80@loadbalancer" --agents 2

kubectl create deployment nginx --image=nginx

kubectl create service clusterip nginx --tcp=80:80

# apiVersion: networking.k8s.io/v1beta1 # for k3s < v1.19
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx
  annotations:
    ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx
            port:
              number: 80

I can get an Ingress running which correctly exposes a running Nginx Deployment ("Welcome to nginx!") (I took this example from here: https://k3d.io/usage/guides/exposing_services/

So I know my setup is working (with nginx).

Now, I simpy wanna point that ingress to my Rails app, but I always get an "Bad Gateway". (I also tried to point to my other services (elasticsearch, kibana, pgadminer) but I always get a "Bad gateway".

I can see my Rails app running at (http://localhost:62333/) last lines of my Dockerfile:

EXPOSE 3001:3001
CMD rm -f tmp/pids/server.pid && bundle exec rails s -b 0.0.0.0 -p 3001

Why is my API has the "bad gateway" but Nginx not?

Does it have something to do with my selectors and labels which are created by kompose convert?

This is my complete Rails-API Deployment:

kubectl apply -f api-deployment.yml -f api.service.yml -f ingress.yml

api-deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    kompose.cmd: kompose convert -c --file metashop-backend/docker-compose.yml --file metashop-backend/docker-compose.override.yml
    kompose.version: 1.22.0 (HEAD)
  creationTimestamp: null
  labels:
    io.kompose.service: api
  name: api
spec:
  replicas: 1
  selector:
    matchLabels:
      io.kompose.service: api
  strategy:
    type: Recreate
  template:
    metadata:
      annotations:
        kompose.cmd: kompose convert -c --file metashop-backend/docker-compose.yml --file metashop-backend/docker-compose.override.yml
        kompose.version: 1.22.0 (HEAD)
      creationTimestamp: null
      labels:
        io.kompose.network/metashop-net: 'true'
        io.kompose.service: api
    spec:
      containers:
        - env:
            - name: APPLICATION_URL
              valueFrom:
                configMapKeyRef:
                  key: APPLICATION_URL
                  name: env
            - name: DEBUG
              value: 'true'
            - name: ELASTICSEARCH_URL
              valueFrom:
                configMapKeyRef:
                  key: ELASTICSEARCH_URL
                  name: env
          image: metashop-backend-api:DockerfileJeanKlaas
          name: api
          ports:
            - containerPort: 3001
          resources: {}
      #     volumeMounts:
      #       - mountPath: /usr/src/app
      #         name: api-claim0
      # restartPolicy: Always
      # volumes:
      #   - name: api-claim0
      #     persistentVolumeClaim:
      #       claimName: api-claim0
status: {}

api-service.yml

apiVersion: v1
kind: Service
metadata:
  annotations:
    kompose.cmd: kompose convert -c --file metashop-backend/docker-compose.yml --file metashop-backend/docker-compose.override.yml
    kompose.version: 1.22.0 (HEAD)
  creationTimestamp: null
  labels:
    app: api
    io.kompose.service: api
  name: api
spec:
  type: ClusterIP
  ports:
    - name: '3001'
      protocol: TCP
      port: 3001
      targetPort: 3001
  selector:
    io.kompose.service: api
status:
  loadBalancer: {}

ingress.yml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api
  annotations:
    ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api
            port:
              number: 3001

configmap.yml

apiVersion: v1
data:
  APPLICATION_URL: localhost:3001
  ELASTICSEARCH_URL: elasticsearch
  RAILS_ENV: development
  RAILS_MAX_THREADS: '5'
kind: ConfigMap
metadata:
  creationTimestamp: null
  labels:
    io.kompose.service: api-env
  name: env

I hope I didn't miss anything.

thank you in advance

EDIT: added endpoint, requested in comment:

kind: endpoint

kind: Endpoints
apiVersion: v1
metadata:
  name: api
  namespace: default
  labels:
    app: api
    io.kompose.service: api
  selfLink: /api/v1/namespaces/default/endpoints/api
subsets:
  - addresses:
      - ip: 10.42.1.105
        nodeName: k3d-metashop-cluster-server-0
        targetRef:
          kind: Pod
          namespace: default
          apiVersion: v1
    ports:
      - name: '3001'
        port: 3001
        protocol: TCP


Solution

  • The problem was within the Dockerfile:

    I had not defined ENV RAILS_LOG_TO_STDOUT true, so I was not able to see any errors in the pod logs.

    After I added ENV RAILS_LOG_TO_STDOUT true I saw errors like database xxxx does not exist