skupperproject / skupper-proxy

A service for bridging cluster-local communication to a Skupper network
https://skupper.io/
Apache License 2.0
8 stars 5 forks source link

Handling privileged ports #6

Closed langesven closed 4 years ago

langesven commented 4 years ago

I started playing around with skupper today and so far it's pretty nice. One thing I noticed where I run into problems is the following scenario

I have a service in one of my clusters that is running on port 80 and also exposing port 80

apiVersion: v1
kind: Service
metadata:
  annotations:
    internal.skupper.io/original-selector: app=test-backend,environment=platform,tier=backend
    skupper.io/proxy: http
  name: test-backend
  namespace: services
spec:
  clusterIP: 172.20.92.156
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    internal.skupper.io/service: test-backend
  type: ClusterIP

which in turn leads to skupper on a different site creating the respective service and proxy deployment

apiVersion: v1
kind: Service
metadata:
  annotations:
    internal.skupper.io/origin: UkucFoCdjw
    internal.skupper.io/original-selector: skupper.io/implements=test-backend
    skupper.io/proxy: http
  name: test-backend
  namespace: remote-services
spec:
  clusterIP: 10.111.181.240
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    internal.skupper.io/service: test-backend
  sessionAffinity: None
  type: ClusterIP

but since the pod runs as non-root but tries to bind port 80 this fails with

2020-02-19T14:38:04.273Z icproxy info GET /api/v1/namespaces/remote-services/pods?labelSelector=skupper.io%2Fimplements%3Dtest-backend
2020-02-19T14:38:04.448Z icproxy info Created HTTP to AMQP bridge 80 => test-backend
2020-02-19T14:38:04.559Z icproxy info listening for http on 80
events.js:167
      throw er; // Unhandled 'error' event
      ^

Error: listen EACCES 0.0.0.0:80
    at Server.setupListenHandle [as _listen2] (net.js:1269:19)
    at listenInCluster (net.js:1334:12)
    at doListen (net.js:1460:7)
    at process._tickCallback (internal/process/next_tick.js:63:19)
    at Function.Module.runMain (internal/modules/cjs/loader.js:744:11)
    at startup (internal/bootstrap/node.js:285:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:739:3)
Emitted 'error' event at:
    at emitErrorNT (net.js:1313:8)
    at process._tickCallback (internal/process/next_tick.js:63:19)
    [... lines matching original stack trace ...]
    at bootstrapNodeJSCore (internal/bootstrap/node.js:739:3)

If I modify the deployment to add runAsUser: 0 it works, but that's a manual process where I'm not even sure it will stick after some reconciler plows through everything.

One idea could be to not bind to privileged ports but rather pick a high port at random and just use port/targetPort on the service to expose the "real" port without having to run the proxy pod as root? Or does anyone have a better idea/maybe I missed some workaround that would allow for this out of the box?

grs commented 4 years ago

@langesven thanks for raising this and giving such a thorough analysis! I like the idea of using the targetPort to avoid having to have the proxy listen on a privileged port. I can't think of an out-of-the-box workaround at present, but will ensure this gets resolved soon.