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

Posted 文火冰糖的硅基工坊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[云原生专题-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 创建和删除NodePort Sevice


前言:

通过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 的抽象,并为它们对外提供一个统一的访问入口,对内实现服务发现与负载均衡,并实现应用的零宕机升级。

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

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的关系


 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地址,无法通过公网IP地址访问,必须结合IP table NAT功能或kube-proxy或前端服务器提供的公网IP地址才能访问。

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

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

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

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

2.2 NodePort Sevice:

(1)NodePort Sevice与ClusterIP Sevice的关系

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

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

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

(2)NodePort Sevice的网络结构

(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:

在 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)四种服务类型之间的关系

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

3.1 查看当前的sevice和depolyment

$ kubectl get service

$ kubectl get depoly

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 depoly xxx-depolyname --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)进入pod内部修改不同pod的nginx欢迎页面

# 通过dash board分别进入每个pod内部

$ cd /usr/share/nginx/html

$ echo "1111" > index.html
$ echo "2222" > index.html
$ echo "3333" > index.html

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

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

# 通过集群内网访问ClusterIP Sevice
$ curl ClusterPrivateIP:port

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

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

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

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

3.4 创建和删除NodePort Sevice

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

$ kubectl expose depoly xxx-depolyname --type=NodePort --port=8000 --target-port=80 
  •  xxx-depolyname: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

(3)进入pod内部修改不同pod的nginx欢迎页面

# 通过dash board分别进入每个pod内部

$ cd /usr/share/nginx/html

$ echo "1111" > index.html
$ echo "2222" > index.html
$ echo "3333" > index.html

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

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

# 通过集群内网访问ClusterIP Sevice
$ curl NodePortSevicePrivateIP:port

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

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

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

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

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

# 获取NodePort service为公网访问动态创建的端口号
# 动态创建的端口号在[30000, 32767]
$ kubectl get service


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

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

 备注:

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

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

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

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


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

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

以上是关于[云原生专题-33]:K8S - 核心概念 - 服务Service管理服务发现负载均衡的主要内容,如果未能解决你的问题,请参考以下文章

[云原生专题-43]:K8S - 核心概念 - placeholder - 加密数据

[云原生专题-42]:K8S - 核心概念 - placeholder-有状态服务

[云原生专题-38]:K8S - 核心概念 - 存储抽象- 空间大小可配置的目录挂载PV+PVC

[云原生专题-40]:K8S - 核心概念 - 网络模型网络通信集群内负载均衡机制(重要重要重要)

[云原生专题-39]:K8S - 核心概念 - 存储抽象- pod配置文件的挂载ConfigMap

[云原生专题-32]:K8S - 核心概念 - 工作负载资源之Depolyment(无状态应用)的概念与常见操作命令