I am having a K8s setup in AWS which is working fine but due to some requirement I need to enable websocket in one of my application.
I tried everything mentioned on #189
but I am still getting the error as he mentioned.
https://github.com/kubernetes-sigs/aws-alb-ingress-controller/issues/189#issuecomment-390313396
Also Aws-alb-ingress-controller creating 1 alb per ingress. Can we do something to fix this as this will increase the cost
@vrathore18 can you share your client/server setup? (i don't think you are using websocket but are using another websocket-like protocol like socket.io, socket.io != websocket)
For plain websocket, you don't need to do any thing special, e.g.
But, you need to make sure two things are configured properly:
/m00nf1sh if you are connecting with ws://<alb_dns>/m00nf1sh)alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=600).If you are using other protocols, you need to make sure the HTTP requests can be handled and are being handled by same server.
For socket.io, it initially doing client-side long polling to simulate websocket like behavior before try to upgrade to use an transport protocol like websocket.
GET /socket.io/?transport=polling&EIO=3&t=1575497560.840519 HTTP/1.1, so you need to ensure your Ingress handles such request path. (e.g. /socket.io/ instead of just /, wildcards like /* works fine too), Note: the path is configurable on your socket.io server/client, while defaults to 'socket.io'pingInterval). so that the heartbeats keeps theidle_timeout.timeout_seconds) and stickiness warm(stickiness.lb_cookie.duration_seconds).alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=60alb.ingress.kubernetes.io/target-type: ip to ensure the requests are been handled by same backend. (the default instance target-type won't work)@M00nF1sh : Thanks for helping.
I am using https://github.com/apollographql/subscriptions-transport-ws websocket for my application. So my current setup: aws-alb-ingress-controller + ingress. And for each ingress one alb is getting created(thats a different issue).
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ template "pd.frontend.fullname" . }}
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: {{ .Values.ingressScheme }}
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS": 443}]'
alb.ingress.kubernetes.io/certificate-arn: {{ .Values.external.acmCertificateARN }}
alb.ingress.kubernetes.io/inbound-cidrs: {{ .Values.ipWhiteList }}
spec:
rules:
- host: app.{{ .Values.domainName }}
http:
paths:
- path: /*
backend:
serviceName: {{ template "pd.frontend.fullname" . }}
servicePort: 80
Do I have to update the configuration on subscriptions-transport-ws as well to make it working?
@vrathore18
I'm haven't used this project,
would you help try below to check whether it works:
alb.ingress.kubernetes.io/target-type: ip to your Ingress30000 (30sec) to https://github.com/apollographql/subscriptions-transport-ws/blob/master/src/server.ts#L91@M00nF1sh : thanks I try that out. Also I don't need to enable stickiness?
@vrathore18 u need to enable stickness as well
Hey @M00nF1sh . I have tried everything you suggested but still websocket is not working. Below is how I am deploying the sample app. Could you please check.
use case: Prisma + Mysql and testing the alb for websockets.
Mysql-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: database
namespace: default
spec:
ports:
- port: 3306
targetPort: 3306
protocol: TCP
selector:
stage: production
name: database
app: mysql
mysql pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: database-disk
namespace: default
labels:
stage: production
name: database
app: mysql
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
mysql-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: database
namespace: default
labels:
stage: production
name: database
app: mysql
spec:
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
stage: production
name: database
app: mysql
spec:
containers:
- name: mysql
image: 'mysql:5.7'
args:
- --ignore-db-dir=lost+found
env:
- name: MYSQL_ROOT_PASSWORD
value: "prisma"
ports:
- name: mysql-3306
containerPort: 3306
volumeMounts:
- name: database-disk
readOnly: false
mountPath: /var/lib/mysql
volumes:
- name: database-disk
persistentVolumeClaim:
claimName: database-disk
prisma-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: prisma-configmap
namespace: default
labels:
stage: production
name: prisma
app: prisma
data:
PRISMA_CONFIG: |
port: 4466
# uncomment the next line and provide the env var PRISMA_MANAGEMENT_API_SECRET=my-secret to activate cluster security
# managementApiSecret: my-secret
databases:
default:
connector: mysql
host: database
port: 3306
user: root
password: prisma
migrations: true
prisma-deploy.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: prisma
namespace: default
labels:
stage: production
name: prisma
app: prisma
spec:
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
stage: production
name: prisma
app: prisma
spec:
containers:
- name: prisma
image: 'prismagraphql/prisma:1.34'
ports:
- name: prisma-4466
containerPort: 4466
env:
- name: PRISMA_CONFIG
valueFrom:
configMapKeyRef:
name: prisma-configmap
key: PRISMA_CONFIG
prisma-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: prisma
namespace: default
spec:
type: NodePort
ports:
- port: 4466
selector:
stage: production
name: prisma
app: prisma
And finally our ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: prisma
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS": 443}]'
alb.ingress.kubernetes.io/certificate-arn: {{ .Values.external.acmCertificateARN }}
alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=60
alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=600
alb.ingress.kubernetes.io/inbound-cidrs: <my ip address>/32
spec:
rules:
- host: pp.{{ .Values.domainName }}
http:
paths:
- path: /*
backend:
serviceName: prisma
servicePort: 4466
I tried locally. The app prisma+mysql is working fine but when I am creating the ingress. Target group and alb is getting created but not able to get the websocket work with alb.
@M00nF1sh : any update on this?
any update? same issue can't seem to make websocket work. It's like the connection and upgrade headers are removed somewhere in the process.
If you upvote the original post, it will help show your support for this to be looked into.
does anyone know how to make it work?
Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.
If this issue is safe to close now please do so with /close.
Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale
Stale issues rot after 30d of inactivity.
Mark the issue as fresh with /remove-lifecycle rotten.
Rotten issues close after an additional 30d of inactivity.
If this issue is safe to close now please do so with /close.
Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle rotten
I did everything suggested by @M00nF1sh on this comment and after that socket.io worked as intended, both long polling and sockets
happens to #metoo
Rotten issues close after 30d of inactivity.
Reopen the issue with /reopen.
Mark the issue as fresh with /remove-lifecycle rotten.
Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/close
@fejta-bot: Closing this issue.
In response to this:
Rotten issues close after 30d of inactivity.
Reopen the issue with/reopen.
Mark the issue as fresh with/remove-lifecycle rotten.Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/close
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.
I found this issue because I was looking for a way to change the timeout. The keyword I was looking for was keepalive_timeout, because both nginx and gke ingress refer to it with that name. Maybe you can add a comment to the documentation, that alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=X can be used to change the keepalive timeout?
Most helpful comment
@vrathore18 can you share your client/server setup? (i don't think you are using websocket but are using another websocket-like protocol like socket.io, socket.io != websocket)
For plain websocket, you don't need to do any thing special, e.g.
But, you need to make sure two things are configured properly:
/m00nf1shif you are connecting withws://<alb_dns>/m00nf1sh)alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=600).If you are using other protocols, you need to make sure the HTTP requests can be handled and are being handled by same server.
For socket.io, it initially doing client-side long polling to simulate websocket like behavior before try to upgrade to use an transport protocol like websocket.
GET /socket.io/?transport=polling&EIO=3&t=1575497560.840519 HTTP/1.1, so you need to ensure your Ingress handles such request path. (e.g./socket.io/instead of just/, wildcards like/*works fine too), Note: the path is configurable on your socket.io server/client, while defaults to 'socket.io'pingInterval). so that the heartbeats keeps theconnection(
idle_timeout.timeout_seconds) and stickiness warm(stickiness.lb_cookie.duration_seconds).alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=60alb.ingress.kubernetes.io/target-type: ipto ensure the requests are been handled by same backend. (the defaultinstancetarget-type won't work)