当前位置:   article > 正文

k8s中Service负载均衡和Service类型介绍_service负载均衡策略

service负载均衡策略

目录

一.service介绍

二.service参数详解

三.定义service的两种方式

1.命令行expose

2.yaml文件

四.service负载均衡配置

1.kube-proxy代理模式

(1)设置ipvs

(2)负载均衡调度策略

2.会话保持

3.案例演示

五.四种Service类型

1.clusterip

2.NodePort

3.LoadBalancer

4.ExternalName


一.service介绍

之前我们讲到的pod创建,里面有服务需要被集群内部访问或被外界访问,这样情况我们就需要借助service来为应用提供统一入口地址,他主要提供网络服务,将请求按负载均衡算法分发到各个容器。在访问时,pod的IP地址时会变化的,显然在pod提供稳定服务时不能通过IP地址去访问。

二.service参数详解

  1. apiVersion: v1 #必写
  2. kind: Service   #必写
  3. metadata:   #必写
  4. annotations:   #自定义的注解属性列表
  5.   kubectl.kubernetes.io/last-applied-configuration: |
  6.     {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"my-nginx","namespace":"myns"},"spec":{"ports":[{"port":80,"protocol":"TCP","targetPort":80}],"selector":{"name":"my-nginx"}}}
  7. creationTimestamp: "2023-12-02T01:18:01Z"
  8. name: my-nginx   #必写
  9. namespace: myns   #必写,建议和你创建pod和pod控制器的名称空间一致
  10. resourceVersion: "1537"
  11. uid: ab1bb8ce-be87-48d4-8396-5e802dfbca8c
  12. spec:   #必写
  13. clusterIP: 10.109.39.11 #虚拟IP,当type=ClusterIP时设置,可以自己指定,也可以不写等系统自己分配
  14. clusterIPs:
  15. - 10.109.39.11
  16. internalTrafficPolicy: Cluster
  17. ipFamilies:
  18. - IPv4
  19. ipFamilyPolicy: SingleStack
  20. ports:   #端口暴露情况
  21. - port: 80 #服务监听的端口
  22.   protocol: TCP #端口协议,默认TCP,支持TCP/UDP
  23.   targetPort: 80 #转发到后端pod的端口
  24.   nodePort: number   #type=NodePort时设置,映射到主机的端口,可以自己指定也可以不写等系统分配,设置了type=NodePort,其他节点和外界就可以通过“此主机地址+这个端口号”进行访问
  25. selector:   #选择器,必写
  26.   name: my-nginx #注意一致性
  27. sessionAffinity: None #是否支持session,默认none,也可以填写ClientIP,表示根据客户端IP来将同一个客户端请求分配到同一个pod
  28. type: ClusterIP #类型选择,ClusterIP、NodePort、LoadBalancer,后面会详细介绍
  29. status:   #当type=LoadBalancer时这只,设置外部负载均衡器的地址(公有云环境),后面演示的时候介绍
  30. loadBalancer: {}

三.定义service的两种方式

1.命令行expose

