关于service
每个pod都有自己的IP地址,当controller用新的pod替代发生故障的pod的时候,这时IP地址就会发生变化,但是如果一组pod对外提供服务,那么这个时候IP地址就会发生变化,就无法再去通过IP地址访问服务,在k8s中就通过service去完成这个事。
kubernetes service从逻辑上代表了一组pod,具体是哪些,则是需要有label来选择,service有自己的一个IP,而且这个IP是不变的,客户端只需要访问这个service的IP地址,k8s负责建立和维护service和pod之间的映射,无论后端怎么变化,对客户端来说则是不会改变,因为service没有改变。
比如我们创建一个:
pod分配了各自的IP,这些IP只能被k8s cluster中的容器或者节点所访问:
这个时候我们创建一个service:
其中selector指明了挑选那些label为 run:httpd的pod作为service的后端,然后将TCP的8080端口映射到80端口上。
此时这个service就得到了一个cluster-IP,然后就通过该IP就可以访问后端的pod。
从图中我们可以看见,除了我们创建的一个service,还有service kubernetes,cluster内部通过这个service访问k8s api server。
此时,我们可以具体查看这个映射关系:
其中endpoints罗列了两个pod的IP和端口,pod的IP是在容器中配置的,service的cluster IP则是通过iptables来实现并且将其映射到pod IP上的。
关于cluster-IP
cluster-IP是一个虚拟IP,是由k8s节点上的iptables规则来管理的。当我们通过iptables-save查看当前规则的时候,其中有两条:
第一条:如果cluster内的pod(10.244.0.0)要访问http-svc,则允许。
第二条:其他地址访问http-svc则跳转到KUBE-SVC-LLMSFKRLGJ6BVN7Z
然后KUBE-SVC-LLMSFKRLGJ6BVN7Z的规则是:
有二分之一的概率跳转到KUBE-SEP-QR5DAR5CWYHCVCRA,剩下的几率跳到 KUBE-SEP-S3AQ2KACAP2OENJQ。
由此可以看见iptables将service的流量转发到后端pod,并且使用了相应的均衡负载策略。
kube-dns
kube-dns是一个DNS服务器,每当有新的service被创建,kube-dns会添加该service的DNS,cluster中的pod可以通过<SERVICE_NAME>.<NAMESPACE_NAME>访问service。
比如上面就可以通过service http-svc.default来访问app。
k8s提供了多种类型的service,默认是cluster-IP。
1、cluster IP:service通过cluster内部的IP对外提供服务,只有cluster内的节点和pod可以访问。
2、nodeport:service通过cluster节点的静态端口对外提供服务,cluster外部可以通过
比如我们修改一下http-svc的配置文件:
然后重新生成一个service,此时通过:
1 | kubectl get service http-svc -o wide |
其中,EXTERNAL—IP若为nodes,表示可通过cluster每个节点自身的IP访问services。PORTS前者表示为cluster的监听端口;后者表示节点上的监听端口,每个节点都会监听这个端口并将请求转发给service。任何一个节点都可以通过node的地址加端口来访问这个service。nodeport这种方式默认是随机选择一个端口,我们可以在配置文件中ports:内加入nodePort:30000来指定端口。
3、load balance:service利用云服务提供商提供的load balance对外提供服务,cloud provider负责将load balance的流量导向service。