当前位置: 首页 > news >正文

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

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

1. k8s环境

k8s使用kubernetes-server-linux-amd64_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. 测试nginx-busybox应用

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

以为是kube-proxy 在iptables 的转发模式所致, 尝试更改 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 在iptables 和 ipvs 模式下,不会处理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的版本配置有关系。

相关文章:

  • Windows核心编程 HOOK
  • 【微服务】springboot整合quartz使用详解
  • 代码随想录二刷 | 栈与队列 |逆波兰表达式求值
  • HarmonyOs 4 (一) 认识HarmonyOs
  • Linux CentOS本地部署SQL Server数据库结合cpolar内网穿透实现公网访问
  • 6-55.汽车类的继承
  • Python-字典详解
  • 阿里云租赁费用_阿里云服务器多配置报价表
  • C语言实现植物大战僵尸(完整版)
  • 基于JavaScript的jimp库处理图片,添加绘制点
  • 阿里云新版公共实例从注册账号到创建设备生成参数教程
  • 【微信小程序】上传头像 微信小程序内接小程序客服
  • Apache Doris 详细教程(三)
  • 外包干了3个月,技术倒退2年。。。
  • 【EasyExcel实践】万能导出,一个接口导出多张表以及任意字段(可指定字段顺序)
  • TimeGPT:时间序列预测模型实例
  • 【系统运维】Centos部署Haproxy+Keepalived+RabbitMQ高可用集群
  • Vue3自定义Hooks定义
  • 2023年十大网络安全上市公司观察
  • 15:00面试,15:06就出来了,问的问题有点变态。。。
  • 经济日报金观平:充分发挥超大规模市场优势
  • 贵州省总工会正厅级副主席梁伟被查,曾任贵州省纪委副书记
  • 黑灰产工作室为境外诈骗集团养号引流,冒充美女与男性裸聊后敲诈勒索
  • 马云再次现身阿里打卡创业公寓“湖畔小屋”,鼓励员工坚持创业精神
  • 康子兴评《文明的追求》|野人脚印:鲁滨逊的恐惧与文明焦虑
  • 外交部:印巴都表示不希望局势升级,望双方都能保持冷静克制