Kubernetes服务发布进阶

目录

简介

一、Ingress基础概念

1.1 Ingress与服务暴露方案对比

1.2 Ingress的核心组成

1.3 Ingress工作流程

二、部署Ingress Nginx Controller

2.1 安装Helm

2.2 配置Ingress Nginx镜像与参数

2.3 部署Ingress Nginx

三、Ingress Nginx核心功能

3.1 基础域名访问配置

3.2 域名重定向(Redirect)

3.3 前后端分离Rewrite

3.4 SSL证书配置(HTTPS)

3.5 基本认证(Basic Auth)

3.6 灰度发布(金丝雀发布)

四、总结


简介

在Kubernetes集群中,服务暴露是连接内部应用与外部世界的关键环节。当我们需要以更灵活的方式管理大量服务和域名时,Ingress成为了生产环境的首选方案。

一、Ingress基础概念

1.1 Ingress与服务暴露方案对比

Kubernetes提供了多种服务暴露方式:

  • NodePort:将服务映射到节点的30000-32767端口,适合测试环境,但端口管理复杂
  • LoadBalancer:依赖云服务商负载均衡器,有费用且受限于云平台
  • ExternalIPs:手动配置外部IP路由到集群节点
  • Ingress:七层反向代理,通过域名和URL路径规则转发请求,只需少量公网IP即可管理大量服务
1.2 Ingress的核心组成

(1)Ingress资源对象

# 示例:基础Ingress资源定义
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  rules:
  - host: nginx.test.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: nginx-service
            port:
              number: 80
  • 本质是一个API对象,通过YAML定义请求转发规则
  • 可配置域名、URL路径、SSL、负载均衡等规则
  • 需配合Ingress Controller实现具体转发

(2)Ingress Controller

  • 具体实现反向代理和负载均衡的组件,常见有Nginx、Traefik、Istio等
  • 以Pod形式运行,动态监控Ingress规则变化,生成Nginx配置并reload生效
  • 工作流程:
  1. 监听Kubernetes API获取Ingress规则
  2. 生成Nginx配置(如upstream、server块)
  3. 应用配置到Nginx服务
1.3 Ingress工作流程

用户访问流程:

  1. 浏览器输入域名(如nginx.test.com)
  2. 域名解析到外部负载均衡器(如阿里云SLB)
  3. 负载均衡器转发请求到Ingress Controller
  4. Ingress根据规则匹配到对应Service
  5. Service转发到后端Pod

二、部署Ingress Nginx Controller

2.1 安装Helm
# 下载Helm 3.9.4(适用于Linux AMD64)
wget https://get.helm.sh/helm-v3.9.4-linux-amd64.tar.gz
# 解压
tar zxvf helm-v3.9.4-linux-amd64.tar.gz
# 移动到系统路径
mv linux-amd64/helm /usr/local/bin/
# 验证安装
helm version

解释:Helm是Kubernetes的包管理器,用于简化应用部署,此处下载稳定版本并配置全局可用。

2.2 配置Ingress Nginx镜像与参数
# 添加Ingress Nginx仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
# 更新仓库索引
helm repo update
# 拉取Chart包
helm pull ingress-nginx/ingress-nginx --version 4.7.1
# 解压配置
tar xvf ingress-nginx-4.7.1.tgz

修改values.yaml配置:

# 修改镜像为国内源(解决拉取慢问题)
controller:
  image:
    registry: registry.cn-hangzhou.aliyuncs.com
    image: tanzu/controller
    tag: "v1.6.4"
    # 注释掉摘要信息
    # digest: sha256:15be4666c53052484dd2992efacf2f50ea77a78ae8aa21ccd91af6baaa7ea22f

# 配置网络模式
controller:
  hostNetwork: true  # 共享节点网络命名空间,提升性能
  dnsPolicy: ClusterFirstWithHostNet  # 适配hostNetwork的DNS策略

# 节点选择器(指定部署节点)
controller:
  nodeSelector:
    ingress: "true"
    kubernetes.io/os: linux

# 修改部署类型为DaemonSet(每个节点运行一个副本)
controller:
  kind: DaemonSet

解释

  • 国内镜像加速:避免因官方镜像仓库网络问题导致拉取失败
  • hostNetwork设为true:让Pod共享节点网络,简化网络配置并提高性能
  • nodeSelector:通过标签将Ingress Controller固定部署在指定节点
  • DaemonSet部署:确保每个节点运行一个控制器实例,提高可用性
