Kubernetes Service与Ingress全方位解析

在Kubernetes(简称K8s)生态中,Pod作为应用程序的运行载体,其IP地址具有动态性——当Pod重启、重建或调度到其他节点时,IP会发生变化,直接通过Pod IP访问服务存在明显缺陷。为解决这一问题,Kubernetes提供了Service资源实现Pod的服务发现与负载均衡;而当集群中服务数量增多,Service的暴露方式(如NodePort、LoadBalancer)面临端口占用、资源浪费等问题时,Ingress则作为7层负载均衡抽象,实现多服务的统一入口管理。本文将从Service的核心原理、类型、使用实践,到Ingress的设计理念与配置方法,进行全面且深入的解析。

一、Service核心解析

Service是Kubernetes中用于聚合同一服务的多个Pod、提供统一访问入口的资源对象。它通过标签选择器(Selector)关联后端Pod,并借助kube-proxy组件在集群节点上实现流量转发规则,确保即便Pod IP变化,服务访问地址仍保持稳定。

1.1 Service工作原理

Service本身是一个“逻辑概念”,真正实现流量转发的是每个Node节点上运行的kube-proxy进程,其工作流程如下:

  1. 资源创建与存储:用户通过kubectl或API创建Service时,K8s API Server会将Service的配置信息(如Selector、端口映射、类型等)写入etcd数据库持久化。
  2. 规则监听与同步kube-proxy通过监听API Server的事件,实时感知Service和Pod的创建、更新、删除操作,动态同步转发规则。
  3. 转发规则生成kube-proxy将Service配置转换为节点本地的网络规则(如iptables、ipvs规则),当外部请求访问Service的统一入口时,规则会将流量分发到后端健康的Pod。

示例验证:通过ipvsadm -Ln命令可查看Service对应的负载均衡规则,如下所示:

