I have a Meteor app deployed using Kubernetes on Google Cloud, configured with Nginx acting as SSL termination. Everything working ok.
However, it appears that if two different clients connect to two different SSL containers, updates don't show up on the respective apps for up to 10 seconds, which makes it seem that Websockets isn't working, but polling is taking effect. I have confirmed that all clients are connected with Websockets, but since updates do not propagate immediately, perhaps Nginx isn't configured to correctly talk with the Meteor app.
Here's my SSL/Nginx service:
apiVersion: v1 kind: Service metadata: name: frontend-ssl labels: name: frontend-ssl spec: ports: - name: http port: 80 targetPort: 80 - name: https port: 443 targetPort: 443 selector: name: frontend-ssl type: LoadBalancer loadBalancerIP: 123.456.123.456 sessionAffinity: ClientIP
And here is the Meteor service:
apiVersion: v1 kind: Service metadata: name: frontend labels: name: frontend spec: ports: - port: 3000 targetPort: 3000 selector: name: flow-frontend type: LoadBalancer loadBalancerIP: 123.456.123.456 sessionAffinity: ClientIP
For SSL termination, I'm using the Kubernetes suggested SSL setup forked with Websockets additions https://github.com/markoshust/nginx-ssl-proxy
The easiest way to run your app would be using Nginx based ingress controller instead of Nginx service.
In my opinion the easiest way to deploy ingress controller is with helm: https://docs.helm.sh/using_helm/#installing-helm https://kubeapps.com/charts/stable/nginx-ingress
But if you prefer not adding another tool to your stack you can use official installation guide: https://github.com/kubernetes/ingress-nginx/tree/master/deploy.
Example ingress object configuration with web sockets support can be found here: https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/websocket
In your NginX config, did you make sure to use the ip_hash
flag to direct websockets to the same server each time? also you need to make sure the websocket Upgrade headers are forwarded:
upstream meteorapp{
ip_hash;
server hostname:port
}
server {
# your server stuff here
#
location / {
proxy_pass http://meteorapp;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_redirect http:// $scheme://;
}
}