Problem with NGINX, Kubernetes and CloudFlare - nginx

I am experiencing exactly this issue: Nginx-ingress-controller fails to start after AKS upgrade to v1.22, with the exception that none of the proposed solutions is working for my case.
I am running a Kubernetes Cluster on Oracle Cloud and I accidentally upgraded the cluster and now I cannot connect anymore to the services through nginx-controller. After reading the official nginx documentation, I am aware of the new version of nginx, so I checked the documentation and re-installed the nginx-controller following Oracle Cloud official documentation.
I am able to perform step by step as I run:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.44.0/deploy/static/provider/cloud/deploy.yaml
And then an ingress-nginx namespace is created and a LoadBalancer is created. Then as in the guide I have created a simple hello application (though not running on port 80):
apiVersion: apps/v1
kind: Deployment
metadata:
name: docker-hello-world
labels:
app: docker-hello-world
spec:
selector:
matchLabels:
app: docker-hello-world
replicas: 1
template:
metadata:
labels:
app: docker-hello-world
spec:
containers:
- name: docker-hello-world
image: scottsbaldwin/docker-hello-world:latest
ports:
- containerPort: 8088
---
apiVersion: v1
kind: Service
metadata:
name: docker-hello-world-svc
spec:
selector:
app: docker-hello-world
ports:
- port: 8088
targetPort: 8088
type: ClusterIP
and then the ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-world-ing
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- secretName: tls-secret
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: docker-hello-world-svc
port:
number: 8088
But when running the curl commands I only get a curl: (56) Recv failure: Connection reset by peer.
So I then tried to connect to some python microservices that are already running by simply editing the ingress, but whatever I do I get the same error message. And when setting the host as the following:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-world-ing
namespace: ingress-nginx
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: SUBDOMAIN.DOMAIN.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ANY_MICROSERVICE_RUNNING_IN_CLUSTER
port:
number: EXPOSED_PORT_BY_MICROSERVICE
Then, by setting the subdomain on CloudFlare I only get a 520 Bad Gateway.
Can you help me find what is that I do not see?

This may be related to your Ingress resource.
In Kubernetes versions v1.19 and above, Ingress resources should use ingressClassName instead of the older annotation syntax. Additional information on what should be done when upgrading can be found on the official Kubernetes documentation.
However, with the changes it requires at face value, from the information you're provided so far, your Ingress resource should look this:
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-world-ing
spec:
ingressClassName: nginx
rules:
- host: SUBDOMAIN.DOMAIN.com
http:
paths:
- backend:
service:
name: docker-hello-world-svc
port:
number: 8088
path: /
pathType: Prefix
tls:
- hosts:
- SUBDOMAIN.DOMAIN.com
secretName: tls-secret
Additionally, please provide the deployment Nginx-ingress logs if you still have issues, as the Cloudflare error does not detail what could be wrong apart from providing a starting point.
As someone who uses Cloudflare and Nginx, there are multiple reasons why you're receiving a 520 error, so it'd be better if we could reduce the scope of what could be the main issue. Let me know if you have any questions.

Related

Intermittent 502 errors on local nginx-ingress router in microk8s cluster

