kubernetes service访问原理
k8s集群中有三类IP:
1:宿主机的物理网卡IP,比如192.168.255.*
2:cni创建的网卡的IP,比如172.16.*.*
3:虚拟的IP(即ClusterIP ,无法ping通,通过代理连接),172.19.*.*
如果在任何一台机器上查看网卡name能看到那么多网卡。如下图。
eth0是真实的网卡:IP段192.168.255.*
cni是k8s为了扁平化管理pod而创建的网卡,这里是172.16.1.1 那么其他节点可能就是172.16.2.1,172.16.3.1
其他看到很多veth的网卡实际上是跟cni网卡相连的。一个veth就代表一个pod,所以这个节点的pod ip就是172.16.1.*
不同节点的pod比如172.16.2.5->172.16.1.3是直接可以访问,底层实现的方式(隧道技术)可以不用太关注。
pod本身是没有状态的。也就是pod重启之后他的ip就发生了变化,所以这里引入了一个service作为服务访问的目标,service ip也是虚拟出的一个东西,比如起了一个nginx的pod,它关联了一个叫my-nginx的服务,那么以下是访问的一个流程。
1:任何一个pod访问my-nginx
2:从/etc/resolv.conf中配置的DNS服务器获取cluster ip地址。可以看到172.19.0.10这个作为DNS服务器,在集群安装的时候已经固定好了,在创建应用的时候会自动写入service 和cluster ip这样一个映射关系,那么pod就获得了my-nginx的cluster ip
3:k8s会在每个节点创建一个proxy的服务,由proxy创建iptable规则,当然在nginx创建的时候规则以及创建好了,当pod连接culster ip的时候就会被转发到nginx pod的ip,所以你通过service +port的形式连接有效,但是直接ping service是无法ping通的,iptable只实现的tcp/udp的转发