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

k8s-服务发布基础

目录

Service的定义

核心定义

Service 的类型

关键组件与机制

工作流程示例

高级特性

 Service工作原理

核心工作原理

标签选择器(Label Selector)

Endpoints 对象

网络代理与负载均衡(kube-proxy)

userspace 模式(已淘汰)

iptables 模式(默认)

IPVS 模式(推荐高性能场景)

Service 类型与流量路由

ClusterIP(默认)

NodePort

LoadBalancer

ExternalName


Service的定义

在 Kubernetes(K8s)中,Service 是一个核心抽象资源,用于为一组具有相同功能的 Pod 提供稳定的网络访问入口,并实现服务发现、负载均衡和抽象隔离。

核心定义

  • 逻辑抽象层:Service 将一组动态变化的 Pod(通过标签选择器匹配)抽象为一个逻辑服务单元,客户端无需关心后端 Pod 的具体数量、IP 地址或位置。
  • 稳定访问入口:为 Pod 分配一个固定的 ClusterIP(虚拟 IP),该 IP 在 Service 生命周期内不变,即使后端 Pod 重建或扩缩容。
  • 负载均衡:自动将客户端请求分发到匹配的 Pod,支持轮询(默认)、随机、会话保持等策略。

Service 的类型

根据网络访问方式,Service 分为以下四种类型:

类型访问范围适用场景
ClusterIP仅集群内部访问(默认)内部服务间通信(如微服务调用、数据库访问)。
NodePort集群外部通过节点 IP+端口访问开发测试或临时暴露服务(需手动指定节点端口,范围通常为 30000-32767)。
LoadBalancer外部负载均衡器(云环境)生产环境暴露服务,自动创建云厂商的负载均衡器(如 AWS ALB、GCP Load Balancer)。
ExternalName通过 DNS CNAME 映射外部服务访问集群外部服务(如数据库、第三方 API),无需在集群内运行 Pod。

关键组件与机制

  • 标签选择器(Label Selector)
    • 通过 spec.selector 字段匹配 Pod 的标签(如 app: nginx),动态关联后端 Pod。
    • 示例:
      apiVersion: v1
      kind: Service
      metadata:name: nginx-service
      spec:selector:app: nginx  # 匹配所有标签为 app=nginx 的 Podports:- protocol: TCPport: 80    # Service 暴露的端口targetPort: 80  # Pod 的容器端口
    • Endpoints 对象
      • K8s 自动为每个 Service 创建同名的 Endpoints 资源,记录当前匹配的 Pod IP 和端口。
      • 通过 kubectl get endpoints nginx-service 可查看实时关联的 Pod。
    • ClusterIP
      • 虚拟 IP,仅在集群内路由有效,由 kube-proxy 通过 iptables/IPVS 实现。
      • 客户端访问 ClusterIP:Port 时,请求会被转发到后端 Pod。
    • DNS 解析
      • 集群内服务可通过 <service-name>.<namespace>.svc.cluster.local 域名访问(如 nginx-service.default.svc.cluster.local)。
      • 简化配置,避免硬编码 IP。

工作流程示例

  1. 创建 Deployment:部署 3 个 Nginx Pod,标签为 app=nginx
  2. 创建 Service
    apiVersion: v1
    kind: Service
    metadata:name: nginx-service
    spec:selector:app: nginxports:- protocol: TCPport: 80targetPort: 80
  3. 访问服务
    • 集群内其他 Pod 可通过 nginx-service:80 或其 ClusterIP 访问。
    • 若为 NodePort 类型,外部可通过 http://<节点IP>:<节点端口> 访问。

高级特性

  • 会话保持(Session Affinity)
    • 通过 sessionAffinity: ClientIP 确保同一客户端请求始终路由到同一 Pod。
  • 外部流量策略
    • externalTrafficPolicy: Local 保留客户端源 IP,避免经过 NAT 丢失信息(仅 NodePort/LoadBalancer 有效)。
  • 无头服务(Headless Service)
    • 设置 clusterIP: None,不分配 ClusterIP,直接返回 Pod IP 列表(适用于 StatefulSet 或需要直接访问 Pod 的场景)。

 Service工作原理

 Kubernetes(K8s)中的 Service 通过抽象一组动态变化的 Pod,提供稳定的网络访问入口和负载均衡能力。其工作原理涉及 标签选择、Endpoint 管理、网络代理(kube-proxy)和负载均衡 等核心机制。

核心工作原理

标签选择器(Label Selector)
  • 作用:Service 通过 spec.selector 字段匹配一组 Pod 的标签(如 app=nginx),动态关联后端 Pod。
  • 动态性:当匹配的 Pod 数量或 IP 变化时(如扩容、重建),Service 会自动更新关联的 Endpoint,无需手动干预。
  • 示例
    apiVersion: v1
    kind: Service
    metadata:name: nginx-service
    spec:selector:app: nginx  # 匹配所有标签为 app=nginx 的 Podports:- protocol: TCPport: 80    # Service 暴露的端口targetPort: 80  # Pod 的容器端口
