[云原生专题-33]:K8S - 核心概念 - 服务Service管理、服务发现、负载均衡

作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客

本文网址:https://blog.csdn.net/HiWangWenBing/article/details/122798876


目录

前言:

第1章 服务Service管理概述

1.1 为什么需要服务?

1.2 什么是服务

1.3 Service与Deployment的关系

1.4 总体的网络架构

第2章 Service的类型与架构

2.1 ClusterIP Sevice

2.2 NodePort Sevice:

2.3 LoadBalancer Sevice:

第3章 Service相关的主要操作命令

3.1 查看当前的sevice和depolyment

3.2 删除当前Sevice和depolyment

3.3 创建自己的ClusterIP Sevice

3.4 创建和删除NodePortSevice


前言:

通过depolyment等工作负载,实现了应用程序的部署与管理,然后此时应用程序还不能提供对外的网络服务, 如果需要提供对外的网络服务,还需要额外的操作,K8S是通过服务Service来标识这部分功能的,并通过称为服务管理来实现这部分网络服务功能。

第1章 服务Service管理概述

1.1 为什么需要服务?

在kubernetes中每个Pod都存在生命周期;

当一个Pod出现故障,极有可能被Pod控制器销毁并新建一个同类Pod取代(Pod控制器对Pod进行扩容也会新建Pod)。因此每个新建的Pod的都会重新获取Pod网络的内部私有IP,因此可以说通过IP获取Pod的服务是不可靠的。

service提供了一种通过固定域名作为访问入口的服务,接受用户的访问请求,通过算法,把对前端的服务请求代理至后端的Pods上。Pods创建和销毁都会及时关联至service上。

1.2 什么是服务

Service 是对一组提供相同功能Pods 的抽象,并为它们对外提供一个统一的访问入口,对内实现服务发现与负载均衡,并实现应用的零宕机升级。

一个集群中会大量的服务,每个服务有自己独一无二的端口号来标识。

[云原生专题-33]:K8S - 核心概念 - 服务Service管理、服务发现、负载均衡_第1张图片

1.3 Service与Deployment的关系

Service与Deployment都是构建在Pods之上,但侧重点不同。Deployment 来保证后Pod的正常运行,Service关注如何屏蔽内部Pod的部署情况,对外提供统一的服务,Service 通过标签来选取服务后端,这些匹配标签的 Pod IP 和端口列表组成 endpoints,由 kube-proxy 负责将服务 IP 负载均衡到这些 endpoints上。

Service是通过Deployment来管辖该服务有哪些Pods。

1.4 总体的网络架构

