microk8s(二)深入

作者: 印随2018 | 来源:发表于2019-07-21 14:22 被阅读0次

    本文讨论的内容需要先阅读《microk8s(一)安装》

    上一篇内容中,使用下面这条命令,讲Pod的开发端口映射到本地节点,其中是怎么实现的呢?

    kubectl port-forward --namespace=kube-system --address=0.0.0.0 pod/kubernetes-dashboard-6fd7f9c494-dgxlj 8443:8443
    

    一般来说,端口映射,也就是NAT的功能大多是通过Iptables来实现,那我们先来看看iptables的规则

    iptables -vL -t nat --line-numbers
    iptables -vL -t filter
    iptables -vL -t mangle
    iptables -vL -t raw
    iptables -vL -t security
    

    检查了所有规则,没有发现关于端口8443的内容。好吧,那我们来看看是哪个进程在监听8443端口

    root@iZt4n3mancztn8h975gqptZ:~# lsof -i:8443
    COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    kubectl 17985 root    6u  IPv4 463409      0t0  TCP *:8443 (LISTEN)
    

    上面的输出说明,进程号为17985在监听8443端口的数据, 我们看看这个进程的启动参数

    # cat /proc/17985/cmdline
    /snap/microk8s/687/kubectl \
    --kubeconfig=/var/snap/microk8s/687/credentials/client.config \
    port-forward \
    --namespace=kube-system \
    --address=0.0.0.0 \
    pod/kubernetes-dashboard-6fd7f9c494-dgxlj8443:8443
    

    查看进程已经打开的文件

    # ls -l /proc/17985/fd
    total 0
    lrwx------ 1 root root 64 Jul 21 11:25 0 -> /dev/pts/4
    lrwx------ 1 root root 64 Jul 21 11:25 1 -> /dev/pts/4
    lrwx------ 1 root root 64 Jul 21 11:25 2 -> /dev/pts/4
    lrwx------ 1 root root 64 Jul 21 11:25 3 -> 'socket:[463392]'
    lrwx------ 1 root root 64 Jul 21 11:25 4 -> 'anon_inode:[eventpoll]'
    lrwx------ 1 root root 64 Jul 21 11:25 5 -> 'socket:[463398]'
    lrwx------ 1 root root 64 Jul 21 11:25 6 -> 'socket:[463409]'
    lrwx------ 1 root root 64 Jul 21 11:27 7 -> 'socket:[472139]'
    

    查看文件对应的socket连接

    # cat /proc/net/tcp | grep `echo "obase=16; 8443" | bc ` | awk '{print $2,$3,$10}'
    00000000:20FB 00000000:0000 0A 463409
    7C6615AC:20FB ACC96871:3EFC 01 472139
    

    上面都是16进制显示的,翻译成10进制如下

    本地                 远端                  inode
    0.0.0.0:8443        0.0.0.0:0             463409
    172.21.102.124:8443 113.104.201.172:16124 472139
    

    查看网络连接,跟上面的输出是一一对应的

    root@iZt4n3mancztn8h975gqptZ:~# netstat -ant | grep 8443
    tcp        0      0 0.0.0.0:8443            0.0.0.0:*               LISTEN
    tcp        0      0 172.21.102.124:8443     113.104.201.172:16124   ESTABLISHED
    

    下面把线索串联一下

    port(8443) -> pid(17985) -> inode(472139) -> tcp(172.21.102.124:8443,113.104.201.172:16124) -> client-ip(113.104.201.172)

    113.104.201.172是我本机的外网IP地址。现在可以确定,8443端口的数据是直接被用户进程kubelet接受并处理。后续可以再执行

    tcpdump -i cbr0 port 8443 -A -nn
    

    可以发现,kubelet确实转发数据到Pod的8443端口,进程是一个真实的TCP代理,负责从Node到Pod的访问流量转发,这种模式称为userspace(用户空间代理)模式。

    查看一下进程17985,发现总共有6个子进程,并且所有的子进程都共享同样的文件描述符。

    ps -eLf|grep 17985|grep -v "grep" | awk '{print $4}' | xargs -I {} ls -l /proc/{}/fd
    

    看起来是启用了SO_REUSEPORT,允许多个进程或者线程绑定到同一端口,提高服务器程序的性能,解决的问题:

    • 允许多个套接字 bind()/listen() 同一个TCP/UDP端口
      • 每一个线程拥有自己的服务器套接字
      • 在服务器套接字上没有了锁的竞争
    • 内核层面实现负载均衡
    • 安全层面,监听同一个端口的套接字只能位于同一个用户下面

    相关文章

      网友评论

        本文标题:microk8s(二)深入

        本文链接:https://www.haomeiwen.com/subject/lxemlctx.html