第六章 Kubernetes Service-概念原理

目录

一、Service概述

二、没有Service存在的问题

三、增加Service层

四、Service核心原理

Service的迭代历史

1、userspace运行模式

2、iptables代理运行模式

3、ipvs代理运行模式

五、修改kube-proxy工作模式为ipvs

1、创建deployment控制器

2、创建service

3、修改kube-proxy模式为ipvs

4、重启kube-proxy让修改生效


Service+kube-proxy结合可以实现对目标pod构建为一个服务集群,并通过统一的服务IP地址暴露给用户访问。其中Service可以通过标签选择器对目标pod的抓取,并形成所谓的集群,kube-proxy通过三种工作模式实现对用户访问的路由分发到目标pod上。

一、Service概述

Service可以实现对集群中服务暴露。

上图中,我们有3个Frontend v1的pod,他们是通过名为Frontend的Deployment控制器产生的。对于我们来讲如何对外部用户暴露Frontend v1的服务呢,可以通过Service来实现。简单来说,我们的pod就绪探测成功后,service的标签选择器会进行抓取甄别,符合标签选择器条件的就会被service通抓取到,然后放到负载均衡集群里面,实现我们的负载访问。

外部用户通过外部端点frontend service,负载均衡到多个pod上,怎么负载到pod上的呢,就是通过service标签选择器,满足两个条件:app=webapp, role=frontend的pod会被负载。

二、没有Service存在的问题

如下图,我们有两类app,一类是tomcat,提供前后端服务的,一类是Nginx,提供负载均衡的。

Tomcat有3个副本,假如其中一个副本pod出现异常退出了,deployment会检测到,所以会重新起一个pod副本,新的pod会有新的IP,但是nginx并不知道新的ip可以路由过去做负载,就会导致新的tomcat的pod空转。当然我们也有办法可以来规避这个问题,比如nginx通过域名来访问tomcat,而不是通过ip地址。

三、增加Service层

增加Service之后的情况如下图:

Service插入到两层之间,形成一个中间层。具体的话通过创建一个tomcat的Service,他的选择器匹配app=tomcat。一旦service创建成功,标签选择器就会把探测到app=tomcat的pod抓取放到一个负载均衡的集群里面。

如果deployment-Tomcat 3副本中有一个副本死掉了,service维护的集群中就会将该pod剔除出去,如果新增加了一个pod,且app=tomcat的话,service会抓取该pod进入集群中,这个pod就可以提供负载访问了。

deployment-nginx的话,他只需要在proxy-pass里面设置service的ip即可。只要kubernetes集群不死掉,当前的service对象就会一直存在。 这样外部用户的访问经过nginx,反向代理到service,service会把访问路由负载到刚才抓取形成的负载均衡集群里面。

Service提供的是4层负载均衡服务。

四、Service核心原理

Service的迭代历史

1、userspace运行模式

kube-proxy的主要作用:

1)监听apiServer,将service对象变化(集群负载均衡信息)修改本地的iptables规则;

2)代理来自当前节点pod的用户请求。当流量比较大的时候,proxy的压力会比较大。

2、iptables代理运行模式

kube-proxy的主要作用相比上一代只有第一项功能了:

1)监听apiServer,将service对象变化(集群负载均衡信息)修改本地的iptables规则;

优点:kube-proxy不再承接对server的请求以及代理返回给client的结果了。这样不会因为本机pod数量增多导致proxy的压力增大的情况。

3、ipvs代理运行模式

四层负载均衡里面,ipvs是优于iptables组件的,性能更强的。

为什么我们安装k8s集群之后默认启用的是iptables而不是ipvs呢,因为可能有些机器没有安装ipvs或者内核中没有开启ipvs,所以不能默认采用ipvs,而iptables是基本上都是安装的。

五、修改kube-proxy工作模式为ipvs

1、创建deployment控制器

创建deployment控制器,并扩容到10个pod。

