简体   繁体   中英

SSL on node.js API running in StatefulSet on GKE

I have an app with the following structure:

  • An R Shiny app which functions as a UI and it lets the user upload files and stores them on a gcePersistentDisk.
  • A node.js server which reads those files on the gcePersistentDisk processes them and provides an API for the Shiny app to retrieve the results.

This runs in a GKE cluster with the following structure:

  • a StatefulSet with a pod containing two containers to allow simultaneous access for both the client and the server to the volume.
  • a headless service for the StatefulSet.
  • an Ingress with a fixed IP to where the domain points.
  • a NodePort as a backend for the Ingress with the selector pointing to the 0th pod of the StatefulSet

At least this is what I did to make this work, I'm not too good in DevOps or networking in general. Now the client came up with a request that a third party app would also use the node.js API but it wishes to do so on https.

My first try was to use greenlock-express.js, however, it needs a public facing IP, but the server can only see it's cluster IP. I don't know if this could/should be changed and if not what other approaches should I take?

Thanks!

YAML's

apiVersion: v1
kind: Service
metadata:
  name: plo-set-service
  labels:
    app: plo
spec:
  clusterIP: None
  selector:
    app: plo
  ports:
  - name: web
    port: 80
    protocol: TCP
    targetPort: ploweb-port
  - name: api
    port: 3300
    protocol: TCP
    targetPort: ploapi-port
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: plo-set
spec:
  serviceName: plo-set-service
  replicas: 1
  selector:
    matchLabels:
      app: plo
  template:
    metadata:
      labels:
        app: plo
    spec:
      containers:
      - name: plo-server
        image: 
        readinessProbe:
          httpGet:
            path: /healthz
            port: 3300
          initialDelaySeconds: 15
          periodSeconds: 15
        ports:
        - name: ploapi-port
          containerPort: 3300
        volumeMounts:
        - mountPath: /data
          name: plo-volume
      - name: plo-client
        image: 
        ports:
        - name: ploweb-port
          containerPort: 80
        volumeMounts:
        - mountPath: /data
          name: plo-volume
  volumeClaimTemplates:
  - metadata:
      name: plo-volume
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 500Gi
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: plo-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: plo-ip
spec:
  backend:
    serviceName: plo-web
    servicePort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: plo-web
spec:
  type: NodePort
  externalTrafficPolicy: Local
  selector:
    statefulset.kubernetes.io/pod-name: plo-set-0
  ports:
  - name: web
    port: 80
    protocol: TCP
    targetPort: 80

By default Nginx Ingress Controller serves on port "HTTP/80" and "HTTPS/443" regardless backend protocol and port.

So in your case, you don't have to change anything to use HTTPS protocol for your backend, if you just use Nginx Ingress Controller out of the box

For example I have Ingress Controller service as below serving on port 80 and 443 which created when deployed Nginx Controller

$ kubectl get svc nginx-ingress-controller
NAME                       TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)                      AGE
nginx-ingress-controller   LoadBalancer   10.15.254.182   <external-ip-addr>   80:32594/TCP,443:31949/TCP   2d

Also I have service for my-nginx deployment listening on port 80

$ kubectl get svc my-nginx
NAME       TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
my-nginx   ClusterIP   10.15.252.11   <none>        80/TCP    30m

And I have deployed simple ingress resource similar to yours

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-nginx-ingress
spec:
  backend:
    serviceName: my-nginx
    servicePort: 80

Now you can call your service via HTTP or HTTPS by requesting to Nginx Controller LoadBalancer IP from outside of cluster, or DNS/ClusterIP within cluster.

HTTP request within cluster from other pod:

# curl -I http://nginx-ingress-controller
HTTP/1.1 200 OK
Server: nginx/1.15.9
...

HTTPS request:

# curl -Ik https://nginx-ingress-controller
HTTP/2 200 
server: nginx/1.15.9
...

Hope it could help you

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM