-
Notifications
You must be signed in to change notification settings - Fork 0
Exposing a local service on the apx.develop.eoepca.org ingress
When quickly prototyping or debugging a service intended to run behind an ingress, such as the APISIX ingress on the EOEPCA development cluster, it can be helpful to expose a server running on a local development machine. This allows a local process to receive and respond to real HTTP requests as actually generated by the ingress.
The method outlined here requires no special software on the local development machine, beyond a standard SSH client. In particular, it does not require anything like remote devcontainers.
Once set up, it makes it possible to have a local process such as, say, a python/uvicorn web server listening on port 8080 on your laptop respond to requests made to https://<BB>.apx.develop.eoepca.org/somepathname
from any system.
SECURITY NOTE: (!!!) You are exposing a local process (on your laptop) on a public endpoint https://<BB>.apx.develop.eoepca.org/
, so BEWARE (e.g. don't run highly unsafe code with high privileges and kill the tunnel when you are not using it)!
The idea is to do the following:
- Run a single
Pod
exposing a port (e.g. 8080), running only a, properly configured, OpenSSH server (listening on another port), - set up a
Service
for the abovePod
, and - set up an ingress route exposing the
Service
ashttps://<BB>.apx.develop.eoepca.org/tmpservice
.
With the above done, https://<BB>.apx.develop.eoepca.org/tmpservice
will now forward to the Pod
on the configured port, where currently nothing is running.
The final step is then to expose a local process, such as our Python/uvicorn server, on the Pod
using a reverse SSH tunnel. This will tunnel any requests to the Pod
port, through the SSH connection, and to our local process.
Modify and apply (e.g. kubectl ... apply -f pod.yaml
) the following Pod
resource where indicated
pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: tmpservice-pod
## NOTE: Make sure to put in the appropriate namespace
namespace: resource-health
## NOTE: You can use whatever labels to identify the pod
labels:
app.kubernetes.io/component: "tmpservice"
spec:
containers:
- name: tmpservice-pod-dev
image: "linuxserver/openssh-server"
ports:
- name: http
containerPort: 8080 ## CHANGE ME IF YOU WANT
protocol: TCP
- name: ssh
containerPort: 2222
protocol: TCP
env:
- name: PUBLIC_KEY
## NOTE: CHANGE ME TO YOUR SSH PUBLIC KEY!
value: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDjEj4U8/kIQ0w9VrekbPqjO4esbRTBYSvW8U2TrYYRG tilo.wiklund@sensmetry.com"
- name: SUDO_ACCESS
value: "true"
## NOTE: CHANGE ME TO WHATEVER USERNAME YOU WANT
- name: USER_NAME
value: tilo
- name: DOCKER_MODS
value: linuxserver/mods:openssh-server-ssh-tunnel
This creates a pod with a single user (specified by USER_NAME
) that can be accessed through ssh using the private key corresponding to the configured PUBLIC_KEY
. See for example here if you need help generating an ssh key.
Create a service for the pod, for example
apiVersion: v1
kind: Service
metadata:
## NOTE: CHANGE ME!
name: resource-health-tmpservice-service
namespace: resource-health
labels:
app.kubernetes.io/component: "tmpservice"
spec:
type: ClusterIP
ports:
- port: 8080
targetPort: 8080
protocol: TCP
name: http
## NOTE: Make sure this matches the labels set in the pod metadata
selector:
app.kubernetes.io/component: "tmpservice"
Then expose this service on the ingress, along the lines of (see here if you have not set up an APISIX route yet):
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
...
spec:
http:
...
...
- name: resource-health-tmpservice-route
match:
hosts:
- resource-health.apx.develop.eoepca.org
paths:
- /tmpservice
- /tmpservice/*
backends:
- serviceName: resource-health-tmpservice-service
servicePort: 8080
plugins:
- name: proxy-rewrite
enable: true
config:
regex_uri: ["^/tmpservice/?(.*)","/$1"]
- ...
plugin_config_name: ...
In order to establish the SSH tunnel, we must first create a local port-forward to reach the ssh server in the Pod
, and then create a tunnel through this forwarded connection.
To forward the SSH server with kubectl
run along the lines of
kubectl --namespace=resource-health port-forward tmpservice-pod 2222:2222
with --namespace=resource-health
and tmpservice-pod
replaced as appropriate.
Finally, in order to set up a tunnel that accept connections from anywhere (0.0.0.0
) on the remote port (8080
) to any process listening locally (on 8080
), run
ssh -R 0.0.0.0:8080:localhost:8080 <USER_NAME SET EARLIER>@localhost -p 2222
You may have to specify the additional argument -i path/to/private/key
.
This should drop you into a remote session like
Welcome to OpenSSH Server
tmpservice-pod:~$
which you can simply let sit (until you are done).
You can test the setup by running something like
python3 -m http.server 8080 -d /some/safe/directory/
and then accessing the route you set up earlier (e.g. resource-health.apx.develop.eoepca.org/tmpservice
).
Once you exit the ssh session
Welcome to OpenSSH Server
tmpservice-pod:~$ exit
logout
Connection to localhost closed.
$
the tunnel should be closed.