K8S-Ingress资源对象

在 Kubernetes 集群中,暴露服务给外部访问是一个常见需求。Service 虽然能实现服务发现和负载均衡,但在大规模应用场景下,NodePort 和 LoadBalancer 两种暴露方式存在明显局限。本文将详细介绍 Kubernetes Ingress 资源对象,包括其工作原理、部署方式及实际应用案例。

一、Ingress 概述

传统 Service 暴露方式的不足

Kubernetes 中 Service 对集群外暴露服务的主要方式有两种,但都存在明显缺点:

  • NodePort 方式:会占用大量集群机器端口,随着服务增多,端口管理变得复杂
  • LoadBalancer 方式:每个 Service 都需要一个独立的负载均衡器,造成资源浪费且依赖外部设备支持

Ingress 的优势

Ingress 作为 Kubernetes 的一种资源对象,仅需一个 NodePort 或 LoadBalancer 即可满足多个 Service 的暴露需求,有效解决了上述问题。

核心概念

Ingress 实现反向代理和负载均衡的核心依赖两个组件:

  • Ingress:Kubernetes 中的资源对象,定义请求如何转发到 Service 的规则
  • Ingress Controller:具体实现反向代理及负载均衡的程序(如 Nginx、Contour、Haproxy 等),负责解析 Ingress 规则并转化为实际的代理配置

工作原理(以 Nginx 为例)

  1. 用户编写 Ingress 规则,定义域名与 Service 的映射关系
  2. Ingress Controller 动态感知规则变化,生成对应的 Nginx 反向代理配置
  3. Ingress Controller 将配置更新到运行中的 Nginx Pod
  4. 最终由配置好规则的 Nginx 提供外部访问服务

二、Ingress 环境搭建

部署 Ingress Controller

以 Nginx Ingress Controller 为例,部署步骤如下:

bash

运行

复制代码
# 创建工作目录
mkdir ingress-controller
cd ingress-controller/

# 获取指定版本的ingress-nginx(本文使用v1.12.0)
wget https://github.com/kubernetes/ingress-nginx/releases/tag/controller-v1.12.0/ingress-nginx-controller-v1.12.0.zip
unzip ingress-nginx-controller-v1.12.0.zip
cd ingress-nginx-controller-v1.12.0/deploy/static/provider/cloud

# 部署ingress-nginx
kubectl apply -f deploy.yaml 

# 检查部署状态
kubectl -n ingress-nginx get pod
kubectl -n ingress-nginx get svc

外部访问策略说明

在部署配置中,externalTrafficPolicy参数有两种取值:

  • Cluster:流量会在集群所有节点间负载均衡,可能导致额外网络跳转
  • Local:流量仅转发到接收请求节点上的服务实例,避免额外跳转但可能导致流量分布不均

三、Ingress 应用案例

1. NodePort 模式验证

准备 Service 和 Pod

创建nginx.yaml文件:

yaml

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-deploy
  name: nginx-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-deploy
  template:
    metadata:
      labels:
        app: nginx-deploy
    spec:
      containers:
      - image: nginx:latest
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-deploy
  name: nginx-svc
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx-deploy
  type: ClusterIP

部署并检查:

bash

运行

复制代码
kubectl apply -f nginx.yaml
kubectl get pod
kubectl get svc
配置 Ingress 规则

创建ingress-http.yaml文件:

yaml

复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.jx.com
    http:
      paths:
      - backend:
          service:
            name: nginx-svc
            port:
              number: 80
        path: /
        pathType: Prefix

其中pathType有两种主要类型:

  • Exact:精确匹配,只有路径完全一致才会匹配
  • Prefix:前缀匹配,只要请求路径以前缀开头就会匹配

部署并检查 Ingress:

bash

运行

复制代码
kubectl create -f ingress-http.yaml
kubectl get ingress nginx-ingress
kubectl describe ingress nginx-ingress
测试访问

配置 hosts 解析(指向运行 ingress-controller 的节点 IP):

plaintext

复制代码
192.168.158.17	nginx.jx.com

使用域名访问测试:

bash

运行

复制代码
curl nginx.jx.com:31502

2. LoadBalancer 模式验证

配置准备

启用严格 ARP 模式:

shell

复制代码
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system

启用严格 ARP 模式的原因:

  • 避免 ARP 冲突,防止多个 Pod 响应同一个 ARP 请求
  • 确保流量正确分发到预期的 Pod
  • 增强网络安全性和稳定性,防止恶意干扰
部署 MetalLB

MetalLB 为非云环境提供 LoadBalancer 支持:

shell

复制代码
# 部署metallb
cd /root/metallb-0.14.8/config/manifests
kubectl apply -f metallb-native.yaml

# 创建IP地址池
cat > IPAddressPool.yaml<<EOF
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: planip-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.158.135-192.168.158.150
EOF

# 关联IP地址池
cat > L2Advertisement.yaml<<EOF
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: planip-pool
  namespace: metallb-system
spec:
  ipAddressPools:
  - planip-pool
EOF

# 应用配置
kubectl apply -f IPAddressPool.yaml
kubectl apply -f L2Advertisement.yaml
多域名路由配置

创建包含多个域名规则的 Ingress:

yaml

复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.jx.com
    http:
      paths:
      - backend:
          service:
            name: nginx-svc
            port:
              number: 80
        path: /
        pathType: Prefix
  - host: nginx2.jx.com
    http:
      paths:
      - backend:
          service:
            name: nginx-svc1
            port:
              number: 80
        path: /
        pathType: Prefix

修改 Ingress 服务类型为 LoadBalancer:

bash

运行

复制代码
kubectl -n ingress-nginx edit svc ingress-nginx-controller
# 将type修改为LoadBalancer

测试访问:

bash

运行

复制代码
curl nginx.jx.com
curl nginx2.jx.com

四、总结

相关推荐
阿拉斯攀登15 小时前
Kubernetes(K8s)全面解析:核心概念、架构与实践
docker·云原生·容器·kubernetes·k8s
小坏讲微服务1 天前
K8S 部署 Spring Cloud Alibaba 微服务企业实战完整使用
spring cloud·docker·微服务·云原生·容器·kubernetes·k8s
新手小白*1 天前
K8S-Statefulset控制器
k8s
新手小白*2 天前
K8S DaemonSet 控制器
k8s
虚伪的空想家4 天前
云镜像,虚拟机镜像怎么转换成容器镜像
服务器·docker·容器·k8s·镜像·云镜像·虚机
ohoy4 天前
ubuntu k8s1.32集群安装
k8s
武子康4 天前
AI研究-134 Java 2025:会衰退吗?LTS 路线、云原生与工程化落地趋势研究
java·开发语言·人工智能·python·ai·云原生·k8s
iru13 天前
kubectl cp详解,k8s集群与本地环境文件拷贝
运维·容器·k8s
竹君子15 天前
研发管理知识库(15)K8s和Istio关系
k8s