关于云计算:Nginx-Ingress-on-TKE-部署最佳实践

9次阅读

共计 6025 个字符,预计需要花费 16 分钟才能阅读完成。

概述

开源的 Ingress Controller 的实现使用量最大的莫过于 Nginx Ingress 了,功能强大且性能极高。Nginx Ingress 有多种部署形式,本文将介绍 Nginx Ingress 在 TKE 上的一些部署计划,这几种计划的原理、各自优缺点以及一些选型和应用上的倡议。

Nginx Ingress 介绍

在介绍如何部署 Nginx Ingress 之前,咱们先简略理解下什么是 Nginx Ingress。

Nginx Ingress 是 Kubernetes Ingress 的一种实现,它通过 watch Kubernetes 集群的 Ingress 资源,将 Ingress 规定转换成 Nginx 的配置,而后让 Nginx 来进行 7 层的流量转发:

理论 Nginx Ingress 有两种实现:

  1. https://github.com/kubernetes…
  2. https://github.com/nginxinc/k…

第一种是 Kubernetes 开源社区的实现,第二种是 Nginx 官网的实现,咱们通常用的是 Kubernetes 社区的实现,这也是本文所关注的重点。

TKE 上 Nginx Ingress 部署计划

那么如何在 TKE 上部署 Nginx Ingress 呢?次要有三种计划,上面别离介绍下这几种计划及其部署办法。

计划一:Deployment + LB

在 TKE 上部署 Nginx Ingress 最简略的形式就是将 Nginx Ingress Controller 以 Deployment 的形式部署,并且为其创立 LoadBalancer 类型的 Service(能够是主动创立 CLB 也能够是绑定已有 CLB),这样就能够让 CLB 接管内部流量,而后转发到 Nginx Ingress 外部:

以后 TKE 上 LoadBalancer 类型的 Service 默认实现是基于 NodePort,CLB 会绑定各节点的 NodePort 作为后端 rs,将流量转发到节点的 NodePort,而后节点上再通过 Iptables 或 IPVS 将申请路由到 Service 对应的后端 Pod,这里的 Pod 就是 Nginx Ingress Controller 的 Pod。后续如果有节点的增删,CLB 也会自动更新节点 NodePort 的绑定。

这是最简略的一种形式,能够间接通过上面命令装置:

kubectl create ns nginx-ingresskubectl apply -f https://raw.githubusercontent.com/TencentCloudContainerTeam/manifest/master/nginx-ingress/nginx-ingress-deployment.yaml -n nginx-ingress

计划二:Daemonset + HostNetwork + LB

计划一尽管简略,然而流量会通过一层 NodePort,会多一层转发。这种形式有一些毛病:

  1. 转发门路较长,流量到了 NodePort 还会再通过 Kubernetes 外部负载平衡,通过 Iptables 或 IPVS 转发到 Nginx,会减少一点网络耗时。
  2. 通过 NodePort 必然产生 SNAT,如果流量过于集中容易导致源端口耗尽或者 conntrack 插入抵触导致丢包,引发局部流量异样。
  3. 每个节点的 NodePort 也充当一个负载均衡器,CLB 如果绑定大量节点的 NodePort,负载平衡的状态就扩散在每个节点上,容易导致全局负载不均。
  4. CLB 会对 NodePort 进行衰弱探测,探测包最终会被转发到 Nginx Ingress 的 Pod,如果 CLB 绑定的节点多,Nginx Ingress 的 Pod 少,会导致探测包对 Nginx Ingress 造成较大的压力。

咱们能够让 Nginx Ingress 应用 hostNetwork,CLB 间接绑节点 IP + 端口(80,443),这样就不必走 NodePort;因为应用 hostNetwork,Nginx Ingress 的 pod 就不能被调度到同一节点防止端口监听抵触。通常做法是提前布局好,选取局部节点作为边缘节点,专门用于部署 Nginx Ingress,为这些节点打上 label,而后 Nginx Ingress 以 DaemonSet 形式部署在这些节点上。上面是架构图:

