Kubernetes调用Etcd服务超时问题求助(K8s 1.5.2)
从你的配置和操作流程来看,核心问题出在Service的端口映射配置错误,导致流量无法正确转发到etcd容器。下面一步步拆解问题并给出修复方案:
关键问题点
1. Service的targetPort指向错误
你的etcd容器内部实际监听的是2379端口(从Dockerfile的启动命令、Pod的containerPort:2379都能确认),但你在Service配置里把targetPort设成了12379——这是你通过hostPort映射到节点主机的端口,并非容器自身的端口。
Service的工作逻辑是:将流量通过ClusterIP:port转发到Pod的targetPort(容器内部的端口),而非节点的hostPort。当你设置targetPort:12379时,Service会尝试访问Pod的12379端口,但容器里根本没有进程监听这个端口,自然会触发context deadline exceeded的超时错误。
2. (可选)不必要的hostPort使用
你给Pod配置了hostPort:12379,这种方式并不推荐在生产环境使用:它会限制Pod的调度(只能被调度到节点上12379端口未被占用的机器),而Service本身已经可以提供集群内外的访问能力,完全不需要依赖hostPort。
修复步骤
步骤1:修正Service配置
修改Service YAML,将targetPort改为容器实际监听的2379,port可以自定义集群内部访问端口(比如保持2379或继续用12379都可以,只要targetPort正确):
apiVersion: v1 kind: Service metadata: name: storageservice namespace: storageplatform spec: type: NodePort ports: - port: 2379 # 集群内部访问的端口,可自定义 targetPort: 2379 # 必须指向容器的2379端口 nodePort: 32379 # 节点外部访问的端口 selector: app: etcd
重新应用配置:
kubectl apply -f your-service.yaml
步骤2:(推荐)移除Pod的hostPort
如果你不需要直接通过节点IP:12379访问etcd,建议去掉Pod里的hostPort配置,避免调度限制:
apiVersion: v1 kind: Pod metadata: name: etcd namespace: storageplatform labels: app: etcd spec: containers: - name: etcd image: "karldoenitz/etcd:3.4.0" ports: - containerPort: 2379 # 只保留容器端口即可
重新创建Pod:
kubectl delete pod etcd -n storageplatform kubectl apply -f your-pod.yaml
步骤3:验证Service可用性
现在可以通过两种方式验证:
- 集群内部访问:使用Service的ClusterIP和配置的port
ETCDCTL_API=3 etcdctl --endpoints=<ClusterIP>:2379 get 1
- 外部访问:使用节点IP和nodePort
ETCDCTL_API=3 etcdctl --endpoints=<host-ip>:32379 get 1
两种方式都应该能正常获取到之前写入的1键值对。
内容的提问来源于stack exchange,提问作者Karl Doenitz

