kubernetes - 为什么使用calico时无法ping通kubernetes集群中的服务ip
问题描述
我使用 calico 作为我的 kubernetes CNI 插件,但是当我从 kubernetes pod ping 服务时,它失败了。首先我找到了服务 ip:
[root@localhost ~]# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
prometheus-1594471894-kube-state-metrics ClusterIP 10.20.39.193 <none> 8080/TCP 3h16m app.kubernetes.io/instance=prometheus-1594471894,app.kubernetes.io/name=kube-state-metrics
然后从任何 pod ping 这个 ip(已经登录到 pod):
root@k8sslave1:/# ping 10.20.39.193
PING 10.20.39.193 (10.20.39.193) 56(84) bytes of data.
没有反应。然后使用 traceroute 检查路径:
root@k8sslave1:/# traceroute 10.20.39.193
traceroute to 10.20.39.193 (10.20.39.193), 64 hops max
1 192.168.31.1 0.522ms 0.539ms 0.570ms
2 192.168.1.1 1.171ms 0.877ms 0.920ms
3 100.81.0.1 3.918ms 3.917ms 3.602ms
4 117.135.40.145 4.768ms 4.337ms 4.232ms
5 * * *
6 * * *
包是路由到互联网,而不是转发到 kubernetes 服务。为什么会发生这种情况?我应该怎么做才能解决它?该 pod 可以访问互联网,并且可以成功 ping 其他 pod 的 ip。
root@k8sslave1:/# ping 10.11.157.67
PING 10.11.157.67 (10.11.157.67) 56(84) bytes of data.
64 bytes from 10.11.157.67: icmp_seq=1 ttl=64 time=0.163 ms
64 bytes from 10.11.157.67: icmp_seq=2 ttl=64 time=0.048 ms
64 bytes from 10.11.157.67: icmp_seq=3 ttl=64 time=0.036 ms
64 bytes from 10.11.157.67: icmp_seq=4 ttl=64 time=0.102 ms
这是我安装 kubernetes 集群时的 ip 配置:
kubeadm init \
--apiserver-advertise-address 0.0.0.0 \
--apiserver-bind-port 6443 \
--cert-dir /etc/kubernetes/pki \
--control-plane-endpoint 192.168.31.29 \
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
--kubernetes-version 1.18.2 \
--pod-network-cidr 10.11.0.0/16 \
--service-cidr 10.20.0.0/16 \
--service-dns-domain cluster.local \
--upload-certs \
--v=6
这是 dns resolv.conf:
cat /etc/resolv.conf
nameserver 10.20.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
这是 pod 的内核路由表:
[root@localhost ~]# kubectl exec -it shell-demo /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
root@k8sslave1:/# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.31.1 0.0.0.0 UG 100 0 0 enp1s0
10.11.102.128 192.168.31.29 255.255.255.192 UG 0 0 0 tunl0
10.11.125.128 192.168.31.31 255.255.255.192 UG 0 0 0 tunl0
10.11.157.64 0.0.0.0 255.255.255.192 U 0 0 0 *
10.11.157.66 0.0.0.0 255.255.255.255 UH 0 0 0 cali4ac004513e1
10.11.157.67 0.0.0.0 255.255.255.255 UH 0 0 0 cali801b80f5d85
10.11.157.68 0.0.0.0 255.255.255.255 UH 0 0 0 caliaa7c2766183
10.11.157.69 0.0.0.0 255.255.255.255 UH 0 0 0 cali83957ce33d2
10.11.157.71 0.0.0.0 255.255.255.255 UH 0 0 0 calia012ca8e3b0
10.11.157.72 0.0.0.0 255.255.255.255 UH 0 0 0 cali3e6b175ded9
10.11.157.73 0.0.0.0 255.255.255.255 UH 0 0 0 calif042b3edac7
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.31.0 0.0.0.0 255.255.255.0 U 100 0 0 enp1s0
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
解决方案
这是一个非常常见的问题,我需要完全迁移 CIDR IP。
这个问题很可能是关于 Pods CIDR(用于为服务和 Pod 分配 IP 的 IP 池)和您的网络的 CIDR 之间的 CIDR 重叠的问题。
在这种情况下,每个节点 (VM) 的路由表将确保:
sudo route -n
因为您没有提供足够的日志,所以我将在这里帮助您解决问题。如果您遇到与我猜想的相同的问题,则需要按照从第 3 步开始的说明更改 pod 的 CIDR 范围。
Step1 : 安装 calicoctl 作为 Kubernetes pod
kubectl apply -f https://docs.projectcalico.org/manifests/calicoctl.yaml
alias calicoctl="kubectl exec -i -n kube-system calicoctl -- /calicoctl"
Step2 : 检查 Calico 实例的状态。
calicoctl node status
# Sample of output ###################
Calico process is running.
IPv4 BGP status
+--------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+--------------+-------------------+-------+----------+-------------+
| 172.17.8.102 | node-to-node mesh | up | 23:30:04 | Established |
+--------------+-------------------+-------+----------+-------------+
如果您在此步骤中遇到问题,请在此处停止并修复它。
否则,您可以继续。
第 3 步:列出现有池
calicoctl get ippool -o wide
第四步:创建新池
确保它不与您的网络 CIDR 重叠。
calicoctl create -f -<<EOF
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: pool-c
spec:
cidr: 10.244.0.0/16
ipipMode: Always
natOutgoing: true
EOF
新池名为pool-c。
Step5:删除当前池:
# get all pools
calicoctl get ippool -o yaml > pools.yaml
# edit the file pools.yaml and remove the current pool.
# file editing ... save & quit
# then apply changes
calicoctl apply -f -<<EOF
# Here, Must be the new content of the file pools.yaml
EOF
第 6 步:检查分配给每个工作负载(pod)的 SDN IP:
calicoctl get wep --all-namespaces
继续重新启动旧的 Pod,重新创建旧的服务,直到确保所有资源都分配了来自新池的 IP。
推荐阅读
- tensorflow - AttributeError:模块“tensorflow.python.pywrap_tensorflow”没有属性“TFE_MonitoringNewCounter0”
- java - “ [main] INFO expect4j.Expect4j - 处理 EOF null” 这个问题到底是什么?
- android - 在 Android 供应商软件中使用 AHardwareBuffer_fromHardwareBuffer()?
- php - 我想在 PHP 中使用 htaccess 从 url 中隐藏 id
- c++ - 为什么我的梯度下降算法不收敛?(对于逻辑回归)
- flutter - 如何使用 darkTheme 在颤动中更改主题:
- r - 如何使用 ggplot2 从条形图中的多列中绘制 3 个单个数字?
- java - 如何在maven中做多个生成源代码的主类
- python - 在不更改python中的数字的情况下将变量的类型从十六进制字符串转换为uint_32
- css - 仅使用 Typescript 编译 css 文件