这里创建一个关于nginx服务的3个副本数的pod,并且使用expose方式为其创建service,其中,--port=80指定nginx服务监听端口,--type=ClusterIP指定类型, --target-port=80指定转发到后端某端口,并使用暴露出来的IP进行访问验证是否成功。

  1. [root@k8s-master service]# cat service1.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. labels:
  6.   name: my-nginx
  7. name: my-nginx
  8. namespace: myns
  9. spec:
  10. replicas: 3
  11. selector:
  12.   matchLabels:
  13.     name: my-nginx
  14. template:
  15.   metadata:
  16.     labels:
  17.       name: my-nginx
  18.   spec:
  19.     containers:
  20.     - name: my-nginx-pod
  21.       image: nginx
  22.       ports:
  23.       - containerPort: 80
  24. [root@k8s-master service]# kubectl get pods -n myns
  25. NAME                       READY   STATUS   RESTARTS   AGE
  26. my-nginx-7c787d8bb-g6fb5   1/1     Running   0         9s
  27. my-nginx-7c787d8bb-t5jdh   1/1     Running   0         9s
  28. my-nginx-7c787d8bb-znd22   1/1     Running   0         9s
  29. [root@k8s-master service]# kubectl get deploy -n myns
  30. NAME       READY   UP-TO-DATE   AVAILABLE   AGE
  31. my-nginx   3/3     3           3           15s
  32. [root@k8s-master service]# kubectl expose deployment my-nginx -n myns --port=80 --type=ClusterIP --target-port=80
  33. service/my-nginx exposed
  34. [root@k8s-master service]# kubectl get service -n myns #使用下方IP进行访问
  35. NAME       TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
  36. my-nginx   ClusterIP   10.111.4.81   <none>       80/TCP   6s
  37. [root@k8s-master service]# curl 10.111.4.81
  38. <!DOCTYPE html>
  39. <html>
  40. <head>
  41. <title>Welcome to nginx!</title>
  42. <style>
  43. html { color-scheme: light dark; }
  44. body { width: 35em; margin: 0 auto;
  45. font-family: Tahoma, Verdana, Arial, sans-serif; }
  46. </style>
  47. </head>
  48. <body>
  49. <h1>Welcome to nginx!</h1>
  50. <p>If you see this page, the nginx web server is successfully installed and
  51. working. Further configuration is required.</p>
  52. <p>For online documentation and support please refer to
  53. <a href="http://nginx.org/">nginx.org</a>.<br/>
  54. Commercial support is available at
  55. <a href="http://nginx.com/">nginx.com</a>.</p>
  56. <p><em>Thank you for using nginx.</em></p>
  57. </body>
  58. </html>
  59. [root@k8s-node1 ~]# curl 10.111.4.81   #在node1上访问,验证ClusterIP集群内部访问是否成功
  60. <!DOCTYPE html>
  61. <html>
  62. <head>
  63. <title>Welcome to nginx!</title>
  64. <style>
  65. html { color-scheme: light dark; }
  66. body { width: 35em; margin: 0 auto;
  67. font-family: Tahoma, Verdana, Arial, sans-serif; }
  68. </style>
  69. </head>
  70. <body>
  71. <h1>Welcome to nginx!</h1>
  72. <p>If you see this page, the nginx web server is successfully installed and
  73. working. Further configuration is required.</p>
  74. <p>For online documentation and support please refer to
  75. <a href="http://nginx.org/">nginx.org</a>.<br/>
  76. Commercial support is available at
  77. <a href="http://nginx.com/">nginx.com</a>.</p>
  78. <p><em>Thank you for using nginx.</em></p>
  79. </body>
  80. </html>

2.yaml文件

这里在上面的deployment基础上继续配置service,ports部分和selector部分显得尤为重要,具体看代码注释

  1. [root@k8s-master service]# cat service1.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. labels:
  6.   name: my-nginx
  7. name: my-nginx
  8. namespace: myns
  9. spec:
  10. replicas: 3
  11. selector:
  12.   matchLabels:
  13.     name: my-nginx-deploy
  14. template:
  15.   metadata:
  16.     labels:
  17.       name: my-nginx-deploy
  18.   spec:
  19.     containers:
  20.     - name: my-nginx-pod
  21.       image: nginx
  22.       ports:
  23.       - containerPort: 80
  24. ---
  25. apiVersion: v1
  26. kind: Service
  27. metadata:
  28. name: my-nginx-service
  29. namespace: myns
  30. spec:
  31. ports:  
  32. - protocol: TCP   #TCP协议
  33.   targetPort: 80   #转发到后端pod的80端口
  34.   port: 80   #服务监听80端口
  35. selector:   #与deploy上面的模板进行匹配,表示为标签为name: my-nginx-deploy的pod开放服务
  36.   name: my-nginx-deploy        
  37. [root@k8s-master service]# kubectl apply -f service1.yaml
  38. deployment.apps/my-nginx created
  39. service/my-nginx-service created
  40. [root@k8s-master service]# kubectl get service -n myns
  41. NAME               TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
  42. my-nginx-service   ClusterIP   10.98.64.75   <none>       80/TCP   7s
  43. [root@k8s-master service]# curl 10.98.64.75
  44. <!DOCTYPE html>
  45. <html>
  46. <head>
  47. <title>Welcome to nginx!</title>
  48. <style>
  49. html { color-scheme: light dark; }
  50. body { width: 35em; margin: 0 auto;
  51. font-family: Tahoma, Verdana, Arial, sans-serif; }
  52. </style>
  53. </head>
  54. <body>
  55. <h1>Welcome to nginx!</h1>
  56. <p>If you see this page, the nginx web server is successfully installed and
  57. working. Further configuration is required.</p>
  58. <p>For online documentation and support please refer to
  59. <a href="http://nginx.org/">nginx.org</a>.<br/>
  60. Commercial support is available at
  61. <a href="http://nginx.com/">nginx.com</a>.</p>
  62. <p><em>Thank you for using nginx.</em></p>
  63. </body>
  64. </html>

