Kubernetes Service解析

简介: 我们都知道,在K8S集群中,每个Pod都有自己的私有IP地址,并且这些IP地址不是固定的。这意味着其不依赖IP地址而存在。例如,当我们因某种业务需求,需要对容器进行更新操作,则容器很有可能在随后的启动运行过程中被分配到其他IP地址。此外,在K8S集群外部看不到该Pod。因此,Pod若单独运行于K8S体系中,在实际的业务场景中是不现实的,故我们需要通过其他的策略去解决,那么解决方案是什么? 由此,我们引入了Serivce这个概念以解决上述问题。

     我们都知道,在K8S集群中,每个Pod都有自己的私有IP地址,并且这些IP地址不是固定的。这意味着其不依赖IP地址而存在。例如,当我们因某种业务需求,需要对容器进行更新操作,则容器很有可能在随后的启动运行过程中被分配到其他IP地址。此外,在K8S集群外部看不到该Pod。因此,Pod若单独运行于K8S体系中,在实际的业务场景中是不现实的,故我们需要通过其他的策略去解决,那么解决方案是什么? 由此,我们引入了Serivce这个概念以解决上述问题。

      如下所示,为简单的Pod配置文件定义:


apiVersion: v1
kind: Pod
metadata:
  name: k8s-activemq-pod
  labels:
    app: k8s-activemq 
spec:
  containers:
  - name: k8s-activemq-prod-container
    image: registry.docker.com/baseimg/k8s-active-mq

     K8s Service是一种抽象,定义了一组逻辑上可用的pod和策略。服务是一个REST对象,就像一个pod一样,并且具有终结点,因此只要类型支持可见性,就可以从外部访问服务。这到底是什么意思?这意味着即使服务也可以对外界隐藏。

     Service 的理念是将一组 Pod 端点划分为单一资源。我们可以配置各种方式来访问该分组。默认情况下,我们会获得稳定的集群 IP 地址,集群内部的客户端可以使用该 IP 地址与 Service 中的 Pod 通信。客户端向稳定 IP 地址发送请求,然后请求会被路由到 Service 的其中一个 Pod。

      Service 通过选择器来识别其成员 Pod。为使 Pod 成为 Service 的成员,该 Pod 必须具有选择器中指定的所有标签。标签是附加到对象的任意键值对。

     下列 Service 清单所具有的选择器指定了两种标签。selector 字段指示同时具有 app: metrics 标签和 department:engineering 标签的任何 Pod 都是该 Service 的成员。Service配置文件语法定义如下:


apiVersion: v1
kind: Service
metadata:
  name: k8s-activemq-prod-service
spec:
  selector:
    app: k8s-activemq
  ports:
    - name: http
      port: 8161
      nodePort: 32190
    - name: tcp
      port: 61616
      nodePort: 32191
  type: NodePort


为何使用 Service?

     在 Kubernetes 集群中,每个 Pod 都具有内部 IP 地址。但是,Deployment 中的 Pod 可以随时加入和退出,而且它们的 IP 地址也不是固定的。因此,直接使用 Pod IP 地址毫无意义。通过 Service,您会获得稳定的 IP 地址,该 IP 地址在 Service 的生命周期内有效,即使成员 Pod 的 IP 地址发生变化也仍然有效。

     Service 还提供负载平衡。客户端会调用单个稳定的 IP 地址,而且客户端请求在 Service 的成员 Pod 之间保持平衡。

      Service 类型

      目前,在K8S生态体系中提供了五种类型的 Service:

      1、ClusterIP(默认):内部客户端向稳定的内部 IP 地址发送请求。

      2、NodePort:客户端向使用 Service 指定的一个或多个 nodePort 值的节点的 IP 地址发送请求。

      3、LoadBalancer:客户端向网络负载平衡器的 IP 地址发送请求。

      4、ExternalName:内部客户端使用 Service 的 DNS 名称作为外部 DNS 名称的别名。          

      5、Headless:如果需要对 Pod 进行分组,同时也不需要稳定的 IP 地址,此场景下可以使用 Headless 服务。  

