第六章 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 <none> 443/TCP 10d

myapp ClusterIP 10.13.55.128 <none> 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。

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 <none> 443/TCP 10d
myapp ClusterIP 10.13.55.128 <none> 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里面列出来的地址一样:

验证是deployment为myapp的10个pod的ip地址。

相关推荐
nangonghen6 小时前
华为云kubernetes部署deepseek r1、ollama和open-webui(已踩过坑)
容器·kubernetes·ollama·open webui·deepseek
jcrose25809 小时前
分析用户请求K8S里ingress-nginx提供的ingress流量路径
nginx·容器·kubernetes
alden_ygq10 小时前
K8S运行时切换-从Docker到Containerd的切换实战
docker·容器·kubernetes
tuohuang030310 小时前
第五章 Kubernetes Pod控制器-Cronjob
kubernetes·cronjob
Linux运维老纪21 小时前
K8s 分布式存储后端(K8s Distributed Storage Backend)
服务器·分布式·云原生·容器·kubernetes·云计算·运维开发
Dusk_橙子1 天前
在K8S中,有哪几种控制器类型?
云原生·容器·kubernetes
a_j582 天前
Kubernetes常见问答(一)
云原生·容器·kubernetes
bjackal2 天前
K8S学习笔记-------1.安装部署K8S集群环境
笔记·学习·kubernetes
Dusk_橙子2 天前
在K8S中,如何把某个worker节点设置为不可调度?
云原生·容器·kubernetes