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

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

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地址,该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

# 获得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       <none>        443/TCP                  4d7h
kube-system            kube-dns                    ClusterIP   10.1.0.10      <none>        53/UDP,53/TCP,9153/TCP   4d7h
kubernetes-dashboard   dashboard-metrics-scraper   ClusterIP   10.1.253.40    <none>        8000/TCP                 4d6h
kubernetes-dashboard   kubernetes-dashboard        NodePort    10.1.176.109   <none>        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   <none>           <none>
my-deploy-8686b49bbd-f2m4c   1/1     Running   0          3h31m   192.168.36.82   k8s-node1   <none>           <none>
my-deploy-8686b49bbd-jz5cx   1/1     Running   0          3h32m   192.168.36.80   k8s-node1   <none>           <none>

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

[root@k8s-master1 ~]# curl 192.168.36.79 
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

为了区分这三个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     <none>        443/TCP    4d8h
my-deploy    ClusterIP   10.1.11.83   <none>        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     <none>        443/TCP    4d8h
my-deploy    ClusterIP   10.1.11.83   <none>        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       <none>        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       <none>        443/TCP          4d8h
my-deploy    NodePort    10.1.138.255   <none>        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       <none>        443/TCP          4d8h
my-deploy    NodePort    10.1.138.255   <none>        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       <none>        443/TCP          4d8h
my-deploy    NodePort    10.1.138.255   <none>        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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

文火冰糖的硅基工坊

你的鼓励是我前进的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值