1. 理解Kubernetes Ingress的核心价值

当你第一次接触Kubernetes时,可能会被各种网络概念搞得晕头转向。Service、Pod、Endpoint...这些组件各自为政,而Ingress就是那个帮你统一管理外部流量的"交通警察"。简单来说,Ingress就是集群的"大门",所有外部请求都要经过它才能进入内部服务。

我刚开始用Kubernetes时,最头疼的就是如何优雅地暴露服务。NodePort需要记住一堆端口号,LoadBalancer又太贵。直到发现了Ingress这个神器,它不仅能基于域名和路径路由流量,还能集中管理TLS证书。举个例子,我们有个电商平台,需要把/user路径路由到用户服务,/product路径路由到商品服务。用Ingress只需要几行YAML配置就能搞定,再也不用为每个服务单独配置暴露方式。

2. 搭建Nginx Ingress Controller实战

2.1 环境准备与安装

在开始之前,确保你已经有一个运行中的Kubernetes集群。我用的是kubeadm搭建的三节点集群(1个master+2个worker),版本是1.25。安装Ingress Controller最方便的方式是使用Helm,这个Kubernetes的包管理工具就像Linux里的apt-get。

先添加Ingress-Nginx的Helm仓库:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

然后执行安装命令。这里有个小技巧,生产环境建议指定节点打标签的方式部署,避免调度到不合适的节点:

helm install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace \
  --set controller.replicaCount=2 \
  --set controller.nodeSelector."kubernetes\.io/os"=linux \
  --set controller.admissionWebhooks.enabled=false

安装完成后别急着走,检查下Pod状态和Service的外部IP:

kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
kubectl get svc -n ingress-nginx

2.2 验证基础功能

看到EXTERNAL-IP显示为IP地址后(如果是云环境可能是负载均衡器的域名),我们可以先做个简单测试。创建一个测试服务:

kubectl create deployment demo --image=nginx
kubectl expose deployment demo --port=80

然后编写一个基础Ingress规则:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: demo.yourdomain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: demo
            port:
              number: 80

应用这个配置后,在本地hosts文件添加一条记录指向Ingress的IP,就能通过浏览器访问了。这个过程中Ingress Controller会自动生成Nginx配置并热加载,完全不需要手动操作。

3. 高级路由配置技巧

3.1 多域名与路径路由

实际项目中,我们经常需要处理更复杂的路由场景。比如有个电商平台,需要将:

  • www.example.com 指向首页服务
  • api.example.com 指向API网关
  • www.example.com/static 指向静态资源服务

对应的Ingress配置是这样的:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: e-commerce
spec:
  ingressClassName: nginx
  rules:
  - host: www.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend
            port:
              number: 80
      - path: /static
        pathType: Prefix
        backend:
          service:
            name: static
            port:
              number: 80
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-gateway
            port:
              number: 8000

3.2 流量切分与金丝雀发布

更高级的玩法是使用注解实现流量切分。比如新版本上线时,想让10%的流量走新版本服务:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-demo
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
  ingressClassName: nginx
  rules:
  - host: demo.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: new-version
            port:
              number: 80

这个功能我在灰度发布时经常用,比直接全量上线稳妥多了。配合监控系统观察新版本的表现,有问题随时调整流量比例。

4. TLS证书自动化管理

4.1 配置Let's Encrypt证书

现在网站不用HTTPS都不好意思见人了。Ingress配合cert-manager可以自动申请和续期Let's Encrypt证书,完全零维护。

首先安装cert-manager:

helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.11.0 \
  --set installCRDs=true

然后创建ClusterIssuer(生产环境建议用Let's Encrypt的production端点):

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: your@email.com
    privateKeySecretRef:
      name: letsencrypt-staging
    solvers:
    - http01:
        ingress:
          class: nginx

4.2 在Ingress中启用TLS

现在修改之前的Ingress配置,添加TLS部分:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: secure-demo
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-staging"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - demo.example.com
    secretName: demo-tls
  rules:
  - host: demo.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: demo
            port:
              number: 80

应用后,cert-manager会自动创建Certificate资源,申请证书并存入指定的Secret。整个过程大概需要1-2分钟,你可以在证书Secret生成后通过浏览器的小锁图标验证。

5. 生产环境最佳实践

5.1 性能调优参数

高并发场景下,默认的Nginx配置可能不够用。可以通过ConfigMap调整参数:

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
  namespace: ingress-nginx
data:
  worker-processes: "4"
  keep-alive: "75"
  upstream-keepalive-connections: "1000"

然后更新Ingress Controller部署时引用这个ConfigMap。我在一个日PV百万级的项目中,通过调整这些参数将QPS从200提升到了1500+。

5.2 监控与告警

任何生产级应用都离不开监控。Ingress-Nginx自带Prometheus指标,可以通过ServiceMonitor暴露给Prometheus:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: nginx-ingress
  namespace: ingress-nginx
spec:
  endpoints:
  - port: metrics
    interval: 15s
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx

建议重点关注这些指标:

  • nginx_ingress_controller_requests:请求量
  • nginx_ingress_controller_request_duration_seconds:延迟
  • nginx_ingress_controller_nginx_process_requests_total:Nginx处理请求数

5.3 安全加固措施

最后分享几个安全小技巧:

  1. 禁用不必要的HTTP方法:
nginx.ingress.kubernetes.io/configuration-snippet: |
  if ($request_method !~ ^(GET|HEAD|POST)$ ) {
    return 405;
  }
  1. 防止DDoS攻击的限速配置:
nginx.ingress.kubernetes.io/limit-rpm: "100"
  1. 启用CSP安全策略:
nginx.ingress.kubernetes.io/server-snippet: |
  add_header Content-Security-Policy "default-src 'self';";

这些配置我都用在实际生产环境中,有效拦截了不少恶意请求。特别是限速功能,在促销活动期间帮了大忙。

更多推荐