Kubernetes Ingress 服务发布进阶

Kubernetes Ingress 服务发布进阶

一、概述

在 Kubernetes 集群中,服务暴露是集群与外部通信的核心环节。Ingress 作为一种灵活且强大的服务暴露方案,通过定义基于域名、URL 路径的转发规则,实现了七层反向代理、负载均衡、SSL 终结等高级功能,成为生产环境中管理大量服务和域名的首选方案。

与其他服务暴露方式相比,Ingress 具有明显优势:

服务暴露方式特点适用场景
NodePort暴露在节点端口(30000-32767),依赖 Kube-Proxy测试环境,少量服务
LoadBalancer依赖云厂商负载均衡器,可能产生额外费用公有云环境,简单服务暴露
Ingress通过统一入口暴露多个 HTTP/HTTPS 服务,支持复杂规则生产环境,微服务架构,多域名 / 路径管理

二、基本概念

1. Service 的核心作用

  • 内部服务发现:跟踪 Pod 变化,更新 Endpoint,解决 Pod IP 动态变化问题。
  • 外部访问入口:类似负载均衡器,提供集群内外对 Pod 的访问能力。

2. Ingress 核心组成

(1)Ingress 对象
  • 是 Kubernetes 的 API 对象,通过 YAML 配置定义请求转发规则(域名、URL 路径与 Service 的映射关系)。
  • 仅为配置模板,需依赖 Ingress Controller 实现具体功能。
(2)Ingress Controller
  • 具体实现反向代理和负载均衡的组件,需单独部署(非 K8s 内置组件)。
  • 常见实现:Ingress Nginx(官方维护)、Traefik、HAProxy、Istio 等。
  • 工作机制:通过与 K8s APIServer 交互感知规则变化,动态生成反向代理配置(如 Nginx 配置)并生效。

三、Ingress 工作原理

ngress 的工作原理主要通过 Ingress Controller 与 Kubernetes 集群的交互及请求转发流程实现,具体如下:

  1. 规则监控与感知:Ingress Controller 持续与 Kubernetes APIServer 进行交互,动态感知集群中 Ingress 规则的变化。
  2. 配置生成与应用:当感知到 Ingress 规则变化后,Ingress Controller 会按照规则(即哪个域名对应哪个 Service 的映射关系)生成相应的反向代理配置,例如 Ingress Nginx 会动态生成 Nginx 配置。生成的配置会被写入到 Ingress Controller 所在 Pod 内的反向代理程序配置文件中(如 Nginx 的 /etc/nginx.conf),并在需要时重新加载程序使新配置生效。
  3. 请求转发流程:外部客户端的请求首先到达 Ingress Controller,Ingress Controller 根据生成的配置规则,将请求转发到对应的 Service,最终由 Service 将请求路由到后端的 Pod 上。

四、安装 Ingress Nginx Controller

1. 环境准备:安装 Helm

Helm 是 Kubernetes 包管理工具,用于简化 Ingress Nginx 的部署。

# 下载 Helm 二进制包(注意:原文档中"he1m"为笔误,正确为"helm")
wget https://get.helm.sh/helm-v3.9.4-linux-amd64.tar.gz

# 解压包
tar zxvf helm-v3.9.4-linux-amd64.tar.gz

# 将 helm 二进制文件移动到全局路径,确保可执行
mv linux-amd64/helm /usr/local/bin/

2. 添加 Helm 仓库并更新

# 添加 Ingress Nginx 仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

# 更新仓库索引
helm repo update

3. 下载并修改配置(values.yaml)

# 拉取 Ingress Nginx Chart 包
helm pull ingress-nginx/ingress-nginx --version 4.7.1

# 解压包
tar xvf ingress-nginx-4.7.1.tgz

# 编辑配置文件(核心配置如下)
vim ingress-nginx/values.yaml

核心配置修改说明:

# 1. 修改镜像仓库为国内地址(加速拉取)
controller:
  image:
    registry: registry.cn-hangzhou.aliyuncs.com  # 国内仓库
    image: tanzu/controller
    tag: "v1.6.4"
    # 注释掉 digest 信息(避免镜像拉取冲突)

# 2. 修改 opentelemetry 镜像地址(可选,按需启用)
opentelemetry:
  enabled: false  # 关闭追踪功能
  image: registry.cn-hangzhou.aliyuncs.com/tanzu/opentelemetry:v20230107

# 3. 修改 admissionWebhook 镜像地址
patch:
  image:
    registry: registry.cn-hangzhou.aliyuncs.com
    image: tanzu/kube-webhook-certgen
    tag: v20220916-gd32f8c343

# 4. 启用主机网络(使 Pod 使用节点网络,便于外部访问)
hostNetwork: true

# 5. 配置 DNS 策略(适配 hostNetwork 模式)
dnsPolicy: ClusterFirstWithHostNet

