K8s service资源

service用途:
service 为后端pod提供一组负载均衡代理

  • userpace在这种模式下,kube-proxy监视Kubernetes主服务器以添加和删除Service和Endpoint对象。对于每个服务,它都会在本地节点上打开一个端口(随机选择)。与此代理端口的任何连接都代理到服务的后端Pod。SessionAffinity在决定使用哪个后端Pod时,kube-proxy会考虑服务的设置。最后,用户控件代理安装iptables规则,以获取服务clusterIP和流量port。规则将流量重定向到代理后端Pod的端口。


    4ec2d5628535e5dd2498b135256bf6e9cc1b62d3.png
  • iptables目前默认的方案,完全以内核iptables的nat方式实现service负载均衡。该方式在大规模情况下存在一些性能问题;首先,iptables没有增量更新的功能,更新一条规则需要整体flush,更新时间长,这段时间之内流量会有不同程度的影响;此外,iptables规则串行匹配,没有预料到Kubernetes这种在一个机器上会有很多规则的情况,流量需要经过所有规则的匹配后在进行转发,对时间和内存都是极大的小号,尤其在大规模情况下对性能的影响十分明显


    f703738da9773912504833aea9b4d71e347ae2c3.png
  • ipvs与iptables、userspace 模式一样,kube-proxy 依然监听Service以及Endpoints对象的变化, 不过它并不创建反向代理, 也不创建大量的 iptables 规则, 而是通过netlink 创建ipvs规则,并使用k8s Service与Endpoints信息,对所在节点的ipvs规则进行定期同步; netlink 与 iptables 底层都是基于 netfilter 钩子,但是 netlink 由于采用了 hash table 而且直接工作在内核态,在性能上比 iptables 更优


    48540923dd54564e3ea2821de073cd84d0584f06.png

同时,ipvs负载均衡除了简单rr规则还有很多选择,适合在大型集群中使用,而缺点是带来了额外的配置维护操作

简单点来说Service的请求先从用户空间进入内核iptables转发到这个端口,然后再回到用户空间,由kube-proxy完成后端endpoint的选择和代理,这样流量会有从用户空间进入内核的过程,效率低,有明显的性能瓶颈

使用Service服务还会涉及到几种IP:

  • ClusterIP
    Pod IP 地址是实际存在于某个网卡(可以是虚拟设备)上的,但clusterIP就不一样了,没有网络设备承载这个地址。它是一个虚拟地址,由kube-proxy使用iptables规则重新定向到其本地端口,再均衡到后端Pod。当kube-proxy发现一个新的service后,它会在本地节点打开一个任意端口,创建相应的iptables规则,重定向服务的clusterIP和port到这个新建的端口,开始接受到达这个服务的连接。

  • Pod IP
    Pod的IP,每个Pod启动时,会自动创建一个镜像为gcr.io/google_containers/pause的容器,Pod内部其他容器的网络模式使用container模式,并指定为pause容器的ID,即:network_mode: "container:pause容器ID",使得Pod内所有容器共享pause容器的网络,与外部的通信经由此容器代理,pause容器的IP也可以称为Pod IP。

  • 节点IP
    Node-IP,service对象在Cluster IP range池中分配到的IP只能在内部访问,如果服务作为一个应用程序内部的层次,还是很合适的。如果这个service作为前端服务,准备为集群外的客户提供业务,我们就需要给这个服务提供公共IP了。指定service的spec.type=NodePort,这个类型的service,系统会给它在集群的各个代理节点上分配一个节点级别的端口,能访问到代理节点的客户端都能访问这个端口,从而访问到服务。

创建一个Service

[root@node1 svc]# vim nginx_svc.yml
apiVsersion: v1
kind: Service    #资源类型
metadata:
  name: myweb  #名称
spec:
  type: NodePort  #形式,端口映射
  ports:
  - port: 80  #vip端口
    nodePort: 30000     #映射宿主机的端口 默认30000-32767
    targetPort: 80    #PodIp地址
  selector:
    app: myweb    #选择器,为myweb设置

创建

[root@node1 svc]# kubectl create -f nginx_svc.yml 
service "myweb" created

查看myweb

[root@node1 svc]# kubectl describe svc myweb 
Name:           myweb
Namespace:      default
Labels:         
Selector:       app=myweb
Type:           NodePort
IP:         10.254.129.217
Port:            80/TCP
NodePort:        30000/TCP
Endpoints:      172.16.102.3:80,172.16.20.2:80
Session Affinity:   None
No events.

使用浏览器可以访问

[http://192.168.1.103:30000/](http://192.168.1.103:30000/)

service服务自动发现

扩展Pod

[root@node1 svc]# kubectl scale rc myweb --replicas=3
replicationcontroller "myweb" scaled
[root@node1 svc]# kubectl get pod -o wide
NAME          READY     STATUS    RESTARTS   AGE       IP             NODE
myweb-0x2z8   1/1       Running   0          29m       172.16.20.2    192.168.1.103
myweb-45qvj   1/1       Running   0          29m       172.16.102.3   192.168.1.114
myweb-phmvg   1/1       Running   0          7s        172.16.14.3    192.168.1.113

Pod会自动加入svc

[root@node1 svc]# kubectl describe svc myweb 
Name:           myweb
Namespace:      default
Labels:         
Selector:       app=myweb
Type:           NodePort
IP:         10.254.129.217
Port:            80/TCP
NodePort:        30000/TCP
Endpoints:      172.16.102.3:80,172.16.14.3:80,172.16.20.2:80
Session Affinity:   None
No events.

service负载均衡

编写页面放入到Pod当中

[root@node1 svc]# echo 'node1' >> index.html
[root@node1 svc]# kubectl cp index.html myweb-0x2z8:/usr/share/nginx/html/index.html
[root@node1 svc]# echo 'node2' > index.html
[root@node1 svc]# kubectl cp index.html myweb-45qvj:/usr/share/nginx/html/index.html
[root@node1 svc]# echo 'node3' > index.html
[root@node1 svc]# kubectl cp index.html myweb-phmvg:/usr/share/nginx/html/index.html

访问IP可以实现轮询

参考文章
https://baijiahao.baidu.com/s?id=1660475099516957179&wfr=spider&for=pc

你可能感兴趣的:(K8s service资源)