0

We run our production Rails app on GKE, and we require all production access to go through a Bastion host.

To access it, I SSH into the Bastion host:

gcloud compute ssh --project=myproject --zone=myzone bastion-vm

Once that connects, I get the name of the desired pod, exec into it, and start an interactive Rails console:

kubectl --context=prod exec -it $(kubectl get pods -n mynamespace --no-headers -o custom-columns=":metadata.name" --selector="app=my-app") -n mynamespace -- /bin/sh -c '/berglas/bin/berglas exec -- bundle exec rails c'

I'd like to turn this into a one-liner that I can run from my local, but I'm struggling. My first attempt:

gcloud compute ssh --project=myproject --zone=usmyzone bastion-vm --command 'kubectl --context=prod exec -it $(kubectl get pods -n mynamespace --no-headers -o custom-columns=":metadata.name" --selector="app=my-app") -n mynamespace -- /bin/sh -c "/berglas/bin/berglas exec -- bundle exec rails c"'

When I ran that, it gave me the usual output I get when connecting to Bastion:

External IP address was not found; defaulting to using IAP tunneling.
WARNING: 

To increase the performance of the tunnel, consider installing NumPy. For instructions,
please see https://cloud.google.com/iap/docs/using-tcp-forwarding#increasing_the_tcp_upload_bandwidth

And then it just hung until I hit ControlC. I figured "oh, okay, I need an interactive SSH session." So I looked at the gcloud docs and didn't see any built-in option for that, but I did see that you can pass flags down to the underlying ssh, and so I tried --ssh-flag='-t':

gcloud compute ssh --project=myproject --zone=usmyzone bastion-vm --ssh-flag='-t' --command 'kubectl --context=prod exec -it $(kubectl get pods -n mynamespace --no-headers -o custom-columns=":metadata.name" --selector="app=my-app") -n mynamespace -- /bin/sh -c "/berglas/bin/berglas exec -- bundle exec rails c"'

This connected as before, then dropped me at a terminal prompt on the bastion host as if I hadn't specified a command. I added -v to the ssh flags and ran it again; it indicates that it's running the command:

debug1: Sending command: kubectl --context=prod exec $(kubectl get pods -n mynamespace --no-headers -o custom-columns=":metadata.name" --selector="app=my-app") -n mynamespace -- /bin/sh -c "/berglas/bin/berglas exec -- bundle exec rails c"

That's the end of the output before the shell prompt on the Bastion host. I see no other output or evidence that indicates that the command actually ran. I've done some additional experimentation, specifying things like ls, /bin/dash, and even things that should error like /bin/foo as the command. Nothing changes; I just always get the shell prompt without further output (or, if I omit the -t, it always just hangs).

I have to imagine that there's a way to accomplish this. What am I missing?

If it matters, I'm on macOS Monterey and my local shell is ZSH.

JakeRobb
  • 105
  • 6

0 Answers0