# 6. 指定部署节点(通过节点标签筛选)
nodeSelector:
  ingress: "true"  # 仅部署到带有 ingress=true 标签的节点
  kubernetes.io/os: linux

# 7. 部署模式改为 DaemonSet(每个节点部署一个副本,提高可用性)
kind: DaemonSet  # 原文档"DeamonSet"为笔误,正确为"DaemonSet"

4. 部署 Ingress Nginx

# 1. 为目标节点打标签(与 values.yaml 中 nodeSelector 匹配)
kubectl label node k8s-node01 ingress=true

# 2. 创建命名空间
kubectl create ns ingress-nginx

# 3. 安装 Ingress Nginx(注意最后一个点表示当前目录的 Chart 包)
cd ingress-nginx
helm install ingress-nginx -n ingress-nginx .

# 4. 验证部署(查看 Pod 状态)
kubectl get po -n ingress-nginx -o wide
# 输出示例:ingress-nginx-controller-2t6qh  1/1  Running  0  17s  192.168.10.102  k8s-node01

五、Ingress Nginx 使用入门

1. 部署测试服务

# 1. 创建命名空间
kubectl create ns study-ingress

# 2. 部署 Nginx 应用
kubectl create deployment nginx --image=nginx:1.7.9 -n study-ingress

# 3. 暴露 Service
kubectl expose deployment nginx --port 80 -n study-ingress

2. 创建 Ingress 规则

创建 web-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress  # Ingress 名称
  namespace: study-ingress  # 与服务同命名空间
spec:
  ingressClassName: nginx  # 指定使用的 Ingress Controller 类型
  rules:
  - host: nginx.test.com  # 绑定域名
    http:
      paths:
      - backend:
          service:
            name: nginx  # 目标 Service 名称
            port:
              number: 80  # Service 端口
        path: /  # 匹配路径
        pathType: ImplementationSpecific  # 路径匹配类型

路径类型说明

  • ImplementationSpecific:由 IngressClass 决定匹配规则(可视为 Prefix 或 Exact)。
  • Exact:精确匹配 URL 路径(区分大小写)。
  • Prefix:前缀匹配(区分大小写,按 / 分割的元素匹配,如 /foo/bar 匹配 /foo/bar/baz 但不匹配 /foo/barbaz)。

3. 应用并测试

# 创建 Ingress 规则
kubectl create -f web-ingress.yaml

# 测试访问(需将 nginx.test.com 解析到 Ingress Controller 所在节点 IP)
# 在客户端 hosts 文件添加:<节点 IP> nginx.test.com
# 访问 http://nginx.test.com,应看到 Nginx 欢迎页

六、高级功能实现

1. 域名重定向(Redirect)

场景:旧域名平滑过渡到新域名,将旧域名请求重定向到新域名。

创建 redirect.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-redirect
  namespace: study-ingress
  annotations:
    # 核心注解:指定重定向目标(新域名)
    nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.redirect.com  # 旧域名
    http:
      paths:
      - backend:
          service:
            name: nginx  # 临时绑定的服务(可不实际使用)
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific

应用并测试:

kubectl create -f redirect.yaml
# 客户端 hosts 添加:<节点 IP> nginx.redirect.com
# 访问 http://nginx.redirect.com 应跳转到 https://www.baidu.com

2. 前后端分离(Rewrite)

场景:前端访问根路径,后端接口路径 /api-a 转发到后端服务,并去除路径前缀。

创建 rewrite.yaml(原文档 “rewirte” 为笔误,正确为 “rewrite”):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: backend-api
  namespace: study-ingress
  annotations:
    # 核心注解:重写路径(将匹配的第二个捕获组作为新路径)
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.test.com
    http:
      paths:
      - backend:
          service:
            name: backend-api  # 后端服务名称
            port:
              number: 80
        # 路径规则:匹配 /api-a 开头的路径,捕获后续内容
        path: /api-a(/|$)(.*)  # 第一个组匹配 / 或结尾,第二个组匹配后续路径
        pathType: ImplementationSpecific

部署后端服务并测试:

# 部署后端服务
kubectl create deployment backend-api --image=nginx:1.7.9 -n study-ingress
kubectl expose deployment backend-api --port 80 -n study-ingress

# 应用 Ingress 规则
kubectl create -f rewrite.yaml

# 测试:访问 http://nginx.test.com/api-a 或 http://nginx.test.com/api-a/index.html
# 应看到 Nginx 欢迎页(路径被重写为 /)

3. SSL 配置(HTTPS)

场景:为服务配置 HTTPS 加密访问。

(1)生成测试证书(生产环境需使用权威证书)
# 生成自签名证书(有效期 365 天,CN 为目标域名)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout tls.key \
  -out tls.crt \
  -subj "/CN=nginx.test.com"
