Kubernetes入门 十一、网络之Service

news2025/1/23 10:46:00

目录

  • 概述
  • Service 原理
  • Service 四种类型
  • 创建 Service
  • 代理 k8s 外部服务
  • 反向代理外部域名

概述

在 Kubernetes 中,Pod 是应用程序的载体,我们可以通过 Pod 的 IP 来访问应用程序,但是 Pod 的 IP 地址不是固定的,这就意味着不方便直接采用 Pod 的 IP 对服务进行访问。

为了解决这个问题,Kubernetes 提供了 Service 资源,Service 会对提供同一个服务的多个 Pod 进行聚合,并且提供一个统一的入口地址,通过访问 Service 的入口地址就能访问到后面的 Pod 服务。

在这里插入图片描述

Service不仅提供了服务发现的功能,还有负载均衡的能力。

Service 原理

Service 在很多情况下只是一个概念,真正起作用的其实是 kube-proxy 服务进程,每个 Node 节点上都运行了一个 kube-proxy 的服务进程。当创建 Service 的时候会通过 API Server 向 etcd 写入创建的 Service 的信息,而 kube-proxy 会基于监听的机制发现这种 Service 的变化,然后它会将最新的 Service 信息转换为对应的访问规则(其实,就是 EndPoint,后面讲)。

Service整体的网络架构如下:
在这里插入图片描述

步骤如下:

  1. 创建Service时,会通过标签选择器,来选择为哪些pod维护网络,内部维护一个Endpoint,用来找到对应的pod。
  2. 当我们在集群内部访问其他pod,先找到service
  3. 在通过service里的Endpoint找到对应pod
  4. 通过iptables(或其他方式)转发到kube-proxy
  5. kube-proxy在找到对应的pod容器

Service 四种类型

  • ClusterIP:默认类型,自动分配一个仅 cluster 内部可以访问的虚拟 IP。选择该值,服务只能够在集群内部访问,这也是默认的 ServiceType。
  • NodePort:在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过 <NodeIP>:NodePort 来访问该服务。如果 kube-proxy 设置了 --nodeport-addresses=10.240.0.0/16(v1.10 支持),那么仅该 NodePort 仅对设置在范围内的 IP 有效。
  • LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到 <NodeIP>:NodePort
  • ExternalName:将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)。需要 kube-dns 版本在 1.7 以上。

另外,也可以将已有的服务以 Service 的形式加入到 Kubernetes 集群中来,只需要在创建 Service 的时候不指定 Label selector,而是在 Service 创建好后手动为其添加 endpoint。

创建 Service

创建文件nginx-svc.yaml,内容如下:

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc  # Service名字
  labels:
    app: nginx-svc  # Service自己的标签
spec:
  selector: # 选中当前 service 匹配哪些 pod,对哪些 pod 的东西流量进行代理
    app: nginx-deploy
  ports:
  - name: http # service 端口配置的名称
    protocol: TCP # 端口绑定的协议,支持 TCP、UDP、SCTP,默认为 TCP
    port: 80 # service 自己的端口
    targetPort: 80 # 目标 pod 的端口
  type: NodePort  # 随机启动一个端口(30000-32767),映射到ports中的端口,该端口直接绑定到node上,集群中每个node都绑定这个端口

创建Service管理的pod,使用前面章节用过的nginx-deploy.yaml,内容如下:

apiVersion: apps/v1  # deployment api 版本
kind: Deployment  # 资源类型为deployment
metadata:  # 元信息
  labels:  # 标签
    app: nginx-deploy
  name: nginx-deploy  # deployment的名字
  namespace: default  # 所在命名空间
