如何通过 SSH 连接到 kubernetes 集群中的 docker 容器?

How to SSH to docker container in kubernetes cluster?

我对 Google 云平台和 Docker 相当陌生,我设置了一个节点集群,创建了一个 Docker 文件来复制一个 repo 并运行一个 Clojure REPL在 public 端口上。我可以从我的 IDE 连接到它并使用我的代码,太棒了!

然而,REPL 可能应该通过 SSH 隧道传输,但这是我的问题开始的地方。 我找不到合适的地方通过 SSH 连接到 以更改 Docker 运行 REPL 的存储库:

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

我知道这不是部署应用程序的典型方式,所以我什至不确定是否可以让多个节点使用修改后的 docker 代码库(节点是否以某种方式共享 JVM?) .

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

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

创建集群时,您会在 google 云项目中配置多个节点 VM。如果您查看 https://console.cloud.google.com/compute/instances,您应该会看到它们,每个都有一个外部 IP 地址,您可以通过 ssh 访问该地址。然后创建到节点 VM 的 ssh 隧道,将本地端口转发到 pod IP 地址。

请注意,如果您是 运行 clojure 应用的多个副本,则必须分别连接到每个副本以更新应用。

通过exec命令附加到容器的最佳方式。

附加到 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

列出实例:

gcloud compute instances list

SSH 进入实例:

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

在实例中,列出 运行 个进程及其容器 ID:

sudo docker ps -a

附加到容器:

sudo docker exec -it <container_id> bash  

对于较新的 Kubernetes 版本,shell 命令应由 --:

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

请注意,bash 需要在容器内执行。对于不同的 OS 口味,您可能需要使用 /bin/sh/bin/bash(或其他)代替。

Kubernetes 1.5.0 的命令格式:

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

如果 pod 在您当前的命名空间中,获取 pods 的列表:

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

现有的答案很棒,只是想贡献一个非常方便的命令,列出所有 pods 和容器,因此您可以选择一个插入 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

例如service-2pod-2

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

注意 如有必要,将 -n namespace 添加到上述任何命令以指定命名空间。

根据您的描述,我相信您正在尝试设置一个基于 kubernetes 云的开发工作区。这样您就可以使用 pod 或节点或集群的 public IP 地址通过 SSH 连接到包含您的代码库的 pod,并使用您的 IDE 编辑 docker container/pod 中的代码] 从笔记本电脑左右。

如果您的最终目标是通过 SSH 远程访问您的私有 Kubernetes 集群节点或 pods,那么您有 2 个选择:

选项#1: 在 docker 容器 pod 中安装并 运行 一个 OpenSSH 服务器。 SSH 服务器侦听端口 22,您需要将其暴露给外部网络。 使用 Kubernetes 服务配置通过 clusterPort 或 nodePort 服务公开 pod 目标端口 22,如下所示。

参考: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(Public 工作节点的 IP 地址,比如 34.100.0.1)和 NodePort 通过 SSH 连接到您的 pod,如下所示

ssh user@34.10.0.1 -p 30022

这里唯一的问题是您需要使用 public IP 地址将您的工作节点暴露给互联网,以便您可以从网络外部访问您的 pod。通过 public IP 向 Internet 公开您的节点或集群不是安全最佳实践,因为它增加了云的攻击面。

选项#2: 另一种更好的方法(从安全角度来看)是使用 Kubernetes 集群远程 SSH 访问解决方案,例如 SocketXP,它不需要将任何 public IP 分配给您的节点或集群。您可以将集群保留为私有集群。您可以使用 IDE 或其他方式通过 SSH 连接到您的 pod 并访问您的代码库。

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

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