(2)创建证书 Secret
kubectl create secret tls ca-secret \
  --cert=tls.crt \  # 证书文件
  --key=tls.key \   # 私钥文件
  -n study-ingress
(3)创建 SSL 配置的 Ingress

创建 ingress-ssl.yaml(原文档 “ingress-ss1.yaml” 为笔误):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress-ssl
  namespace: study-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.test.com  # 与证书 CN 匹配
    http:
      paths:
      - backend:
          service:
            name: nginx
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific
  tls:  # SSL 配置
  - hosts:
    - nginx.test.com  # 证书生效的域名
    secretName: ca-secret  # 引用证书 Secret

应用并测试:

kubectl create -f ingress-ssl.yaml
# 客户端访问 https://nginx.test.com(忽略证书警告),应看到 Nginx 欢迎页

4. 基本认证(Basic Auth)

场景:限制服务访问,需输入用户名密码验证。

(1)安装工具并创建用户密码
# 安装 httpd 工具包(含 htpasswd)
yum -y install httpd

# 创建密码文件(用户名 zhangsan,会生成 auth 文件)
htpasswd -c auth zhangsan
# 输入密码并确认
(2)创建认证 Secret
kubectl create secret generic basic-auth \
  --from-file=auth \  # 引用密码文件
  -n study-ingress
(3)创建带认证的 Ingress

创建 ingress-with-auth.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-with-auth
  namespace: study-ingress
  annotations:
    nginx.ingress.kubernetes.io/auth-realm: "Please Input Your Username and Password"  # 认证提示
    nginx.ingress.kubernetes.io/auth-secret: basic-auth  # 引用认证 Secret
    nginx.ingress.kubernetes.io/auth-type: basic  # 认证类型
spec:
  ingressClassName: nginx
  rules:
  - host: auth.test.com  # 认证域名
    http:
      paths:
      - backend:
          service:
            name: nginx
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific

应用并测试:

kubectl create -f ingress-with-auth.yaml
# 客户端 hosts 添加:<节点 IP> auth.test.com
# 访问 http://auth.test.com,应弹出用户名密码输入框,输入 zhangsan 和密码后可访问

5. 灰度发布 / 金丝雀发布

场景:将部分流量路由到新版本服务,验证稳定后逐步扩大流量比例。

(1)部署生产环境(V1 版本)
# 创建命名空间
kubectl create ns production

# 部署 V1 版本应用
kubectl create deployment canary-v1 \
  --image=registry.cn-beijing.aliyuncs.com/dotbalo/canary:v1 -n production

# 暴露服务
kubectl expose deployment canary-v1 --port 8080 -n production

# 创建 V1 版本 Ingress
cat > v1-ingress.yaml << EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-v1
  namespace: production
spec:
  ingressClassName: nginx
  rules:
  - host: canary.com  # 统一访问域名
    http:
      paths:
      - backend:
          service:
            name: canary-v1
            port:
              number: 8080
        path: /
        pathType: ImplementationSpecific
EOF
kubectl create -f v1-ingress.yaml
(2)部署灰度环境(V2 版本)
# 创建命名空间
kubectl create ns canary

# 部署 V2 版本应用
kubectl create deployment canary-v2 \
  --image=registry.cn-beijing.aliyuncs.com/dotbalo/canary:v2 -n canary

# 暴露服务
kubectl expose deployment canary-v2 --port 8080 -n canary
(3)配置灰度流量规则

创建 canary-v2.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-v2
  namespace: canary
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"  # 启用金丝雀模式
    nginx.ingress.kubernetes.io/canary-weight: "10"  # 灰度流量比例(10% 到 V2)
spec:
  ingressClassName: nginx
  rules:
  - host: canary.com  # 与 V1 版本相同的访问域名
    http:
      paths:
      - backend:
          service:
            name: canary-v2  # 灰度服务
            port:
              number: 8080
        path: /
        pathType: ImplementationSpecific

应用并测试:

kubectl create -f canary-v2.yaml

# 测试:多次访问 canary.com,观察返回结果
for i in $(seq 10); do curl -s canary.com; done
# 预期:约 10% 返回 "<h1>Canary v2</h1>",90% 返回 "<h1>Canary v1</h1>"

# 调整权重:编辑 Ingress 规则,将 canary-weight 改为 50,重复测试
kubectl edit ingress canary-v2 -n canary
# 预期:约 50% 流量到 V2 版本

六、总结

Ingress 作为 Kubernetes 服务发布的核心方案,通过 Ingress Controller 实现了灵活的流量管理。本文涵盖了 Ingress 基本概念、工作原理、安装部署及高级功能(重定向、HTTPS、认证、灰度发布)的实战配置。掌握这些内容可帮助在生产环境中高效、安全地管理服务发布,适应微服务架构的复杂需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值