spec:
  replicas: 3  # 期望副本数
  revisionHistoryLimit: 10  # 进行滚动更新后,保留的历史版本数
  selector:  # 选择器,用于找到匹配的RS,管理指定标签的Rs
    matchLabels:  # 按照标签匹配
      app: nginx-deploy  # 匹配的标签
  strategy:  # 更新策略
    rollingUpdate:  # 滚动更新配置
      maxSurge: 25%  # 进行滚动更新时,更新的个数超过期望副本数的比例
      maxUnavailable: 25%  # 进行滚动更新时,最大不可用更新比例,也就是更新不成功最多能有多少个
    type: RollingUpdate  # 更新策略采用滚动更新
  template:  # pod模板
    metadata:  # pod的元信息
      labels:  # pod的标签
        app: nginx-deploy
    spec:  # pod的描述信息
      containers: # pod的描述信息
      - image: nginx:1.7.9   # pod使用镜像
        imagePullPolicy: IfNotPresent   # 镜像拉取策略
        name: nginx  # 容器名称
      restartPolicy: Always  # 重启策略
      terminationGracePeriodSeconds: 30  # 容器删除等待时间

部署deployment:

kubectl apply -f nginx-deploy.yaml
# deployment.apps/nginx-deploy created

查看po信息如下:

在这里插入图片描述

重点看下3个pod的IP和lables。

然后部署Service:

kubectl apply -f nginx-svc.yaml
# service/nginx-svc created

查看信息:

kubectl get svc
# 结果如下
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
nginx-svc    NodePort    10.108.244.247   <none>        80:30087/TCP   2m45s

查看具体信息,可以看到NodePort绑定的端口信息和Endpoints信息:

kubectl describe svc nginx-svc
# 结果如下
Name:                     nginx-svc
Namespace:                default
Labels:                   app=nginx-svc
Annotations:              <none>
Selector:                 app=nginx-deploy
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.108.244.247
IPs:                      10.108.244.247
LoadBalancer Ingress:     localhost
Port:                     http  80/TCP
TargetPort:               80/TCP
NodePort:                 http  30087/TCP  # NodePort绑定的端口信息
Endpoints:                10.1.0.112:80,10.1.0.113:80,10.1.0.114:80  # Endpoints信息
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

可以看到Endpoints对应的3个IP分别是3个Pod的IP。

下面我们就创建另外一个Pod来访问前面创建的Pod。

还创建我们前面用过的busybox:

kubectl run -it --image busybox dns-test --restart=Never --rm /bin/sh

创建完成后我们使用通过服务名来访问:

# 使用wget命令访问
wget http://nginx-svc
# 结果如下,成功下载到了index.html
Connecting to nginx-svc (10.108.244.247:80)  # 请求到了svc地址,然后svc找到pod访问
saving to 'index.html'
index.html           100% |*******************************************************************|   612  0:00:00 ETA
'index.html' saved

也可以在后面加上命名空间实现跨命名空间访问:

 wget http://nginx-svc.defaul

代理 k8s 外部服务

虽然Service是用来负责集群内部服务互相访问,但是有时我们想要Service代理外部服务也是可以的,也就是当我们访问Service时,它可以把请求转发到集群外部去。

例如,当我们的服务部署时,分为开发环境和测试环境,那一个服务部署请求另一个服务时,希望是开发环境的服务请求另一个服务时,也请求到开发环境,同理测试环境也是。

再比如,当我们把一部分服务迁移到K8s中时,还有一部分没有迁移,这时候也需要能够通过Service调用即可。

要实现这个效果,需要额外做以下两件事:

  • 编写 service 配置文件时,不指定 selector 属性(这时不会自动创建endpoint)
  • 自己创建 endpoint

下面就来看看如何实现。

  1. 创建Service

创建文件pgsql-svc-external.yaml,去掉selector,内容如下:

apiVersion: v1
kind: Service
metadata:
  name: pgsql-svc-external  # Service名字
  labels:
    app: pgsql  # Service自己的标签
spec:
  ports:
  - name: pgsql # service 端口配置的名称
    port: 80 # service 自己的端口
    targetPort: 5432 # 目标端口
  type: ClusterIP

创建Service:

kubectl apply -f pgsql-svc-external.yaml
# service/nginx-svc-external created

查看endpoint:

kubectl get ep
# 发现没有为我们自动创建endpoint即可
  1. 创建endpoint

创建资源文件pgsql-ep.yaml,内容如下:

