在学习前要知道一个服务下可能有多个pod,每个pod可能在不同的主机上。一个主机可能有多个服务。而每个container又几乎模拟的是一个主机。所以不是只有主机才有ip和端口号。
容器网络实例
服务中的3个端口设置
这几个port的概念很容易混淆,比如创建如下service:
apiVersion: v1
kind: Service
metadata:
labels:
name: app1
name: app1
namespace: default
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 30062
selector:
name: app1
port
即,这里的port表示:service暴露在cluster ip上的端口,<cluster ip>:port
是提供给集群内部客户访问service的入口。
nodePort
首先,nodePort是kubernetes提供给集群外部客户访问service入口的一种方式(另一种方式是LoadBalancer),所以,<nodeIP>:nodePort
是提供给集群外部客户访问service的入口。
targetPort
targetPort很好理解,targetPort是pod上的端口,从port和nodePort上到来的数据最终经过kube-proxy流入到后端pod的targetPort上进入容器。
port、nodePort总结
总的来说,port和nodePort都是service的端口,前者暴露给集群内客户访问服务,后者暴露给集群外客户访问服务。从这两个端口到来的数据都需要经过反向代理kube-proxy流入后端pod的targetPod,从而到达pod上的容器内。
kube-proxy与iptables
当service有了port和nodePort之后,就可以对内/外提供服务。那么其具体是通过什么原理来实现的呢?奥妙就在kube-proxy在本地node上创建的iptables规则。
Kube-Proxy 通过配置 DNAT 规则(从容器出来的访问,从本地主机出来的访问两方面),将到这个服务地址的访问映射到本地的kube-proxy端口(随机端口)。然后 Kube-Proxy 会监听在本地的对应端口,将到这个端口的访问给代理到远端真实的 pod 地址上去。
kube-proxy会在nat表里生成4个chain,分别如上所示(主要是从容器出来的访问,从本地主机出来的访问两方面)。
创建service以后,kube-proxy会自动在集群里的node上创建以下两条规则:
KUBE-PORTALS-CONTAINER
KUBE-PORTALS-HOST
如果是NodePort方式,还会额外生成两条:
KUBE-NODEPORT-CONTAINER
KUBE-NODEPORT-HOST
KUBE-PORTALS-CONTAINER
主要将由网络接口到来的通过服务集群入口:port的请求重定向到本地kube-proxy端口(随机端口)的映射,即来自本地容器的服务访问请求;
注:我认为,这种情况的网络包不可能来自外部网络,因为cluster ip是个virtual ip,外部网络中不存在这样的路由将该数据包发送到本机;所以该请求只能来自本地容器,从本地容器出来的访问,服务访问请求是通过本地容器虚拟网卡输入到本地网络接口的。
KUBE-NODEPORT-CONTAINER
主要将由网络接口到来的通过服务集群外部入口:nodePort的请求重定向到本地kube-proxy端口(随机端口)的映射;即来自k8s集群外部网络的服务访问请求,可以来自本机容器,也可以来自其他node的容器,还可以来自其他node的进程;
KUBE-PORTALS-HOST
主要将该node本地进程通过服务集群入口:port的请求重定向到本地kube-proxy端口(随机端口)的映射。
KUBE-NODEPORT-HOST
主要将该node本地进程通过服务集群外部入口:nodePort的请求重定向到本地kube-proxy端口(随机端口)的映射。
kube-proxy反向代理
不管是通过集群内部服务入口:port还是通过集群外部服务入口:nodePort的请求都将重定向到本地kube-proxy端口(随机端口)的映射,然后将到这个kube-proxy端口的访问给代理到远端真实的 pod 地址上去。
案例
另一个案例
总结
所以这里我们要知道的关于ip的东西。
我们部署k8s的服务器肯定不是只有一台主机。一般是多台主机在一个局域网里面。并能为外界提供一个或多个外网ip。所以每台主机会有局域网ip和外网ip。局域网ip为192.168.xx.xx,而外网ip在阿里云或华为云的控制台中可以看到。
而k8s中对外提供服务的资源为service。一个k8s集群可能有多个service,要么使用端口号进行区分,要么使用ip地址+端口号进行区分。在k8s里面,为每个service设置了集群ip。10.233.xxx.xxx:port
如果设置了service的ports属性type为nodeport,则请求每个服务器192.168.xx.xx上的nodePort端口号,都会映射到该service上。而service里面包含多个容器组,不同的容器组部署在不同的服务器上,在service里面服务器为node。服务内部,可能会读取node上的数据,所以一个服务里面也会为node分配ip。不同service内,同一个服务器代表的node,nodeip是不一样的。