Error in implementing WebSocket in Kubernetes - kubernetes

We are trying to implement WebSocket in Kubernetes by following steps given in GCP document "https://cloud.google.com/kubernetes-engine/docs/concepts/ingress#support_for_websocket" & "https://cloud.google.com/kubernetes-engine/docs/how-to/configure-backend-service" . but we are getting "Error during WebSocket handshake: Unexpected response code: 502”.
Error Message : “WebSocket connection to 'wss://..../backend-channeladaptor-web/socket.io/?EIO=3&transport=websocket' failed: Error during WebSocket handshake: Unexpected response code: 502”.
I have also attached Files created for gke implementation:
Backend-channeladaptor-web.yaml
Deployment content
Service content
Backendconfig content
Converse-ingress.yaml (It has details of other services as well you can ignore that except backend-channeladaptor-web).
Converse-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: converse-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: $Static-Ip-Name
kubernetes.io/ingress.allow-http: "false"
spec:
tls:
- secretName: $SSL-certificate
rules:
- host: $HostName
http:
paths:
- path: /*
backend:
serviceName: frontend-chat-client
servicePort: 3040
- path: /socket-io/*
backend:
serviceName: backend-channeladaptor-engineerportal
servicePort: 11009
- path: /login/*
backend:
serviceName: frontend-engineeringportal
servicePort: 3021
- path: /frontend-engineeringportal/*
backend:
serviceName: frontend-engineeringportal
servicePort: 3021
- path: /backend-channeladaptor-web/*
backend:
serviceName: backend-channeladaptor-web
servicePort: 11006
Backend-channeladaptor-web.yaml
apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
name: backend-channeladaptor-web-backendconfig
spec:
timeoutSec: 3600
connectionDraining:
drainingTimeoutSec: 3600
---
apiVersion: v1
kind: Service
metadata:
name: backend-channeladaptor-web
annotations:
beta.cloud.google.com/backend-config: '{"ports": {"8081":"backend-channeladaptor-web-backendconfig"}}'
spec:
type: NodePort
ports:
- port: 8081
targetPort: 11006
protocol: TCP
nodePort: 30078
name: http
selector:
app: backend-channeladaptor-web
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: backend-channeladaptor-web
spec:
selector:
matchLabels:
app: backend-channeladaptor-web
replicas: 1
template:
metadata:
labels:
app: backend-channeladaptor-web
spec:
containers:
- image: gcr.io/acn-careful-granite-240620/backend-channeladaptor-web:0.2
name: backend-channeladaptor-web
ports:
- name: http
containerPort: 11006
hostPort: 11006
env:
- name: NODE_ENV
value: dev
I expect the response status code 101 but getting 502 Bad Gateway

It looks like your ingress has the URI /backend-channeladaptor-web/* pointed to the Service backend-channeladaptor-web and is expecting the Service to be listening in 11006. However, the NodePort configuration is listening in 8081.
The confusion might come from the targetPort directive, pointing to 11006 in the actual backend (the Deployment).
This is causing 502's, meaning that althought you're reaching an intermediary (the load balancer in your case), it is unable to reach the backend (the Deployment, served by the NodePort Service).
You can change the ingress definition to point to 8081 instead, matching the current NodePort configuration.

Related

Kubernetes nginx-ingress controller always 401 http response

I'm researching kubernetes and trying to configure nginx-ingress controller. So I created yaml config file for it, like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-srv
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: 'true'
spec:
rules:
- host: acme.com
http:
paths:
- path: /api/platforms
pathType: Prefix
backend:
service:
name: platforms-clusterip-service
port:
number: 80
- path: /api/c/platforms
pathType: Prefix
backend:
service:
name: command-clusterip-service
port:
number: 80
And created relevant services like this:
apiVersion: apps/v1
kind: Deployment
metadata:
name: platforms-depl
spec:
replicas: 1
selector:
matchLabels:
app: platformservice
template:
metadata:
labels:
app: platformservice
spec:
containers:
- name: platformservice
image: yuriyborovskyi91/platformsservice:latest
---
apiVersion: v1
kind: Service
metadata:
name: platforms-clusterip-service
spec:
type: ClusterIP
selector:
app: platformservice
ports:
- name: platformservice
protocol: TCP
port: 80
targetPort: 80
And added acme.com to windows hosts file, like:
127.0.0.1 acme.com
But when trying to access http://acme.com/api/platforms or any other api route, I'm receiving 401 http error, and confused by it, because I didn't configure any authorization. Using all default settings. If to call my service by nodeport everything works fine.
Output of my kubectl get services, where service I'm trying to access running:
and response of kubectl get services --namespace=ingress-nginx

Azure Kubernetes Nginx Ingress: How do I properly route to an API service and an Nginx web server with HTTPS and avoid 502?

I have 2 services, one serves up a rest API and the other serves up static content via nginx web server.
I can retrieve the static content from the pod running an nginx web server via the ingress controller using https provided that I don't use the following annotation within the ingress yaml
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
However, the backend API service no longer works. If I add that annotation back, the backend service URL https://fqdn/restservices/engine-rest/v1/api works but the front end https://fqdn/ web server throws a 502.
Ingress
Ingress
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: ingress
namespace: namespace-abc
annotations:
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
spec:
rules:
- http:
paths:
- path: /restservices/engine-rest/v1
backend:
serviceName: a
servicePort: 8080
- path: /
backend:
serviceName: b
servicePort: 8011
Service API
kind: Service
apiVersion: v1
metadata:
name: a
namespace: namespace-abc
labels:
app: a
version: 1
spec:
ports:
- name: https
protocol: TCP
port: 80
targetPort: 8080
nodePort: 31019
selector:
app: a
version: 1
clusterIP: <cluster ip>
type: LoadBalancer
sessionAffinity: ClientIP
externalTrafficPolicy: Cluster
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
Service UI
kind: Service
apiVersion: v1
metadata:
name: b
namespace: namespace-abc
labels:
app: b
version: 1
annotations:
spec:
ports:
- name: http
protocol: TCP
port: 8011
targetPort: 8011
nodePort: 32620
selector:
app: b
version: 1
clusterIP: <cluster ip>
type: LoadBalancer
sessionAffinity: None
externalTrafficPolicy: Cluster
If your problem is that adding nginx.ingress.kubernetes.io/backend-protocol: HTTPS makes service-A work but fails service-B, and removing it makes service-A fail but works for service-B, then the solution is to create two different Ingress objects so they can be annotated independently
---
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: ingress-a
namespace: namespace-abc
annotations:
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
spec:
rules:
- http:
paths:
- path: /restservices/engine-rest/v1
backend:
serviceName: a
servicePort: 8080
---
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: ingress-b
namespace: namespace-abc
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: b
servicePort: 8011

Kubernetes Nginx Ingress phpmyadmin 502 error

I am trying to solve quite an annoying problem I encounter when using Kubernetes. When I am trying to reach PHPMyAdmin on my server, it returns an Nginx 502 Bad Gateway error.
My structure in my cluster is as follows. I use an Nginx ingress LoadBalancer on DigitalOcean to get traffic into my cluster. It then passes my ingress (in the first code block), which splits the traffic across the subdomains.
When traffic goes to the phpmyadmin subdomain, the request is passed to the 'phpmyadmin-service' with service port 8085.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
kubernetes.io/ingress.class: nginx
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: "app1.example.com"
http:
paths:
- path: /
backend:
serviceName: app1-service
servicePort: 80
- host: "phpmyadmin.example.com"
http:
paths:
- path: /
backend:
serviceName: phpmyadmin-service
servicePort: 8085
Then, the service receives the request, and passes it to the 'phpmyadmin-deployment' deployment. This is a deployment that runs the phpmyadmin/phpmyadmin:fpm docker image.
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
name: phpmyadmin-deployment
labels:
app: phpmyadmin
spec:
selector:
matchLabels:
app: phpmyadmin
template:
metadata:
creationTimestamp: null
labels:
app: phpmyadmin
spec:
containers:
- name: phpmyadmin
image: phpmyadmin/phpmyadmin:fpm
ports:
- containerPort: 8087
env:
- name: PMA_ABSOLUTE_URI
value: 'phpmyadmin.example.com'
- name: PMA_HOST
value: mysql
- name: PMA_PORT
value: "3306"
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secrets
key: rootpw
---
apiVersion: v1
kind: Service
metadata:
name: phpmyadmin-service
spec:
type: ClusterIP
selector:
app: phpmyadmin
ports:
- port: 8085
targetPort: 8087
So something is giving me the 502 Bad Gateway error, and I don't know what it is. Thanks in advance for replying!

Nginx ingress - (Connection refused) while connecting to upstream

I'm trying to expose my deployment on my Kubernetes cluster using a service and a Nginx ingress. I currently have following configuration.
apiVersion: apps/v1
kind: Deployment
metadata:
name: mira-api-deployment
spec:
replicas: 1
selector:
matchLabels:
app: mira-api
template:
metadata:
labels:
app: mira-api
spec:
containers:
- name: backend
image: registry.gitlab.com/izit/mira-backend
ports:
- containerPort: 8080
name: http
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: mira-api-service
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
app: mira-api
type: NodePort
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: mira-api-ingress
spec:
tls:
- hosts:
- kubernetes.mira-appservice.be
secretName: mirasecret
rules:
- host: kubernetes.mira-appservice.be
http:
paths:
- backend:
serviceName: mira-api-service
servicePort: 8080
This configuration makes my deployment publically available over HTTPS with the correct certificate etc.
The only problem is that I receive a HTTP 502 error message when making a request.
When I check the logs of the ingress is see following error message:
When I describe the ingress I get the following information:
Is the configuration of my service correct? Or is there something else missing in the configuration?
UPDATE
Output for service:

default backend - 404 returned from nginx-controller when dns is used

a bit of background is that I have setup an Azure Kubernetes Service cluster and deployed a basic .Net Core api as a deployment object. I then deployed a nodeport service to expose the api and then deployed a nginx-controller and an ingress object to configure it. I use the IP of the ingress-controller to route the request and that works eg.http://1.2.3.4/hello-world-one/api/values.
But when I replace the Ip with the generated dns, somehow the path is ignored and I get the default backend - 404 returned from the nginx controller. The expected behaviour is that the dns will resolve then the path "api/values" will be sent to my service.
Can anyone help me with this?
Thanks in advance.
My deployment, service and ingress configs are below.
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: test-deployment
labels:
app: test
spec:
replicas: 1
selector:
matchLabels:
app: test
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: test
spec:
containers:
- name: test-service
image: <my-repo>.azurecr.io/testservice
imagePullPolicy: Always
ports:
- name: tcp
containerPort: 80
imagePullSecrets:
- name: regsecret
---
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
type: NodePort
selector:
app: test
ports:
- name: http
port: 32768
targetPort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: hello-world-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.global-static-ip-name: dev-pip-usw-qa-aks
kubernetes.io/ingress.class: addon-http-application-routing
spec:
rules:
- host: hello-world-ingress.be543d4af69d4c7ca489.westus.aksapp.io
- http:
paths:
- path: /
backend:
serviceName: frontend
servicePort: http
- path: /hello-world-one
backend:
serviceName: frontend
servicePort: http
- path: /hello-world-two
backend:
serviceName: frontend
servicePort: http
pretty sure rules should look like this:
rules:
- host: hello-world-ingress.be543d4af69d4c7ca489.westus.aksapp.io
http:
paths:
- path: /
backend:
serviceName: frontend
servicePort: http
- path: /hello-world-one
backend:
serviceName: frontend
servicePort: http
- path: /hello-world-two
backend:
serviceName: frontend
servicePort: http
reading: https://kubernetes.io/docs/concepts/services-networking/ingress/#types-of-ingress