1.4kubernetes基本概念和术语(4) -- service

欢迎各位读者评论留言,共同学习,共同进步。
《kubernetes权威指南》笔记
1.4kubernetes基本概念和术语(1)
1.4kubernetes基本概念和术语(2)
1.4kubernetes基本概念和术语(3)

8.Service

  • Service服务也是Kubernetes里的核心资源对象之一,Kubernetes里的每个Service其实就是我们经常提起的微服务架构中的一个微服务。



    Kubernetes的Service定义了一个服务的访问入口地址,
    前端的应用(Pod)通过这个入口地址访问其背后的一组由Pod副本组成的集群实例,
    Service与其后端Pod副本集群之间则是通过Label Selector来实现无缝对接的。
    RC的作用实际上是保证Service的服务能力和服务质量始终符合预期标准。

  • 我们的系统最终由多个提供不同业务能力而又彼此独立的微服务单元组成的,服务之间通过TCP/IP进行通信,从而形成了强大而又灵活的弹性网格,拥有强大的分布式能力、弹性扩展能力、容错能力,程序架构也变得简单和直观许多

Q1: 客户端如何访问service?
  • (1) 一般做法:给这些Pod的Endpoint列表加入如8000端口转发列表,客户端通过负载均衡起的对外Ip地址+服务器端口来访问此服务。
    k8s上每个Node上的Kube-proxy进程就是一个智能的软件负载均衡器,负责把对Service的请求转发到后端的某个Pod实例上,并在内部实现服务的负载均衡与会话保持机制
    (2) service做法:给每个service都分配一个全局唯一的虚拟IP地址,成为cluster Ip,这样服务间可以通过唯一IP地址进行通信。
    原因:pod的Endpoint地址会随着Pod的销毁和重新创建而改变,因为新Pod的Ip地址和之前旧的Pod的不同。而service一旦被创建,在其生命周期内 cluster Ip不会变。最后只要用Service的Name与Service的Cluster IP地址做一个DNS域名映射即可完美解决问题。
    (3) 结论:客户端 -- 通过serviceName --> service --通过label selector --> 实际service节点

配置文件使用:


image.png

targetPort: 在spec.ports的定义中,targetPort属性用来确定提供该服务的容器所暴露(EXPOSE)的端口号,即具体业务进程在容器内的targetPort上提供TCP/IP接入;
port: port属性则定义了Service的虚端口。前面定义Tomcat服务时没有指定targetPort,则默认targetPort与port相同

Q2: 多端口为什么要定义多个端口名?服务发现机制是什么?
  • 大多数大数据分布式系统采用的是特定API接口实习服务发现,但这样做会导致平台的侵入性比较强,也增加了开发、测试的难度。
  • k8s的方法: cluster Ip和service Name是固定的,只需要存储这两个的关系即可。
    最早时Kubernetes采用了Linux环境变量解决这个问题,即每个Service都生成一些对应的Linux环境变量(ENV),并在每个Pod的容器启动时自动注入这些环境变量。
    通过环境变量获取Service地址的方式仍然不太方便、不够直观,后来Kubernetes通过Add-On增值包引入了DNS系统,把服务名作为DNS域名,这样程序就可以直接使用服务名来建立通信连接了。目前,Kubernetes上的大部分应用都已经采用了DNS这种新兴的服务发现机制,后面会讲解如何部署DNS系统。
Q3:外部系统如何访问serice?
  • a. Node Ip:实际物理网卡的Ip地址
  • b.Pod Ip: 它是Docker Engine根据docker0网桥的IP地址段进行分配的,通常是一个虚拟的二层网络。
    Kubernetes要求位于不同Node上的Pod都能够彼此直接通信,所以Kubernetes里一个Pod里的容器访问另外一个Pod里的容器时,就是通过Pod IP所在的虚拟二层网络进行通信的,而真实的TCP/IP流量是通过Node IP所在的物理网卡流出的。
  • c. Cluster Ip: 虚拟ip,
    特点:◎ Cluster IP仅仅作用于Kubernetes Service这个对象,并由Kubernetes管理和分配IP地址(来源于ClusterIP地址池)。
    ◎ Cluster IP无法被Ping,因为没有一个“实体网络对象”来响应。
    ◎ Cluster IP只能结合Service Port组成一个具体的通信端口,单独的Cluster IP不具备TCP/IP通信的基础,并且它们属于Kubernetes集群这样一个封闭的空间,集群外的节点如果要访问这个通信端口,则需要做一些额外的工作。
    ◎ 在Kubernetes集群内,Node IP网、Pod IP网与Cluster IP网之间的通信,采用的是Kubernetes自己设计的一种编程方式的特殊路由规则,与我们熟知的IP路由有很大的不同。

实际访问是通过NodeIp+NodePort.
a. NodePort的实现方式是在Kubernetes集群里的每个Node上都为需要外部访问的Service开启一个对应的TCP监听端口,外部系统只要用任意一个Node的IP地址+具体的NodePort端口号即可访问此服务。
b. 负载均衡问题:假如在我们的集群中有10个Node,则此时最好有一个负载均衡器,外部的请求只需访问此负载均衡器的IP地址,由负载均衡器负责转发流量到后面某个Node的NodePort上。

image.png

Load balancer组件独立于Kubernetes集群之外,通常是一个硬件的负载均衡器,或者是以软件方式实现的,例如HAProxy或者Nginx。对于每个Service,我们通常需要配置一个对应的Load balancer实例来转发流量到后端的Node上,这的确增加了工作量及出错的概率。于是Kubernetes提供了自动化的解决方案,如果我们的集群运行在谷歌的公有云GCE上,那么只要把Service的type=NodePort改为type=LoadBalancer,Kubernetes就会自动创建一个对应的Load balancer实例并返回它的IP地址供外部客户端使用。其他公有云提供商只要实现了支持此特性的驱动,则也可以达到上述目的。此外,裸机上的类似机制(Bare Metal Service Load Balancers)也在被开发。

总结: 外部客户端请求-- 通过load balancer (如nginx) --> 分配一个Node IP ,根据Node Port 访问 k8s某个Node 节点 --> Node IP 通过 Cluster Ip ,找到集群对应Pod(注意是整个集群中的Pod,而非某个Node上的Pod) --> 通过kube-proxy 从service 转发到后端某个Pod实例上。

image.png

你可能感兴趣的:(1.4kubernetes基本概念和术语(4) -- service)