[root@k8s-master01 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.97.97.97:80 rr  # Service入口(10.97.97.97:80),调度策略为轮询(rr)
  -> 10.244.1.39:80               Masq    1      0          0  # 后端Pod1
  -> 10.244.1.40:80               Masq    1      0          0  # 后端Pod2
  -> 10.244.2.33:80               Masq    1      0          0  # 后端Pod3

上述规则表示:访问10.244.1.39:80的请求,会通过轮询策略分发到3个后端Pod,实现负载均衡。

1.2 kube-proxy工作模式

kube-proxy支持三种工作模式,不同模式在性能、功能上存在差异,需根据业务场景选择:

模式 核心原理 优点 缺点 适用场景
userspace kube-proxy在用户空间为每个Service创建监听端口,请求先被iptables重定向到该端口,再由kube-proxy转发到Pod 稳定性高(用户空间与内核空间隔离,规则异常不影响内核) 性能低(需在用户空间与内核空间之间拷贝数据) 早期K8s版本,或对稳定性要求极高、性能不敏感的场景
iptables kube-proxy直接在Linux内核的iptables中创建规则,请求跳过用户空间,直接由内核转发到Pod 性能比userspace高(无数据拷贝) 不支持灵活的负载均衡策略(如会话保持外的复杂策略);Pod不可用时无法自动重试 对性能有一定要求,且后端Pod稳定性高的场景
ipvs 基于Linux内核的IPVS(IP Virtual Server)模块,kube-proxy动态维护IPVS规则,请求由内核层转发 性能最优(IPVS专为负载均衡设计,支持百万级并发);支持多种负载均衡算法(如轮询、加权轮询、最少连接等) 需手动安装IPVS内核模块(否则会降级为iptables模式) 高并发、高性能需求的生产环境(推荐首选)
开启ipvs模式步骤
  1. 编辑kube-proxy的ConfigMap(存储配置的资源):
    [root@k8s-master01 ~]# kubectl edit cm kube-proxy -n kube-system
    
    在配置中修改mode: "ipvs"(默认可能为iptablesuserspace)。
  2. 重启kube-proxy Pod,使配置生效:
    [root@k8s-master01 ~]# kubectl delete pod -l k8s-app=kube-proxy -n kube-system
    
  3. 验证模式:通过ipvsadm -Ln查看规则,若能看到Service对应的IPVS条目,说明模式开启成功。

1.3 Service资源清单详解

Service的配置通过YAML文件定义,核心字段如下(以基础模板为例):

apiVersion: v1  # 固定版本(Service属于v1组资源)
kind: Service   # 资源类型为Service
metadata:
  name: service-demo  # Service名称(需唯一)
  namespace: dev      # 命名空间(默认default,建议按业务划分)
spec:
  selector:           # 标签选择器:关联后端Pod的标签(关键!)
    app: nginx-pod    # 需与Pod的metadata.labels.app一致
  type: ClusterIP     # Service类型(后续详细说明)
  clusterIP: 10.97.97.97  # 虚拟IP(仅ClusterIP类型有效,不指定则自动分配)
  sessionAffinity: None  # 会话亲和性(None/ClientIP,控制请求是否转发到固定Pod)
  ports:              # 端口映射配置(数组形式,支持多端口)
  - protocol: TCP      # 协议(TCP/UDP/SCTP,默认TCP)
    port: 80           # Service暴露的端口(集群内访问用)
    targetPort: 80     # 后端Pod的端口(需与Pod的containerPort一致)
    nodePort: 30002    # 仅NodePort类型有效:节点暴露的端口(30000-32767)

1.4 Service类型与实践

根据服务暴露范围(集群内/外)和方式,Service分为5种类型,每种类型对应不同的使用场景:

1.4.1 ClusterIP(默认类型)

功能:为Service分配一个集群内部唯一的虚拟IP(ClusterIP),仅允许集群内的Pod或节点访问,无法暴露到集群外。
适用场景:集群内部服务间通信(如微服务中的API调用)。

实践步骤
  1. 准备后端Pod:通过Deployment创建3个带app: nginx-pod标签的Nginx Pod(确保Pod正常运行):

    # deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: pc-deployment
      namespace: dev
    spec:
      replicas: 3  # 副本数3
      selector:
        matchLabels:
          app: nginx-pod
      template:
        metadata:
          labels:
            app: nginx-pod
        spec:
          containers:
          - name: nginx
            image: nginx:1.17.1
            ports:
            - containerPort: 80  # Pod端口
    

    创建Deployment:

    [root@k8s-master01 ~]# kubectl create -f deployment.yaml
    

    验证Pod状态:

    [root@k8s-master01 ~]# kubectl get pods -n dev -o wide --show-labels
    NAME                             READY   STATUS    IP            NODE     LABELS
    pc-deployment-66cb59b984-8p84h   1/1     Running   10.244.1.39   node1    app=nginx-pod
    pc-deployment-66cb59b984-vx8vx   1/1     Running   10.244.2.33   node2    app=nginx-pod
    pc-deployment-66cb59b984-wnncx   1/1     Running   10.244.1.40   node1    app=nginx-pod
    
  2. 创建ClusterIP Service

    # service-clusterip.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: service-clusterip
      namespace: dev
    spec:
      selector:
        app: nginx-pod  # 关联上述Pod标签
      type: ClusterIP
      clusterIP: 10.97.97.97  # 手动指定ClusterIP(可选,不指定则自动分配)
      ports:
      - port: 80        # Service端口
        targetPort: 80  # Pod端口
    

    创建Service:

    [root@k8s-master01 ~]# kubectl create -f service-clusterip.yaml
    
  3. 验证Service

    • 查看Service基本信息:
      [root@k8s-master01 ~]# kubectl get svc -n dev -o wide
      NAME                TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
      service-clusterip   ClusterIP   10.97.97.97   <none>        80/TCP    13s
      
    • 查看Service详情(重点关注Endpoints,即后端Pod列表):
      [root@k8s-master01 ~]# kubectl describe svc service-clusterip -n dev
      ...
      Endpoints:         10.244.1.39:80,10.244.1.40:80,10.244.2.33:80  # 后端Pod地址
      ...
      
    • 集群内访问测试:在集群任意节点或Pod中,通过ClusterIP访问服务:
      [root@k8s-master01 ~]# curl 10.97.97.97:80
      10.244.2.33  # 返回后端Pod的IP(轮询策略下每次访问可能不同)
      
1.4.2 Headless Service(无头服务)

功能:不分配ClusterIP,而是通过Service的域名直接解析到后端所有Pod的IP地址。用户需自行实现负载均衡逻辑(如客户端轮询)。
适用场景:需要直接访问后端每个Pod的场景(如分布式数据库、StatefulSet管理的有状态服务)。

实践特点
  • 配置关键:将spec.clusterIP设为None,其他与ClusterIP类似:
    # service-headliness.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: service-headliness
      namespace: dev
    spec:
      selector:
        app: nginx-pod
      clusterIP: None  # 核心配置:无头服务标识
      type: ClusterIP  # 类型仍为ClusterIP,但clusterIP为None
      ports:
      - port: 80
        targetPort: 80
    
  • 域名解析:Service的域名为{service-name}.{namespace}.svc.cluster.local,解析时会返回所有后端Pod的IP:
    # 在集群内Pod中执行域名解析(以busybox为例)
    [root@k8s-master01 ~]# kubectl run busybox11 --image busybox -n dev -- sleep 6000
    [root@k8s-master01 ~]# kubectl exec -it busybox11 -n dev -- /bin/sh
    / # nslookup service-headliness.dev.svc.cluster.local
    Name:      service-headliness.dev.svc.cluster.local
    Address 1: 10.244.1.39
    Address 2: 10.244.1.40
    Address 3: 10.244.2.33
    
  • 访问方式:通过域名直接访问某个Pod(需客户端自行处理负载均衡):
    / # wget -O - -q service-headliness.dev.svc.cluster.local  # 访问其中一个Pod
    10.244.1.39
    
1.4.3 NodePort(集群外访问)

功能:在ClusterIP基础上,将Service端口映射到集群中每个Node的固定端口(NodePort,范围30000-32767),外部可通过NodeIP:NodePort访问服务。
适用场景:需临时暴露服务到集群外(如测试环境、小型应用)。

实践步骤
  1. 创建NodePort Service
    # service-nodeport.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: service-nodeport
      namespace: dev
    spec:
      selector:
        app: nginx-pod
      type: NodePort  # 类型设为NodePort
      ports:
      - port: 80        # Service内部端口
        targetPort: 80  # Pod端口
        nodePort: 30002 # 节点暴露端口(可选,不指定则自动分配)
    
  2. 验证与访问
    • 查看Service:PORT(S)字段显示80:30002/TCP,表示Service端口80映射到节点的30002端口:
      [root@k8s-master01 ~]# kubectl get svc -n dev -o wide
      NAME               TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)       AGE
      service-nodeport   NodePort   10.105.64.191   <none>        80:30002/TCP  5s
      
    • 外部访问:在集群外的机器(如本地电脑),通过任意Node的IP和NodePort访问:
      # 浏览器访问:http://192.168.100.101:30002(192.168.100.101为NodeIP)
      