root@k8s-master01 5\]# kubectl create deployment myapp --image=nginx:v1 deployment.apps/myapp created \[root@k8s-master01 5\]# kubectl get pod NAME READY STATUS RESTARTS AGE myapp-6cc4846d7f-wsjd8 1/1 Running 0 24s \[root@k8s-master01 5\]# kubectl scale deployment myapp --replicas=10 deployment.apps/myapp scaled \[root@k8s-master01 5\]# kubectl get pod NAME READY STATUS RESTARTS AGE myapp-6cc4846d7f-2smpw 1/1 Running 0 4s myapp-6cc4846d7f-5fwmm 1/1 Running 0 4s myapp-6cc4846d7f-5vnrs 1/1 Running 0 4s myapp-6cc4846d7f-7hvn7 1/1 Running 0 4s myapp-6cc4846d7f-q8p9f 1/1 Running 0 4s myapp-6cc4846d7f-rc6kg 1/1 Running 0 4s myapp-6cc4846d7f-wjlh6 1/1 Running 0 4s myapp-6cc4846d7f-wsjd8 1/1 Running 0 65s myapp-6cc4846d7f-xvszm 1/1 Running 0 4s myapp-6cc4846d7f-z7q8b 1/1 Running 0 4s ### 2、创建service \[root@k8s-master01 5\]# kubectl create svc clusterip myapp --tcp=80:80 service/myapp created \[root@k8s-master01 5\]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.0.0.1 \ 443/TCP 10d myapp ClusterIP 10.13.55.128 \ 80/TCP 3m39s 我们检查下服务是否正常能够访问。 \[root@k8s-master01 5\]# curl 10.13.55.128 Welcome to Nginx V1.0 !!! 结果:服务访问正常,service对象创建成功。 查看ipvs是否被启用 \[root@k8s-master01 5\]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -\> RemoteAddress:Port Forward Weight ActiveConn InActConn 结果:没有启用ipvs,所以系统默认启用的是iptables。接下来我们通过修改kube-proxy的configmap配置文件中mode工作模式的默认值为ipvs。 ### 3、修改kube-proxy模式为ipvs 执行命令:kubectl edit configmap kube-proxy -n kube-system 修改kube-proxy的configmap,修改里面的mode参数。-n表示命名空间。 configmap是专门存储当前配置参数的一种存储方式或存储类型,下一章会讲解到。 注意:-n没有的话,默认是default命名空间。 \[root@k8s-master01 5\]# kubectl edit configmap kube-proxy -n kube-system configmap/kube-proxy edited 如下图,左图是未修改前,右图为修改mode=ipvs。 ![](https://i-blog.csdnimg.cn/direct/9f70c2b0ac6345b2a67b580c00860282.png)![](https://i-blog.csdnimg.cn/direct/002415058a134d2ebc7e16c4f9609b28.png) ### 4、重启kube-proxy让修改生效 上面只是修改了mode参数,要让mode参数生效,还需要重启kube-proxy。 \[root@k8s-master01 5\]# kubectl get pod -n kube-system -l k8s-app=kube-proxy NAME READY STATUS RESTARTS AGE kube-proxy-6z8h4 1/1 Running 2 (4d14h ago) 10d kube-proxy-8rmhn 1/1 Running 2 (4d14h ago) 10d kube-proxy-dv4bk 1/1 Running 2 (4d14h ago) 10d 将kube-proxy杀死重建: \[root@k8s-master01 5\]# kubectl delete pod -n kube-system -l k8s-app=kube-proxy pod "kube-proxy-6z8h4" deleted pod "kube-proxy-8rmhn" deleted pod "kube-proxy-dv4bk" deleted \[root@k8s-master01 5\]# kubectl get pod -n kube-system NAME READY STATUS RESTARTS AGE calico-kube-controllers-5fc7d6cf67-8jfs6 1/1 Running 2 (4d14h ago) 10d calico-node-4xntb 1/1 Running 2 (4d14h ago) 10d calico-node-m5rm6 1/1 Running 2 (4d14h ago) 10d calico-node-nwvp6 1/1 Running 2 (4d14h ago) 10d coredns-857d9ff4c9-7nf6s 1/1 Running 2 (4d14h ago) 10d coredns-857d9ff4c9-j8rwt 1/1 Running 2 (4d14h ago) 10d etcd-k8s-master01 1/1 Running 2 (4d14h ago) 10d kube-apiserver-k8s-master01 1/1 Running 3 (4d22h ago) 10d kube-controller-manager-k8s-master01 1/1 Running 3 (26h ago) 10d kube-proxy-bd8q6 1/1 Running 0 23s kube-proxy-rqcq2 1/1 Running 0 23s kube-proxy-xm9jf 1/1 Running 0 23s kube-scheduler-k8s-master01 1/1 Running 3 (26h ago) 10d 从上面结果看,kube-proxy重建并启动起来了。 验证下ipvs是否被kube-proxy启用: \[root@k8s-master01 5\]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -\> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.0.0.1:443 rr -\> 192.168.21.11:6443 Masq 1 1 0 TCP 10.0.0.10:53 rr -\> 10.244.32.134:53 Masq 1 0 0 -\> 10.244.32.136:53 Masq 1 0 0 TCP 10.0.0.10:9153 rr -\> 10.244.32.134:9153 Masq 1 0 0 -\> 10.244.32.136:9153 Masq 1 0 0 **TCP 10.13.55.128:80 rr** -\> 10.244.58.228:80 Masq 1 0 0 -\> 10.244.58.230:80 Masq 1 0 0 -\> 10.244.58.231:80 Masq 1 0 0 -\> 10.244.58.232:80 Masq 1 0 0 -\> 10.244.58.237:80 Masq 1 0 0 -\> 10.244.85.203:80 Masq 1 0 0 -\> 10.244.85.204:80 Masq 1 0 0 -\> 10.244.85.205:80 Masq 1 0 0 -\> 10.244.85.206:80 Masq 1 0 0 -\> 10.244.85.209:80 Masq 1 0 0 UDP 10.0.0.10:53 rr -\> 10.244.32.134:53 Masq 1 0 0 -\> 10.244.32.136:53 Masq 1 0 0 我们查看下service服务地址: \[root@k8s-master01 5\]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.0.0.1 \ 443/TCP 10d **myapp ClusterIP 10.13.55.128 \ 80/TCP 24m** \[root@k8s-master01 5\]# curl 10.13.55.128 Welcome to Nginx V1.0 !!! 从上面标红的红色字体可以看出来,我们的service集群ip地址,在ipvs里面采用rr即round robin轮训算法,将**10.13.55.128:80路由分发到下面的各个pod上。**可以查看各个pod的IP地址是否和ipvs里面列出来的地址一样: ![](https://i-blog.csdnimg.cn/direct/9e357393e20e4018b87c3aae7163224c.png) 验证是deployment为myapp的10个pod的ip地址。

相关推荐
可观测性用观测云1 小时前
Kubernetes APIServer 可观测最佳实践
kubernetes
碣石潇湘无限路3 小时前
【云原生】Kubernetes CEL 速查表
容器·贪心算法·kubernetes
企鹅侠客7 小时前
Prometheus operator怎么添加targets和告警规则
运维·云原生·kubernetes·prometheus·pod
Leo Han9 小时前
k8s常用命令(持续更新中)
docker·容器·kubernetes
KubeSphere 云原生9 小时前
云原生周刊:Kubernetes v1.33 要来了
云原生·容器·kubernetes
dessler10 小时前
Kubernetes(k8s)-日志(logs)和exec内部逻辑
linux·运维·kubernetes
tingting01191 天前
k8s 1.30 安装ingress-nginx
nginx·容器·kubernetes
陈陈CHENCHEN1 天前
【Kubernetes】CentOS 7 安装 Kubernetes 1.30.1
kubernetes
2201_761199041 天前
k8s2部署
云原生·容器·kubernetes
云上艺旅1 天前
K8S学习之基础六十四:helm常用命令
学习·云原生·容器·kubernetes