How to SSH to docker container in kubernetes cluster?

DockerGoogle Compute-EngineKubernetesGoogle Cloud-PlatformGoogle Kubernetes-Engine

Docker Problem Overview


I am fairly new to the Google Cloud platform and Docker and set-up a cluster of nodes, made a Dockerfile that copies a repo and runs a Clojure REPL on a public port. I can connect to it from my IDE and play around with my code, awesome!

That REPL should however probably tunneled through SSH, but here is where my problem starts. I can't find a suitable place to SSH into for making changes to the repo that Docker runs the REPL on:

  • The exposed IP just exposes the REPL service (correct kubernetes term?) and does not allow me to SSH in.
  • Neither does the cluster master endpoint, it gives me a public key error even though I've followed the Adding or removing SSH keys for all of the instances in your project part here.

I would like to edit the source files via SSH but I would need to access the docker code repo. I don't know how to proceed.

I understand this isn't exactly a typical way to deploy applications so I am not even sure it's possible to have multiple nodes work with a modified docker codebase (do the nodes share the JVM somehow?).

Concretely my question is how do I SSH into the docker container to access the codebase?

Docker Solutions


Solution 1 - Docker

For more recent Kubernetes versions the shell command should be separated by the --:

kubectl exec -it <POD NAME> -c <CONTAINER NAME> -- bash

Please note that bash needs to be availalble for execution inside of the container. For different OS flavours you might need to use /bin/sh, /bin/bash (or others) instead.

The command format for Kubernetes 1.5.0:

kubectl exec -it <POD NAME> -c <CONTAINER NAME> bash

Solution 2 - Docker

List instances:

gcloud compute instances list

SSH into instance:

gcloud compute ssh <instance_name> --zone=<instance_zone>

In the instance, list the running processes and their container IDs:

sudo docker ps -a

Attach to a container:

sudo docker exec -it <container_id> bash  

Solution 3 - Docker

The best way to attach to the container through exec command.

Attach to docker running container

docker exec -it  YOUR_CONTAINER_ID bash

Attach to Kubernetes running container.

kubectl exec -it  YOUR_CONTAINER/POD_NAME bash

Attach to Kubernetes running container in a given namespace.

kubectl exec -it  YOUR_CONTAINER/POD_NAME -n YOUR_NAMESPACE bash

Solution 4 - Docker

If the pod is in your current namespace, get the list of pods:

kubectl get pods

Pick a pod. Execute a bash session on it:

kubectl exec -it [POD_NAME] -- /bin/bash

Alternatively, find the pod you want in a different namespace:

kubectl get pods --all-namespaces

Pick a pod and execute a bash session on it:

kubectl exec -it [POD_NAME] --namespace [NAMESPACE] -- /bin/bash

Solution 5 - Docker

> I can't find a suitable place to SSH into for making changes to the repo that Docker runs the REPL on

When you create a cluster, you provision a number of node VMs in your google cloud project. If you look at https://console.cloud.google.com/compute/instances you should see them and each one will have a External IP address which you will be able to ssh into. Then create an ssh tunnel to a node VM that forwards a local port to the pod IP address.

Note that if you are running multiple replicas of your clojure app, you must connect to each replica separately to update the app.

Solution 6 - Docker

The existing answers are great, just wanted to contribute a really convenient command that lists all pods and containers, so you can choose one to plug into the kubectl exec command.

kubectl get pods -o=custom-columns=POD:.metadata.name,CONTAINERS:.spec.containers[*].name

Gives output like this

POD     CONTAINERS
pod-1   service-1,service-2
pod-2   service-1,service-2
pod-3   service-3
pod-4   service-3

Then ssh into any of those containers by just plugging in the names

kubectl exec -it POD -c CONTAINER /bin/sh

e.g. service-2 in pod-2

kubectl exec -it pod-2 -c service-2 /bin/sh

NOTE add -n namespace to any of the above commands to specify a namespace if necessary.

Solution 7 - Docker

Based on your description, I believe you are trying to setup a kubernetes cloud based development workspace. So that you could SSH into the pod containing your codebase using the public IP address of the pod or node or cluster, and edit the code in the docker container/pod using your IDE from laptop or so.

If your endgoal is to get remote SSH access to your private Kubernetes cluster nodes or pods, then you have 2 options:

Option# 1: Install and run an OpenSSH server inside your docker container pod. SSH server listens on port 22 and you need to expose that to the outside network. Expose the pod target port 22 through a clusterPort or nodePort service using a Kubernetes service configuration as shown below.

Reference: https://kubernetes.io/docs/concepts/services-networking/service/

apiVersion: v1
kind: Service
metadata:
name: my-ssh-service
spec:
type: NodePort
selector:
app: MyApp
ports:
- port: 22
targetPort: 22
nodePort: 30022

Now you could SSH into your pod using the NodeIP (Public IP address of the worker node, say 34.100.0.1) and NodePort as shown below

ssh [email protected] -p 30022

The only catch here is that you need to expose your worker node to the internet using a public IP address, so that you could access your pod from outside the network. It is not a security best practice to expose your node or cluster via a public IP to the internet as it increases the attack surface of your cloud.

Option #2: An alternate and better approach (from a security standpoint) would be to use a Kubernetes Cluster Remote SSH Access solution like SocketXP which doesn't require any public IP to be assigned to your nodes or cluster. You can retain your cluster as a private cluster. You can use IDE or something to SSH into your pod and access your codebase.

Reference: https://www.socketxp.com/docs/guide/kubernetes-pod-remote-ssh-access.html

Disclaimer: I'm the founder of SocketXP Kubernetes Remote Access solution. So I don't want to discuss my solution in detail here. You can go to the reference link above if you need the details and instructions to set it up.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionbbsView Question on Stackoverflow
Solution 1 - DockerSergey ShcherbakovView Answer on Stackoverflow
Solution 2 - DockerYoshua WuytsView Answer on Stackoverflow
Solution 3 - DockerNitinView Answer on Stackoverflow
Solution 4 - DockerJohn McGeheeView Answer on Stackoverflow
Solution 5 - DockerRobert BaileyView Answer on Stackoverflow
Solution 6 - DockerdavnicwilView Answer on Stackoverflow
Solution 7 - DockerGanesh VelrajanView Answer on Stackoverflow