1.4.4 LoadBalancer(云环境专用)

功能:在NodePort基础上,集成云服务商的负载均衡器(如AWS ELB、阿里云SLB),外部请求先发送到云负载均衡器,再由其分发到集群Node的NodePort。
适用场景:生产环境中需要高可用、高并发的外部访问(依赖云服务商支持)。

特点
  • 配置简单:仅需将spec.type设为LoadBalancer,无需手动指定NodePort(自动分配):
    spec:
      type: LoadBalancer  # 类型设为LoadBalancer
      ports:
      - port: 80
        targetPort: 80
    
  • 外部IP:云负载均衡器会分配一个公网IP(显示在EXTERNAL-IP字段),外部通过该IP直接访问:
    [root@k8s-master01 ~]# kubectl get svc -n dev
    NAME             TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
    service-lb       LoadBalancer   10.10.20.30    106.xx.xx.xx    80:30003/TCP   10s
    
  • 局限性:依赖云环境,本地私有集群无法使用(需自行部署负载均衡器,如HAProxy)。
1.4.5 ExternalName(引入外部服务)

功能:将集群外部的服务(如公网API、数据库)映射为集群内部的Service,通过Service域名即可访问外部服务,无需暴露外部IP。
适用场景:集群内服务需访问外部固定服务(如访问百度API、外部MySQL数据库)。

实践配置
  • 核心字段:spec.externalName指定外部服务的域名或IP:
    # service-externalname.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: service-externalname
      namespace: dev
    spec:
      type: ExternalName  # 类型设为ExternalName
      externalName: www.baidu.com  # 外部服务域名(或IP,如192.168.1.100)
    
  • 访问测试:在集群内通过Service域名访问外部服务:
    [root@k8s-master01 ~]# kubectl exec -it busybox11 -n dev -- /bin/sh
    / # curl service-externalname.dev.svc.cluster.local  # 访问百度
    <!DOCTYPE html>
    <html>
    <head><title>百度一下,你就知道</title>...</head>
    </html>
    