I'm new to Kubernetes and am experiencing a weird issue with my nginx-ingress router. My cluster is run locally on a raspberry pi using Microk8s, where I have 4 different deployments. The cluster uses an ingress router to route packets for the UI and API.
In short, my issue is that I receive intermittent 502 errors on calls from the UI to the backend. Intermittent meaning that for every 3 successful POSTs, there are 3 unsuccessful 502 requests (regardless of how quickly these requests are called). E.g.,
I've applied the following Ingress configuration to my cluster:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-router
annotations:
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ui
port:
number: 80
- http:
paths:
- path: /lighting/.*
pathType: Prefix
backend:
service:
name: api
port:
number: 8000
And the deployments for UI and API are as follow:
UI:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ui
spec:
selector:
matchLabels:
app: iot-control-center
replicas: 3
template:
metadata:
labels:
app: iot-control-center
spec:
containers:
- name: ui-container
image: canadrian72/iot-control-center:ui
imagePullPolicy: Always
ports:
- containerPort: 80
API:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
selector:
matchLabels:
app: iot-control-center
replicas: 3
template:
metadata:
labels:
app: iot-control-center
spec:
containers:
- name: api-container
image: canadrian72/iot-control-center:api
imagePullPolicy: Always
ports:
- containerPort: 8000
- containerPort: 1883
After looking around online, I found this Reddit post which most closely resembles my issue, although I'm not too sure where to go from here. I have a feeling it's a load issue for either the pods or the ingress controller, so I tried adding 3 replicas to each pod (it was 1 before), but this only decreased the frequency of 502 errors.
Edit
It’s not necessarily 1 to one for 200 and 502 responses, it’s fairly random but about an even distribution of 502 and 200 responses. Also to add that I had configured this same setup with LoadBalancer (metallb) and everything worked like a charm, except for CORS. Which is why I went for Ingress to deal with CORS.
Leaving this up if anyone has a similar issue. My issue was that in the ingress configuration, the backend services referenced the deployments themselves instead of a nodeport/clusterIP service.
I instead created two cluster IP services for the UI and API, like follows:
UI
apiVersion: v1
kind: Service
metadata:
name: ui-cluster-ip
spec:
type: ClusterIP
selector:
app: iot-control-center
svc: ui
ports:
- port: 80
API
apiVersion: v1
kind: Service
metadata:
name: lighting-api-cluster-ip
spec:
type: ClusterIP
selector:
app: iot-control-center
svc: lighting-api
ports:
- port: 8000
And then referenced these services from the ingress yaml as follows:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-router
annotations:
kubernetes.io/ingress.class: public
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "Access-Control-Allow-Origin: $http_origin";
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: PUT, GET, POST,
OPTIONS, DELETE, PATCH
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ui-cluster-ip
port:
number: 80
- http:
paths:
- path: /lighting/.*
pathType: Prefix
backend:
service:
name: lighting-api-cluster-ip
port:
number: 8000
I'm not sure why the previous configuration posted resulted in some 503 responses and some 200 (in my mind it should've all been 503), but in any case this solution works.

Minikube Ingress Does not resolve but minikube IP does

I am running a simple pod with an image from local image registry in a minikube cluster on Windows 10. I am also running a simple nodeport service. The container is available when I try accessing it from the browser with <minikube_ip>:30080.
However, now I want to set an ingress controller because I want to set up a domain and not access it using the IP. The ingress works for something simple like a basic nginx pod, but does not work for this pod that I'm trying to use. I was previously using jwilder/nginx-proxy in docker-compose and it had some conf files that needed to be attached in the conf.d directory. However, since I am moving to Kubernetes, I thought to totally omit the conf files and the reverse proxy image.
Now after the hosts fie is updated, the domain is reachable via curl, the domain is also pingable, however, it simply cannot be reached on the browser.
pod-yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
io.kompose.service: api
name: api
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: api
strategy:
type: RollingUpdate
template:
metadata:
labels:
io.kompose.service: api
spec:
containers:
- env:
- name: DEV_PORT
value: "80"
image: localhost:5000/api:2.3
imagePullPolicy: "IfNotPresent"
name: api
resources: {}
restartPolicy: Always
serviceAccountName: ""
status: {}
Service.yaml
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: C:\Users\***kompose.exe
convert
kompose.version: 1.21.0 (992df58d8)
creationTimestamp: null
labels:
io.kompose.service: api
name: api
spec:
selector:
io.kompose.service: api
type: NodePort
ports:
- name: "http"
port: 80
targetPort: 80
nodePort: 30080
Ingress.yaml
apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use extensions/v1beta1
kind: Ingress
metadata:
name: tls-ingress
spec:
tls:
- secretName: oaky-tls
hosts:
- api.localhost
rules:
- host: api.localhost
http:
paths:
- path: /
backend:
serviceName: api
servicePort: 80
I have checked and the TLS secret is available, I am not understanding the issue here and would really appreciate some help.
Solved:
Chrome was overlooking the etc hosts file, so I did the following:
Switched to Firefox and instantly the URLs were working.
Added annotations to denote the class:
kubernetes.io/ingress.class: nginx
Added annotations to make sure requests are redirected to ssl
nginx.ingress.kubernetes.io/ssl-redirect: "true"

Send messages to RabbitMQ from outside kubernetes cluster using nginx-ingress