装置步骤:

  1. 将布局好的用于部署 Nginx Ingress 的节点打上 label: kubectl label node 10.0.0.3 nginx-ingress=true(留神替换节点名称)。
  2. 将 Nginx Ingress 部署在这些节点上:

    kubectl create ns nginx-ingresskubectl apply -f https://raw.githubusercontent.com/TencentCloudContainerTeam/manifest/master/nginx-ingress/nginx-ingress-daemonset-hostnetwork.yaml -n nginx-ingress
  3. 手动创立 CLB,创立 80 和 443 端口的 TCP 监听器,别离绑定部署了 Nginx Ingress 的这些节点的 80 和 443 端口。

计划三:Deployment + LB 直通 Pod

计划二尽管相比计划一有一些劣势,但同时也引入了手动保护 CLB 和 Nginx Ingress 节点的运维老本,须要提前布局好 Nginx Ingress 的节点,增删 Nginx Ingress 节点时须要手动在 CLB 控制台绑定和解绑节点,也无奈反对主动扩缩容。
如果你的网络模式是 VPC-CNI,那么所有的 Pod 都应用的弹性网卡,弹性网卡的 Pod 是反对 CLB 间接绑 Pod 的,能够绕过 NodePort,并且不必手动治理 CLB,反对主动扩缩容:

如果你的网络模式是 Global Router(大多集群都是这种模式),你能够为集群开启 VPC-CNI 的反对,即两种网络模式混用,在集群信息页可关上:

确保集群反对 VPC-CNI 之后,能够应用上面命令装置 Nginx Ingress:

kubectl create ns nginx-ingresskubectl apply -f https://raw.githubusercontent.com/TencentCloudContainerTeam/manifest/master/nginx-ingress/nginx-ingress-deployment-eni.yaml -n nginx-ingress

部署计划选型倡议

后面介绍了 Nginx Ingress 在 TKE 上部署的三种计划,也说了各种计划的优缺点,这里做一个简略汇总下,给出一些选型倡议:

  1. 计划一较为简单通用,但在大规模和高并发场景可能有一点性能问题。如果对性能要求不那么严格,能够思考应用这种计划。
  2. 计划二应用 hostNetwork 性能好,但须要手动保护 CLB 和 Nginx Ingress 节点,也无奈实现主动扩缩容,通常不太倡议用这种计划。
  3. 计划三性能好,而且不须要手动保护 CLB,是最现实的计划。它须要集群反对 VPC-CNI,如果你的集群自身用的 VPC-CNI 网络插件,或者用的 Global Router 网络插件并开启了 VPC-CNI 的反对(两种模式混用),那么倡议间接应用这种计划。

常见问题

如何反对内网 Ingress ?

计划二因为是手动治理 CLB,自行创立 CLB 时能够抉择用公网还是内网;计划一和计划三默认会创立公网 CLB,如果要用内网,能够改下部署 YAML,给 nginx-ingress-controller 这个 Service 加一个 key 为 service.kubernetes.io/qcloud-loadbalancer-internal-subnetid,value 为内网 CLB 所被创立的子网 id 的 annotation,示例:

apiVersion: v1
kind: Service
metadata:
  annotations:
    service.kubernetes.io/qcloud-loadbalancer-internal-subnetid: subnet-xxxxxx # value 替换为集群所在 vpc 的其中一个子网 id
  labels:
    app: nginx-ingress
    component: controller
  name: nginx-ingress-controller

如何复用已有 LB ?

计划一和计划三默认会主动创立新的 CLB,Ingress 的流量入口地址取决于新创建进去的 CLB 的 IP 地址。如果业务对入口地址有依赖,比方配置了 DNS 解析到之前的 CLB IP,不心愿切换 IP;或者想应用包年包月的 CLB (默认创立是按量计费),那么也能够让 Nginx Ingress 绑定已有的 CLB。

操作方法同样也是批改下部署 yaml,给 nginx-ingress-controller 这个 Service 加一个 key 为 service.kubernetes.io/tke-existed-lbid,value 为 CLB ID 的 annotation,示例:

apiVersion: v1
kind: Service
metadata:
  annotations:
    service.kubernetes.io/tke-existed-lbid: lb-6swtxxxx # value 替换为 CLB 的 ID
  labels:
    app: nginx-ingress
    component: controller
  name: nginx-ingress-controller

