Kubernetes资源管理之Service

1、概述

Kubernetes Service是对一组提供相同功能的Pod提供统一入口的抽象,借助Service,应用可以方便的实现服务发现与负载均衡,并实现应用的无缝升级。

2、原理

Service通过标签Label来选取后端服务,一般配合ReplicaSet或Deployment来保证后端容器的正常运行,这些匹配Label的Pod IP和端口列表组成endpoints,由kube-proxy负责将服务IP负载均衡到这些endpoint上。

3、工作模式

Service有三种工作方式,分别是userspace、iptables、ipvs

3.1、UserSpace

15-K8s网络之Service - 图1

如上图,client Pod要访问Server Pod时,先将请求发给本机内核空间中的service规则,由它将请求转发给监听在用户空间指定套接字上的kube-proxy,kube-proxy处理并分发请求到内核空间Service IP,由Service转发请求到Server Pod。

此方式需要频繁在用户空间和内核空间交互通信,效率很低。故在k8s 1.1以后均不在使用此模式

3.2、iptables

15-K8s网络之Service - 图2

此方式在client Pod发起请求后,由内核空间中的Service iptables规则接收,并直接调度给Server Pod

3.3、ipvs

15-K8s网络之Service - 图3

ipvs方式直接由内核中的ipvs规则来接收Client Pod请求,并处理该请求,由内核封包后,直接转发给Server Pod。要使用这种方式,必须要在系统中激活ipvs模块,若ipvs没有被激活,则会降级使用iptables模式。

:以上无论哪一种方式,kube-proxy都通过list-watch方式监控着kube-ApiServer写入etcd中关于Pod的最新状态信息,一旦检测到一个Pod资源有了更新,则立即将这些变化反应在iptables或ipvs规则中,以便iptables或ipvs在调度client pod请求到server pod时,不会出现pod不存在的情况。

4、Service四种类型

Service有四种类型,分别是ClusterIP、NodePort、LoadBalancer、ExternalName

4.1、ClusterIP

默认类型,用于集群内Pod访问时,提供固定的访问地址,默认是自动分配地址。

4.2、NodePort

基于ClusterIP,用于为集群外部访问Service后面Pod提供访问的入口,工作流程为:

  • Client ——>NodeIP:NodePort——>ClusterIP:ServicePort——>PodIP:ContainerPort(targetPort)

4.3、LoadBalancer

用于当K8s运行在云环境中,若该云环境支持LBaaS,则此类型可自动触发创建一个软件负载均衡用于对Service做负载均衡调度。

4.4、ExternalName

用于将集群外部的服务引入到集群内部,在集群内部可直接访问来获取服务。通过DNS Cname记录方式转发到指定的域名,需要kube-dns版本在1.7以上。

5、iptable/ipvs下Service规则解析

5.1、创建Service示例

  1. # 创建deployment
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. labels:
  6. app: webdepoyment
  7. name: webdepoyment
  8. spec:
  9. replicas: 3
  10. selector:
  11. matchLabels:
  12. app: webdepoyment
  13. strategy: {}
  14. template:
  15. metadata:
  16. labels:
  17. app: webdepoyment
  18. spec:
  19. containers:
  20. - image: nginx
  21. name: nginx
  22. resources: {}
  23. ---
  24. # 创建service
  25. apiVersion: v1
  26. kind: Service
  27. metadata:
  28. name: web-service
  29. namespace: default
  30. spec:
  31. selector: # 指定标签选择器选择的标签范围
  32. app: webdepoyment
  33. type: NodePort
  34. ports:
  35. - name: http
  36. port: 80 # 设定Service提供服务的端口
  37. targetPort: 80 # 设定容器Pod的端口
  38. nodePort: 30080 # 仅在type为NodePort时才需要指定,如不指定默认会自动分配

Service在对外提供服务时,还支持会话保持,字段为sessionAffinity,支持ClientIP和None两种方式。

  • None:不做会话保持,进行随机调度
  • ClientIP:根据客户端IP来调度,同一个客户端IP都调度到同一个Server Pod

可以在配置清单中配置或者通过补丁方式来增加配置:

$ kubectl patch svc myapp-service -p '{"spec":{"sessionAffinity":"ClientIP"}}'
$ kubectl describe svc myapp-service    #可以查看到多了一个Session Affinity的字段.
  • 查看service和pod信息
[root@k8s-master resource]# kubectl get pod,svc
NAME                                READY   STATUS    RESTARTS   AGE
pod/webdepoyment-78cff8f5f7-2jc52   1/1     Running   0          53m
pod/webdepoyment-78cff8f5f7-2xhgc   1/1     Running   0          53m
pod/webdepoyment-78cff8f5f7-cdt8l   1/1     Running   0          53m

NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP        3h4m
service/web-service   NodePort    10.105.144.52   <none>        80:30080/TCP   53m

5.2、iptable下Service路由规则

可以通过iptables-save |grep [ServiceName|链名]来查看

  • 第一步:所有访问10.105.144.52的tcp 80端口的请求都转发到KUBE-SVC-LHVVVX6K6XR7TB6A链
-A KUBE-SERVICES -d 10.105.144.52/32 -p tcp -m comment --comment "default/web-service:http cluster IP" -m tcp --dport 80 -j KUBE-SVC-LHVVVX6K6XR7TB6A
  • 第二步:对经过KUBE-SVC-LHVVVX6K6XR7TB6A链的流量进行权重设置,并转发到对应链处理。
    逐条匹配,匹配到第一条的几率为33.3%,如果未匹配第二条几率为50%,最后一条几率为100%。
-A KUBE-SVC-LHVVVX6K6XR7TB6A -m comment --comment "default/web-service:http" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-EF2MT6LT2XA6QOB5
-A KUBE-SVC-LHVVVX6K6XR7TB6A -m comment --comment "default/web-service:http" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-TSO6USMBI4DALFPR
-A KUBE-SVC-LHVVVX6K6XR7TB6A -m comment --comment "default/web-service:http" -j KUBE-SEP-5VVM6DLIDKSFKFVS
  • 第三步:最终将流量分发到对应的容器进行DNAT转发处理。
-A KUBE-SEP-EF2MT6LT2XA6QOB5 -p tcp -m comment --comment "default/web-service:http" -m tcp -j DNAT --to-destination 10.244.0.70:80
-A KUBE-SEP-TSO6USMBI4DALFPR -p tcp -m comment --comment "default/web-service:http" -m tcp -j DNAT --to-destination 10.244.92.7:80
-A KUBE-SEP-5VVM6DLIDKSFKFVS -p tcp -m comment --comment "default/web-service:http" -m tcp -j DNAT --to-destination 10.244.92.8:80

5.3、ipvs下Service路由规则

默认kube-proxy使用iptables规则,如果要切换成ipvs,需要满足以下条件:

  • 修改kube-proxy工作模式为ipvs。
  • 节点需安装ipvsadm组件。

5.3.1、切换节点为ipvs工作模式
kubectl edit configmap kube-proxy -n kube-system
# 修改mode字段为ipvs
yum -y install ipvsadm
# 安装ipvsadm组件
kubectl delete pod kube-proxy-gm2b2 -n kube-system
# 选择一个节点上的kube-proxy删除,重建此kube-proxy

5.3.2、查看ipvs规则
$ ipvsadm -L -n
TCP  10.211.55.102:30080 rr
  -> 10.244.0.70:80               Masq    1      0          0
  -> 10.244.92.7:80               Masq    1      0          0
  -> 10.244.92.8:80               Masq    1      0          0

默认ipvs使用rr调度方式将请求调度到后端real-server。

5.3.3、修改ipvs调度算法
kubectl edit configmap kube-proxy -n kube-system

# 修改字段scheduler为指定算法

5.4、ipvs和iptables对比

  • iptables

    • 灵活、功能强大
    • 规则遍历匹配和更新,呈线性时延。
  • ipvs

    • 工作在内核态,有更好的性能。
    • 调度算法丰富:rr、wrr、lc、wlc、ip hash等

6、HeadLess Service(无头服务)

所谓headless service是指,没有ClusterIP的Service,它仅有一个service name,这个服务名解析得到的不再是Service的集群IP,而是Pod的IP,当客户端访问该Service时,将直接获得Pod的IP,进行访问

apiVersion: v1
kind: Service
metadata:
  name: myapp-service-headless
  namespace: default
spec:
  selector:
    app: myapp
    release: canary
  clusterIP: None   # headless service的clusterip指定为None
  ports:
  - name: http
    port: 80
    targetPort: 80

创建完成后,可以通过dig来查看service解析的地址

$ dig -t A myapp-service-headless.default.svc.cluster.local. @10.96.0.10

;; ANSWER SECTION:
myapp-service-headless.default.svc.cluster.local. 30 IN A 10.244.1.64
myapp-service-headless.default.svc.cluster.local. 30 IN A 10.244.1.62
myapp-service-headless.default.svc.cluster.local. 30 IN A 10.244.1.66
myapp-service-headless.default.svc.cluster.local. 30 IN A 10.244.1.63
myapp-service-headless.default.svc.cluster.local. 30 IN A 10.244.1.65

7、Service DNS服务