四.service负载均衡配置

1.kube-proxy代理模式

这里主要介绍ipvs代理,他实现从service到后端endpoint的负载分发任务,相较于旧版本的userspace和iptables来讲,ipvs具有更高的转发效率和吞吐率,也支持更多的负载均衡策略接下来介绍如何开启ipvs(之前介绍label那篇文章也讲到过),若不开启,会自动切换到iptables。

(1)设置ipvs

  1. [root@k8s-master service]# lsmod | grep ip_vs   #加载查看内核模块
  2. ip_vs_sh               12688 0
  3. ip_vs_wrr             12697 0
  4. ip_vs_rr               12600 0
  5. ip_vs                 145458 6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
  6. nf_conntrack         139264 10 ip_vs,nf_nat,nf_nat_ipv4,nf_nat_ipv6,xt_conntrack,nf_nat_masquerade_ipv4,nf_nat_masquerade_ipv6,nf_conntrack_netlink,nf_conntrack_ipv4,nf_conntrack_ipv6
  7. libcrc32c             12644 4 xfs,ip_vs,nf_nat,nf_conntrack
  8. #将node部分改为ipvs
  9. [root@k8s-master service]# kubectl edit configmap kube-proxy -n kube-system
  10. configmap/kube-proxy edited
  11. metricsBindAddress: ""
  12.   mode: "ipvs"
  13.   nodePortAddresses: null
  14.   oomScoreAdj: null
  15. #删除kube-proxy的pod,自动重新拉取
  16. [root@k8s-master service]# kubectl get pods -n kube-system | grep kube-proxy
  17. kube-proxy-95q7f                           1/1     Running   0         94m
  18. kube-proxy-qf7wh                           1/1     Running   0         92m
  19. kube-proxy-rtg5c                           1/1     Running   0         92m
  20. [root@k8s-master service]# kubectl delete pod kube-proxy-95q7f kube-proxy-qf7wh kube-proxy-rtg5c -n kube-system
  21. pod "kube-proxy-95q7f" deleted
  22. pod "kube-proxy-qf7wh" deleted
  23. pod "kube-proxy-rtg5c" deleted
  24. [root@k8s-master service]# kubectl get pods -n kube-system | grep kube-proxy
  25. kube-proxy-7b5fc                           1/1     Running   0         6s
  26. kube-proxy-pvv6k                           1/1     Running   0         6s
  27. kube-proxy-vbfnd                           1/1     Running   0         6s
  28. #验证生效
  29. [root@k8s-master service]# kubectl logs kube-proxy-7b5fc -n kube-system | grep ipvs
  30. I1202 02:44:06.831781       1 server_others.go:218] "Using ipvs Proxier"
  31. [root@k8s-master service]# ipvsadm -Ln
  32. IP Virtual Server version 1.2.1 (size=4096)
  33. Prot LocalAddress:Port Scheduler Flags
  34. -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
  35. TCP 192.168.2.150:30572 rr
  36. -> 10.244.36.75:80             Masq   1     0         0        
  37. -> 10.244.169.147:80           Masq   1     0         0        
  38. -> 10.244.169.148:80           Masq   1     0         0        
  39. TCP 10.96.0.1:443 rr
  40. -> 192.168.2.150:6443           Masq   1     1         0        
  41. TCP 10.96.0.10:53 rr
  42. -> 10.244.235.193:53           Masq   1     0         0        
  43. -> 10.244.235.194:53           Masq   1     0         0        
  44. TCP 10.96.0.10:9153 rr
  45. -> 10.244.235.193:9153         Masq   1     0         0        
  46. -> 10.244.235.194:9153         Masq   1     0         0        
  47. TCP 10.98.197.131:80 rr
  48. -> 10.244.36.75:80             Masq   1     0         0        
  49. -> 10.244.169.147:80           Masq   1     0         0        
  50. -> 10.244.169.148:80           Masq   1     0         0        
  51. TCP 10.244.235.192:30572 rr
  52. -> 10.244.36.75:80             Masq   1     0         0        
  53. -> 10.244.169.147:80           Masq   1     0         0        
  54. -> 10.244.169.148:80           Masq   1     0         0        
  55. UDP 10.96.0.10:53 rr
  56. -> 10.244.235.193:53           Masq   1     0         0        
  57. -> 10.244.235.194:53           Masq   1     0         0      