apiVersion: v1
kind: Endpoints
metadata:
  labels:
    app: pgsql # 与 service 一致
  name: pgsql-svc-external # 与 service 一致
  namespace: default # 与 service 一致
subsets:
- addresses:
  - ip: 10.2.8.79
  ports: 
  - port: 5432

假如要在集群内部访问集群外部的pg数据库。

创建endpoint:

kubectl apply -f pgsql-ep.yaml
# endpoints/nginx-svc-external created

查看创建的:

kubectl get ep
# 结果如下
NAME                 ENDPOINTS           AGE
pgsql-svc-external   10.2.8.79:5432      5s

kubectl describe ep pgsql-svc-external
# 结果如下
Name:         pgsql-svc-external
Namespace:    default
Labels:       app=pgsql
Annotations:  <none>
Subsets:
  Addresses:          10.2.8.79
  NotReadyAddresses:  <none>
  Ports:
    Name     Port  Protocol
    ----     ----  --------
    <unset>  5432  TCP

Events:  <none>

以上就是将外部 IP 地址和服务引入到 k8s 集群内部(其他节点),由 service 作为一个代理来达到能够访问外部服务的目的。

没实操实现,有时间再看看。

反向代理外部域名

使用ExternalName类型的Service即可,配置如下:

apiVersion: v1
kind: Service
metadata:
  name: baidu-svc  # Service名字
  labels:
    app: baidu  # Service自己的标签
spec:
  type: ExternalName
  externalName: www.baidu.com

不再演示。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/942688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MyBatisPlus实现多租户功能

前言&#xff1a;多租户是一种软件架构技术&#xff0c;在多用户的环境下&#xff0c;共有同一套系统&#xff0c;并且要注意数据之间的隔离性。 一、SaaS多租户简介 1.1、SaaS多租户 SaaS&#xff0c;是Software-as-a-Service的缩写名称&#xff0c;意思为软件即服务&#x…

【电源专题】读一读单节锂电池保护IC规格书

在文章【电源专题】单节锂离子电池的保护的基本原理 中我们了解了电池包的过充、过放、过流、短路等保护功能。那么这些功能都会在电池保护IC规格书中体现吗?体现在哪些地方?哪些参数是我们应关注的呢? 对于手册中的电压检测,如放电过流、充电过流和负载短路等检测电压都代…

开源软件的国际化和本地化

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

centos7删除乱码文件

centos7删除乱码文件1. 小白教程&#xff0c;一看就会&#xff0c;一做就成。 1.解释 当文件名为乱码的时候&#xff0c;无法通过键盘输入文件名&#xff0c;所以在终端下就不能直接利用rm&#xff0c;mv等命令管理文件了。 但是每个文件都有一个i节点号&#xff0c;可以通过…

《Flink学习笔记》——第三章 Flink的部署模式

不同的应用场景&#xff0c;有时候对集群资源的分配和占用有不同的需求。所以Flink为各种场景提供了不同的部署模式。 3.1 部署模式&#xff08;作业角度/通用分类&#xff09; 根据集群的生命周期、资源的分配方式、main方法到底在哪里执行——客户端还是Client还是JobManage…

AIGC - 生成模型

