NGINX.COM
Web Server Load Balancing with NGINX Plus

如果您正在生产环境中使用 Kubernetes,那么很可能在使用 Ingress controller(Ingress 控制器)。Ingress controller 是管理 Kubernetes 集群进出流量的核心引擎。鉴于 Ingress controller 是部署在集群内运行的,应如何将流量路由到它呢?又应如何将外部流量路由到内部 Kubernetes Service 呢?

云提供商提供了一种简便的方法,使用外部负载均衡器暴露 Kubernetes Service。只需部署一个托管 Kubernetes Service(EKS、GKE、AKS)并创建一个 LoadBalancer 类型的 Kubernetes Service 即可。云提供商将托管并部署一个提供公共 IP 地址的负载均衡器后,外部用户可通过此公共入口点连接到 Kubernetes Service。

不过,该集成仅适用于云提供商托管的 Kubernetes Service。如果您在私有云/本地环境中部署 Kubernetes,则需部署自己的负载均衡器,并将其与 Kubernetes 集群相集成。此外,云端 Kubernetes 负载均衡集成仅限于 TCP 负载均衡,通常缺乏对指标、日志和链路追踪的可视化。

我们建议:

  • 采用与工作负载底层运行基础设施无关的解决方案
  • 容量规划指南,来避免高流量带来的瓶颈问题
  • 实现不仅限于基本 TCP/HTTP 负载均衡的应用交付用例

在下述解决方案中,我将 NGINX Plus 部署为 Kubernetes 的外部负载均衡服务,并将流量路由到 NGINX Ingress Controller。然后,NGINX Ingress Controller 会将流量路由到应用后端。NLK (NGINX Load Balancer for Kubernetes) 部署是一种新型 NGINX 控制器,可监控指定的 Kubernetes Service,并发送 API 调用以管理 NGINX 外部负载均衡器的上游端点。

在本文中,我将在 Kubernetes 集群和作为外部负载均衡器的 NGINX Plus 中部署组件。

注:我个人喜欢将 NLK 和 Kubernetes 集群部署在同一子网中,以避免出现网络问题。但这并非一项硬性要求

 

准备工作

本文假设您拥有 Kubernetes 环境操作经验。此外,您还需要:

  • Kubernetes 环境的访问权限;裸机、Rancher Kubernetes Engine (RKE)、VMWare Tanzu Kubernetes (VTK)、Amazon Elastic Kubernetes (EKS)、Google Kubernetes Engine (GKE)、Microsoft Azure Kubernetes Service (AKS) 及 RedHat OpenShift
  • NGINX Ingress Controller —— 在 Kubernetes 集群中部署 NGINX Ingress Controller。有关安装说明,请查阅文档
  • NGINX Plus —— 将 NGINX Plus 部署至具有 SSH 访问权限的虚拟机或裸机。这将是 Kubernetes 集群的外部负载均衡服务。安装说明可在文档中找到。您必须拥有 NGINX Plus 的有效许可,并可立即申请 30 天免费试用版

 

设置 Kubernetes 环境

首先部署后端应用。您可以部署自己的应用,也可以部署基本 café 应用,如本例所示。

$ kubectl apply –f cafe.yaml

现在,为 Ingress controller 配置路由和 TLS 设置

$ kubectl apply –f cafe-secret.yaml 

$ kubectl apply –f cafe-virtualserver.yaml

为了确保成功应用 Ingress 规则,请检查 kubectl get vs 的输出。

VirtualServer 定义应处于 Valid 状态。

NAMESPACE     NAME             STATE    HOST                         IP      PORTS   
default       cafe-vs          Valid    cafe.example.com

 

将 NGINX Plus 设置为外部负载均衡器

全新安装的 NGINX Plus 将在 /etc/nginx/conf.d 目录中提供 default.conf 文件。我们还需要将另外两个文件添加到此目录下。只需将下列文件复制到 /etc/nginx/conf.d 目录中即可

  • dashboard.conf;它将启用 NGINX Plus 的实时监控仪表盘
  • kube_lb.conf;该 nginx 配置充当 Kubernetes 的外部负载均衡器。您可以根据自己的需求更改配置文件。在本文中,我们为一个集群启用了基本路由和 TLS。

您还需要生成 TLS 证书/密钥,并将其放在 NGINX Plus 实例的 /etc/ssl/nginx 文件夹中。在本例中,我们将使用 openssl 生成自签名证书。  

$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout default.key -out default.crt -subj "/CN=NLK"

注:自签名证书仅供测试使用。在实际生产环境中,建议使用安全的 Vault 来保存密钥和受信任 CA(证书颁发机构)。

现在可以验证配置,然后重新加载 nginx 以使变更生效。

$ nginx –t
$ nginx –s reload

现在,我可以连接到 NGINX Plus 仪表盘,具体方法是打开浏览器并输入

http://<external-ip-nginx>:9000/dashboard.html#upstreams

 

HTTP upstream表应为空,因为我们尚未部署 NLK 控制器。