(2)负载均衡调度策略

rr(Round Robin):轮询算法,将请求按照顺序依次分发给后端服务器。每个请求都按照先后顺序分配给下一个服务器,直到所有服务器都被分配到一个请求。然后再从头开始循环。

lc(Least Connections):最小连接数算法,将请求分发给当前连接数最少的服务器。通过监视服务器上的活动连接数并选择最少连接的服务器,可以实现负载均衡。

dh(Destination Hashing):目标哈希算法,根据请求的特定目标信息(例如源 IP 地址或会话 ID)计算哈希值,并将请求分发给与哈希值匹配的服务器。这样可以确保相同的请求始终被分发到相同的服务器上。

sh(Source Hashing):源哈希算法,类似于目标哈希算法,但是使用源 IP 地址而不是目标信息来计算哈希值。这样可以确保来自同一来源的请求始终被发送到同一台服务器。

sed(Shortest Expected Delay):最短期望延迟算法,根据每个服务器的预计延迟时间来选择服务器。该算法会考虑服务器的负载和延迟,并选择具有最短预计延迟的服务器来处理请求。

nq(Nginx Queue):Nginx 队列算法(永不排队),将请求放入队列中,并按照特定规则进行调度。这种算法通常与 Nginx 反向代理服务器一起使用,可以根据不同的规则(例如权重、连接数等)进行请求调度。

2.会话保持

通过sessionAffinity设置首次将客户端发起的请求发送某pod,之后的该客户端的请求都发往此pod,同时还可以配置timeoutSeconds:为其设置会话保持时间,详情见案例演示。

3.案例演示

没设置会话保持时,自动按照算法按照调度给3个pod(pod配置不同的页面以方面验证)

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. labels:
  5.   name: my-nginx
  6. name: my-nginx
  7. namespace: myns
  8. spec:
  9. replicas: 3
  10. selector:
  11.   matchLabels:
  12.     name: my-nginx-deploy
  13. template:
  14.   metadata:
  15.     labels:
  16.       name: my-nginx-deploy
  17.   spec:
  18.     containers:
  19.     - name: my-nginx-pod
  20.       image: nginx
  21.       ports:
  22.       - containerPort: 80
  23. ---
  24. apiVersion: v1
  25. kind: Service
  26. metadata:
  27. name: my-nginx-service
  28. namespace: myns
  29. spec:
  30. ports:
  31. - port: 80
  32.   protocol: TCP
  33.   targetPort: 80
  34. selector:
  35.   name: my-nginx-deploy
  36. type: ClusterIP
  37. [root@k8s-master service]# curl 10.107.18.89
  38. pod3
  39. [root@k8s-master service]# curl 10.107.18.89
  40. pod2
  41. [root@k8s-master service]# curl 10.107.18.89
  42. pod1
  43. [root@k8s-master service]# curl 10.107.18.89
  44. pod3
  45. [root@k8s-master service]# curl 10.107.18.89
  46. pod2

