无法通过Nginx Ingress访问K8s容器SSH服务的问题排查
问题描述
在AWS EKS集群中部署了运行SSH服务的Ubuntu容器,容器暴露22端口,目标是通过Ingress实现ssh user@vm.my-domain.com -p 22直接登录,但执行命令后连接超时,报错如下:
OpenSSH_9.0p1, LibreSSL 3.3.6 debug1: Reading configuration data /etc/ssh/ssh_config debug1: /etc/ssh/ssh_config line 21: include /etc/ssh/ssh_config.d/* matched no files debug1: /etc/ssh/ssh_config line 54: Applying options for * debug1: Authenticator provider $SSH_SK_PROVIDER did not resolve; disabling debug1: Connecting to vm.daba-dev.dabafinance.com port 22. ssh: connect to host vm.daba-dev.dabafinance.com port 22: Operation timed out
但通过kubectl port-forward svc/vm -n daba 6060:2222端口转发后,能正常登录容器,说明容器内SSH服务正常,问题出在Ingress转发环节。
核心原因
Nginx Ingress默认仅处理HTTP/HTTPS流量
标准Nginx Ingress Controller本质是HTTP反向代理,仅支持解析HTTP协议的请求。SSH是基于TCP的独立协议,无法通过Ingress的HTTP规则进行转发,必须配置专门的TCP端口转发规则。Ingress配置存在语法错误
提供的Ingress YAML中,端口号写为22.(末尾带点),这是无效的语法,会导致Kubernetes无法识别该端口,转发规则无法生效。Docker启动命令冲突(潜在问题)
Dockerfile中定义了三个CMD指令,只有最后一个CMD ["/lib/systemd/systemd"]会生效,前两个启动SSH和Docker daemon的命令不会执行。不过端口转发能正常登录,说明实际容器中SSH服务已正常启动,可能是部署时修改了启动逻辑,但这个问题仍需修正以避免后续异常。
解决方案
1. 配置Nginx Ingress的TCP端口转发
Nginx Ingress支持通过ConfigMap配置TCP协议转发,步骤如下:
- 创建TCP转发配置的ConfigMap
apiVersion: v1 kind: ConfigMap metadata: name: tcp-services namespace: nginx-ingress # 需与Ingress Controller所在命名空间一致 data: "22": "vm-ns/vm:22" # 格式:外部端口:目标命名空间/服务名:服务端口 - 修改Ingress Controller的配置
在Ingress Controller的Deployment/DaemonSet中,添加启动参数指定TCP配置的ConfigMap:args: - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services - 更新Ingress Controller的Service
确保LoadBalancer类型的Ingress Service暴露22端口:spec: ports: - name: ssh port: 22 targetPort: 22 protocol: TCP
2. 修正Ingress配置的语法错误
将Ingress YAML中的number: 22.修改为number: 22,去掉端口号末尾的点:
# 修正后的Ingress端口配置 backend: service: name: 'vm' port: number: 22
3. 修复Docker容器启动命令(可选)
为确保SSH服务、Docker daemon和systemd都能启动,替换Dockerfile中的多个CMD为启动脚本:
- 创建
start.sh脚本:#!/bin/bash # 启动SSH服务 /usr/sbin/sshd -D & # 启动Docker daemon dockerd & # 启动systemd作为主进程 exec /lib/systemd/systemd - 修改Dockerfile:
# 移除原有的三个CMD指令,添加以下内容 COPY start.sh /start.sh RUN chmod +x /start.sh CMD ["/start.sh"]
4. 验证网络连通性
- 检查AWS Load Balancer的安全组,确保22端口对客户端IP段开放
- 检查EKS集群节点安全组,允许Ingress Controller节点与Pod所在节点的22端口通信
- 使用
telnet vm.my-domain.com 22测试端口连通性,确认端口已正常开放
内容的提问来源于stack exchange,提问作者sam hassan