Endpoints 对象
  • 自动生成:K8s 为每个 Service 创建一个同名的 Endpoints 资源(如 nginx-service),记录当前匹配的 Pod IP 和端口。
  • 实时更新:当 Pod 状态变化(如新增、删除、IP 变更),Endpoints 会同步更新,确保流量始终路由到健康的 Pod。
  • 查看 Endpoints
    kubectl get endpoints nginx-service

        输出实例:

NAME            ENDPOINTS                          AGE
nginx-service   10.244.1.3:80,10.244.2.5:80      5m

网络代理与负载均衡(kube-proxy)

kube-proxy 是运行在每个节点上的网络代理,负责实现 Service 的负载均衡和流量转发。它支持三种工作模式:

userspace 模式(已淘汰)
  • 原理:kube-proxy 作为用户态进程,通过 iptables 捕获 Service 的 ClusterIP 流量,然后转发到后端 Pod。
  • 缺点:性能较差(上下文切换开销大),已逐渐被弃用。
iptables 模式(默认)
  • 原理
    1. kube-proxy 监听 Service 和 Endpoint 的变化,动态生成 iptables 规则。
    2. 当客户端访问 Service 的 ClusterIP 时,iptables 随机选择一个后端 Pod IP,并将请求转发过去。
  • 特点
    • 纯内核态转发,性能较高。
    • 支持基本的轮询负载均衡。
    • 无法处理会话保持(需通过 sessionAffinity: ClientIP 实现)。
  • 查看 iptables 规则
    kubectl get svc nginx-service -o yaml  # 获取 ClusterIP
    iptables -t nat -L | grep <ClusterIP>
     
IPVS 模式(推荐高性能场景)
  • 原理
    1. kube-proxy 调用 Linux 内核的 IPVS 模块(基于哈希表的负载均衡器)。
    2. IPVS 支持多种负载均衡算法(如轮询、加权轮询、最少连接等),性能优于 iptables。
  • 启用方式
    • 修改 kube-proxy 启动参数:--proxy-mode=ipvs
    • 确保节点已加载 IPVS 内核模块(如 ip_vs_rrip_vs_wrr)。
  • 查看 IPVS 规则
    ipvsadm -Ln

 

Service 类型与流量路由

根据访问范围,Service 分为四种类型,其流量路由方式如下:

ClusterIP(默认)
  • 访问范围:仅集群内部。
  • 路由过程
    1. 客户端访问 nginx-service:80 或 ClusterIP。
    2. kube-proxy 通过 iptables/IPVS 将请求转发到匹配的 Pod。
  • 适用场景:内部服务间通信(如微服务调用)。

ClusterIP实例:

apiVersion: v1
kind: Service
metadata:name: my-service       # 服务名称namespace: default     # 命名空间(可选)labels:app: my-app          # 服务标签
spec:type: ClusterIP        # 指定为ClusterIP类型(默认可省略)selector:app: my-app          # 匹配Pod的标签ports:- protocol: TCP      # 协议类型(TCP/UDP)port: 80           # 服务暴露的端口(集群内部访问)targetPort: 8080   # 后端Pod的端口

NodePort
  • 访问范围:外部通过节点 IP + 端口访问。
  • 路由过程
    1. 客户端访问 <节点IP>:<NodePort>(如 192.168.1.100:30080)。
    2. 节点上的 iptables/IPVS 将请求转发到 Service 的 ClusterIP,再路由到 Pod。
  • 特点
    • NodePort 范围默认 30000-32767。
    • 外部流量需手动配置负载均衡器(如 Nginx)分发到多个节点。

NodePort实例:

apiVersion: v1
kind: Service
metadata:name: my-nodeport-servicenamespace: defaultlabels:app: my-app
spec:type: NodePort        # 指定为NodePort类型selector:app: my-app         # 匹配Pod的标签ports:- protocol: TCPport: 80          # 服务内部端口(供集群内部访问)targetPort: 8080  # 后端Pod的端口nodePort: 30080   # 节点上暴露的端口(可选,默认自动分配30000-32767)

LoadBalancer
  • 访问范围:外部通过云厂商负载均衡器访问。
  • 路由过程
    1. 创建 Service 时指定 type: LoadBalancer
    2. 云控制器(Cloud Controller Manager)自动创建外部负载均衡器(如 AWS ALB)。
    3. 外部流量通过负载均衡器分发到节点,再路由到 Pod。
  • 适用场景:生产环境暴露服务。

loadBalancer实例:

apiVersion: v1
kind: Service
metadata:name: my-loadbalancer-servicenamespace: defaultlabels:app: my-appannotations:# 可选:云服务商特定的注解(如AWS、GKE)service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:type: LoadBalancer       # 指定为LoadBalancer类型selector:app: my-app            # 匹配Pod的标签ports:- protocol: TCPport: 80             # 服务暴露的端口(负载均衡器端口)targetPort: 8080     # 后端Pod的端口nodePort: 30080      # 可选:自动分配的NodePort(LoadBalancer依赖NodePort实现)externalTrafficPolicy: Cluster  # 可选:Cluster(默认)或Local