配置会话保持

  1. [root@k8s-master service]# cat service1.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. labels:
  6.   name: my-nginx
  7. name: my-nginx
  8. namespace: myns
  9. spec:
  10. replicas: 3
  11. selector:
  12.   matchLabels:
  13.     name: my-nginx-deploy
  14. template:
  15.   metadata:
  16.     labels:
  17.       name: my-nginx-deploy
  18.   spec:
  19.     containers:
  20.     - name: my-nginx-pod
  21.       image: nginx
  22.       ports:
  23.       - containerPort: 80
  24. ---
  25. apiVersion: v1
  26. kind: Service
  27. metadata:
  28. name: my-nginx-service
  29. namespace: myns
  30. spec:
  31. sessionAffinity: ClientIP
  32. sessionAffinityConfig:
  33.   clientIP:
  34.     timeoutSeconds: 10
  35. ports:
  36. - port: 80
  37.   protocol: TCP
  38.   targetPort: 80
  39. selector:
  40.   name: my-nginx-deploy
  41. type: ClusterIP
  42. [root@k8s-master service]# curl 10.107.18.89
  43. pod1
  44. [root@k8s-master service]# curl 10.107.18.89
  45. pod1
  46. [root@k8s-master service]# curl 10.107.18.89
  47. pod1
  48. [root@k8s-master service]# curl 10.107.18.89
  49. pod1
  50. [root@k8s-master service]# curl 10.107.18.89
  51. pod1
  52. [root@k8s-master service]# curl 10.107.18.89
  53. pod1
  54. [root@k8s-master service]# curl 10.107.18.89
  55. pod1
  56. [root@k8s-master service]# curl 10.107.18.89
  57. pod1
  58. [root@k8s-master service]# curl 10.107.18.89
  59. pod1

五.四种Service类型

1.clusterip

上面已经讲到clusterip是集群内部访问类型,并且已经演示,接下来介绍其他类型

2.NodePort

这个类型使得服务不仅可以被集群内部访问,还可以被集群外部访问,nodeport暴露的是TCP4层,但会对集群节点主机端口产生占用,不适合大规模使用。需要注意的是:指定了类型为nodeport后,指定或自定暴露出来的端口的node的port(主机port),那么集群外部访问就需要使用node的ip(主机ip)+ node的port去访问。若是指定端口,应保持在30000-32767这个范围内。

  1. [root@k8s-master service]# cat service1.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. labels:
  6.   name: my-nginx
  7. name: my-nginx
  8. namespace: myns
  9. spec:
  10. replicas: 3
  11. selector:
  12.   matchLabels:
  13.     name: my-nginx-deploy
  14. template:
  15.   metadata:
  16.     labels:
  17.       name: my-nginx-deploy
  18.   spec:
  19.     containers:
  20.     - name: my-nginx-pod
  21.       image: nginx
  22.       ports:
  23.       - containerPort: 80
  24. ---
  25. apiVersion: v1
  26. kind: Service
  27. metadata:
  28. name: my-nginx-service
  29. namespace: myns
  30. spec:
  31. ports:
  32. - port: 80
  33.   protocol: TCP
  34.   targetPort: 80
  35.   nodePort: 30572 #指定暴露node上的端口
  36. selector:
  37.   name: my-nginx-deploy
  38. type: NodePort #指定类型
  39. [root@k8s-master service]# kubectl apply -f service1.yaml
  40. deployment.apps/my-nginx unchanged
  41. service/my-nginx-service created
  42. [root@k8s-master service]# kubectl get service -n myns
  43. NAME               TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)       AGE
  44. my-nginx-service   NodePort   10.98.197.131   <none>       80:30572/TCP   9s
  45. #如下,集群内部同样可以使用clusterip进行访问
  46. [root@k8s-node1 ~]# curl 10.98.197.131
  47. <!DOCTYPE html>
  48. <html>
  49. <head>
  50. <title>Welcome to nginx!</title>
  51. <style>
  52. html { color-scheme: light dark; }
  53. body { width: 35em; margin: 0 auto;
  54. font-family: Tahoma, Verdana, Arial, sans-serif; }
  55. </style>
  56. </head>
  57. <body>
  58. <h1>Welcome to nginx!</h1>
  59. <p>If you see this page, the nginx web server is successfully installed and
  60. working. Further configuration is required.</p>
  61. <p>For online documentation and support please refer to
  62. <a href="http://nginx.org/">nginx.org</a>.<br/>
  63. Commercial support is available at
  64. <a href="http://nginx.com/">nginx.com</a>.</p>
  65. <p><em>Thank you for using nginx.</em></p>
  66. </body>
  67. </html>

  如下图,集群外部要使用主机地址+该端口进行访问

