Service 和 Ingress

Service 和 Ingress

service 和 ingress 是kubernetes 中用来转发网络请求的两个服务,两个服务用处不同,service 主要提供集群内部网络调用、负载均衡(四层负载),ingress 提供外部访问,反向代理,负载均衡(七层负载)

在这里插入图片描述

Service

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

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

可以说 Service 是一个应用服务的抽象,定义了 Pod 逻辑集合和访问这个 Pod 集合的策略。Service 代理 Pod 集合,对外表现为一个访问入口,访问该入口的请求将经过负载均衡,转发到后端 Pod 中的容器。

Endpoint

每一个service 都会有一个 Endpoint controller , 在endponit 里面会维护 address,targetPort 和 容器之间的关系。整个访问链是 通过 service -> endpoint -iptables->kube-proxy -> 容器

在这里插入图片描述

service 的定义

Yaml 文件案例

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc  # service name
  labels:
    app: nginx-svc  # service 自己的标签
spec:
  ports:
  - name: http # service 端口配置的名称
    protocol: TCP # 端口绑定的协议,支持 TCP、UDP、SCTP,默认为 TCP
    port: 1080 # service 自己的端口
    targetPort: 80 # 目标 pod 的端口
  type: NodePort # 默认是ClusterIP 类型,只能在集群内部使用  
   	             # NodePort 用于将服务暴露给外部访问
  selector: # 选中当前 service 匹配哪些 pod,对哪些 pod 的东西流量进行代理
    app: nginx

使用命令

# 创建 service
kubectl create -f nginx-svc.yaml

# 查看 service 信息,通过 service 的 cluster ip 进行访问
kubectl get svc 

# 查看 pod 信息,通过 pod 的 ip 进行访问
kubectl get po -owide

# 创建其他 pod 通过 service name 进行访问(推荐)
kubectl exec -it busybox -- sh
curl http://nginx-svc

# 默认在当前 namespace 中访问,如果需要跨 namespace 访问 pod,则在 service name 后面加上 .<namespace> 即可
curl http://nginx-svc.default

代理集群外部服务

用于解决外部服务迁移到k8s 集群,各个环境访问名称统一,容器内部访问外部服务等需求

实现方式:

  1. 编写 service 配置文件时,不指定 selector 属性

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-svc  # service name
      labels:
        app: nginx-svc  # service 自己的标签
    spec:
      ports:
      - name: http # service 端口配置的名称
        protocol: TCP # 端口绑定的协议,支持 TCP、UDP、SCTP,默认为 TCP
        port: 1080 # service 自己的端口
        targetPort: 80 # 目标 pod 的端口
      type: ClusterIP # 默认是ClusterIP 类型,只能在集群内部使用  
       	             # NodePort 用于将服务暴露给外部访问
    
  2. 自己创建 endpoint

apiVersion: v1
kind: Endpoints
metadata:
  labels:
    app: nginx-svc # 与 service 一致
  name: nginx-svc # 与 service 一致
  namespace: default # 与 service 一致
subsets:  # 子网设置
- addresses:
  - ip: <target ip> # 目标 ip 地址
  ports: # 与 service 一致
  - name: http  # service 中ports.name 属性保持一致
    port: 80
    protocol: TCP

反向代理外部域名

直接通过在容器内部直接通过外部域名去访问

apiVersion: v1
kind: Service
metadata:
  labels:
    app: baidu-external-domain
  name: baidu-external-domain
spec:
  type: ExternalName
  externalName: www.baidu.com

Service 常用类型

Type用途补充
ClusterIP只能在集群内部使用,不配置类型的话默认就是 ClusterIP
ExternalName返回定义的 CNAME 别名,可以配置为域名
LoadBalancer使用云服务商(阿里云、腾讯云等)提供的负载均衡器服务
NodePort在所有安装了 kube-proxy 的节点都绑定一个端口,此端口可以代理至对应的 Pod,集群外部可以使用任意节点 ip + NodePort 的端口号访问到集群中对应 Pod 中的服务。一般用于测试环境,生产环境使用ingress

补充:

NodePort 映射是一个O(N) 的时间复杂度,当节点数越多的时候,效率越低,内部代码是通过轮询来处理的

当类型设置为 NodePort 后,可以在 ports 配置中增加 nodePort 配置指定端口,需要在下方的端口范围内,如果不指定会随机指定端口

端口范围:30000~32767

端口范围配置在 /usr/lib/systemd/system/kube-apiserver.service 文件中

Ingress

Ingress 可以提供外网访问 Service 的能力。可以把某个请求地址映射、路由到特定的 service。

