How to connect to an application, without exposing it to the world

Suppose I have an application installed with juju, and I do not want to expose it to the public Internet, but I do want to connect to it from my local machine, for testing/diagnostic purposes, what is the best way to do this?

As a real-world example of something I did recently, where this would apply:

A microservice uses CouchDB as a datastore, but CouchDB should not be exposed. During administrative or testing tasks, I could easily connect to CouchDB using kubectl port-forward, and then interact with its REST API.

Is there a simple way to do the same in juju?

I am running juju on Kubernetes, so I can use kubectl port-forward directly, but I feel like I shouldn’t need to do that.

Thanks

Hello @flimzy. Thank you for the question!

The upcoming release of Juju (2.9) takes a --to-cidrs and --to-spaces argument to the juju expose command, which might address the issue. Here’s a quick copy and paste from the help:

--to-cidrs (= "")
    A comma-delimited list of CIDRs that should be able to access the application ports once exposed
--to-spaces (= "")
    A comma-delimited list of spaces that should be able to access the application ports once exposed

You can try out the release candidate by bootstrapping a controller with the latest client snap:

sudo snap refresh juju --channel latest/candidate
juju bootstrap <cloud> <name for your test controller>
1 Like

If I’m understanding correcting, it looks like this can provide a partial work-around, but doesn’t seem like an ideal solution. In particular, in contrast to kubectl port-forward, this solution differs in that:

  1. It requires me to determine my public IP address, which generally not difficult, is an extra step.
  2. It’s not inherently temporary (kubectl port-foward, by default, stops working when you hit Ctrl-C, and dosn’t need to be otherwise undone)
  3. There are still some security implications, when connecting via NATS, for example. i.e. perhaps my entire office has access to that service now, not just my workstation. And in conjunction with #2, it’s worse if my public IP address changes, and I don’t notice, or worse, forget to ever clean up.

Further, I imagine it also only works for applications that are configured for external access (i.e. configured with an ingress, in kubernetes parlance). kubectl port-forward, in contrast, can work with any DNS-resolvable kubernetes hostname, so an individal pod, or a service.

So you can certainly do things like ssh port forwarding juju ssh unit/0 -L 8080:localhost:80, and while I believe we support SSH on K8s I’m not sure if port forwarding is enabled as part of that.

It would be reasonable to expose something like “juju port-forward” as a syntax for that sort of functionality on K8s. It would essentially just be doing what “kubectl port-forward” is doing, but not require you to have a separate tool and tracking of the cluster and applications that you are running. It also lets you discuss things in terms of Juju objects (port forward to this application rather than this k8s artifact).

The new ‘expose’ work is really about things that you want to have externally available over the long term. (eg, expose the internal website, but only to internal clients.)