WEBKT

K8s Ingress Controller 深度解析:原理、配置与流量管理实战

566 0 0 0

作为一名后端开发,你肯定遇到过这样的场景:辛辛苦苦用 K8s 部署了一堆服务,结果外部用户根本访问不到!这时候,Ingress Controller 就如同救星般出现,帮你打通 K8s 集群与外部世界的桥梁。今天,咱们就来深入聊聊 Ingress Controller,从原理到配置,再到实际应用,让你彻底掌握它。

什么是 Ingress?它和 Ingress Controller 有什么关系?

首先,我们要搞清楚 Ingress 和 Ingress Controller 之间的关系。Ingress 就像一张路由规则表,它定义了外部请求如何转发到 K8s 集群内部的服务。而 Ingress Controller 则是这张表的执行者,它负责监听 Ingress 规则的变化,并根据这些规则配置底层的负载均衡器,从而实现流量的转发。

你可以把 Ingress 比作交通规则,Ingress Controller 比作交警。交通规则定义了车辆行驶的路线,而交警则负责指挥交通,确保车辆按照规则行驶。

简单来说:

  • Ingress: 定义流量如何进入集群的规则。
  • Ingress Controller: 实现这些规则的具体组件。

没有 Ingress Controller,Ingress 规则就只是一堆 YAML 文件,没有任何实际作用。只有部署了 Ingress Controller,Ingress 规则才能生效,外部流量才能正确地路由到 K8s 集群内部的服务。

为什么要使用 Ingress Controller?

你可能会问,K8s 不是已经有 Service 了吗?为什么还需要 Ingress Controller 呢?

Service 主要用于集群内部的服务发现和负载均衡。如果你想让外部流量访问到你的服务,通常需要将 Service 的类型设置为 LoadBalancerNodePort。但是,这两种方式都有一些缺点:

  • LoadBalancer: 每创建一个 LoadBalancer 类型的 Service,K8s 都会向云服务商申请一个负载均衡器。这会增加你的成本,而且负载均衡器的数量是有限制的。
  • NodePort: NodePort 会在每个 Node 节点上开放一个端口,外部流量可以通过 NodeIP:NodePort 的方式访问到你的服务。但是,这种方式不够灵活,而且暴露了 Node 节点的 IP 地址,存在安全风险。

而 Ingress Controller 可以很好地解决这些问题。它只需要一个外部负载均衡器,就可以管理多个 Service 的外部访问。你可以通过配置 Ingress 规则,将不同的域名或路径映射到不同的 Service 上。这样,你就可以用一个负载均衡器,对外提供多个服务,大大节省了成本。

此外,Ingress Controller 还提供了更多的功能,例如:

  • SSL termination: 在 Ingress Controller 上配置 SSL 证书,可以实现 HTTPS 加密,保护用户的数据安全。
  • Name-based virtual hosting: 可以根据不同的域名,将流量路由到不同的 Service 上。
  • Path-based routing: 可以根据不同的 URL 路径,将流量路由到不同的 Service 上。
  • Load balancing: 可以对后端服务进行负载均衡,提高服务的可用性和性能。

常见的 Ingress Controller 实现

目前有很多 Ingress Controller 的实现,常见的有:

  • NGINX Ingress Controller: 基于 Nginx,功能强大,配置灵活,社区活跃。
  • Traefik: 云原生 Ingress Controller,易于配置,支持自动发现。
  • HAProxy Ingress Controller: 基于 HAProxy,性能优异,稳定性高。
  • Contour: 基于 Envoy,高性能,可扩展,适用于大型集群。

选择哪个 Ingress Controller,取决于你的具体需求和技术栈。如果你对 Nginx 比较熟悉,可以选择 NGINX Ingress Controller。如果你追求易用性,可以选择 Traefik。如果你需要高性能和可扩展性,可以选择 Contour。

在本文中,我们将以 NGINX Ingress Controller 为例,介绍 Ingress Controller 的配置和使用。

NGINX Ingress Controller 的安装与配置

1. 安装 NGINX Ingress Controller

你可以通过 Helm 或 YAML 文件安装 NGINX Ingress Controller。这里我们以 Helm 为例:

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

这条命令会在你的 K8s 集群中安装 NGINX Ingress Controller。安装完成后,你可以通过以下命令查看 Ingress Controller 的状态:

kubectl get pods -n ingress-nginx

