mac电脑下无法访问minikube的NodePort端口

背景

前段时间换了工作,喜提一台mac电脑,为了方便在本地搞k8s开发,就打算安装minikube。minikube的安装步骤就不赘述了,参照官网即可。 当minikube安装完了之后,为了测试下是否安装成功,就起了个deployment 然后暴露了一个service 使用nodeport访问,但是我在本地浏览器访问却发现访问不通??? 基于此,就研究了下minikube的网络。

现象

我首先启动了一个deployment ,然后暴露了service,如下

# 启动一个nginx的deployment
MacBook-Pro-2:~ jxrt$ kubectl get deployments.apps 
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy        1/1     1            1           23d

# 将nginx服务暴露在31908的nodeport上
MacBook-Pro-2:~ jxrt$ kubectl get svc
NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
nginx-deploy     NodePort    10.103.97.88     <none>        80:31908/TCP     23d

然后我使用minikube的ip 访问

# 查看minikube的ip
MacBook-Pro-2:~ jxrt$ minikube ip
192.168.49.2

# 访问minikube的nodeport的端口,发现访问不通
MacBook-Pro-2:~ jxrt$ wget 192.168.49.2:31908
--2022-07-15 15:48:28--  http://192.168.49.2:31908/
正在连接 192.168.49.2:31908... 

# ping了 minikube的ip也不通
MacBook-Pro-2:~ jxrt$ ping 192.168.49.2
PING 192.168.49.2 (192.168.49.2): 56 data bytes
Request timeout for icmp_seq 0
^C
--- 192.168.49.2 ping statistics ---
2 packets transmitted, 0 packets received, 100.0% packet loss

从上面可以看到,访问minikube 的ip是不通的,我的minikube是通过docker方式启动的,mac电脑的docker是运行在虚机中的,目前看来是宿主机和虚机的网络不通。

又查了下文档,通过docker启动的minikube确实没有和宿主机打通网络,严格来说是没有打通二层和三层的网络,minikube给出的解决方案是通过端口代理的方式来访问服务,如下:

# 可以使用这种方式来访问minikube中暴露出来的service,本质是临时起了一个ssh端口转发的隧道
MacBook-Pro-2:~ jxrt$ minikube service nginx-deploy --url

  Starting tunnel for service nginx-deploy.
❗  Because you are using a Docker driver on darwin, the terminal needs to be open to run it.

但是我的电脑上这种方式好像不生效,查了下github也有其他人遇到了这种问题,目前还无解,参考GitHub的 Issues 14268

深入排查

因为mac下的docker是运行在hyperkit的虚机中的,所以就打算看下hyperkit启动的虚机是怎么解决网络问题的,目前的现象是虽然minikube 的ip不通,但是使用 minikube sshkubectl 命令还是可以访问到虚机中的服务,因此在四层的网络应该还是通的,只是二层和三层的不通。

kit

接着又查了一下hyperkit的文档,看到了hyperkit中是使用kit这个组件来提供宿主机和虚机的网络传输的,然后又看了下kit的文档,kit的网络流向大概如下图,kit一端连接在虚机内的交换设备Switch上充当一个网关,另一端在宿主机上暴露socket服务,所以我们在宿主机上只能通过四层tcp和udp的协议访问到虚机中的服务,minikube也是通过创建ssh隧道然后端口转发的方式,将内部服务暴露到宿主机上。

mac电脑下无法访问minikube的NodePort端口_第1张图片

解决思路

基于上面的点,宿主机和hyperkit的虚机还是能通过tcp端口通信的,docker的端口映射也是基于此的,那我们其实也可以利用这个点,把宿主机和内部虚机的二层和三层网络打通,这里会借助socat端口转发、docker端口映射、Linux 网桥和open server来打通网络,对这块没兴趣的同学可以忽略,直接跳转到下一节上手操作

查看minikube的网络

首先我们查看一下minikube的ip,然后可以找到对应的Linux网桥,其实通过命名也可以直接找到网桥

# 查看一下minikube的ip地址,其实可以猜一下看这个ip应该也是某个网桥给分配的
MacBook-Pro-2:~ jxrt$ minikube ip
192.168.49.2

#然后我们查看一下网桥信息
jxrtdeMacBook-Pro-2:~ jxrt$ docker network ls
NETWORK ID     NAME                         DRIVER    SCOPE
ce64d9141d75   host                         host      local
03517ace23ec   minikube                     bridge    local

# 查看一下minikube 网桥的详细信息,信息太多了我就截取了一小段如下
xrtdeMacBook-Pro-2:~ jxrt$ docker network inspect 03517ace23ec
[
    {
        "Name": "minikube",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.49.0/24",
                    "Gateway": "192.168.49.1"
                }
            ]
        },

}]

从上面minikube的网桥IPAM中可以看到网段是 192.168.49.0/24,我们的目标就是在宿主机上打通虚机的这个网段即可。

使用open server打通网络

我们知道docker是运行在上面的虚机中的,那我们其实可以在docker中启动一个 server的容器那么这个 server其实就运行在这个虚机中了,然后我们再把server的地址暴露在宿主机上,那我们其实就可以基于打通宿主机和虚机的网络了,但是这里还有几个问题要解决

首先docker启动 server 的时候必须使用host网络模式才可以,因为 server 必须要使用虚机本地的网络,而不是docker的网络。如果使用host网络模式,那么端口就没法映射到宿主机了,因为docker的host网络不会新创建网络命名空间,直接加入本地网络,所以也不用做端口映射。

使用socat做端口转发

所以我们就需要在起一个端口转发的容器,做一个docker端口映射,将宿主机的端口映射到容器中,容器中在将端口转发到本地的open server。

宿主机使用 client连接 server

当这些都就绪之后,我们只需要配置一下 server的转发规则,将流量转发到192.168.49.0/24网段,宿主机上启动open client,连接到docker的端口转发容器,这样整体网络就通了

上手操作

在mac上安装了docker-desktop 之后会一起安装docker-compose 使用docker-compose安装会方便的多,需要用到的yml和配置文件我都上传github了,可以直接下载下来,改一下配置使用

  1. 下载仓库代码
    仓库地址: https://github.com/yuzhaopeng/minikube-mac-network

    git clone [email protected]:yuzhaopeng/minikube-mac-network.git
    
  2. 使用docker-compose启动

    docker-compose up -d 
    
  3. 启动之后会在当前目录下生成客户端的配置文件 docker-for-mac.o

  4. 安装客户端 Tunnelblick

    官网似乎是被墙了,一直没打开过,可以到github上下载,下载地址

  5. 启动客户端,将配置文件拖到客户端界面,点击连接
    mac电脑下无法访问minikube的NodePort端口_第2张图片

  6. 测试网络是否通了

    # 发现此时可以ping通minikube的ip了
    MacBook-Pro-2:~ jxrt$ ping 192.168.49.2
    PING 192.168.49.2 (192.168.49.2): 56 data bytes
    64 bytes from 192.168.49.2: icmp_seq=0 ttl=63 time=11.028 ms
    64 bytes from 192.168.49.2: icmp_seq=1 ttl=63 time=5.558 ms
    ^C
    --- 192.168.49.2 ping statistics ---
    2 packets transmitted, 2 packets received, 0.0% packet loss
    round-trip min/avg/max/stddev = 5.558/8.293/11.028/2.735 ms
    

写在最后

关于kit在网上找到的资料不太多,如果有同学感兴趣的可以在评论区留个言,一起讨论

你可能感兴趣的:(k8s,macos,docker,容器,kubernetes,minikube)