1.5 Service负载分发策略

Kubernetes为Service提供两种核心负载分发策略,用于控制请求如何分配到后端Pod:

1.5.1 默认策略(基于kube-proxy模式)
  • ipvs模式:支持多种算法,默认是轮询(rr),还包括加权轮询(wrr)、最少连接(lc)、加权最少连接(wlc)等(需通过kube-proxy配置指定)。
  • iptables模式:默认是随机(通过iptables的random模块实现)。
  • 验证:通过ipvsadm -Ln查看策略(如rr表示轮询):
    [root@k8s-master01 ~]# ipvsadm -Ln
    TCP  10.97.97.97:80 rr  # rr=轮询
    
1.5.2 会话亲和性(Session Affinity)
  • 功能:将来自同一客户端IP的所有请求转发到固定的Pod,确保会话一致性(如用户登录状态保持)。
  • 配置:在Service的spec中添加sessionAffinity: ClientIP
    spec:
      sessionAffinity: ClientIP  # 开启客户端IP亲和性
    
  • 验证:配置后ipvsadm规则会显示persistent 10800(表示会话保持10800秒,即3小时):
    [root@k8s-master01 ~]# ipvsadm -Ln
    TCP  10.97.97.97:80 rr persistent 10800  # 会话保持3小时
    
  • 测试:同一客户端多次访问,返回相同Pod的IP:
    [root@k8s-master01 ~]# while true;do curl 10.97.97.97; sleep 5; done;
    10.244.2.33
    10.244.2.33
    10.244.2.33
    

1.6 Endpoints:Service与Pod的桥梁

定义:Endpoints是Kubernetes的内置资源,用于存储Service关联的所有Pod的IP和端口列表,是Service与Pod之间的“桥梁”。
工作机制

  • 当创建Service时,K8s会根据Service的selector自动筛选匹配的Pod,生成Endpoints;
  • 当Pod新增、删除或IP变化时,Endpoints会实时更新;
  • Service的流量转发规则(如ipvs/iptables)本质上是基于Endpoints的列表生成的。

查看Endpoints

[root@k8s-master01 ~]# kubectl get endpoints -n dev -o wide
NAME                ENDPOINTS                                      AGE
service-clusterip   10.244.1.39:80,10.244.1.40:80,10.244.2.33:80   30m

注意:若Service不指定selector(如ExternalName类型),则不会自动生成Endpoints,需手动创建Endpoints关联外部服务。

二、Ingress:多服务的统一入口

当集群中服务数量增多时,使用NodePort会占用大量节点端口,使用LoadBalancer则需为每个服务创建一个负载均衡器(成本高、管理复杂)。Ingress作为7层(HTTP/HTTPS)负载均衡抽象,通过一个入口(如一个NodePort或LoadBalancer)即可管理多个Service的访问规则,解决上述问题。

2.1 Ingress核心概念

Ingress由两部分组成,二者协同工作实现流量转发:

  1. Ingress资源:用户定义的“规则集合”,描述“哪个域名的请求转发到哪个Service”(如nginx.chenyu.com转发到nginx-service)。
  2. Ingress Controller:具体的反向代理程序(如Nginx、HAProxy),负责监听Ingress资源的变化,将规则转换为自身的配置(如Nginx的nginx.conf),并执行流量转发。

工作流程(以Nginx Ingress Controller为例):

  1. 用户编写Ingress规则,定义域名与Service的映射;
  2. Ingress Controller通过K8s API监听Ingress资源的变化;
  3. Ingress Controller将Ingress规则转换为Nginx的反向代理配置,并更新到运行中的Nginx服务;
  4. 外部请求访问Ingress Controller的入口(如NodePort),Nginx根据配置将请求转发到对应的Service,再由Service分发到Pod。

2.2 Ingress Controller部署(Nginx版)

Ingress Controller需手动部署,以下是基于官方Nginx Ingress Controller的部署步骤(适用于私有集群):

步骤1:下载部署文件
# 创建目录存储配置文件
[root@k8s-master01 ~]# mkdir ingress-controller && cd ingress-controller
# 下载官方部署文件(适用于baremetal(裸金属)集群)
[root@k8s-master01 ingress-controller]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/deploy.yaml
步骤2:修改部署文件(可选)
  • 若集群无法访问国外镜像仓库,需替换镜像地址为国内镜像(如华为云、阿里云镜像):
    # 编辑deploy.yaml,找到nginx-ingress-controller的容器配置
    spec:
      containers:
      - name: nginx-ingress-controller
        image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/ingress-nginx/controller:v1.9.6  # 国内镜像
    
