HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

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

评论 1 条评论

发布
用户头像
都乱码了
2024-07-30 09:34 · 北京
回复
没有更多了
发现更多内容

StarRocks 巧用 Storage Volume,强大又便捷

Ding_Kai

数据库 StarRocks

Go 程序如何实现优雅退出?来看看 K8s 是怎么做的——下篇

江湖十年

k8s 设计模式 k8s知识 Go web #k8s

豆包大模型更多行业落地实践,9月3日邀你见证

新消费日报

星河AI电力网络,电力智能化的飞跃起点

脑极体

AI

VLDB 2024丨与 TiDB 一起探索数据库学术前沿

PingCAP

数据库 TiDB

Python并发编程:多线程(threading模块)

我再BUG界嘎嘎乱杀

Python 编程 并发编程 后端 多线程

git中的cherry-pick和merge有些区别以及cherry-pick怎么用

百度搜索:蓝易云

Apache RocketMQ 中文社区全新升级丨阿里云云原生 7 月产品月报

阿里巴巴云原生

Apache 阿里云 RocketMQ 云原生

如果让你设计一个秒杀系统,你会怎么做?

江南一点雨

腾讯云入选Gartner®首份AI代码助手魔力象限报告

Geek_2d6073

Python 实时聊天室搭建:发布订阅频道API实战应用

幂简集成

Python API

PingCAP 孙晓光:TiDB Cloud Serverless 将成为 AI 应用创新的最佳搭档

PingCAP

人工智能 Serverless Cloud TiDB

十种超赞的 MyBatis 写法!

秃头小帅oi

云知声多模态模型:实时多模态输入输出;独立于 Siri ,苹果或开发新 AI 用于机器人丨 RTE 开发者日报

声网

解锁豆包MarsCode奥秘,打造你的专属创意工坊!|动手实验室新一期又来啦

豆包MarsCode

人工智能 编程 程序员 AI 计算机

Nginx和Tomcat负载均衡实现session共享

百度搜索:蓝易云

试用 Kubernetes Gateway API 的五大理由

NGINX开源社区

nginx 开源 Kubernetes 前端 灰度发布

5 大场景上手通义灵码企业知识库 RAG

阿里巴巴云原生

阿里云 云原生 通义灵码

探究Python中的函数与模块

我再BUG界嘎嘎乱杀

Python 编程 后端 函数 开发语言

5 大场景上手通义灵码企业知识库 RAG

阿里云云效

阿里云 云原生 通义灵码

聚合博客网址导航大全代码分享

博客趣

个人博客 博客导航 博客大全 博客趣

建筑行业项目管理新宠,10款软件助你轻松驾驭

爱吃小舅的鱼

项目管理 建筑行业

豆瓣评分7.6!Python大牛教你如何采集网络数据

我再BUG界嘎嘎乱杀

Python 编程 爬虫 后端 数据采集

操作系统笔记 day5

万里无云万里天

操作系统

dolphinscheduler docker compose安装配置

百度搜索:蓝易云

AI 驱动的产品全生命周期:从概念设计阶段到生命周期的全面管理

Altair RapidMiner

人工智能 AI 数据分析 仿真 智能制造

Spring中的动态表达式SpEL

SpEL表达式 SpEL @Value

Linux禁止用户或IP通过SSH登录

百度搜索:蓝易云

StarRocks 存算分离成本优化最佳实践

Ding_Kai

数据库 StarRocks

深入解析京东商品详情API返回值:从零到一的全面指南

代码忍者

API 测试 API 策略

动手实践:如何高效构建企业级AI搜索

阿里云大数据AI技术

人工智能 elasticsearch 阿里云 最佳实践 AI搜索

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