写点什么

12 张图,带你轻松理解 Kubernetes Service

  • 2020-05-25
  • 本文字数:3110 字

    阅读完需:约 10 分钟

12张图,带你轻松理解Kubernetes Service

内容摘要

Kubernetes 有四种 service 类型,而 ClusterIP 是最基础的:



如上图所示,你可以想象一下,如果你要创建一个 NodePort 类型的 service,Kubernetes 也会创建一个 ClusterIP。如果你要创建一个 LoadBalancer 类型的 service,Kubernetes 会创建一个 NodePort 以及 ClusterIP。如果你以这样的方式思考,对 Kubernetes service 的理解将变得容易。


接下来我们将会对此进行一一解释。

Services 和 Pods

Services 通过使用 labels 直接指向 pods,而不是指向 deployments 或者 replicasets。这种设计的灵活性极高,因为创建 pods 的方式有很多,而 Service 不需要关心 pods 通过哪种方式创建。


我们先阐述一个简单的示例,然后逐步介绍不同的 service 类型,来了解它们是如何在彼此之上构建的。

不使用 Services

首先,让我们看下不使用 services 的情况。



如上图,我们有 2 个 node 和 1 个 pod。两个 node 分别使用外部 IP 地址(4.4.4.1 和 4.4.4.2)以及内部 IP 地址(1.1.1.1 和 1.1.1.2),而名为 pod-python 的 pod 只有一个内部 IP 地址。



如上图,现在我们添加第二个名为 pod-nginx 的 pod,它被调度到了 node-1 上。虽然两个 pod 在不同的 node 上,但这不影响它们互相访问。在 Kubernetes 集群中,所有的 pod 都可以通过内部 IP 地址访问其他的 pod,不管它们运行在哪个 node 上。


这就意味着 pod-nginx 能通过内部 IP 地址 1.1.1.3 ping 通或者连接 pod-python。



如上图,现在我们考虑将 pod-python 杀死并重建一个新 pod。(本文不负责介绍如何管理和控制 pod。)操作完成之后,pod-nginx 就无法继续访问 IP 地址 1.1.1.3,这样系统就中断崩溃了。为了避免这种问题,我们来创建第一类 service!

ClusterIP 类型


与上述场景一样,但这次我们配置了一个 ClusterIP 类型的 service。service 不像 pod 会调度到特定的 node 上,在本文中你可以假定 service 仅在整个集群的内存中生效。


现在,pod-nginx 总是能够安全地连接 IP 地址 1.1.10.1 或者域名地址 service-python,然后重定向到一个活跃的 python pod 上。没有灾难,一切美好。



我们来延申下这个示例,将 python 服务扩展到 3 个实例,并且现在我们把 service 和所有 pod 实例的内部 IP 地址以及端口都标注在图中。


集群中的所有 pod 都能通过 http://1.1.10.1:3000 或者 http://service-python:3000 访问到 python pod 的 443 端口。service-python 这个 ClusterIP 类型的 service 将基于随机或者轮询方式分发请求。这就是 ClusterIP 类型的 service 要做的事情,它能够让集群中的 pod 通过一个名字或者 IP 达到可用性。


