kubernetes(k8s)容器内无法连接同所绑定的Service ClusterIP问题记录

1. k8s环境

k8s使用kubernetesserverlinuxamd64_1.19.10.tar.gz 二进制bin方式手动部署

k8s 版本:

[root@master ~]# kubectl version
Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.10", GitCommit:"98d5dc5d36d34a7ee13368a7893dcb400ec4e566", GitTreeState:"clean", BuildDate:"2021-04-15T03:28:42Z", GoVersion:"go1.15.10", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.10", GitCommit:"98d5dc5d36d34a7ee13368a7893dcb400ec4e566", GitTreeState:"clean", BuildDate:"2021-04-15T03:20:25Z", GoVersion:"go1.15.10", Compiler:"gc", Platform:"linux/amd64"}
2. 测试nginxbusybox应用

2.1 构建nginx测试镜像Dockerfile

# 基于官方 Nginx 镜像
FROM nginx

# 安装 Busybox
RUN apt-get update && apt-get install -y busybox

# 复制 Nginx 配置文件
# COPY nginx.conf /etc/nginx/nginx.conf

# 复制自定义 HTML 文件(可选)
COPY index.html /usr/share/nginx/html/

# 在容器启动执行命令
CMD ["nginx", "-g", "daemon off;"]
echo "hello world" > index.html
docker build . -t nginx-busybox:v1.0

2.2 创建k8s 测试资源nbusybox_deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nbusybox-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nbusybox
  template:
    metadata:
      labels:
        app: nbusybox
    spec:
      containers:
        - name: nbusybox
          image: nginx-busybox:v1.0
          ports:
            - containerPort: 80


---
apiVersion: v1
kind: Service
metadata:
  annotations: {}
  labels:
    k8s.kuboard.cn/name: nbusybox-service-v1
  name: nbusybox-service
spec:
  clusterIP: 10.233.0.45
  ports:
    - name: mrmsqs
      nodePort: 30233
      port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: nbusybox
  sessionAffinity: None
  type: NodePort

kubectl create -f nbusybox_deployment.yaml

2.3 ping service 测试

[root@master ~]# docker ps | grep nbusybox
975b550531df   3740b49d5078           "/docker-entrypoint.…"   31 minutes ago   Up 31 minutes             k8s_nbusybox_nbusybox-deployment-6b48bb8f65-mpnhg_default_1a60a955-c5fa-4e08-b8f3-7461edd9ea48_0
6d4a77f60cee   k8s.gcr.io/pause:3.2   "/pause"                 31 minutes ago   Up 31 minutes             k8s_POD_nbusybox-deployment-6b48bb8f65-mpnhg_default_1a60a955-c5fa-4e08-b8f3-7461edd9ea48_0

进入容器:

 docker exec -it 975b550531df  /bin/bash

http get 所在的service clusterIP 发现不通:

root@nbusybox-deployment-6b48bb8f65-mpnhg:/# busybox wget nbusybox-service.default.svc.cluster.local
Connecting to nbusybox-service.default.svc.cluster.local (10.233.0.45:80)

而在http get 其他的service clusterIP 发现可通:

root@nbusybox-deployment-6b48bb8f65-mpnhg:/# busybox wget nginxbusybox-service.default.svc.cluster.local
Connecting to nginxbusybox-service.default.svc.cluster.local (10.233.0.62:80)
saving to 'index.html'
index.html           100% |*******************************************************************************************************************************|    11  0:00:00 ETA
'index.html' saved

以为是kubeproxyiptables转发模式所致, 尝试更改 kube-proxy 的代理模式为ipvs

./kube-proxy --logtostderr=true --v=4 --hostname-override=192.168.0.251 --master=http://192.168.0.250:8080 --proxy-mode=ipvs

发现问题仍然存在

kube-proxy 在iptablesipvs 模式下,不会处理ip 包的转发,而是交由linux 网络协议处理。猜测是linux 网络协议栈的处理问题尝试宿主机对docker0 网卡抓包:
在这里插入图片描述

发现 nbusybox-service.default.svc.cluster.local 这个service 可以正常连接了。
在这里插入图片描述

当一但关掉 wireshark, nbusybox-service.default.svc.cluster.local 这个service 就连接不了。

wireshark 的抓包记录中,发现一条 从 10.0.9.2(容器ip) 发往 10.0.9.2 的http 响应,似乎构成了回环。

询问chatgpt:

linux 网络协议栈,对于源IP, 源MAC 跟目标IP, 目标MAC一样的IP包,能正常发送吗?

在 Linux 网络协议栈中,对于源 IP 地址(Source IP)和源 MAC 地址(Source MAC)与目标 IP 地址(Destination IP)和目标 MAC 地址(Destination MAC)完全相同的 IP 包,通常是无法正常发送的。

这是因为在以太网(Ethernet)协议中,源 MAC 和目标 MAC 是用于网络中的数据链路层寻址交换的重要字段。当一个主机发送一个 IP 包时,它会填充源 IP 和源 MAC 字段,同时指定目标 IP 和目标 MAC 字段。当数据包通过网络进行传输时,数据链路层设备(如交换机)会根据目标 MAC 地址数据包转发正确的目的地。

如果源 IP 和源 MAC 与目标 IP 和目标 MAC 完全相同,这意味着数据包将被送回到自身,形成了一个循环。为了避免这种无限循环的情况发生,Linux 网络协议栈通常会阻止发送这样的数据包。

当尝试发送源 IP 和源 MAC 与目标 IP 和目标 MAC 完全相同的数据包时,Linux 网络协议栈通常会丢弃这些数据包或者不进行发送。这是为了确保网络的正常运行和防止数据包的无限循环需要注意的是,这种行为可能会因操作系统和网络配置而有所不同,但在大多数常见的 Linux 发行版和网络环境中,源 IP 和源 MAC 与目标 IP 和目标 MAC 完全相同的 IP 包通常无法正常发送。

关掉 wireshark 的混杂模式
在这里插入图片描述

再次开启wireshark 对docker0 抓包, 容器内对 nbusybox-service.default.svc.cluster.local service 就连接不了。

问题已初步定位,当启用了 docker0 的混杂模式,容器内对 nbusybox-service.default.svc.cluster.local service 就可以连接。

再次验证, 手动对docker0 启用混杂模式

ifconfig docker0 promisc

测试:
在这里插入图片描述

发现 容器内对 nbusybox-service.default.svc.cluster.local service 就可以连接。

3. 结论

当在容器内(10.0.9.2)访问 service, 而这个service 经负载均衡后,找回这个容器自身(10.0.9.2),这时tcp 连接就无法建立,这时开启docker0网卡的混杂模式,tcp连接就可以建立。 但笔者在使用v1.23.17 的k8s 版本在某云厂商的云服务器部署,是可以在容器内访问自身的Service 的,因此该结论可能还跟操作系统或k8s的版本配置有关系。

原文地址:https://blog.csdn.net/kong_dzq/article/details/134706816

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_18019.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注