Kubernetes-8 K8s的Service

这里写个前言吧

前面我们了解到Deployment只是保证了支撑服务的微服务Pod的数量,但是没有解决如何访问这些服务的问题。一个Pod只是一个运行服务的实例,随时可能在一个节点上停止,在另一个节点以一个新的IP启动一个新的Pod,因此不能以确定的IP的和端口号提供服务。

要稳定的提供服务需要服务发现和负载均衡能力。服务发现完成的工作,是针对客户端访问的服务,找到对应的后端服务实例。在K8s集群中,客户端需要访问的服务就是Service对象。每个Service会对应一个集群内部有效的虚拟IP,集群内部通过虚拟IP访问一个服务。

在K8s集群中,微服务的负载均衡是有kube-proxy实现的。kube-proxy是K8s集群内部的负载均衡器。它是一个分布式代理服务器,在K8s的每个节点上都有一个;这体现了它的弹性伸缩优势,需要访问服务的节点越多,提供负载均衡能力的kube-proxy就越多,高可用节点也随之增多。与之相比,我们平时在服务器端使用反向代理作负载均衡,还要进一步解决反向代理的高可用问题。

Service存在的意义

防止Pod失联(服务发现)

因为Pod每次创建都对应一个IP地址,而这个IP地址是短暂的,每次随着Pod的更新都会变化,假设我们的前端页面有多个Pod时,同时后端那也有多个Pod,这时候,他们之间的相互访问,就需要通过注册中心,拿到Pod的IP地址,然后去访问对应的Pod

定义Pod访问策略(负载均衡)

页面前端的Pod访问到后端的Pod,中间会通过Service一层,而Service在这里还能做负载均衡,负载均衡的策略有很多种实现策略,例如

  • 随机
  • 轮询
  • 响应比
    在这里插入图片描述

Pod和Service的关系

这里Pod和Service之间还是根据label和selector建立关联的(和Controller一样)
在这里插入图片描述
我们访问Service的时候,其实也是需要有一个IP地址,这个IP肯定不是pod的IP地址,而是虚拟IP

Service常用类型

SVC常用类型有四种:

  • ClusterIP:默认类型,自动分配一个仅Cluster内部可以访问的虚拟IP
  • NodePort:在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过NodeIP:NodePort来访问该服务
  • LoadBalancer:在NodePort的基础上,接触Cloud provider创建一个外部负载均衡器,将请求转发到NodeIP:NodePort
  • ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用,没有任何类型代理(kubernetes1.7或更高版本的kube-dns支持)

举例

导出一个包含service的文件

kubectl expose deployment web --port=80 --target-port=80 --dry-run=client -o yaml > service.yaml


apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: web
  name: web1
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: web
status:
  loadBalancer: {
    
    }

如果没有做设置的话,默认使用的是第一种方式ClusterIP,也就是只能在集群内部使用,我们可以添加type字段,来设置SVC的类型

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: web
  name: web1
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: web
  type: NodePort
status:
  loadBalancer: {
    
    }

修改完成导入即可

kubectl apply -f service.yaml

kubectl get svc
就可以看到已经成功修改为NodePort类型了

然后是LoadBalanced: 对外访问应用使用公有云

node一般是在内网进行部署,而外网一般是不能被访问到的:

  • 先找一台可以通过外网访问机器,安装nginx,反向代理
  • 手动把可以访问的节点添加到nginx中

如果我们使用LoadBalancer,就会有负载均衡的控制器,类似与nginx的功能,就不需要自己添加到nginx上

最后一种是ExternalName
这种类型的SVC是通过返回CANME和它的值,可以将服务映射到externalName字段的内容(例如:www.yyjl.com)。ExternalName Service是Service的特例,它没有selector,也没有定义任何端口和Endpoint。相反,相对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供。
当查询主SVC_NAME.NAMESPACE.svc.cluster.local
时,集群的DNS服务将会返回一个值www.yyjl.com的CNAME记录。访问这个服务的工作方式和其他的相同,唯一不同的时重定向发生在DNS层,而且不会进行代理或者转发。

注意

SVC能够提供负载均衡的能力,但是在使用上有以下限制:
只提供4层负载能力,而没有7层负载功能,但有时候我们可能需要更多的匹配规则来转发请求,这点上4层负载均衡技术是不支持的

猜你喜欢

转载自blog.csdn.net/qq_51574197/article/details/115264379