如果所有的 Pod 都处于 Running 状态,说明 Ingress Controller 已经成功安装。

2. 配置 Ingress 规则

接下来,我们需要创建一个 Ingress 规则,定义外部请求如何转发到 K8s 集群内部的服务。假设我们有两个 Service:web-appapi-server。我们希望将域名 example.com 上的流量,按照以下规则进行转发:

  • 访问 example.com/web 的流量,转发到 web-app Service。
  • 访问 example.com/api 的流量,转发到 api-server Service。

我们可以创建一个如下的 Ingress 规则:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: web-app
            port:
              number: 80
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-server
            port:
              number: 80

这个 YAML 文件定义了一个名为 my-ingress 的 Ingress 规则。rules 字段定义了流量转发的规则。host 字段指定了域名,paths 字段指定了 URL 路径。backend 字段指定了后端 Service 的名称和端口。

需要注意的是,nginx.ingress.kubernetes.io/rewrite-target: / 这个 annotation 的作用是将请求的 URL 路径重写为 /。这是因为我们的 web-appapi-server Service 可能只监听根路径 /。如果不进行重写,请求可能会因为找不到对应的路径而失败。

保存这个 YAML 文件,并使用以下命令创建 Ingress 规则:

kubectl apply -f my-ingress.yaml

3. 配置 DNS

最后,我们需要将域名 example.com 解析到 Ingress Controller 的外部 IP 地址。你可以通过以下命令获取 Ingress Controller 的外部 IP 地址:

kubectl get service -n ingress-nginx my-nginx-ingress-ingress-nginx-controller -o wide

找到 EXTERNAL-IP 字段,这就是 Ingress Controller 的外部 IP 地址。将域名 example.com 解析到这个 IP 地址,就可以通过域名访问你的服务了。

Ingress Controller 的高级用法

除了基本的流量转发功能,Ingress Controller 还提供了很多高级用法,可以满足更复杂的需求。

1. SSL Termination

如果你想使用 HTTPS 加密,可以在 Ingress Controller 上配置 SSL 证书。首先,你需要创建一个 Secret,存储 SSL 证书和私钥:

kubectl create secret tls my-tls-secret --key tls.key --cert tls.crt

然后,在 Ingress 规则中指定这个 Secret:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  tls:
  - hosts:
    - example.com
    secretName: my-tls-secret
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-app
            port:
              number: 80

tls 字段指定了 SSL 证书的配置。hosts 字段指定了域名,secretName 字段指定了存储 SSL 证书的 Secret 的名称。

2. Load Balancing

Ingress Controller 可以对后端服务进行负载均衡,提高服务的可用性和性能。NGINX Ingress Controller 提供了多种负载均衡算法,例如:

  • Round Robin: 轮询算法,将请求依次分配给后端服务。
  • Least Connections: 最少连接算法,将请求分配给连接数最少的后端服务。
  • IP Hash: IP 哈希算法,将来自同一个 IP 地址的请求分配给同一个后端服务。

你可以通过 annotation 配置负载均衡算法:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    nginx.ingress.kubernetes.io/upstream-hash-by: ip
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-app
            port:
              number: 80

nginx.ingress.kubernetes.io/upstream-hash-by: ip 这个 annotation 指定使用 IP 哈希算法进行负载均衡。

3. Canary Deployment

Ingress Controller 还可以用于实现灰度发布(Canary Deployment)。你可以将一部分流量转发到新版本的服务,观察新版本的运行情况。如果新版本运行稳定,可以将所有流量都切换到新版本。

你可以通过 annotation 配置灰度发布的权重:

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

nginx.ingress.kubernetes.io/canary: "true" 这个 annotation 启用灰度发布。nginx.ingress.kubernetes.io/canary-weight: "20" 这个 annotation 指定将 20% 的流量转发到新版本的服务。

总结

Ingress Controller 是 K8s 集群中非常重要的一个组件,它可以帮助你实现外部流量的接入和负载均衡。通过本文的介绍,相信你已经对 Ingress Controller 的原理、配置和高级用法有了深入的了解。在实际应用中,你可以根据自己的需求选择合适的 Ingress Controller 实现,并灵活配置 Ingress 规则,从而构建稳定、高效的 K8s 集群。

希望这篇文章能帮助你更好地理解和使用 K8s Ingress Controller。如果你有任何问题或建议,欢迎在评论区留言。

K8s探索者 K8sIngress ControllerKubernetes网络

评论点评