步骤3:部署Ingress Controller
[root@k8s-master01 ingress-controller]# kubectl apply -f deploy.yaml
步骤4:验证部署
  • 查看Ingress Controller的Pod(位于ingress-nginx命名空间):
    [root@k8s-master01 ~]# kubectl get pod -n ingress-nginx
    NAME                                           READY   STATUS    RESTARTS   AGE
    nginx-ingress-controller-fbf967dd5-4qpbp       1/1     Running   0          12h
    
  • 查看Ingress Controller的Service(默认是NodePort类型,提供外部访问入口):
    [root@k8s-master01 ~]# kubectl get svc -n ingress-nginx
    NAME            TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
    ingress-nginx   NodePort   10.98.75.163   <none>        80:32240/TCP,443:31335/TCP   11h
    
    上述结果表示:HTTP请求通过NodeIP:32240访问,HTTPS请求通过NodeIP:31335访问。

2.3 Ingress实践:HTTP与HTTPS代理

Ingress支持HTTP和HTTPS两种协议的代理,以下分别介绍配置方法(需先准备后端Service和Pod)。

2.3.1 环境准备:后端Service与Pod

创建Nginx和Tomcat的Deployment与Service(均为Headless Service,避免额外ClusterIP):

# tomcat-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: dev
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.1
        ports:
        - containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-deployment
  namespace: dev
spec:
  replicas: 3
  selector:
    matchLabels:
      app: tomcat-pod
  template:
    metadata:
      labels:
        app: tomcat-pod
    spec:
      containers:
      - name: tomcat
        image: tomcat:8.5-jre10-slim
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: dev
spec:
  selector:
    app: nginx-pod
  clusterIP: None
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: tomcat-service
  namespace: dev
spec:
  selector:
    app: tomcat-pod
  clusterIP: None
  type: ClusterIP
  ports:
  - port: 8080
    targetPort: 8080

创建资源:

[root@k8s-master01 ~]# kubectl create -f tomcat-nginx.yaml
2.3.2 HTTP代理配置

需求:将nginx.chenyu.com的HTTP请求转发到nginx-servicetomcat.chenyu.com的HTTP请求转发到tomcat-service

步骤1:创建Ingress规则
# ingress-http.yaml
apiVersion: networking.k8s.io/v1  # Ingress的API版本(v1为当前稳定版)
kind: Ingress
metadata:
  name: ingress-http
  namespace: dev
spec:
  ingressClassName: nginx  # 指定使用的Ingress Controller(需与部署时一致)
  rules:  # 规则列表(可配置多个域名)
  - host: nginx.chenyu.com  # 域名1:nginx.chenyu.com
    http:
      paths:  # 路径规则(可配置多个路径)
      - path: /  # 匹配根路径(所有请求)
        pathType: Prefix  # 路径匹配类型(Prefix=前缀匹配,Exact=精确匹配)
        backend:  # 后端Service
          service:
            name: nginx-service  # 关联的Service名称
            port:
              number: 80  # Service端口
  - host: tomcat.chenyu.com  # 域名2:tomcat.chenyu.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: tomcat-service
            port:
              number: 8080
步骤2:创建Ingress资源
[root@k8s-master01 ~]# kubectl create -f ingress-http.yaml
步骤3:验证Ingress
  • 查看Ingress基本信息:
    [root@k8s-master01 ~]# kubectl get ing ingress-http -n dev
    NAME           HOSTS                                  ADDRESS         PORTS   AGE
    ingress-http   nginx.chenyu.com,tomcat.chenyu.com     10.98.75.163    80      22s
    
  • 查看Ingress详情(确认规则是否正确关联Service):
    [root@k8s-master01 ~]# kubectl describe ing ingress-http -n dev
    ...
    Rules:
      Host                Path  Backends
      ----                ----  --------
      nginx.chenyu.com    /     nginx-service:80 (10.244.1.96:80,10.244.1.97:80,10.244.2.112:80)
      tomcat.chenyu.com   /     tomcat-service:8080 (10.244.1.94:8080,10.244.1.95:8080,10.244.2.111:8080)
    ...
    