76346aa2c54e4906b15afa1d1718d6db.png

3.LoadBalancer

对外暴露服务的基础上又可以做负载均衡,LoadBalancer类型专属于云服务,可以动态分配网关,又可以分为 MetalLB 、PureLB 、OpenELB,之后的文章会讲述几类负载均衡器如何使用。

4.ExternalName

它允许将 Kubernetes 集群内部的服务映射到集群外部的服务地址。这种服务类型通常用于需要访问集群外部服务的情况,在 Pod 内部,你可以通过该 Service 的名称来进行访问,Kubernetes 会负责将请求路由到外部服务地址

  1. [root@k8s-master service]# cat service2.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. labels:
  6.   name: my-nginx
  7. name: my-nginx
  8. namespace: myns
  9. spec:
  10. replicas: 3
  11. selector:
  12.   matchLabels:
  13.     name: my-nginx-deploy
  14. template:
  15.   metadata:
  16.     labels:
  17.       name: my-nginx-deploy
  18.   spec:
  19.     containers:
  20.     - name: my-nginx-pod
  21.       image: nginx
  22.       ports:
  23.       - containerPort: 80
  24. ---
  25. apiVersion: v1
  26. kind: Service
  27. metadata:
  28. name: my-nginx-service
  29. namespace: myns
  30. spec:
  31. ports:
  32. - port: 80
  33.   protocol: TCP
  34.   targetPort: 80
  35. selector:
  36.   name: my-nginx-deploy
  37. type: ExternalName   #指定类型为ExternalName
  38. externalName: www.baidu.com   #要访问的外部地址,可以是域名、IP等
  39. [root@k8s-master service]# kubectl get pods -n myns
  40. NAME                       READY   STATUS   RESTARTS   AGE
  41. my-nginx-5d67c8f488-48dsc   1/1     Running   0         19m
  42. my-nginx-5d67c8f488-mn9qt   1/1     Running   0         19m
  43. my-nginx-5d67c8f488-xgbgw   1/1     Running   0         19m
  44. # nslookup my-nginx-service
  45. Server: 10.96.0.10
  46. Address: 10.96.0.10#53
  47. my-nginx-service.myns.svc.cluster.local canonical name = www.baidu.com.
  48. Name: www.baidu.com
  49. Address: 39.156.66.14
  50. Name: www.baidu.com
  51. Address: 39.156.66.18
  52. Name: www.baidu.com
  53. Address: 2409:8c00:6c21:104f:0:ff:b03f:3ae
  54. Name: www.baidu.com
  55. Address: 2409:8c00:6c21:1051:0:ff:b0af:279a
  56. # ping my-nginx-service
  57. PING www.baidu.com (39.156.66.18): 56 data bytes
  58. 64 bytes from 39.156.66.18: icmp_seq=0 ttl=127 time=43.167 ms
  59. 64 bytes from 39.156.66.18: icmp_seq=1 ttl=127 time=147.273 ms
  60. 64 bytes from 39.156.66.18: icmp_seq=2 ttl=127 time=53.310 ms
  61. ^C--- www.baidu.com ping statistics ---
  62. 3 packets transmitted, 3 packets received, 0% packet loss
  63. round-trip min/avg/max/stddev = 43.167/81.250/147.273/46.869 ms
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/982031
推荐阅读
相关标签
  

闽ICP备14008679号