ingress 需要配合 ingress controller 一起使用才能发挥作用,ingress 只是相当于路由规则的集合而已,真正实现路由功能的,是 Ingress Controller,ingress controller 和其它 k8s 组件一样,也是在 Pod 中运行。

在这里插入图片描述

Ingress-nginx

Ingress 是一个更高层的抽象,具体实现还需要借助于Ingress controller 列如 Ingress-nginx 其他控制器参考 官网文档 https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress-controllers

安装

参考官网地址:https://kubernetes.github.io/ingress-nginx/deploy/#using-helm

官网默认采用helm,因此需要先安装helm

  1. 下载安装包 wget https://get.helm.sh/helm-v3.14.2-linux-amd64.tar.gz
  2. tar -zxvf helm-v3.2.3-linux-amd64.tar.gz
  3. cp helm /usr/local/bin/
# 添加ingree 仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

# 查看仓库列表
helm repo list

# 搜索 ingress-nginx
helm search repo ingress-nginx

# 下载安装包
helm pull ingress-nginx/ingress-nginx  --version 4.4.2

# 解压安装包
tar -zxvf ingress-nginx-4.4.2.tgz

# 解压后,进入解压完成的目录
cd ingress-nginx

# 修改 values.yaml
  镜像地址:修改为国内镜像
  registry: registry.cn-hangzhou.aliyuncs.com
  image: google_containers/nginx-ingress-controller
  image: google_containers/kube-webhook-certgen
  tag: 两个image 版本保持一致 或者 不动也行

  hostNetwork: true
  dnsPolicy: ClusterFirstWithHostNet

  修改部署配置的 kind: /DaemonSet    # Deployment 改成 DaemonSet
  nodeSelector:
    ingress: "true" # 增加选择器,如果 node 上有 ingress=true 就部署

  将 admissionWebhooks.enabled 修改为 falseservice 中的 type 由 LoadBalancer 修改为 ClusterIP,如果服务器是云平台才用 LoadBalancer
  
# 为 ingress 专门创建一个 namespace
kubectl create ns ingress-nginx

# 为需要部署 ingress 的节点上加标签
kubectl label node k8s-master ingress=true

# 安装 ingress-nginx
helm install ingress-nginx -n ingress-nginx .

使用

apiVersion: networking.k8s.io/v1
kind: Ingress # 资源类型为 Ingress
metadata:
  name: demo-nginx-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /  # 重写路径
spec:
  rules: # ingress 规则配置,可以配置多个
  - host: k8s.demo.cn #域名配置,可以使用通配符 *   可以配置多个host  也可以不配置host 直接通过ip:port 方式访问 配置了host 就只能通过host 不能选择ip:port 的形式
    http:
      paths: # 相当于 nginx 的 location 配置,可以配置多个 paths
    	- path: /api # 等价于 nginx 中的 location 的路径前缀匹配
      	pathType: Prefix # 路径类型,按照路径类型进行匹配 ImplementationSpecific 需要指定 IngressClass,具体匹配规则以 IngressClass 中的规则为准。Exact:精确匹配,URL需要与path完全匹配上,且区分大小写的。Prefix:以 / 作为分隔符来进行前缀匹配
        backend:
          service: 
            name: nginx-svc # 代理到哪个 service
            port:   # 可以直接写 80 也可以如下写法
              number: 80 # service 的端口