2.3 部署Ingress Nginx
# 给目标节点打标签
kubectl label node k8s-node01 ingress=true
# 创建命名空间
kubectl create ns ingress-nginx
# 安装Ingress Nginx
helm install ingress-nginx . -n ingress-nginx
# 验证部署
kubectl get po -n ingress-nginx -o wide

输出示例

NAME                             READY   STATUS      RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
ingress-nginx-controller-2t6qh   1/1     Running     0          17s   192.168.10.102   k8s-node01   <none>           <none>

解释

  • 节点标签用于精准调度Ingress Controller
  • 独立命名空间隔离资源,便于管理
  • Helm安装时通过​​.​​​指定当前目录的Chart,​​-n​​指定命名空间

三、Ingress Nginx核心功能

3.1 基础域名访问配置

1. 创建测试环境

# 创建命名空间
kubectl create ns study-ingress
# 部署Nginx应用
kubectl create deployment nginx --image=nginx:1.7.9 -n study-ingress
# 暴露为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
  namespace: study-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.test.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: nginx
            port:
              number: 80

解释

  • ​ingressClassName: nginx​​:指定使用Nginx控制器
  • ​host: nginx.test.com​​:配置访问域名
  • ​pathType: ImplementationSpecific​​:由控制器决定路径匹配方式(等效于Prefix)

3. 应用并测试