apiVersion: v1kind: Servicemetadata:    name: service-pythonspec:    ports:    - port: 3000      protocol: TCP      targetPort: 443    selector:      run: pod-python    type: ClusterIP```</li>
运行命令 kubectl get svc,结果如下:
![](https://static001.infoq.cn/resource/image/48/f9/483e81565b6dfcfaf51648c80a5528f9.png)
## NodePort 类型
现在我们想让 ClusterIP 类型的 service 在集群外部也能够使用,所以将其转换成 NodePort 类型的 service。基于我们的示例,只需将 service-python 的 yaml 文件做两处简单的修改,如下所示:

复制代码


apiVersion: v1


kind: Service


metadata:


name: service-python


spec:


ports:


  • port: 3000

  • protocol: TCP

  • targetPort: 443

  • nodePort: 30080

  • selector:

  • run: pod-python

  • type: NodePort



![](https://static001.infoq.cn/resource/image/93/36/934b90eeb8d7a5a411f7d323420cb336.png)
<center>通过 node-2 的外部请求</center>
如上图所示,现在我们集群内部的 service-python 也能通过所有 node 的内部以及外部 IP 地址和端口 30080 访问。
![](https://static001.infoq.cn/resource/image/82/b1/827b73da352266de0e899e5b7eaa7fb1.png)
运行命令 kubectl get svc,结果展示了相同的 cluster ip,但类型显示不一样了,而且多了个额外的 NodePort 端口。
![](https://static001.infoq.cn/resource/image/ac/4d/ac7ceb1597331368e60a8f2e413ed04d.png)
在集群内部,NodePort 类型的 service 同样扮演着之前 ClusterIP 类型 service 的角色。这帮助了我们去想象一个 NodePort 类型的 service 创建了一个 ClusterIP 类型的 service,尽管事实上并没有额外增加一个 ClusterIP 类型的 service。
## LoadBalancer 类型
当我们想通过一个 IP 地址将请求分发到所有 node 节点的外部 IP 地址时,可以使用 LoadBalancer 类型的 service。因此,它是构建于 NodePort 类型的 service 之上,如下图所示:
![](https://static001.infoq.cn/resource/image/ac/46/aca0d4a0a1bc18beef144a410f841746.png)
我们可以想象成一个 LoadBalancer 类型的 service 创建了一个 NodePort 类型的 service,接着创建了一个 ClusterIP 类型的 service。只需简单修改下 NodePort 类型的 yaml 文件即可变更为 LoadBalancer 类型,如下所示:

复制代码


apiVersion: v1


kind: Service


metadata:


name: service-python


spec:


ports:


  • port: 3000

  • protocol: TCP

  • targetPort: 443

  • nodePort: 30080

  • selector:

  • run: pod-python

  • type: LoadBalance



LoadBalancer类型的 service 所要做的就是创建一个 NodePort 类型的 service,然后发消息给部署 Kubernetes 集群的云服务提供商,请求其为所有 node 节点的外部 IP 地址以及设定的 NodePort 端口配置负载均衡。如果云服务提供商不支持这类请求消息的处理,任何事情都不会发生,LoadBalancer 类型的 service 就会和 NodePort 类型一样了。
运行命令 kubectl get svc,结果仅多展示了一个 EXTERNAL-IP 字段以及不同的类型。
![](https://static001.infoq.cn/resource/image/38/de/38dba8cdf96dff962f629d4fa2de26de.png)
LoadBalancer 类型的 service 同样会在所有 node 节点内外 IP 地址上开放 30080 端口。在集群内部,它和 ClusterIP 类型的 service 作用一样。
## ExternalName 类型
最后介绍下 ExternalName 类型的 service,它可以被认为是有点分开的,和之前介绍的 3 种不在一个技术栈。简而言之,它创建了一个内部服务,端点指向了一个 DNS 域名。
基于我们之前的示例,现在假设 pod-nginx 已经迁移到了我们新的 Kubernetes 集群,但 Python 服务还在外部(原来的地方):
![](https://static001.infoq.cn/resource/image/04/ce/04e6d1e1bf70136cd6471f1f86f9dece.png)
如上图所示,pod-nginx 可以直接连接 http://remote.server.url.com,这样是没有问题的。但不久之后,我们想将 python 服务也迁移到新的集群中,到那时就会出问题了,因此我们可以创建一个 ExternalName 类型的 service。
![](https://static001.infoq.cn/resource/image/75/29/75e06a43b982cdc82bf6ada698601729.png)
使用的 yaml 文件内容如下:

复制代码


kind: Service


apiVersion: v1


metadata:


name: service-python


spec:


ports:


  • port: 3000

  • protocol: TCP

  • targetPort: 443

  • type: ExternalName

  • externalName: remote.server.url.com



现在,pod-nginx 可以简单地与 http://service-python:3000 建立连接,就像使用 ClusterIP 类型的 service 一样。当最终我们决定将Python 服务迁移到新的 Kubernetes 集群中时,我们只需要将 service 的类型改成 ClusterIP 并使用对应的 labels 配置即可。
![](https://static001.infoq.cn/resource/image/8d/c1/8db0d9b9d13337a8fda3ad31dbb873c1.png)
使用 ExternalName 类型 service 的最大好处在于,你可以先建设好 Kubernetes 集群基础设施,并且基于 services 和 IP 地址设定好规则与限制,尽管有些服务依然存在于集群外部。
>原文链接:><https://medium.com/swlh/kubernetes-services-simply-visually-explained-2d84e58d70e5>
复制代码


2020-05-25 16:411020

评论 2 条评论

发布
用户头像
都乱码了
2024-07-30 09:34 · 北京
回复
关键也没有12张图呢
2025-02-12 22:51 · 上海
回复
没有更多了
发现更多内容

《清华管理评论》:智能时代的人力资源管理“智效合一”转型

用友BIP

人力资源管理

inIoT分享专栏丨如何破解物联网设备连接困境

inBuilder低代码平台

华为阅读与二十一世纪出版社集团签约 共创优质少儿阅读内容生态

最新动态

使用 Amazon ECS Anywhere 在边缘部署 Amazon IoT Greengrass

亚马逊云科技 (Amazon Web Services)

物联网 ECS

Web3到底是个啥?

BSN研习社

一种新型的系统设计解决方案:模块树驱动设计

得物技术

架构 架构设计 企业号 8 月 PK 榜

基于流量回放的自动化回归测试平台 AREX Agent 技术实现细节分享

AREX 中文社区

开源 Java Agent 自动化测试 流量录制

作者推荐 | 【底层服务/编程功底系列】「底层技术原理」史上最清晰的采用程序员的视角方式进行深入探索Linux零拷贝技术原理及实现

洛神灬殇

Linux 操作系统 零拷贝 zero copy 底层原理

大文件跨国传输慢有哪些因素,附大文件跨国快速传输解决方案

镭速

大文件跨国传输

RHG之漏洞自动化利用(AEG)

云起无垠

TiDB 源码编译之 PD/TiDB Dashboard 篇

TiDB 社区干货传送门

开发语言 7.x 实践

命令行非明文密码连接 TiDB

TiDB 社区干货传送门

实践案例 集群管理 数据库连接

【SOP】最佳实践之 TiDB 业务写变慢分析

TiDB 社区干货传送门

性能调优 管理与运维 故障排查/诊断 应用适配

千帆大模型平台最新升级:接入 Llama 2 等 33 个模型!

Baidu AICLOUD

千帆大模型平台 LMops

低代码,更利好前端研发的红海

互联网工科生

前端 低代码 项目 可视化开发 JNPF

Sprint Boot学习路线6

小万哥

Java spring 微服务 后端 springboot

你真的了解appium吗?

QE_LAB

测试框架 appium

ChatGPT 助力开发人员改进代码的5个方式

SEAL安全

开发者 ChatGPT 企业号 8 月 PK 榜

中企出海关心的多数据中心问题,答案在这里!

用友BIP

中企出海

2023-08-04:村里面一共有 n 栋房子 我们希望通过建造水井和铺设管道来为所有房子供水。 对于每个房子 i,我们有两种可选的供水方案: 一种是直接在房子内建造水井 成本为 wells[i -

福大大架构师每日一题

福大大架构师每日一题

“有一群人在一起,就很好!”RTE Open Day 首场活动圆满结束

声网

活动

如何将超大文件传输给别人,超大文件如何传输呢?

镭速

超大文件传输

MobPush iOS SDK iOS实时活动

MobTech袤博科技

ios 消息推送 sdk

实战指南:如何利用Postman流畅调试微信支付接口

Liam

程序员 后端 微信支付 Postman API 调试

如何用 NPS 确定研发优先级,打破技术与业务的次元壁?

LigaAI

敏捷开发 业务价值 NPS 研发效能管理 企业号 8 月 PK 榜

暴徒猎手 HUNTDOWN for Mac(动感射击游戏)v1.0中文版

mac

游戏 暴徒猎手 HUNTDOWN

BenchmarkSQL 支持 TiDB 驱动以及 tidb-loadbalance

TiDB 社区干货传送门

开发语言 性能测评 应用适配 数据库连接

性能全面飙升!StarRocks 在贝壳找房的极速统一实践

StarRocks

数据库 大数据 MPP 湖仓一体 贝壳找房

极光笔记 | 浅谈企业级SaaS产品的客户成长旅程管理(上)—— 分析篇

极光JIGUANG

产品 用户体验 SaaS 产品

参加HDC用Petal出行,专属打车券立减20元

最新动态

12张图,带你轻松理解Kubernetes Service_文化 & 方法_Rancher_InfoQ精选文章