AIGC - 生成模型 0. 前言1. 生成模型2. 生成模型与判别模型的区别2.1 模型对比2.2 条件生成模型2.3 生成模型的发展2.4 生成模型与人工智能 3. 生成模型示例3.1 简单示例3.2 生成模型框架 4. 表示学习5. 生成模型与概率论6. 生成模型分类小结 0. 前言 生成式人工智能 (Generat…

【最强最全】视频号下载助手(支持视频号视频, 直播,回放下载)

视频号下载助手支持视频号视频, 直播,回放的下载&#xff0c;本工具基于秦天sunny中间件编写&#xff0c;无需再使用其它抓包软件&#xff0c;无需再使用其它下载软件。 当然&#xff0c;你也可以右键复制抓取后的视频源再用其它下载软件下载。 使用说明 解压文件&#xff0c;…

CSS中如何实现弹性盒子布局(Flexbox)的换行和排序功能?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 换行&#xff08;Flexbox Wrapping&#xff09;⭐ 示例&#xff1a;实现换行⭐ 排序&#xff08;Flexbox Ordering&#xff09;⭐ 示例&#xff1a;实现排序⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得…

基于java swing和mysql实现的仓库商品管理系统(源码+数据库+运行指导视频)

一、项目简介 本项目是一套基于java swing和mysql实现的仓库商品管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经…

流媒体弱网优化之路(BBR应用)——GCC与BBR的算法思想分析

流媒体弱网优化之路(WebRTC)——GCC与BBR的算法思想分析 —— 我正在的github给大家开发一个用于做实验的项目 —— github.com/qw225967/Bifrost目标&#xff1a;可以让大家熟悉各类Qos能力、带宽估计能力&#xff0c;提供每个环节关键参数调节接口并实现一个json全配置&…

【洛谷算法题】P1001-A+B Problem【入门1顺序结构】

&#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P1001-AB Problem【入门1顺序结构】&#x1f30f;题目背景&#x1f30f;题目描述…

【Linux操作系统】Linux系统编程中条件变量实现生产者消费者模型

在Linux系统编程中&#xff0c;条件变量是一种用于线程间同步的机制&#xff0c;常用于实现生产者消费者模型。生产者消费者模型是一种常见的并发编程模型&#xff0c;用于解决多线程环境下的数据共享和同步问题。在该模型中&#xff0c;生产者负责生产数据&#xff0c;消费者负…

53 个 CSS 特效 3(完)

53 个 CSS 特效 3&#xff08;完&#xff09; 前两篇地址&#xff1a; 53 个 CSS 特效 153 个 CSS 特效 2 这里是第 33 到 53 个&#xff0c;很多内容都挺重复的&#xff0c;所以这里解释没之前的细&#xff0c;如果漏了一些之前的笔记会补一下&#xff0c;写过的就会跳过。…

【算法训练-模拟】模拟设计LRU缓存结构

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是LRU缓存结构设计&#xff0c;这类题目出现频率还是很高的&#xff0c;几乎所有大厂都常考。 当然面对这道题&#xff0c;首先要讲清楚LRU是干什么…

JavaScript—对象与构造方法

目录 json对象&#xff08;字面值&#xff09; js中对象是什么&#xff1f; 如何使用&#xff1f; 关联数组 js对象和C#对象有什么区别&#xff1f; 构造函数 什么是构造方法&#xff1f; 如何使用构造方法&#xff1f; 如何添加成员&#xff1f; 对象的动态成员 正则…

PageObject三层架构模式实现

1&#xff1a;PageObject三层架构分为&#xff1a; 接下来用163邮箱的登录功能来举例说明三层架构的使用。 1&#xff1a;先创建目录结构&#xff0c;如下图 2&#xff1a;在工具Util中&#xff0c;先封装查找元素定位的工具&#xff0c;创建一个find_ele.py文件。内容如下&am…

JavaScript—DOM(文档对象模型)

目录 DOM是什么&#xff1f; DOM有什么作用&#xff1f; 一、事件 理解事件 事件怎么写&#xff08;要做什么就写什么&#xff09;&#xff1f; 实战演练 1、页面加载完毕以后&#xff0c;打印一句话 2、如果有一个a标签&#xff0c;并给其添加一个点击事件 3、事件默…

电脑如何投屏到手机?Windows投屏到iPhone也可以吗?

我们知道&#xff0c;因为各大品牌厂商越来越维护自己的名声&#xff0c;都会推出“全家桶”&#xff0c;就是某些功能&#xff0c;你在使用同一品牌的电脑、手机、平板时非常好用&#xff0c;但一旦跨品牌就用不了。电脑投屏到手机也会遇到这种“品牌隔离”。 如果参会人使用…

对DataFrame对象中的数据将各行列进行整体平移DataFrame.shift()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 对DataFrame对象中的数据 将各行列进行整体平移 DataFrame.shift() [太阳]选择题 以下python代码错误的是? import pandas as pd dfpd.DataFrame({A:[1,2,3],B:[4,5,6]}) print(【显示】df&…