kubectl create -f web-ingress.yaml
# 访问测试(需将nginx.test.com解析到Ingress节点IP)
curl http://nginx.test.com
# 输出:Welcome to nginx!
3.2 域名重定向(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:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: nginx
            port:
              number: 80

关键注解解释

  • ​nginx.ingress.kubernetes.io/permanent-redirect​​:设置永久重定向(301状态码),值为目标URL
  • 当访问​​nginx.redirect.com​​时,会自动跳转到百度

测试

# 添加域名解析到hosts文件
echo "192.168.10.102 nginx.redirect.com" >> /etc/hosts
# 访问测试
curl -I http://nginx.redirect.com
# 输出:HTTP/1.1 301 Moved Permanently
#       Location: https://www.baidu.com
3.3 前后端分离Rewrite

在前后端分离架构中,常需将​​/api​​路径重写为后端服务可识别的路径:

# rewrite.yaml
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:
      - path: /api-a(/|$)(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: backend-api
            port:
              number: 80

规则解析

  • ​path: /api-a(/|$)(.*)​​:正则表达式匹配路径
  • 第一个捕获组​​(/|$)​​​匹配​​/​​或路径结尾
  • 第二个捕获组​​(.*)​​匹配任意字符
  • ​rewrite-target: /$2​​​:将请求路径重写为​​/$2​​​,即去掉​​/api-a​​前缀
  • 示例:访问​​/api-a/user​​​会被重写为​​/user​​转发到后端服务

测试

# 访问重写后的路径
curl http://nginx.test.com/api-a
# 输出:Welcome to nginx!(假设后端服务根路径返回Nginx默认页)
3.4 SSL证书配置(HTTPS)

生产环境需配置HTTPS保障通信安全,以下是自签名证书示例(生产环境需使用CA签名证书):

1. 生成自签名证书

openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout tls.key -out tls.crt \
  -subj "/CN=nginx.test.com"

参数解释

  • ​-x509​​:生成自签名证书
  • ​-nodes​​:不加密私钥(测试用,生产环境建议加密)
  • ​-days 365​​:证书有效期1年
  • ​-newkey rsa:2048​​:生成2048位RSA密钥对
  • ​-subj "/CN=nginx.test.com"​​:证书绑定域名

2. 创建证书Secret

kubectl create secret tls ca-secret \
  --cert=tls.crt --key=tls.key \
  -n study-ingress

解释

  • ​tls​​类型Secret专门用于存储SSL证书
  • 证书和私钥分别通过​​--cert​​​和​​--key​​指定

3. 配置HTTPS Ingress

# ingress-ssl.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress-ssl
  namespace: study-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.test.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: nginx
            port:
              number: 80
  tls:
  - hosts:
    - nginx.test.com
    secretName: ca-secret

关键字段解释

  • ​tls​​字段:配置HTTPS证书
  • ​hosts​​:证书绑定的域名列表
  • ​secretName​​:引用之前创建的Secret名称

4. 测试HTTPS访问

curl https://nginx.test.com --insecure
# 输出:Welcome to nginx!(因自签名证书需加--insecure跳过验证)
3.5 基本认证(Basic Auth)

对敏感服务添加密码访问控制:

1. 安装htpasswd工具

yum -y install httpd  # 包含htpasswd工具

2. 创建用户密码

htpasswd -c auth zhangsan
# 输入密码(两次)
New password: ******
Re-type new password: ******
# 输出:Adding password for user zhangsan

参数解释

  • ​-c​​:创建新密码文件
  • ​auth​​:密码文件名
  • ​zhangsan​​:用户名

3. 创建认证Secret

kubectl create secret generic basic-auth \
  --from-file=auth \
  -n study-ingress

解释

  • ​generic​​类型Secret存储普通配置
  • ​--from-file=auth​​:将本地auth文件存入Secret

4. 配置认证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
    nginx.ingress.kubernetes.io/auth-type: basic
spec:
  ingressClassName: nginx
  rules:
  - host: auth.test.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: nginx
            port:
              number: 80

注解解释

  • ​auth-realm​​:认证提示信息
  • ​auth-secret​​:引用认证Secret名称
  • ​auth-type​​:认证类型(basic为基本认证)

5. 测试认证

# 浏览器访问auth.test.com会弹出登录框
# 使用zhangsan:密码登录
curl -u zhangsan:密码 http://auth.test.com
# 输出:Welcome to nginx!
3.6 灰度发布(金丝雀发布)

灰度发布允许将部分流量切换到新版本,降低发布风险:

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

2. 配置生产环境Ingress

# v1-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-v1
  namespace: production
spec:
  ingressClassName: nginx
  rules:
  - host: canary.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: canary-v1
            port:
              number: 8080

3. 创建灰度环境(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

4. 配置灰度Ingress(10%流量)

# 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"
spec:
  ingressClassName: nginx
  rules:
  - host: canary.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: canary-v2
            port:
              number: 8080

注解解释

  • ​canary: "true"​​:标记为灰度环境
  • ​canary-weight: "10"​​:分配10%流量给v2版本,原v1版本获得90%

5. 流量测试

# 循环访问10次查看流量分布
for i in $(seq 10); do curl -s canary.com; done
# 输出示例:
# <h1>Canary v2</h1>    (1次,10%)
# <h1>Canary v1</h1>    (9次,90%)

# 修改流量权重为50%
kubectl edit ingress canary-v2 -n canary
# 修改注解:nginx.ingress.kubernetes.io/canary-weight: "50"

# 再次测试
for i in $(seq 10); do curl -s canary.com; done
# 输出示例:v1和v2各约5次

四、总结

  1. 高可用部署
  • 使用DaemonSet部署Ingress Controller,确保每个节点运行实例
  • 配合外部负载均衡器(如HAProxy)实现Controller的负载均衡和故障转移
  1. 资源隔离
  • 为Ingress Controller单独创建命名空间(如​​ingress-nginx​​)
  • 通过​​nodeSelector​​将Controller固定部署在专用节点
  1. 安全配置
  • 生产环境使用CA签名的SSL证书
  • 对敏感服务启用Basic Auth或结合OIDC/Keycloak实现单点登录
  • 限制Ingress的域名解析范围,避免未授权访问
  1. 流量管理
  • 灰度发布时从1%开始逐步增加流量,密切监控新版本性能
  • 结合Prometheus监控Ingress的请求量、错误率等指标
  1. 日志与审计
  • 配置Ingress Nginx的访问日志,便于问题排查
  • 启用审计日志记录Ingress资源的变更历史

Ingress Nginx作为Kubernetes服务发布的核心组件,提供了从基础域名访问到复杂流量管理的全场景解决方案。本文讲解了:

  • Ingress的核心原理与工作流程
  • 生产环境部署Ingress Nginx Controller的完整流程
  • 域名重定向、路径Rewrite、SSL、基本认证、灰度发布等高级功能
  • 每个配置项的实际意义与应用场景

在微服务架构日益普及的今天,熟练掌握Ingress Nginx将极大提升Kubernetes集群的服务管理效率,为业务的稳定运行和快速迭代提供坚实保障。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值