在Kubernetes集群中如何SSH到Docker容器?

63

我对Google Cloud平台和Docker还比较陌生,我建立了一个节点集群,并创建了一个Dockerfile,复制了一个仓库并在公共端口上运行Clojure REPL。我可以从我的IDE连接并测试我的代码,非常棒!

然而,这个REPL可能需要通过SSH隧道访问,但问题就出在这里。 我找不到适合的地方进行SSH访问,以便对Docker运行的仓库进行更改:

  • 暴露的IP只是暴露了REPL服务(正确的Kubernetes术语?),并不允许我进行SSH访问。
  • 群集主节点端点也不行,它给我返回了一个公钥错误,即使我已经遵循了这里的为项目中的所有实例添加或删除SSH密钥部分(参考链接)

我想通过SSH编辑源文件,但我需要访问docker代码仓库。 我不知道该如何操作。

我理解这不是部署应用程序的典型方式,因此我甚至不确定是否有可能让多个节点使用修改后的docker代码库(节点是否以某种方式共享JVM?)。

具体而言,我的问题是如何通过SSH进入docker容器以访问代码库?

7个回答

90

对于更新的 Kubernetes 版本,Shell 命令应该使用 -- 分隔:


Translated text:

对于更新的 Kubernetes 版本,Shell 命令应该使用 -- 分隔:

kubectl exec -it <POD NAME> -c <CONTAINER NAME> -- bash
请注意:bash需要在容器内部可用以执行。对于不同的操作系统版本,您可能需要使用/bin/sh/bin/bash(或其他命令)。

Kubernetes 1.5.0的命令格式为:

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

7
非常好用。如果出现“Error from server (NotFound): pods "blabla" not found”错误,可能需要添加-n <NAMESPACE>。 - rdeboo
3
可以,除了我必须使用“sh”而不是“bash”之外,这很有效。 - jacob
1
这取决于您的容器内有哪个shell可用。 - Sergey Shcherbakov
1
似乎这个选项已被弃用。 我建议使用这个代替:kubectl exec --stdin --tty <POD_NAME> -- /bin/bash - spotHound
@spotHound 什么?我昨天刚用过,你能分享一下链接吗? - Sergey Shcherbakov
显示剩余3条评论

28

列出实例:

gcloud compute instances list

登录实例:

gcloud compute ssh <instance_name> --zone=<instance_zone>
在这个实例中,列出正在运行的进程及其容器 ID:
sudo docker ps -a

附加到一个容器:

sudo docker exec -it <container_id> bash  

谢谢!我有一个gcr.io/cloudsql-docker/gce-proxy容器一直无法启动,我正在尝试诊断。我使用了docker run -it <image_id> sh,但我需要查看我的挂载点。你知道在节点上时docker run的卷参数是什么样子的吗? - kross
SSH对我不起作用:$ gcloud compute ssh --zone us-west1-b gke-xxx-default-pool-yyy-3q77 -- ps ssh:无法连接到主机35.100.100.10端口22:连接超时 - Ark-kun

19

通过执行命令附加到容器的最佳方法。

附加到正在运行的Docker容器

docker exec -it YOUR_CONTAINER_ID bash

附加到正在运行的Kubernetes容器。

kubectl exec -it YOUR_CONTAINER/POD_NAME bash

在给定的命名空间中附加到正在运行的Kubernetes容器。

kubectl exec -it YOUR_CONTAINER/POD_NAME -n YOUR_NAMESPACE bash

17

如果Pod在当前命名空间中,请获取Pod列表:

kubectl get pods

选择一个 Pod,在其上执行 bash 会话:

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

或者,在不同的命名空间中找到您想要的pod:

kubectl get pods --all-namespaces

选择一个 Pod 并在其上执行 bash 会话:

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

6
kubectl exec -it [POD_NAME] sh 对我来说可行,代替了别的方法。 - jurl
kubectl exec -it [POD_NAME] --namespace [NAMESPACE] -- /bin/bash 对我有效。 - ravthiru

7
现有答案已经很好了,我只想贡献一个非常方便的命令,可以列出所有的 pod 和容器,这样你就可以选择一个插入到 kubectl exec 命令中。
kubectl get pods -o=custom-columns=POD:.metadata.name,CONTAINERS:.spec.containers[*].name

生成如下输出
POD     CONTAINERS
pod-1   service-1,service-2
pod-2   service-1,service-2
pod-3   service-3
pod-4   service-3

然后通过输入名称,只需登录其中任何一个容器即可进行ssh访问。

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

例如,在pod-2中的service-2

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

注意: 如果需要指定命名空间,请在上述任何命令中添加-n namespace


5
无法找到适合的SSH连接位置来更改Docker运行REPL仓库的位置
创建群集时,您在Google Cloud项目中提供了一些节点VM。如果您查看https://console.cloud.google.com/compute/instances,您应该会看到它们,每个VM都将有一个外部IP地址,您可以通过ssh连接到它们。然后,创建一个ssh隧道到一个节点VM,将本地端口转发到pod IP地址。
请注意,如果您运行多个clojure应用程序副本,则必须分别连接到每个副本以更新应用程序。

1
根据您的描述,我认为您正在尝试设置一个基于Kubernetes云的开发工作区。这样,您就可以使用Pod或节点或集群的公共IP地址SSH到包含代码库的Pod中,并使用笔记本电脑等设备中的IDE在Docker容器/Pod中编辑代码。
如果您的最终目标是远程SSH访问私有Kubernetes集群节点或Pod,则有两个选项:
选项1: 在Docker容器Pod内安装并运行OpenSSH服务器。 SSH服务器侦听端口22,您需要将其暴露到外部网络。 通过使用如下所示的Kubernetes服务配置,将Pod目标端口22通过ClusterPort或NodePort服务公开。
参考: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
现在,您可以使用NodeIP(工作节点的公共IP地址,例如34.100.0.1)和NodePort通过SSH登录到您的pod,如下所示:
ssh user@34.10.0.1 -p 30022
唯一的问题是您需要使用公共IP地址将您的工作节点暴露到互联网上,以便您可以从网络外部访问您的pod。但是,将您的节点或集群通过公共IP暴露到互联网上并不是最佳安全实践,因为这会增加云的攻击面。 选项#2: 另一种更好的方法(从安全角度来看)是使用Kubernetes集群远程SSH访问解决方案,如SocketXP,它不需要为您的节点或集群分配任何公共IP。您可以将您的集群保留为私有集群。您可以使用IDE或其他工具SSH进入您的pod并访问您的代码库。
参考:https://www.socketxp.com/docs/guide/kubernetes-pod-remote-ssh-access.html

免责声明:我是SocketXP Kubernetes远程访问解决方案的创始人。因此,我不想在这里详细讨论我的解决方案。如果您需要详细信息和设置说明,请转到上面的参考链接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接