ExternalName
  • 访问范围:通过 DNS CNAME 映射外部服务。
  • 路由过程
    1. 客户端访问 Service 的 DNS 名称(如 my-db.default.svc.cluster.local)。
    2. DNS 解析返回外部服务的 CNAME(如 mysql.example.com)。
  • 适用场景:访问集群外部数据库或 API。

 创建101命名空间所需要的yaml文件

[root@k8s-master opt]# cat myapp01.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:name: myapp01namespace: test01
spec:replicas: 1selector: #标签选择器matchLabels: #匹配的标签为app: myapp01release: canarytemplate:metadata:labels:app: myapp01 #和上面的myapp要匹配release: canaryspec:containers:- name: myappimage: ikubernetes/myapp:v1ports:- name: http01containerPort: 80
[root@k8s-master opt]# cat myapp-svc-extername01.yaml 
kind: Service
apiVersion: v1
metadata:name: myapp-svcname02namespace: test01
spec:type: ExternalNameexternalName: myapp-svc02.test02.svc.cluster.local
[root@k8s-master opt]# cat myapp-svc-headless01.yaml 
apiVersion: v1
kind: Service
metadata:name: myapp-svc01namespace: test01
spec:selector:app: myapp01 #挑选的pod还是myapp01。一个pod可以有多个servicerelease: canaryclusterIP: None #None表示是无头serviceports:- port: 39320 #service ip中的端口targetPort: 80 #容器ip中的端口

 创建102命名空间所需要的yaml文件

[root@k8s-master opt]# cat myapp-svc-headless02.yaml 
apiVersion: v1
kind: Service
metadata:name: myapp-svc02namespace: test02
spec:selector:app: myapp02 #挑选的pod还是myapp。一个pod可以有多个servicerelease: canaryclusterIP: None #None表示是无头serviceports:- port: 39320 #service ip中的端口targetPort: 80 #容器ip中的端口
[root@k8s-master opt]# cat myapp-svc-extername02.yaml 
kind: Service
apiVersion: v1
metadata:name: myapp-svcname01namespace: test02
spec:type: ExternalNameexternalName: myapp-svc01.test01.svc.cluster.local
[root@k8s-master opt]# cat myapp02.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:name: myapp02namespace: test02
spec:replicas: 1selector: #标签选择器matchLabels: #匹配的标签为app: myapp02release: canarytemplate:metadata:labels:app: myapp02 #和上面的myapp要匹配release: canaryspec:containers:- name: myapp02image: ikubernetes/myapp:v1ports:- name: http02containerPort: 80

验证:

##查看test01容器的ip地址
[root@k8s-master opt]# ku get pods -n test01 -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
myapp01-696c886d6b-bbvrn   1/1     Running   0          30m   10.244.36.80   k8s-node1   <none>           <none>##登陆到test02命名空间的容器,访问test01容器的ip
[root@k8s-master opt]# ku exec -it myapp02-55ffcd5f64-xmgq8 -n test02 -- sh
/ # ping 10.244.36.80
PING 10.244.36.80 (10.244.36.80): 56 data bytes
64 bytes from 10.244.36.80: seq=0 ttl=63 time=0.059 ms
64 bytes from 10.244.36.80: seq=1 ttl=63 time=0.121 ms

 

 

 

 

 

 

http://www.dtcms.com/a/268127.html

相关文章:

  • 数据结构实验习题
  • 定时器和守护线程
  • 【Guava】1.0.设计虚拟机的方向
  • tensorflow武林志第二卷第九章:玄功九转
  • 广东省省考备考(第四十天7.6)——资料分析(第八节课)
  • Python Bcrypt详解:从原理到实战的安全密码存储方案
  • 【C++】C++四种类型转换操作符详解
  • 【Note】《Kafka: The Definitive Guide》第一章:Meet Kafka
  • LeetCode--41.缺失的第一个正数
  • get: ()=>state 和get: ()=>{state}
  • Java 集合
  • ClickHouse 全生命周期性能优化
  • Java 大视界 -- Java 大数据机器学习模型在金融衍生品创新设计与风险评估中的应用(335)
  • 人工智能在软件开发领域的应用优势劣分析及应对策略
  • js event.preventDefault()的作用
  • Web前端开发-HTML、CSS
  • 【从0-1的CSS】第3篇:盒子模型与弹性布局
  • Application的onLowMemory从Android API 34开始系统不再触发,从API 35开始废弃
  • 网安系列【7】之文件上传漏洞
  • 云服务器环境配置——安装Tomcat
  • Redis集群部署指南:高可用与分布式实践
  • 网关多次读取流问题
  • 老树新花语新颜,汉字筑渠话情流——与ai助手闲聊成诗(智普清言)
  • 程序员在线接单
  • Python设计小游戏方法简介
  • SpringBoot基于Mysql的商业辅助决策系统设计与实现
  • Web前端开发-Vue
  • 【网络安全基础】第九章---IP安全
  • unix环境编程试题
  • 平台设备总线相关概念(RK3588)