Nginx Ingress 公网带宽有多大?

有同学可能会问:我的 Nginx Ingress 的公网带宽到底有多大?是否支撑住我服务的并发量?

这里须要遍及一下,腾讯云账号有带宽上移和非带宽上移两种类型:

  1. 非带宽上移,是指带宽在云主机 (CVM) 上治理。
  2. 带宽上移,是指带宽上移到了 CLB 或 IP 上治理。

具体来讲,如果你的账号是非带宽上移类型,Nginx Ingress 应用公网 CLB,那么 Nginx Ingress 的公网带宽是 CLB 所绑定的 TKE 节点的带宽之和;如果应用计划三,CLB 直通 Pod,也就是 CLB 不是间接绑的 TKE 节点,而是弹性网卡,那么此时 Nginx Ingress 的公网带宽是所有 Nginx Ingress Controller Pod 被调度到的节点上的带宽之和。

如果你的账号是带宽上移类型就简略了,Nginx Ingress 的带宽就等于你所购买的 CLB 的带宽,默认是 10Mbps (按量计费),你能够按需调整下。

因为历史遗留起因,以前注册的账号大多是非带宽上移类型,参考文档 辨别腾讯云账户类型 来辨别本人账号的类型。

如何创立 Ingress ?

目前还没有实现对 Nginx Ingress 的产品化反对,所以如果是在 TKE 上自行了部署 Nginx Ingress,想要应用 Nginx Ingress 来治理 Ingress,目前是无奈通过在 TKE 控制台(网页) 上进行操作的,只有通过 YAML 的形式来创立,并且须要给每个 Ingress 都指定 Ingress Class 的 annotation,示例:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    kubernetes.io/ingress.class: nginx # 这里是重点
spec:
  rules:
  - host: *
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-v1
          servicePort: 80

如何监控?

通过下面的办法装置的 Nginx Ingress,曾经裸露了 metrics 端口,能够被 Prometheus 采集。如果集群内装置了 prometheus-operator,能够应用上面的 ServiceMonitor 来采集 Nginx Ingress 的监控数据:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: nginx-ingress-controller
  namespace: nginx-ingress
  labels:
    app: nginx-ingress
    component: controller
spec:
  endpoints:
  - port: metrics
    interval: 10s
  namespaceSelector:
    matchNames:
    - nginx-ingress
  selector:
    matchLabels:
      app: nginx-ingress
      component: controller

这里也给个原生 Prometheus 配置的示例:

    - job_name: nginx-ingress
      scrape_interval: 5s
      kubernetes_sd_configs:
      - role: endpoints
        namespaces:
          names:
          - nginx-ingress
      relabel_configs:
      - action: keep
        source_labels:
        - __meta_kubernetes_service_label_app
        - __meta_kubernetes_service_label_component
        regex: nginx-ingress;controller
      - action: keep
        source_labels:
        - __meta_kubernetes_endpoint_port_name
        regex: metrics

有了数据后,咱们再给 grafana 配置一下面板来展现数据,Nginx Ingress 社区提供了面板:https://github.com/kubernetes…

咱们间接复制 json 导入到 grafana 即可导入面板。其中,nginx.json 是展现 Nginx Ingress 各种惯例监控的面板:

request-handling-performance.json 是展现 Nginx Ingress 性能方面的监控面板:

总结

本文梳理了 Nginx Ingress 在 TKE 上部署的三种计划以及许多实用的倡议,对于想要在 TKE 上应用 Nginx Ingress 的同学是一个很好的参考。因为 Nginx Ingress 的应用需求量较大,咱们也正在做 Nginx Ingress 的产品化反对,能够实现一键部署,集成日志和监控能力,并且会对其进行性能优化。置信在不久的未来,咱们就可能在 TKE 上更简略高效的应用 Nginx Ingress 了,敬请期待吧!

参考资料

  1. TKE Service YAML 示例: https://cloud.tencent.com/doc…
  2. TKE Service 应用已有 CLB: https://cloud.tencent.com/doc…
  3. 辨别腾讯云账户类型: https://cloud.tencent.com/doc…

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!

正文完
 0