当前位置: 首页 > news >正文

k8s服务发现之第五弹--使用 Service 连接到应用

Kubernetes 的网络模型

通过前面教程的学习,我们已经可以将容器化的应用程序在 Kubernetes 中运行起来,并且发布到 Kubernetes 内/外的网络上。

通常,Docker 使用一种 host-private 的联网方式,在此情况下,只有两个容器都在同一个节点(主机)上时,一个容器才可以通过网络连接另一个容器。为了使 Docker 容器可以跨节点通信,必须在宿主节点(主机)的 IP 地址上分配端口,并将该端口接收到的网络请求转发(或代理)到容器中。这意味着,用户必须非常小心地为容器分配宿主节点(主机)的端口号,或者端口号可以自动分配。

在一个集群中,多个开发者之间协调分配端口号是非常困难的。Kubernetes 认为集群中的两个 Pod 应该能够互相通信,无论他们各自在哪个节点上。每一个 Pod 都被分配自己的 “cluster-private-IP”,因此,您无需在 Pod 间建立连接,或者将容器的端口映射到宿主机的端口。因此:

  • Pod 中的任意容器可以使用 localhost 直连同 Pod 中另一个容器的端口
  • 集群中的任意 Pod 可以使用另一的 Pod 的 cluster-private-IP 直连对方的端口,(无需 NAT 映射)

在集群中部署nginx

创建文件 run-my-nginx.yaml

apiVersion: apps/v1
kind: Deployment
metadata:name: my-nginx
spec:selector:matchLabels:run: my-nginxreplicas: 2template:metadata:labels:run: my-nginxspec:containers:- name: my-nginximage: nginxports:- containerPort: 80
  • 部署 Pod
kubectl apply -f ./run-my-nginx.yaml
  • 检查运行情况:
kubectl get pods -l run=my-nginx -o wide

输出结果:

NAME                        READY     STATUS    RESTARTS   AGE       IP            NODE
my-nginx-3800858182-jr4a2   1/1       Running   0          13s       10.244.3.4    kubernetes-minion-905m
my-nginx-3800858182-kna2y   1/1       Running   0          13s       10.244.2.5    kubernetes-minion-ljyd
  • 执行命令 kubectl get pods -l run=my-nginx -o yaml | grep podIP, 检查 Pod 的 IP 地址,输出结果如下:
cni.projectcalico.org/podIP: 10.244.84.185/32cni.projectcalico.org/podIPs: 10.244.84.185/32podIP: 10.244.84.185podIPs:cni.projectcalico.org/podIP: 10.244.14.61/32cni.projectcalico.org/podIPs: 10.244.14.61/32podIP: 10.244.14.61podIPs:

在集群中的任意节点上,您可以执行curl 10.244.84.185curl 10.244.14.61 获得 nginx 的响应。

  • 容器并没有使用节点上的 80 端口
  • 没有使用 NAT 规则对容器端口进行映射

这意味着,您可以

  • 在同一节点上使用 80 端口运行多个 nginx Pod
  • 在集群的任意节点/Pod 上使用 nginx Pod 的 clusterIP 访问 nginx 的 80 端口

同 Docker 一样,Kubernets 中,仍然可以将 Pod 的端口映射到宿主节点的网络地址上(使用 nodePort),但是使用 Kubernetes 的网络模型时,这类需求已经大大减少了。

创建 Service

上面的步骤中,我们已经创建了 nginx Pod,运行在集群的 IP 地址空间。您可以直接通过 Pod 的地址访问其端口,但是如果某一个 Pod 终止了该怎么办?Pod 因为故障或其他原因终止后,Deployment Controller 将创建一个新的 Pod 以替代该 Pod,但是 IP 地址将发生变化。Kubernetes Service 解决了这样的问题。

Kubernetes Service:

  • 定义了集群中一组 Pod 的逻辑集合,该集合中的 Pod 提供了相同的功能
  • 被创建后,获得一个唯一的 IP 地址(ClusterIP)。直到该 Service 被删除,此地址不会发生改变
  • Pod 可以直接连接 Service IP 地址上的端口,且发送到该 IP 地址的网络请求被自动负载均衡分发到 Service 所选取的 Pod 集合中

