K8s 服务无法 ping 通
K8s service not pingable
我在 minikube 集群中有一个 k8s service/deployment(default
命名空间中的名称 amq
:
D20181472:argo-k8s gms$ kubectl get svc --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
argo argo-ui ClusterIP 10.97.242.57 <none> 80/TCP 5h19m
default amq LoadBalancer 10.102.205.126 <pending> 61616:32514/TCP 4m4s
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5h23m
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 5h23m
我启动了 infoblox/dnstools,并尝试了 amq.default
的 nslookup
、dig
和 ping
,结果如下:
dnstools# nslookup amq.default
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: amq.default.svc.cluster.local
Address: 10.102.205.126
dnstools# ping amq.default
PING amq.default (10.102.205.126): 56 data bytes
^C
--- amq.default ping statistics ---
28 packets transmitted, 0 packets received, 100% packet loss
dnstools# dig amq.default
; <<>> DiG 9.11.3 <<>> amq.default
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 15104
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;amq.default. IN A
;; Query time: 32 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Sat Jan 26 01:58:13 UTC 2019
;; MSG SIZE rcvd: 29
dnstools# ping amq.default
PING amq.default (10.102.205.126): 56 data bytes
^C
--- amq.default ping statistics ---
897 packets transmitted, 0 packets received, 100% packet loss
(注意:直接ping IP地址得到相同的结果)
我承认我对 DNS 的深层运作不是很了解,所以我不确定为什么我可以查找和挖掘主机名,但不能 ping 它。
I admittedly am not very knowledgable about the deep workings of DNS, so I am not sure why I can do a lookup and dig for the hostname, but not ping it.
因为 Service
IP 地址是集群想象的虚构,由 iptables 或 ipvs 引起,实际上并不存在。您可以在 运行 kube-proxy
(或 ipvsadm -ln
)的任何节点上使用 iptables -t nat -L -n
查看它们,如有用的 Debug[-ing] Services 页面 [=19= 所述]
由于它们不是绑定到实际 NIC 的真实 IP,因此除了在 Service
资源中注册的端口号外,它们不会响应任何流量。测试服务连接性的正确方法是使用 curl
或 netcat
之类的东西,并使用您期望应用程序流量传输的端口号。
因为服务的集群IP是虚拟IP,只有和服务端口结合才有意义
每当 API 服务器创建服务时,都会立即为其分配一个虚拟 IP 地址,之后,API 服务器会通知 运行 上的所有 kube-proxy 代理已创建新服务的工作节点。然后,kube-proxy 的工作是使该服务在它 运行 所在的节点上可寻址。 kube-proxy 通过设置一些 iptables 规则来做到这一点,这些规则确保发往服务 IP/port 对的每个数据包都被拦截并修改其目标地址,因此数据包被重定向到 pods 之一支持服务。
我在 minikube 集群中有一个 k8s service/deployment(default
命名空间中的名称 amq
:
D20181472:argo-k8s gms$ kubectl get svc --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
argo argo-ui ClusterIP 10.97.242.57 <none> 80/TCP 5h19m
default amq LoadBalancer 10.102.205.126 <pending> 61616:32514/TCP 4m4s
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5h23m
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 5h23m
我启动了 infoblox/dnstools,并尝试了 amq.default
的 nslookup
、dig
和 ping
,结果如下:
dnstools# nslookup amq.default
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: amq.default.svc.cluster.local
Address: 10.102.205.126
dnstools# ping amq.default
PING amq.default (10.102.205.126): 56 data bytes
^C
--- amq.default ping statistics ---
28 packets transmitted, 0 packets received, 100% packet loss
dnstools# dig amq.default
; <<>> DiG 9.11.3 <<>> amq.default
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 15104
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;amq.default. IN A
;; Query time: 32 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Sat Jan 26 01:58:13 UTC 2019
;; MSG SIZE rcvd: 29
dnstools# ping amq.default
PING amq.default (10.102.205.126): 56 data bytes
^C
--- amq.default ping statistics ---
897 packets transmitted, 0 packets received, 100% packet loss
(注意:直接ping IP地址得到相同的结果)
我承认我对 DNS 的深层运作不是很了解,所以我不确定为什么我可以查找和挖掘主机名,但不能 ping 它。
I admittedly am not very knowledgable about the deep workings of DNS, so I am not sure why I can do a lookup and dig for the hostname, but not ping it.
因为 Service
IP 地址是集群想象的虚构,由 iptables 或 ipvs 引起,实际上并不存在。您可以在 运行 kube-proxy
(或 ipvsadm -ln
)的任何节点上使用 iptables -t nat -L -n
查看它们,如有用的 Debug[-ing] Services 页面 [=19= 所述]
由于它们不是绑定到实际 NIC 的真实 IP,因此除了在 Service
资源中注册的端口号外,它们不会响应任何流量。测试服务连接性的正确方法是使用 curl
或 netcat
之类的东西,并使用您期望应用程序流量传输的端口号。
因为服务的集群IP是虚拟IP,只有和服务端口结合才有意义
每当 API 服务器创建服务时,都会立即为其分配一个虚拟 IP 地址,之后,API 服务器会通知 运行 上的所有 kube-proxy 代理已创建新服务的工作节点。然后,kube-proxy 的工作是使该服务在它 运行 所在的节点上可寻址。 kube-proxy 通过设置一些 iptables 规则来做到这一点,这些规则确保发往服务 IP/port 对的每个数据包都被拦截并修改其目标地址,因此数据包被重定向到 pods 之一支持服务。