<think>嗯,用户问既然已经有ServiceIngress了,为什么还需要引入Service Mesh比如Istio。这个问题看起来是想了解Service Mesh的价值所在。首先,我需要回忆一下KubernetesServiceIngress的基本功能。Service提供四层负载均衡,负责内部服务发现流量分发;Ingress则是七层负载均衡,处理HTTP/HTTPS路由,提供更高级的路由规则。 接下来,用户可能已经知道这些基础组件,但可能在实际使用中遇到了它们无法解决的问题。比如,微服务架构中的复杂流量管理、安全需求、可观测性不足等。这时候Service Mesh如Istio的作用就体现出来了。需要详细说明Service Mesh在哪些方面补充了ServiceIngress的不足。 可能用户没有说出来的深层需求是,他们可能在处理微服务间的通信时遇到了挑战,比如服务间认证、熔断、金丝雀发布、流量镜像等。这些都是ServiceIngress不直接支持的功能。需要举一些具体的例子,比如Istio的流量拆分、故障注入等。 另外,用户可能对Service Mesh的工作原理不太清楚,需要解释Sidecar模式如何将流量劫持并处理,实现细粒度的控制。同时,对比Service Mesh传统Kubernetes网络组件的不同,强调其非侵入性语言无关性。 还要提到可观测性,比如分布式追踪、指标收集日志聚合,这些在ServiceIngress中需要额外工具支持,而Service Mesh内置了这些功能。安全方面,mTLS的自动管理也是Service Mesh的一大优势。 需要结构清晰,分点说明,避免技术术语过多,但又要足够深入。同时结合用户给出的历史回答,他们之前提到过Istio的负载均衡策略,可以在这里呼应,说明Service Mesh在负载均衡上的更多可能性。 最后,总结使用场景,帮助用户判断是否需要引入Service Mesh,比如是否面临复杂的微服务治理问题,是否需要统一的安全策略等。可能用户属于中大规模集群,或者有跨云需求,这时候Service Mesh的优势会更明显。</think>以下从架构演进、功能扩展、控制维度三个层面解析Service Mesh的必要性,并结合Istio示例说明其核心价值: --- ### 一、架构层面对比 #### 1. 传统Kubernetes网络模型局限 ```mermaid graph LR Client -->|流量| Ingress --> Service --> Pod Service -->|四层负载| Pod Pod --> Pod(通过Service IP) ``` - **数据平面缺陷**:流量管控仅作用于入口/出口边界,缺乏服务间通信的精细控制 - **控制平面局限**:LB策略配置分散在Service/Ingress/应用代码中 #### 2. Service Mesh架构突破 ```mermaid graph LR Client --> Sidecar -->|全流量劫持| Ingress Ingress --> Sidecar --> Service Service --> Sidecar --> Pod Pod --> Sidecar --> Pod ``` - **Sidecar模式**:每个Pod注入代理(如Envoy),实现流量透明拦截 - **控制平面统一**:Istiod集中管理所有流量规则 --- ### 二、核心能力扩展 #### 1. 流量治理维度对比 | 能力 | Service/Ingress | Istio Service Mesh | |--------------------|--------------------------|--------------------------| | 负载均衡算法 | 基础rr/wrr/lc | 动态自适应LB+熔断 | | 流量拆分 | 仅金丝雀权重 | 多版本精准分流+条件路由 | | 故障恢复 | 无 | 重试/超时/断路隔离 | | 故障注入 | 不可实现 | 精准模拟网络异常 | **示例:Istio流量镜像配置** ```yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService spec: hosts: ["reviews.prod.svc.cluster.local"] http: - route: - destination: host: reviews.prod.svc.cluster.local subset: v1 weight: 100 mirror: host: reviews.canary.svc.cluster.local mirrorPercentage: 20 # 复制20%流量到镜像服务 ``` #### 2. 安全能力升级 - **传输层安全**:自动mTLS加密所有服务间通信 - **细粒度授权**:基于JWT的RBAC控制(如限制特定服务访问数据库) ```yaml apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: db-access spec: selector: matchLabels: app: mysql rules: - from: - source: principals: ["cluster.local/ns/default/sa/webapp-sa"] to: - operation: methods: ["SELECT"] ``` #### 3. 可观测性增强 ```mermaid graph TD Envoy --> 生成访问日志 --> 日志系统 Envoy --> 采集Metrics --> Prometheus Envoy --> 传播Trace --> Jaeger/Zipkin ``` - **分布式追踪**:自动生成全链路调用图 - **黄金指标**:实时监控延迟/错误/流量/饱度 --- ### 三、生产环境典型场景 #### 场景1:跨集群流量治理 ```bash # 配置多集群服务网格 istioctl x create-remote-secret --name=cluster-east > cluster-secret.yaml kubectl apply -f cluster-secret.yaml --context=cluster-west ``` #### 场景2:渐进式发布 ```yaml # 分阶段发布策略 http: - match: - headers: user-type: exact: vip route: - destination: host: payment.prod.svc.cluster.local subset: v2-new - route: # 默认用户走v1 - destination: host: payment.prod.svc.cluster.local subset: v1 ``` --- ### 四、落地成本权衡 #### 1. 适用场景 - 50+微服务的中大型分布式系统 - 需要统一治理跨语言服务(Java/Go/Python等) - 严格的安全合规要求(如金融行业) #### 2. 不适用场景 - 小型单体应用集群 - 无跨服务通信需求的简单系统 - 资源受限的边缘计算节点 --- **决策建议**:当系统复杂度达到需要统一控制服务间通信时(如出现服务调用链混乱、难以定位跨服务故障等问题),Service Mesh的价值将超过其运维成本。对于新项目,建议从Istio 1.12+版本开始逐步引入,重点关注`Sidecar自动注入``渐进式流量管理`能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

go&Python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值