(1)早期代理的方式(管理面与业务面未分离模式

client先请求serviceip,经由iptables转发到kube-proxy上之后再转发到pod上去。

这种方式效率比较低。

(2)当前iptables代理方式(管理面与业务面分离模式

client请求serviceip后会直接转发到pod上。

这种模式性能会高很多。

kube-proxy就会负责将pod地址生成在node节点iptables规则中,kube-proxy只实现管理面和控制面的功能 。

(3)ipvs代理方式(管理面与业务面分离模式)

这种方式是通过内核模块ipvs替代用户空间的IP Table实现转发,这种效率更高。

第2章 Service的类型与架构

Service 是对一组提供相同功能Pods 的抽象,并为它们对外提供一个统一的访问入口,对内实现服务发现与负载均衡,并实现应用的零宕机升级。

也就是说Sevice是一组相同功能Pods 的代表,要想访问部署在不同Node上的特定功能的Pod应用程序时,必须通过Sevice来进行中转。

K8S支持4种类型的Sevice:

  • ClusterIP Sevice
  • NodePort Sevice
  • LoadBalancer Sevice
  • ExternalName Sevice

2.1 ClusterIP Sevice

(1)ClusterIP Sevice与特定功能pods的关系

[云原生专题-33]:K8S - 核心概念 - 服务Service管理、服务发现、负载均衡_第2张图片


[云原生专题-33]:K8S - 核心概念 - 服务Service管理、服务发现、负载均衡_第3张图片

 Service的默认类型,也是Service基础类型,该类型的Service能够获得集群内的虚拟的私有IP地址,并通过该集群内的虚拟私有IP地址,访问部署在不同节点上的特定端口号的Pod的服务。

该这种类的Service没有公网IP地址,因此无法直接从集群外部访问该服务以及该服务管辖下的Pod中的应用程序。

ClusterIP Sevice的主要功能包括:

  • 根据端口号进行服务发现的功能

所谓服务发现,就是ClusterIP Sevice能够自动监控集群中,部署在所有节点中的特定Port端口的Pod应用程序的状态,能够自动发现新加入到集群中的特定端口的Pod,并把新发现特定端口port的Pod加入到该Sevice中。同时能够发现特定端口pod的离开集群,并从service中删除。

  • 在不同Pod间进行负载均衡的功能

当有新的服务请求达到ClusterIP Sevice时,它能够根据内部的负载均衡的策略以及所管辖的Pod的部署位置、当前状态等信息,把该服务请求分发到不同Node节点上的Pod中。

(2)ClusterIP Sevice的缺点

ClusterIP Sevice的缺点最大缺点就自身没有公网IP地址,该Sevice只有集群内部的私有IP地址,无法通过公网IP地址访问,必须结合IP table NAT功能或kube-proxy或前端服务器提供的公网IP地址才能访问。

  • ClusterIP Sevice
  • kube-proxy
  • 前端服务器

(3)ClusterIP Sevice在整个集群中的架构

[云原生专题-33]:K8S - 核心概念 - 服务Service管理、服务发现、负载均衡_第4张图片

[云原生专题-33]:K8S - 核心概念 - 服务Service管理、服务发现、负载均衡_第5张图片

(4)Service私网IP访问与Node公网IP地址访问的关系

[云原生专题-33]:K8S - 核心概念 - 服务Service管理、服务发现、负载均衡_第6张图片

每个节点的公网IP地址的访问请求,不会转发给ClusterIP Sevice。

2.2 NodePort Sevice:

(1)NodePort Sevice与ClusterIP Sevice的关系

[云原生专题-33]:K8S - 核心概念 - 服务Service管理、服务发现、负载均衡_第7张图片

 在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过 NodeIP:NodePort 来访问该服务。

因此,NodePort Sevice具备ClusterIP Sevice的所有功能,即私网ip地址:port访问、负载均衡、服务发现。

同时,NodePort Sevice还可以通过每个节点的公网IP地址:动态端口号的方式,负载均衡的访问该服务管辖下的所有pod。

(2)NodePort Sevice的网络结构

[云原生专题-33]:K8S - 核心概念 - 服务Service管理、服务发现、负载均衡_第8张图片

(3)NodePort Service私网IP访问与Node公网IP地址访问的关系

 NodePort Service创建时,会在每个Node节点上建立一个公网IP:动态端口号的映射表。

每个Node都会把来自公网IP:动态port的业务请求转发给NodePort Service,再由NodePort Service完成pod服务的负载均衡,NodePort Service会把业务请求转换成Pod的私网IP:私网端口号,发送给每个pod。

2.3 LoadBalancer Sevice:

[云原生专题-33]:K8S - 核心概念 - 服务Service管理、服务发现、负载均衡_第9张图片

在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到 :NodePort


(4)ExternalName Sevice:

把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有 Kubernetes 1.7或更高版本的kube-dns才支持。

将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)。需要 kube-dns 版本在 1.7 以上。
另外,也可以将已有的服务以 Service 的形式加入到 Kubernetes 集群中来,只需要在创建 Service 的时候不指定 Label selector,而是在 Service 创建好后手动为其添加 endpoint。
 

(5)四种服务类型之间的关系

[云原生专题-33]:K8S - 核心概念 - 服务Service管理、服务发现、负载均衡_第10张图片

第3章 Service相关的主要操作命令

3.1 查看当前的sevice和depolyment

# 获得K8S自身创建的service
[root@k8s-master1 ~]# kubectl get service -A
NAMESPACE              NAME                        TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                  AGE
default                kubernetes                  ClusterIP   10.1.0.1               443/TCP                  4d7h
kube-system            kube-dns                    ClusterIP   10.1.0.10              53/UDP,53/TCP,9153/TCP   4d7h
kubernetes-dashboard   dashboard-metrics-scraper   ClusterIP   10.1.253.40            8000/TCP                 4d6h
kubernetes-dashboard   kubernetes-dashboard        NodePort    10.1.176.109           443:30586/TCP            4d6h


# 获得所有的deploy对象
[root@k8s-master1 ~]# kubectl get deploy -A
NAMESPACE              NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
default                my-deploy                   3/3     3            3           3h27m
dev                    my-deploy                   4/4     4            4           3h29m
kube-system            calico-kube-controllers     1/1     1            1           4d5h
kube-system            coredns                     2/2     2            2           4d7h
kubernetes-dashboard   dashboard-metrics-scraper   1/1     1            1           4d6h
kubernetes-dashboard   kubernetes-dashboard        1/1     1            1           4d6h


# 默认名字空间的pod
[root@k8s-master1 ~]# kubectl get pod -owide
NAME                         READY   STATUS    RESTARTS   AGE     IP              NODE        NOMINATED NODE   READINESS GATES
my-deploy-8686b49bbd-b8w65   1/1     Running   0          3h32m   192.168.36.79   k8s-node1              
my-deploy-8686b49bbd-f2m4c   1/1     Running   0          3h31m   192.168.36.82   k8s-node1              
my-deploy-8686b49bbd-jz5cx   1/1     Running   0          3h32m   192.168.36.80   k8s-node1              

在default名字空间中,有一个my-deploy,部署了三个pods,每个pod有不同的IP地址,每个Pod是一个nginx服务,如下所示:

[root@k8s-master1 ~]# curl 192.168.36.79 



Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

为了区分这三个pod的服务,我们分别进入三个pod的内部,用IP地址信息覆盖默认的页面。

$ kubectl exec -it my-deploy-8686b49bbd-b8w65 -- /bin/sh

$ cd /usr/share/nginx/html/

$ echo "192.168.36.79" > index.html

$ exit

# 同理,修改其他pod nginx服务的首页,确保IP地址与首页内容一致,一边与后续验证

[root@k8s-master1 ~]# curl 192.168.36.80
192.168.36.80
[root@k8s-master1 ~]# curl 192.168.36.82
192.168.36.82
[root@k8s-master1 ~]# curl 192.168.36.79
192.168.36.79

3.2 删除当前Sevice和depolyment

$ kubectl delete service xxx-sevice-name

$ kubectl delete depoly xxx-depoly-name

3.3 创建自己的ClusterIP Sevice

(1)通过命令行创建一个新的ClusterIP Sevice

$ kubectl expose deploy my-deploy --type=ClusterIP --port=8000 --target-port=80
  •  xxx-depolyname:depoly的名称,这非常重要,通过depolyment,Sevice能够知道该服务有哪些Pod,建立了Pod在不同节点node上的映射表,它是sevice能够进行服务自动发现和负载均衡的基础。
  • --port:service提供的对外服务端口号,如8000。
  • --target-port: service实际的、内部Pod的应用程序的端口号,如80(http)

ClusterIP Sevice在进行服务请求分发的时候,会把ClusterPrivateIP:port的服务请求,转换成PodPrivateIP: target-port。

(2)通过配置文件一个新的ClusterIP Sevice

(3)通过ClusterPrivateIP访问ClusterIP Sevice的服务

# 通过get sevice获取ClusterIP Sevice的Private IP address
[root@k8s-master1 ~]#  kubectl get service
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.1.0.1             443/TCP    4d8h
my-deploy    ClusterIP   10.1.11.83           8000/TCP   40s

备注:ClusterIP Sevice会把服务请求,分发到不同Node节点上的Pod中。

(5)通过ClusterIP Sevice的服务名访问ClusterIP Sevice的服务

# 通过service IP地址和端口号访问其所管辖的pod服务
[root@k8s-master1 ~]# curl 10.1.11.83:8000
192.168.36.82
[root@k8s-master1 ~]# curl 10.1.11.83:8000
192.168.36.79
[root@k8s-master1 ~]# curl 10.1.11.83:8000
192.168.36.82
[root@k8s-master1 ~]# curl 10.1.11.83:8000
192.168.36.79
[root@k8s-master1 ~]# curl 10.1.11.83:8000
192.168.36.82
[root@k8s-master1 ~]# curl 10.1.11.83:8000
192.168.36.79
[root@k8s-master1 ~]# curl 10.1.11.83:8000
192.168.36.80
[root@k8s-master1 ~]# curl 10.1.11.83:8000

从上面的访问可以看出:

  • 通过service的集群内私有IP地址和端口号,可以访问pod中的服务。
  • service对象对其服务请求进行了负载均衡,把输入的请求随机的转发给其管辖的Pod。

3.4 创建和删除NodePortSevice

 (1)通过命令行创建一个新的ClusterIP Sevice

[root@k8s-master1 ~]# kubectl get service
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.1.0.1             443/TCP    4d8h
my-deploy    ClusterIP   10.1.11.83           8000/TCP   10m


[root@k8s-master1 ~]# kubectl delete service my-deploy 

[root@k8s-master1 ~]# kubectl get service
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.1.0.1               443/TCP          4d8h

[root@k8s-master1 ~]# kubectl expose deploy my-deploy --type=NodePort --port=8000 --target-port=80

[root@k8s-master1 ~]# kubectl get service
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.1.0.1               443/TCP          4d8h
my-deploy    NodePort    10.1.138.255           8000:32608/TCP   47s

  •  my-deploy:depoly的名称,这非常重要,通过depolyment,Sevice能够知道该服务有哪些Pod,建立了Pod在不同节点node上的映射表,它是sevice能够进行服务自动发现和负载均衡的基础。
  • --port:service提供的对外服务端口号,如8000。
  • --target-port: service实际的、内部Pod的应用程序的端口号,如80(http)

NodePort Sevice在进行服务请求分发的时候,会把ClusterPrivateIP:port的服务请求,转换成PodPrivateIP: target-port。

NodePort Sevice在进行服务请求分发的时候,也会把NodePublicIP:port的服务请求,转换成PodPrivateIP: target-port。

(2)通过配置文件一个新的NodePort Sevice

apiVersion: v1
kind: Service
metadata:
 name: nginx-service
spec:
 type: NodePort         // 配置为NodePort,外部可以访问
 ports:
 - port: 30080          // 容器间,服务调用的端口
   targetPort: 80       // 容器暴露的端口,与Dockerfile暴露端口保持一致
   nodePort: 30001      // NodePort,外部访问的端口
 selector:
  name: nginx-pod
[root@k8s-master1 ~]#  kubectl get service
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.1.0.1               443/TCP          4d8h
my-deploy    NodePort    10.1.138.255           8000:32608/TCP   3m7s

(3)通过NodePort的PrivateIP:私有端口号访问NodePort Sevice下的 服务

备注:NodePort Sevice会把服务请求,分发到不同Node节点上的Pod中。

[root@k8s-master1 ~]# curl 10.1.138.255:8000
192.168.36.80
[root@k8s-master1 ~]# curl 10.1.138.255:8000
192.168.36.79
[root@k8s-master1 ~]# curl 10.1.138.255:8000
192.168.36.82
[root@k8s-master1 ~]# curl 10.1.138.255:8000
192.168.36.79

(4)通过NodePort Sevice的服务名访问NodePort Sevice的服务

# 通过get sevice获取NodePort Sevice的Private IP address
$ kubectl get service

# 通过集群内网访问NodePort Sevice
$ curl xxx-service-name.namespace.svc:port

(5)通过每个节点Node公网IP:动态端口号访问NodePort 服务(新增加)

# 获取NodePort service为公网访问动态创建的端口号
[root@k8s-master1 ~]# kubectl get service
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.1.0.1               443/TCP          4d8h
my-deploy    NodePort    10.1.138.255           8000:32608/TCP   14m


# 为每个Node设置新的安全策略,开放32608端口

# 通过个人主机的IE浏览器访问
http://公网IP地址:动态端口号

# 或通过命令行访问
[root@k8s-master1 ~]# curl 47.96.137.180:32608
192.168.36.80
[root@k8s-master1 ~]# curl 47.96.137.180:32608
192.168.36.82
[root@k8s-master1 ~]# curl 47.96.137.180:32608
192.168.36.79
[root@k8s-master1 ~]# curl 47.96.137.180:32608
192.168.36.79
[root@k8s-master1 ~]# curl 47.96.137.180:32608
192.168.36.82

 备注:

通过每个Node节点的公网IP地址访问,一样可以实现负载均衡地访问该服务下的每个pod应用程序。

端口号的映射关系:32608 -> 8000 -> 80

IP地址转换关系:节点的公网IP -> NodePortSevicePrivateIP -> PodPrivateIP

公网服务访问的转换关系:节点的公网IP: 30948 => NodePortSevicePrivateIP:8000 => PodPrivateIP:80。


作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客

本文网址:https://blog.csdn.net/HiWangWenBing/article/details/122798876

你可能感兴趣的:(云原生专题,云原生,cloud,native,服务,负载均衡,K8S)