写点什么

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

评论 2 条评论

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

云钉一体应用创新:音视频如何带来灵活高效的协同体验

阿里云CloudImagine

阿里云 音视频

五层验证系统,带你预防区块链业务漏洞

华为云开发者联盟

区块链 智能合约 漏洞 可信 自免疫系统

如何从Java字节码角度解决问题

叫我阿柒啊

Java 字节码

Java 并发编程—— Semaphore

Antway

6月日更

书单 | 阿里技术书单,满足你的“大厂情结”!

博文视点Broadview

如何快速分类整理电脑文件

TroyLiu

文件管理 文件整理 电脑文件 文件分类 快速整理文件

怒肝最新保姆级前端学习路线,速成贴心全面!

程序员鱼皮

CSS JavaScript Vue 大前端 React

牛掰!阿里首席架构师用7部分讲明白了Java百亿级高并发系统(全彩版小册开源)

Java架构追梦

Java 学习 阿里巴巴 架构 百亿级并发架构设计

流程即代码:低代码 & 云研发 IDE —— Uncode

Phodal

ide 云开发 云研发

助力初创企业加速升级,华为云初创扶持计划微光训练营南京站开营仪式成功举办

科技热闻

机器学习- 吴恩达Andrew Ng 编程作业技巧 -John 易筋 ARTS 打卡 Week 50

John(易筋)

ARTS 打卡计划

搞定研发知识管理,你的企业就能跑快一步

华为云开发者联盟

知识管理 华为云 devcloud 研发团队 研发知识

信息流动过程中的聚类问题

Ryan Zheng

Webpack 系列4:彻底理解 module.issuer 属性

范文杰

webpack 6月日更

QQ春节红包活动如何应对10亿级流量?看看大佬的复盘总结

TakinTalks稳定性社区

活动 系统运维 高并发优化 高可用系统的架构 高可用架构

《漫画算法2》2021全新进阶版来袭!

博文视点Broadview

Apache APISIX 开源 2 周年!

API7.ai 技术团队

开源 架构 后端 网关

从原理到实践,手把手带你轻松get数仓双集群容灾

华为云开发者联盟

容灾 集群 数仓 集群容灾 双集群

☕️【Java 技术之旅】深入分析JDK动态代理的分析(源码深入)

码界西柚

Java JVM 动态代理 6月日更

架构实战营 - 模块五作业

Sun

工作多年,Linux文件系统还不太了解?

架构精进之路

Linux 文件 6月日更

Apache Calcite:异质数据源优化查询框架

余生

sql Apache Calcite

毕业设计So Easy:基于Java Web学生选课系统

不脱发的程序猿

Java web 毕业设计 学生选课系统

关于MySQL库表名大小写问题

Simon

MySQL

先立个Flag

追风少年

限流篇,欣赏guava的RateLimiter

下雨喽

Java 架构 设计 限流 Guava

来自Linux老学员的经验分享,新生必看!

学神来啦

Linux 运维 安全 虚拟机

一文讲懂服务的优雅重启和更新

万俊峰Kevin

微服务 web开发 Go 语言 优雅停机

一口气了解【2021 阿里云峰会】重磅发布

阿里云CloudImagine

阿里云

HarmonyOS IoT首著,走进万物互联的世界!

博文视点Broadview

并发编程概览-从Lock和Synchronized说起

追风少年

Java 并发编程

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