尝试连接到 Kubernetes 中的服务时连接被拒绝

Connection refused when trying to connect to services in Kubernetes

我正在尝试创建一个 Kubernetes 集群用于学习目的。因此,我创建了 3 个 Vagrant 的虚拟机,其中主机的 IP 地址为 172.17.8.101,另外两个是 172.17.8.102172.17.8.103

很明显,我们需要Flannel,这样我们在不同机器上的容器就可以在不进行端口映射的情况下相互连接。为了让 Flannel 工作,我们需要 Etcd,因为 flannel 使用这个 Datastore 来放置和获取它的数据。

我在主节点上安装了 Etcd 并使用命令 etcdctl set /coreos.com/network/config '{"Network": "10.33.0.0/16"}'

Flannel 网络地址放在上面

为了启用 ip masquerading 并在虚拟机中使用专用网络接口,我将 --ip-masq --iface=enp0s8 添加到 /etc/sysconfig/flannel 文件中的 FLANNEL_OPTIONS

为了让Docker使用Flannel网络,我在/etc/sysconfig/docker文件中的OPTIONS变量中添加了--bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}'。请注意,FLANNEL_SUBNETFLANNEL_MTU 变量的值是由 /run/flannel/subnet.env 文件中的 Flannel 设置的值。

完成所有这些设置后,我在主节点上安装了 kubernetes-masterkubernetes-client,在所有节点上安装了 kubernetes-node。对于最终配置,我将 /etc/kubernetes/apiserver 文件中的 KUBE_SERVICE_ADDRESSES 值更改为 --service-cluster-ip-range=10.33.0.0/16 /etc/kubernetes/kubelet 文件中的 KUBELET_API_SERVER 值到 --api-servers=http://172.17.8.101:8080.

这是包含完整文件的 link 到 k8s-tutorial project 存储库。

经过所有这些努力,所有服务都成功启动并运行良好。当我使用命令kubectl get nodes时,很明显有3个节点运行。我可以使用命令 kubectl run nginx-pod --image=nginx --port=80 --labels="app=nginx" 成功创建一个 nginx pod 并使用 kubectl expose pod nginx-pod --port=8000 --target-port=80 --name="service-pod" 命令创建一个服务。

命令kubectl describe service service-pod输出结果如下:

Name:           service-pod
Namespace:      default
Labels:         app=nginx
Selector:       app=nginx
Type:           ClusterIP
IP:             10.33.39.222
Port:           <unset> 8000/TCP
Endpoints:      10.33.72.2:80
Session Affinity:   None
No events.

挑战在于,当我尝试使用 curl 10.33.79.222:8000 连接到创建的服务时,我得到 curl: (7) Failed connect to 10.33.72.2:8000; Connection refused 但是如果我尝试 curl 10.33.72.2:80 我得到默认的 nginx 页面.另外,我无法 ping 到 10.33.79.222,所有数据包都丢失了。

有些人建议停止并禁用 Firewalld,但它根本不是 运行 在节点上。由于 Docker 在 1.13 版本后的 Iptables 中将 FORWARD 链策略更改为 DROP 我将其更改回 ACCEPT 但它也没有帮助。我最终尝试更改 CIDR 并使用不同的 IP/subnets 但没有成功。

有谁知道我哪里出错了,或者如何找出我无法连接到创建的服务的问题?

您的服务是 ClusterIP 类型,这意味着它只能被其他 Kubernetes pods 访问。要实现您正在尝试做的事情,请考虑切换到 NodePort 类型的服务。然后您可以使用命令 curl <Kubernetes-IP-address>:<exposedServicePort>

连接到它

有关使用 NodePort 的示例,请参阅 https://kubernetes.io/docs/tasks/access-application-cluster/service-access-application-cluster/

我能看到您唯一有冲突的是您用于服务的 PodCidr 和 Cidr。

Flannel 网络:'{"Network": "10.33.0.0/16"}'。然后在 kube-apiserver --service-cluster-ip-range=10.33.0.0/16 上。这是相同的范围,它应该不同,所以你有你的 kube-proxy 为 10.33.0.0/16 设置服务然后你有你的覆盖认为它需要路由到 pods 运行 10.33.0.0/16。我将从为您的 pods 和服务选择一个完全不重叠的 Cidr 开始。

例如,在我的集群上(我使用的是 Calico),我有一个 192.168.0.0/16 的 podCidr,我有一个 10.96.0.0/12

的服务 Cidr

注意:您将无法 ping 10.33.79.222,因为在这种情况下不允许使用 ICMP。