I am trying to setup a RabbitMQ tasks queue in a kubernetes cluster and need to be able to populate the task queue from outside of the kubernetes cluster. I am trying to accomplish this using the nginx ingress controller. I am running into errors when trying to declare a queue or send messages to an existing queue from outside of the cluster. Using the amqp-tools cli in Ubuntu from outside the cluster I get an error:
$ export BROKER_URL=amqp://<host-name>:80/rabbitmq
$ /usr/bin/amqp-declare-queue --url=$BROKER_URL -q foo -d
logging in to AMQP server: invalid AMQP data
If I do this same thing from a VM inside the cluster, I can create and send message to the queue just fine. I am also able to connect to the RabbitMQ management UI from outside of the cluster but if I try to declare a queue from the UI I get the error Management API returned status code 405 - displayed at the bottom of the screen.
I was reading that the virtual host in RabbitMQ '/' has problems with nginx because of how it parses the host but I am not very experienced with this sort of thing and dont know how to fix that.
Any help with this would be greatly appreciated.
I am deploying the nginx ingress controller with the recommended manifest:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
RabbitMQ is deployed with this manifest:
---
apiVersion: v1
kind: Namespace
metadata:
name: rabbitmq
labels:
app: rabbitmq
---
apiVersion: v1
kind: Service
metadata:
name: rabbitmq-service
namespace: rabbitmq
labels:
component: rabbitmq
spec:
type: ClusterIP
ports:
- name: amqp
port: 5672
targetPort: 5672
protocol: TCP
- name: http
port: 80
targetPort: 15672
protocol: TCP
selector:
app: taskQueue
component: rabbitmq
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: rabbit-ingress
namespace: rabbitmq
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host: <host-name>
http:
paths:
- path: /rabbitmq/?(.*)
backend:
serviceName: rabbitmq-service
servicePort: 5672
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: rabbit-manage-ingress
namespace: rabbitmq
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host: <host-name>
http:
paths:
- path: /rabbitmq-manage/?(.*)
backend:
serviceName: rabbitmq-service
servicePort: 80
---
apiVersion: v1
kind: ReplicationController
metadata:
labels:
app: taskQueue
component: rabbitmq
name: rabbitmq-controller
namespace: rabbitmq
spec:
replicas: 1
template:
metadata:
labels:
app: taskQueue
component: rabbitmq
spec:
containers:
- image: rabbitmq:3-management
name: rabbitmq
ports:
- containerPort: 5672
- containerPort: 15672
resources:
limits:
cpu: 100m
As far as i know, RabbitMQ does not provide a HTTP-API for interacting (at least it's not the default). NGINX-Ingress cannot use an Ingress resource to expose anything different to a HTTP-Service. Take a look at the documentation to learn how to expose a TCP- or UDP-Based service.

K8S baremetal nginx ingress controller not works

I encountered a problem when integrating K8S nginx ingress. I installed the nginx ingress controller and established the testing ingress resources according to the instructions on the document, but I was not able to jump to the normal path. The test serive was normal and Accessible via cluster IP. Am I missing something?
Install script
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
Bare-metal Using NodePort
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/service-nodeport.yaml
Ingress controller is OK
Testing ingress resource
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
app: my-nginx
template:
metadata:
labels:
app: my-nginx
spec:
containers:
- name: my-nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
app: my-nginx
spec:
ports:
- port: 80
protocol: TCP
name: http
selector:
app: my-nginx
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-nginx
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: nginx1.beencoding.com
http:
paths:
- path: /
backend:
serviceName: nginx-1
servicePort: 80
We can see the test nginx pod raised and works fine, I can access the nginx index page by cluster IP
But I can't access nginx1.beencoding.com
Can't access via browser
I have solved the problem by setting hostnetwork: true
It says can't resolve.
Either put the domain in /etc/hosts/ file, or do the curl as follows:
curl -H "Host: nginx1.beecoding.com" IP_ADDRESS
Should work.

Kubernetes nginx ingress is not resolving services

Cloud: Google Cloud Platform.
I have the following configuration
kind: Deployment
apiVersion: apps/v1
metadata:
name: api
spec:
replicas: 2
selector:
matchLabels:
run: api
template:
metadata:
labels:
run: api
spec:
containers:
- name: api
image: gcr.io/*************/api
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /_ah/health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
---
kind: Service
apiVersion: v1
metadata:
name: api
spec:
selector:
run: api
type: NodePort
ports:
- protocol: TCP
port: 8080
targetPort: 8080
---
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: main-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- http:
paths:
- path: /api/*
backend:
serviceName: api
servicePort: 8080
All set. GKE saying that all deployments are okay, pods number are met and main ingress with nginx-ingress-controllers are set as well. But I'm not able to reach any of the services. Even application specific 404. Nothing. Like, it's not resolved at all.
Another related question I see to entrypoints. The first one through main-ingress. It created it's own LoadBalancer with own IP address. The second one address from nginx-ingress-controller. The second one is at least returning 404 from default backend, but also not pointing to expected api service.

Resources