ClusterIP

      通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType。简要拓扑如下:

     如上图所示,ClusterIP类型的Service就是在K8S节点上创建一个满足Service IP地址的Iptables或Ipvs规则。这种类型的Service的IP地址一定是我们在初始化集群时,指定的Service网络中的地址,这意味着这种类型的Service不能被集群外部客户端所访问,仅能在集群节点上访问。

      以下为 ClusterIP 类型的 Service 的实例配置:


apiVersion: v1
kind: Service
metadata:
  name: springboot-demo-service
spec:
  selector:
    app: metrics
    department: sales
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080


NodePort

      NodePort 类型是 ClusterIP 类型的扩展。因此,NodePort 类型的 Service 具有集群 IP 地址。通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 :,可以从集群的外部访问一个 NodePort 服务。简要拓扑如下:

      如上图所示,NodePort类型的Service,是建构在ClusterIP的基础上做的扩展,主要解决了集群外部客户端访问问题。在上图拓扑中,我们可以看到NodePort类型Service在创建时,它会为每个节点上创建一条DNAT规则,外部客户端访问集群任意节点的指定端口,都会被DNAT到对应的Service上,从而实现访问集群内部Pod。对于集群内部客户端的访问它还是通过ClusterIP进行的,NodePort类型Service与ClusterIP类型Service唯一不同的是:NodePort类型Service能够被外部客户端所访问,在集群每个节点上都有对应的DNAT规则。

       以下是 NodePort 类型的 Service 的实例配置:


apiVersion: v1
kind: Service
metadata:
  name: springboot-demo-service
spec:
  selector:
    app: metrics
    department: sales
  type: NodePort
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080


LoadBalancer

       LoadBalancer 类型是 NodePort 类型的扩展。因此,LoadBalancer 类型的 Service 具有集群 IP 地址以及一个或多个 NodePort 值。简要拓扑如下:

      如上图所示,LoadBalancer主要基于云提供商的负载均衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。LoadBalancer这种类型的Service是在NodePort的基础上做的扩展,这种类型Service只能在底层是云环境的K8S上创建,如果底层是非云环境,这种类型无法实现,只能手动搭建反向代理进行对NodePort类型的Service进行反代;它主要解决NodePort类型Service被集群外部访问时的端口映射以及负载。

      以下是 LoadBalancer类型的 Service 的实例配置:


apiVersion: v1
kind: Service
metadata:
  name: springboot-demo-service
spec:
  selector:
    app: metrics
    department: engineering
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 8080


ExternalName

     ExternalName 类型的 Service 为外部 DNS 名称提供内部别名。内部客户端使用内部 DNS 名称发出请求,然后请求会被重定向到外部名称。简要拓扑如下:

      如上图所示,ExternalName这种类型Service主要用来解决对应Service引用集群外部的服务。我们知道对于Service来说,它就是一条Iptables或Ipvs规则,对于后端引用的资源是什么,取决于对应Endpoint关联的是什么资源的Ip地址和端口。如果我们需要在集群中使用集群外部的服务,我们就可以创建ExternalName类型的Service,指定后端关联外部某个服务端ip地址或域名即可。它的工作流程如上图所示,在集群内部客户端访问对应Service时,首先要去Ccore-DNS上查询对应域名的Ip地址,然后再根据Dns返回的Ip地址去连接对应的服务,使用这种类型Service的前提是对应的Coredns能够连接到外部网络解析对应的域名。

      以下是 ExternalName类型的 Service 的实例配置:


apiVersion: v1
kind: Service
metadata:
  name: springboot-demo-service
spec:
  type: ExternalName
  externalName: example.com

      ExternalName Service 类型与其他 Service 类型完全不同。事实上,ExternalName 类型的 Service 不符合本主题开头提出的 Service 定义。ExternalName 类型的 Service 不与一组 Pod 相关联,也没有稳定的 IP 地址。相反,ExternalName 类型的 Service 从内部 DNS 名称映射到外部 DNS 名称。  

Headless

      在某些场景中,我们有时候不需要负载均衡,以及单独的 Service IP,可以通过指定 Cluster IP(spec.clusterIP)的值为 "None" 来创建 Headless Service。我们可以使用 Headless Service 与其他服务发现机制进行接口,而不必与 Kubernetes 的实现捆绑在一起。

      对 Headless Service 而言,并不会分配 Cluster IP,Kube-Proxy 不会处理它们,而且平台也不会为它们进行负载均衡和路由。DNS 如何实现自动配置,依赖于 Service 是否定义了 selector。其简要拓扑如下:

       以下是 Headless Service类型的 Service 的实例配置:


