尝试连接到 Kubernetes 中的服务时连接被拒绝
Connection refused when trying to connect to services in Kubernetes
我正在尝试创建一个 Kubernetes
集群用于学习目的。因此,我创建了 3 个 Vagrant
的虚拟机,其中主机的 IP 地址为 172.17.8.101
,另外两个是 172.17.8.102
和 172.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_SUBNET
和 FLANNEL_MTU
变量的值是由 /run/flannel/subnet.env
文件中的 Flannel
设置的值。
完成所有这些设置后,我在主节点上安装了 kubernetes-master
和 kubernetes-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。
我正在尝试创建一个 Kubernetes
集群用于学习目的。因此,我创建了 3 个 Vagrant
的虚拟机,其中主机的 IP 地址为 172.17.8.101
,另外两个是 172.17.8.102
和 172.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_SUBNET
和 FLANNEL_MTU
变量的值是由 /run/flannel/subnet.env
文件中的 Flannel
设置的值。
完成所有这些设置后,我在主节点上安装了 kubernetes-master
和 kubernetes-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
注意:您将无法 ping 10.33.79.222
,因为在这种情况下不允许使用 ICMP。