在下一节中,我们将进行 NLK 控制器的部署。  

 

安装 NLK 控制器

您可将 NLK Controller 安装为 Kubernetes 部署,后者将使用 NGINX Plus API 为外部负载均衡器配置 Upstream 端点。首先,创建 NLK 命名空间

$ kubectl create ns nlk 

将 RBAC 设置应用于 NKL 部署

$ kubectl apply -f serviceaccount.yaml 
$ kubectl apply -f clusterrole.yaml
$ kubectl apply -f clusterrolebinding.yaml
$ kubectl apply -f secret.yaml

下一步,创建一个 ConfigMap,定义 NGINX Plus 外部负载均衡器的 API 端点。NLK 控制器使用 API 端点来配置 NGINX Plus 上游端点。我们只需将 GitHub 仓库清单中的 nginx-hosts 字段修改为 NGINX 外部负载均衡器的 IP 地址即可。

nginx-hosts: 

    http://<nginx-plus-external-ip>:9000/api

应用更新的 ConfigMap,并部署 NLK 控制器

$ kubectl apply –f nkl-configmap.yaml 

$ kubectl apply –f nkl-deployment

现在可以验证 NLK 控制器部署是否正在运行,以及是否应用了 ConfigMap 数据。

$ kubectl get pods –o wide –n nlk 	
$ kubectl describe cm nginx-config –n nlk  

NLK 部署的状态应为 Running(运行中),nginx-hosts 下应该定义了 URL。URL 是外部负载均衡器的 NGINX Plus API 端点。现在,NKL 控制器已部署成功,外部负载均衡器可随时将流量路由到集群。

最后一步是部署 Kubernetes Service 类型 NodePort,以便将 Kubernetes 集群暴露给 NGINX Plus。

$ kubectl apply –f nodeport.yaml 

关于 NodePort Service 清单,以下几点需要注意。对于 NLK 部署,必须填写第 7 行和第 14 行的字段才能正确配置外部负载均衡器:

  • nginxinc.io/nklcluster 注解
  • 与 NGINX Plus 配置中 upstream 代码块定义相匹配的端口名称(参见 kube_lb.conf 中的第 42 行),以及前面的 nkl-
apiVersion: v1 
kind: Service 
metadata: 
  name: nginx-ingress 
  namespace: nginx-ingress 
  annotations: 
    nginxinc.io/nlk-cluster1-https: "http"   # 必须添加 
spec: 
  type: NodePort  
  ports: 
  - port: 443 
    targetPort: 443 
    protocol: TCP 
    name: nlk-cluster1-https 
  selector: 
    app: nginx-ingress  

 
应用服务后,您需要记下分配的节点端口,选择 NGINX Ingress Controller 部署。在本例中,节点端口为 32222。

$ kubectl get svc –o wide –n nginx-ingress
		
NAME            TYPE       CLUSTER-IP   PORT(S)          SELECTOR

nginx-ingress   NodePort   x.x.x.x      443:32222/TCP    app=nginx-ingress

如果重新连接到 NGINX Pus 仪表盘,则 upstream 选项卡中应填充 Kubernetes 集群的 worker 节点 IP,并与 nginx-ingress Service (32222) 的节点端口相匹配。

您可以列出集群的节点 IP,确保它们与仪表盘 upstream 选项卡中的 IP 匹配。

 $ kubectl get nodes -o wide | awk '{print $6}' 

INTERNAL-IP 

10.224.0.6 
10.224.0.5 
10.224.0.4

现在可以从本地计算机连接到 Kubernetes 应用了。我们示例中所用的主机名 (cafe.example.com) 应解析为 NGINX Plus 负载均衡器的 IP 地址。

 

结语

大多数在生产环境中部署 Kubernetes 的企业都会安装一个 Ingress controller。在 Kubernetes 等容器编排器中,它是公认的应用交付标准。现在,DevOps/NetOps 工程师正在寻求相关指导,以了解如何尽可能高效地扩展其 Kubernetes 部署。由于企业正在采用混合方法,因此需要在云提供商外部实现自己的集成。

我们提出的解决方案:

  • 适用于混合环境(尤其是本地环境)
  • 容量规划信息可避免大规模流量带来的瓶颈问题
  • 具有不仅限于 TCP 负载均衡服务的企业负载均衡功能

在本系列文章的下一篇,我将更详细地介绍第三点,并探讨 NGINX Plus 的零信任用例,帮助您增强混合模式的安全防护。

 

Hero image
免费白皮书:
NGINX 企阅版全解析

助力企业用户规避开源治理风险,应对开源使用挑战

关于作者

关于 F5 NGINX

F5, Inc. 是备受欢迎的开源软件 NGINX 背后的商业公司。我们为现代应用的开发和交付提供一整套技术。我们的联合解决方案弥合了 NetOps 和 DevOps 之间的横沟,提供从代码到用户的多云应用服务。访问 nginx-cn.net 了解更多相关信息。