步骤4:外部访问测试
  • 配置本地Host:在本地电脑的hosts文件(Windows:C:\Windows\System32\drivers\etc\hosts;Linux:/etc/hosts)中添加域名解析:
    192.168.100.100  nginx.chenyu.com  # 192.168.100.100为Ingress Controller的NodeIP
    192.168.100.100  tomcat.chenyu.com
    
  • 访问测试
    • 访问Nginx:浏览器输入http://nginx.chenyu.com:32240(32240为Ingress Controller的HTTP NodePort),显示Nginx默认页面;
    • 访问Tomcat:浏览器输入http://tomcat.chenyu.com:32240,显示Tomcat默认页面。
2.3.3 HTTPS代理配置

需求:为上述两个域名配置HTTPS加密访问(需先删除HTTP的Ingress,避免冲突)。

步骤1:生成HTTPS证书

使用openssl生成自签名证书(生产环境需使用CA机构颁发的证书):

# 生成私钥(tls.key)和证书(tls.crt),有效期365天
[root@k8s-master01 ~]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=BJ/L=BJ/O=nginx/CN=chenyu.com"
步骤2:创建Secret存储证书

Kubernetes通过Secret存储敏感信息(如证书),创建TLS类型的Secret:

[root@k8s-master01 ~]# kubectl create secret tls tls-secret --key tls.key --cert tls.crt -n dev

验证Secret:

[root@k8s-master01 ~]# kubectl get secret -n dev
NAME         TYPE                DATA   AGE
tls-secret   kubernetes.io/tls   2      10s
步骤3:创建HTTPS Ingress规则
# ingress-https.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-https
  namespace: dev
spec:
  tls:  # HTTPS配置(关联Secret)
    - hosts:  # 证书覆盖的域名
      - nginx.chenyu.com
      - tomcat.chenyu.com
      secretName: tls-secret  # 关联上述创建的Secret
  ingressClassName: nginx
  rules:  # 规则与HTTP一致
  - host: nginx.chenyu.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80
  - host: tomcat.chenyu.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: tomcat-service
            port:
              number: 8080
步骤4:创建并验证Ingress
[root@k8s-master01 ~]# kubectl create -f ingress-https.yaml

查看Ingress:PORTS字段显示80,443,表示支持HTTP和HTTPS(HTTP会自动重定向到HTTPS):

[root@k8s-master01 ~]# kubectl get ing ingress-https -n dev
NAME            HOSTS                                  ADDRESS         PORTS     AGE
ingress-https   nginx.chenyu.com,tomcat.chenyu.com     10.98.75.163    80,443    2m
步骤5:HTTPS访问测试
  • 浏览器输入https://nginx.chenyu.com:31335(31335为Ingress Controller的HTTPS NodePort);
  • 由于是自签名证书,浏览器会提示“不安全”,点击“高级”->“继续访问”,即可看到Nginx页面;
  • 同理访问https://tomcat.chenyu.com:31335,可看到Tomcat页面。

三、总结与最佳实践

3.1 Service选型建议

  • 集群内通信:优先使用ClusterIP(简单、高效);若需直接访问Pod,使用Headless Service(如StatefulSet服务)。
  • 临时外部访问:使用NodePort(测试环境、小型应用)。
  • 生产环境外部访问:云环境用LoadBalancer(高可用),私有集群用NodePort + Ingress(成本低、易管理)。
  • 访问外部服务:使用ExternalName(隐藏外部服务IP,便于维护)。

3.2 Ingress最佳实践

  • Ingress Controller选择:Nginx Ingress Controller(功能全、社区活跃)、Traefik(云原生、动态配置)。
  • 证书管理:生产环境使用cert-manager自动管理Let’s Encrypt证书(避免手动更新)。
  • 路径匹配:明确pathTypePrefix适合通用场景,Exact适合精确匹配API路径)。
  • 高可用:部署多个Ingress Controller Pod(通过Deployment的replicas配置),避免单点故障。

3.3 性能优化

  • Service转发:优先使用ipvs模式(性能最优),确保节点已安装IPVS内核模块。
  • Ingress性能:调整Nginx配置(如 worker_processes、worker_connections),开启缓存(如静态资源缓存)。

通过Service和Ingress的配合,Kubernetes实现了服务的稳定访问、灵活暴露和高效管理,是构建云原生应用的核心组件。掌握其原理与实践,能有效提升集群的可扩展性和可维护性。

更多推荐