执行命令 kubectl expose deployment/my-nginx 可以为上面的两个 nginx Pod 创建 Service,输出结果如下所示:

service/my-nginx exposed

该命令等价于 kubectl apply -f nginx-svc.yaml,其中 nginx-svc.yaml 文件的内容如下所示:

apiVersion: v1
kind: Service
metadata:name: my-nginxlabels:run: my-nginx
spec:ports:- port: 80targetPort: 80protocol: TCPselector:run: my-nginx

该 yaml 文件将创建一个 Service:

  • 该 Service 通过 label selector 选取包含 run: my-nginx 标签的 Pod 作为后端 Pod
  • 该 Service 暴露一个端口 80(spec.ports[*].port
  • 该 Service 将 80 端口上接收到的网络请求转发到后端 Pod 的 80 (spec.ports[*].targetPort)端口上,支持负载均衡

执行命令 kubectl get svc my-nginx,输出结果如下

NAME       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
my-nginx   ClusterIP   10.100.223.157   <none>        80/TCP    75s

Service 的后端 Pod 实际上通过 Endpoints 来暴露。Kubernetes 会持续检查 Service 的 label selector spec.selector,并将符合条件的 Pod 更新到与 Service 同名(my-nginx)的 Endpoints 对象。如果 Pod 终止了,该 Pod 将被自动从 Endpoints 中移除,新建的 Pod 将自动被添加到该 Endpoint。

执行命令 kubectl describe svc my-nginx,输出结果如下,请注意 Endpoints 中的 IP 地址与上面获得的 Pod 地址相同:

Name:              my-nginx
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          run=my-nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.100.223.157
IPs:               10.100.223.157
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.14.61:80,10.244.84.185:80
Session Affinity:  None
Events:            <none>

执行命令 kubectl get ep my-nginx,输出结果

NAME       ENDPOINTS                          AGE
my-nginx   10.244.14.61:80,10.244.84.185:80   8m37s

此时,您可以在集群的任意节点上执行curl 10.100.223.157:80,通过 Service 的 ClusterIP:Port 访问 nginx。

访问 Service

Kubernetes 支持两种方式发现服务:

  • 环境变量
  • DNS 参考

环境变量

针对每一个有效的 Service,kubelet 在创建 Pod 时,向 Pod 添加一组环境变量。这种做法引发了一个 Pod 和 Service 的顺序问题。例如,

  • 执行命令 kubectl exec my-nginx-df7bbf6f5-87hqg -- printenv | grep SERVICE (您的 Pod 名字可能不一样),输出结果如下
KUARD_SERVICE_PORT=80
KUBERNETES_SERVICE_PORT_HTTPS=443
KUARD_SERVICE_HOST=10.110.143.73
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443

DNS

Kubernetes 提供了一个 DNS cluster addon,可自动为 Service 分配 DNS name。

查看该 addon 在您的集群上是否可用

kubectl get services kube-dns --namespace=kube-system

输出结果:

NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   140d

可以从集群中任何 Pod 中按 Service 的名称访问该 Service。

  • 执行命令 kubectl run curl --image=radial/busyboxplus:curl -i --tty 获得 busyboxplus 容器的命令行终端,该命令输出结果
If you don't see a command prompt, try pressing enter.
[ root@curl:/ ]$
  • 然后,单击回车键,并执行命令 nslookup my-nginx,输出结果如下所示:
[ root@curl:/ ]$  nslookup my-nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.localName:      my-nginx
Address 1: 10.100.223.157 my-nginx.default.svc.cluster.local
  • 执行命令 curl my-nginx:80,可获得 Nginx 的响应。
[ root@curl:/ ]$ curl my-nginx:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>
  • 执行命令 exit 可推出该容器的命令行
  • 执行命令 kubectl delete deployment curl 可删除刚才创建的 curl 测试容器

相关文章:

k8s服务发现之第五弹--使用 Service 连接到应用

Kubernetes 的网络模型 通过前面教程的学习&#xff0c;我们已经可以将容器化的应用程序在 Kubernetes 中运行起来&#xff0c;并且发布到 Kubernetes 内/外的网络上。 通常&#xff0c;Docker 使用一种 host-private 的联网方式&#xff0c;在此情况下&#xff0c;只有两个容…...

SAP ABAP 自定义表数据导入

一:效果展示&#xff1a; 读取 Excel 数据到 SAP 数据库表。 二&#xff1a;源码&#xff1a; *&---------------------------------------------------------------------* *& Report ZTEST_DRW02 *&----------------------------------------------------------…...

目标检测识别——大恒(DaHeng)相机操作与控制编程

文章目录 引言正文相关开发库的介绍编程准备配置引用头文件GalaxyIncludes.h配置lib文件 具体编程过程初始化和反初始化枚举设备开关设备 属性控制属性控制器种类 图像采集控制和图像处理采单帧回调采集 总结 引言 在做老师的横向项目时&#xff0c;需要用大恒相机&#xff0c…...

国标GB28181视频监控平台EasyGBS视频无法播放,抓包返回ICMP是什么原因?

国标GB28181视频平台EasyGBS是基于国标GB/T28181协议的行业内安防视频流媒体能力平台&#xff0c;可实现的视频功能包括&#xff1a;实时监控直播、录像、检索与回看、语音对讲、云存储、告警、平台级联等功能。国标GB28181视频监控平台部署简单、可拓展性强&#xff0c;支持将…...

如何正确使用npm常用命令

npm常用命令&#xff1a; 官方文档&#xff1a;CLI Commands | npm Docs 1. npm -v&#xff1a;查看 npm 版本 2. npm init&#xff1a;初始化后会出现一个 Package.json 配置文件&#xff0c;可以在后面加上 -y&#xff0c;快速跳到问答界面 3. npm install&#xff1a;会…...

无人机影像配准并发布(共线方程)

无人机影像 DEM 计算四个角点坐标&#xff08;刚性变换&#xff09; 像空间坐标&#xff08;x,y,-f&#xff09; 像空间坐标畸变纠正 deltax,deltay 已知(x,y)&#xff0c;求解(X,Y, Z)或者(Lat,Lon) 这里的Z是DEM上获取的坐标和Zs为相机坐标的高程&#xff0c;如果均为已…...

openGauss学习笔记-23 openGauss 简单数据管理-时间/日期函数和操作符

文章目录 openGauss学习笔记-23 openGauss 简单数据管理-时间/日期函数和操作符23.1 时间日期操作符23.2 时间/日期函数23.3 TIMESTAMPDIFF23.4 EXTRACT23.5 date_part openGauss学习笔记-23 openGauss 简单数据管理-时间/日期函数和操作符 23.1 时间日期操作符 用户在使用时…...

C++OpenCV(7):图像形态学基础操作

&#x1f506; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 &#x1f506; OpenCV项目地址及源代码&#xff1a;点击这里 文章目录 膨胀与腐蚀形态学基础 膨胀与腐蚀 膨胀与腐蚀是数学形态学在图像处理中最基础的操作。 膨胀操作是取每个位置领域内最大值&#xff0…...

Appium+python自动化(二十二)- 控件坐标获取(超详解)

简介 有些小伙伴或者是童鞋可能会好奇会问上一篇中的那个monkey脚本里的坐标点是如何获取的&#xff0c;不是自己随便蒙的猜的&#xff0c;或者是自己用目光或者是尺子量出来的吧&#xff0c;答案当然是&#xff1a;NO。获取控件坐标点的方式这里宏哥给小伙伴们分享和讲解三种方…...

Tensorflow benchmark 实操指南

环境搭建篇见环境搭建-CentOS7下Nvidia Docker容器基于TensorFlow1.15测试GPU_东方狱兔的博客-CSDN博客 1. 下载Benchmarks源码 从 TensorFlow 的 Github 仓库上下载 TensorFlow Benchmarks&#xff0c;可以通过以下命令来下载 https://github.com/tensorflow/benchmarks 我…...

【linux】调试工具介绍

文章目录 前言一、kdb二、ftrace三、gdb 前言 在Linux内核调试过程中&#xff0c;可以使用各种工具和技术来诊断和解决问题。以下是一些常用的Linux内核调试方法&#xff1a; printk&#xff1a;printk是Linux内核中的打印函数&#xff0c;可以在代码中插入打印语句来输出调试…...

2.获取DOM元素

获取DOM元素就是利用JS选择页面中的标签元素 2.1 根据CSS选择器来获取DOM元素(重点) 2.1.1选择匹配的第一个元素 语法: document.querySelector( css选择器 )参数: 包含一个或多个有效的CSS选择器 字符串 返回值: CSS选择器匹配的第一个元素&#xff0c;一个HTMLElement对象…...

flask中redirect、url_for、endpoint介绍

flask中redirect、url_for、endpoint介绍 redirect 在 Flask 中&#xff0c;redirect() 是一个非常有用的函数&#xff0c;可以使服务器发送一个HTTP响应&#xff0c;指示客户端&#xff08;通常是浏览器&#xff09;自动导航到新的 URL。基本上&#xff0c;它是用来重定向用…...

《MySQL》第十二篇 数据类型

目录 一. 整数类型二. 浮点类型三. 日期和时间类型四. 字符串类型五. 枚举值类型六. 二进制类型七. 小结 MySQL 支持多种数据类型&#xff0c;学习好数据类型&#xff0c;才能更好的学习 MySQL 表的设计&#xff0c;让表的设计更加合理。 一. 整数类型 类型大小SIGNED(有符号)…...

Python与OpenCV环境中,借助SIFT、单应性、KNN以及Ransac技术进行实现的图像拼接算法详细解析及应用

一、引言 在当今数字化时代,图像处理技术的重要性不言而喻。它在无人驾驶、计算机视觉、人脸识别等领域发挥着关键作用。作为图像处理的一个重要部分,图像拼接算法是实现广阔视野图像的重要手段。今天我们将会讲解在Python和OpenCV环境下,如何使用SIFT、单应性、KNN以及Ran…...

苍穹外卖Day01项目日志

1.软件开发流程和人员分工是怎样的&#xff1f; 软件开发流程 一个软件是怎么被开发出来的&#xff1f; 需求分析 先得知道软件定位人群、用户群体、有什么功能、要实现什么效果等。 需要得到需求规格说明书、产品原型。 需求规格说明书 其中前后端工程师要关注的就是产品原…...

Netty学习(二)

文章目录 二. Netty 入门1. 概述1.1 Netty 是什么&#xff1f;1.2 Netty 的作者1.3 Netty 的地位1.4 Netty 的优势 2. Hello World2.1 目标加入依赖 2.2 服务器端2.3 客户端2.4 流程梳理课堂示例服务端客户端 分析提示&#xff08;重要&#xff09; 3. 组件3.1 EventLoop事件循…...

ReactRouterv5在BrowserRouter和HashRouter模式下对location.state的支持

结论&#xff1a;HashRouter不支持location.state 文档&#xff1a;ReactRouter v5 从文档可看到history.push()方法支持2个参数&#xff1a;path, [state] state即是location.state&#xff0c;常用于隐式地传递状态参数 但文档未提的是&#xff0c;仅适用于BrowserRouter&am…...

Aerotech系列文章(3)运动设置命令Motion Setup Commands

1.运动设置命令Motion Setup Commands 斜坡类型&#xff1a; 直线&#xff0c;S曲线&#xff0c;与正弦曲线 Enumerator: RAMPTYPE_Linear Linear-based ramp type. RAMPTYPE_Scurve S-curve-based ramp type. RAMPTYPE_Sine Sine-based ramp type. 函数原型&a…...

线性神经网络——softmax 回归随笔【深度学习】【PyTorch】【d2l】

文章目录 3.2、softmax 回归3.2.1、softmax运算3.2.2、交叉熵损失函数3.2.3、PyTorch 从零实现 softmax 回归3.2.4、简单实现 softmax 回归 3.2、softmax 回归 3.2.1、softmax运算 softmax 函数是一种常用的激活函数&#xff0c;用于将实数向量转换为概率分布向量。它在多类别…...

GitHub Trending 每日精选 - 2026-03-27

GitHub Trending 每日精选 - 2026-03-27 &#x1f4c8; 今日概览 今天是 2026-03-27&#xff0c;GitHub Trending 榜单上有哪些值得关注的开源项目&#xff1f;注&#xff1a;此博客为自动化生成&#xff0c;系统会在每日运行时获取最新 Trending 数据并填充具体项目信息。&…...

还在手工整理IT报表?这套自动化模板让你彻底解放双手

在不断变化的IT管理环境中&#xff0c;透明度和合规性已成为企业生存和发展的基石。面对日益繁杂的法规与标准&#xff0c;组织需要精细的报表与审计流程来支撑业务稳健运行。作为一款专为现代IT打造的尖端平台&#xff0c;Endpoint Central不仅大幅减轻了合规负担&#xff0c;…...

当NB-IoT遇上同步轨道卫星:GEO场景下的定时关系增强全指南(基于3GPP Release 17最新规范)

GEO卫星场景下NB-IoT定时关系增强技术解析 1. GEO卫星通信与NB-IoT的技术融合挑战 地球静止轨道&#xff08;GEO&#xff09;卫星通信与窄带物联网&#xff08;NB-IoT&#xff09;技术的结合&#xff0c;为全球物联网覆盖提供了革命性解决方案。GEO卫星位于地球赤道上空35,786公…...

别再只盯着PID了!用MATLAB的musyn命令,5步搞定复杂不确定系统的鲁棒控制器设计

别再只盯着PID了&#xff01;用MATLAB的musyn命令&#xff0c;5步搞定复杂不确定系统的鲁棒控制器设计 当你的无人机在强风环境下出现姿态抖动&#xff0c;或者工业机械臂负载突变时产生振荡&#xff0c;传统PID控制器往往显得力不从心。这类具有参数不确定性、动态扰动的多变量…...

中文句子相似度分析神器:StructBERT本地部署全流程详解(附代码)

中文句子相似度分析神器&#xff1a;StructBERT本地部署全流程详解&#xff08;附代码&#xff09; 1. 工具概览与核心价值 中文语义相似度分析是自然语言处理中的一项基础但关键的任务。无论是智能客服中的问题匹配&#xff0c;还是内容平台的文章查重&#xff0c;都需要准确…...

Crawl4AI浏览器配置文件创建与键盘交互处理终极指南:打造个性化爬虫身份

Crawl4AI浏览器配置文件创建与键盘交互处理终极指南&#xff1a;打造个性化爬虫身份 【免费下载链接】crawl4ai &#x1f525;&#x1f577;️ Crawl4AI: Open-source LLM Friendly Web Crawler & Scrapper 项目地址: https://gitcode.com/GitHub_Trending/craw/crawl4ai…...

终极DBeaver多线程查询优先级控制:基于查询类型的动态调整指南

终极DBeaver多线程查询优先级控制&#xff1a;基于查询类型的动态调整指南 【免费下载链接】dbeaver DBeaver 是一个通用的数据库管理工具&#xff0c;支持跨平台使用。* 支持多种数据库类型&#xff0c;如 MySQL、PostgreSQL、MongoDB 等&#xff1b;提供 SQL 编辑、查询、调试…...

Python边缘部署不是“复制粘贴”!12个生产环境真实报错日志溯源分析(附可复用诊断矩阵表)

第一章&#xff1a;Python边缘部署的本质认知与误区破除Python边缘部署不是将桌面或服务器环境简单“搬移”到嵌入式设备&#xff0c;而是面向资源受限、实时性敏感、网络不可靠、运维通道受限等物理约束下的系统性重构。其本质是**在算力、内存、存储、功耗与可靠性之间达成动…...

二次开发入门:修改nanobot镜像适配我的OpenClaw需求

二次开发入门&#xff1a;修改nanobot镜像适配我的OpenClaw需求 1. 为什么需要定制nanobot镜像 第一次接触OpenClaw时&#xff0c;我直接使用了官方提供的标准镜像。但在实际使用中&#xff0c;发现几个痛点&#xff1a;默认的chainlit界面过于简单&#xff0c;无法展示我需要…...

OpenClaw智能邮件助手:nanobot镜像自动分类与回复重要邮件

OpenClaw智能邮件助手&#xff1a;nanobot镜像自动分类与回复重要邮件 1. 为什么需要智能邮件助手 每天早晨打开邮箱&#xff0c;看到堆积如山的未读邮件总是让人头疼。重要客户的询盘可能被埋没在促销广告中&#xff0c;紧急的协作请求可能因为延迟回复而影响项目进度。作为…...