现场实操破解开发瓶颈,「2023 百度云智大会·智算大会 开发者沙龙」不容错过! 了解详情
写点什么

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:41793

评论

发布
暂无评论
发现更多内容

互联网公司的「敏捷开发」流程是怎么样的?典型的敏捷团队是什么样?

PingCode

敏捷 敏捷开发 研发管理 研发效能 研发工具

如果软件测试行业没门槛了,你开心么?

程序员阿沐

软件测试 自动化测试 测试开发 测试工程师 黑盒测试

接口测试--apipost变量使用(一)

测试人生路

重磅丨国资委下发通知,加快推进国有企业数字化转型

PingCode

团队管理 项目管理 研发管理 研发效能 研发工具

谷歌开发安卓系统!Android面试你必须要知道的那些知识,全网疯传

欢喜学安卓

android 程序员 面试 移动开发

开源分享 | 火遍全网的「蚂蚁呀嘿」教程来了!

百度开发者中心

paddle 开源 #飞桨#

LeetCode题解:188. 买卖股票的最佳时机 IV,动态规划,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

最新热点:钉钉公布低代码开发者画像,这些数据意味着什么?

优秀

PingCode新成员Goals开放内测!

PingCode

项目管理 敏捷 敏捷开发 研发管理 研发效能

【LeetCode】二维区域和检索 - 矩阵不可变Java题解

Albert

算法 LeetCode 28天写作

话说 synchronized

木子的昼夜

Java

总结:近几年有哪些不错的scrum工具

PingCode

Scrum 敏捷 敏捷开发 研发管理 研发工具

Pgbouncer最佳实践:系列二

PostgreSQLChina

数据库 postgresql 开源 软件 开源社区

高效搜索信息,你需要掌握这些谷歌搜索技巧

LeanCloud

开发者 大前端 工作效率

与 Hadoop 对比,我是如何看待 Spark 技术?

TASKCTL

大数据 hadoop spark 存储

ETL工具—Taskctl 如何搭建配置作业类型的管理

TASKCTL

大数据 kettle 运维自动化 海豚调度 ETL

腾讯音乐-全民K歌iOS面经

iOSer

ios 面试 腾讯大厂 金三银四跳槽

在敏捷项目管理情境下,如何做多项目管理?

PingCode

敏捷 敏捷开发 研发管理 研发效能 研发工具

RocketMQ安装部署

云淡风轻

RocketMQ

SQL Server 多表数据增量获取和发布 2.2

happlyfox

数据库 学习 28天写作 3月日更

力扣(LeetCode)刷题,简单+中等题(第30期)

不脱发的程序猿

面试 程序人生 算法 LeetCode 28天写作

微服务框架相关技术整理

架构 微服务

作为产品经理,如何分析和管理你的产品需求?

PingCode

敏捷开发 研发管理 需求管理 需求 研发工具

力扣 (LeetCode)-两数之和,有效的括号,两数相加

我是哪吒

面试 算法 LeetCode 28天写作

连续两次入围Gartner魔力象限的Quick BI到底有何魔力?

【黑科技】爬虫也可以一键获取 [加载更多] 数据,无编码学爬虫之三。

梦想橡皮擦

Python 28天写作 3月日更

哪些应用场景在使用语音连麦

anyRTC开发者

音视频 WebRTC RTC 语音社交

Java程序员福音!蚂蚁+字节+腾讯+龙湖地产+美团+滴滴+猿辅导1000+面试题总结

Java架构追梦

Java 架构 面试 金三银四

直流电源防反接电路设计

不脱发的程序猿

嵌入式 28天写作 硬件设计 直流电源 防反接电路设计

谷歌android!通宵都要看完这个Android关键技术点,威力加强版

欢喜学安卓

android 程序员 面试 移动开发

最新整理:Google/网易/腾讯/百度/华为面经(25个专题 1W字答案解析)

比伯

Java 编程 程序员 架构 面试

  • 扫码添加小助手
    领取最新资料包
12张图,带你轻松理解Kubernetes Service_文化 & 方法_Rancher_InfoQ精选文章