apiVersion: v1
kind: Service
metadata:
  name: gateway-test
  labels:
    app: gateway_test
spec:
  ports:
  - port: 433
    name: gateway_api
  # clusterIP 设置为 None
  clusterIP: None
  selector:
    app: gateway_test

      Headless Services 主要有以下应用场景:

      1、自主选择权,有时候 client 想自己来决定使用哪个Real Server,可以通过查询DNS来获取 Real Server 的信息。

     2、Headless Service 的对应的每一个 Endpoints,即每一个Pod,都会有对应的DNS域名,这样Pod之间就可以互相访问。

      至此,K8S生态体系中的五种类型的 Service简要介绍完成。具体,可以依据当前项目实际场景进行规划与选择。


相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
缓存 Kubernetes Docker
GitLab Runner 全面解析:Kubernetes 环境下的应用
GitLab Runner 是 GitLab CI/CD 的核心组件,负责执行由 `.gitlab-ci.yml` 定义的任务。它支持多种执行方式(如 Shell、Docker、Kubernetes),可在不同环境中运行作业。本文详细介绍了 GitLab Runner 的基本概念、功能特点及使用方法,重点探讨了流水线缓存(以 Python 项目为例)和构建镜像的应用,特别是在 Kubernetes 环境中的配置与优化。通过合理配置缓存和镜像构建,能够显著提升 CI/CD 流水线的效率和可靠性,助力开发团队实现持续集成与交付的目标。
|
Kubernetes 容器
K8S的Service的LoadBanlance之Metallb解决方案
本文介绍了如何在Kubernetes中使用MetalLB来实现Service的LoadBalancer功能,包括MetalLB的部署、配置、以及通过创建地址池和部署服务来测试MetalLB的过程。
838 2
K8S的Service的LoadBanlance之Metallb解决方案
|
Kubernetes 监控 API
深入解析Kubernetes及其在生产环境中的最佳实践
深入解析Kubernetes及其在生产环境中的最佳实践
812 93
|
Kubernetes Linux 虚拟化
入门级容器技术解析:Docker和K8s的区别与关系
本文介绍了容器技术的发展历程及其重要组成部分Docker和Kubernetes。从传统物理机到虚拟机,再到容器化,每一步都旨在更高效地利用服务器资源并简化应用部署。容器技术通过隔离环境、减少依赖冲突和提高可移植性,解决了传统部署方式中的诸多问题。Docker作为容器化平台,专注于创建和管理容器;而Kubernetes则是一个强大的容器编排系统,用于自动化部署、扩展和管理容器化应用。两者相辅相成,共同推动了现代云原生应用的快速发展。
3361 11
|
12月前
|
运维 分布式计算 Kubernetes
ACK One多集群Service帮助大批量应用跨集群无缝迁移
ACK One多集群Service可以帮助您,在无需关注服务间的依赖,和最小化迁移风险的前提下,完成跨集群无缝迁移大批量应用。
|
运维 Kubernetes Cloud Native
Kubernetes云原生架构深度解析与实践指南####
本文深入探讨了Kubernetes作为领先的云原生应用编排平台,其设计理念、核心组件及高级特性。通过剖析Kubernetes的工作原理,结合具体案例分析,为读者呈现如何在实际项目中高效部署、管理和扩展容器化应用的策略与技巧。文章还涵盖了服务发现、负载均衡、配置管理、自动化伸缩等关键议题,旨在帮助开发者和运维人员掌握利用Kubernetes构建健壮、可伸缩的云原生生态系统的能力。 ####
|
存储 Kubernetes 调度
深度解析Kubernetes中的Pod生命周期管理
深度解析Kubernetes中的Pod生命周期管理
|
存储 Kubernetes 监控
深度解析Kubernetes在微服务架构中的应用与优化
【10月更文挑战第18天】深度解析Kubernetes在微服务架构中的应用与优化
624 0
|
11月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
1075 29
|
11月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
460 4

推荐镜像

更多