使用NGINX Plus负载均衡Kubernetes服务

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 本文讲的是使用NGINX Plus负载均衡Kubernetes服务,【编者的话】此篇文章是Nginx的Michael Pleshakov发表在Nginx官方博客的一篇博文,通过这篇文章概括回顾了Kubernetes暴露服务相关的解决方案,并对最新的Ingreess API进行了说明,最后给出了Kubernetes通过集成NGINX Plus来暴露服务到互联网的解决方案。
本文讲的是使用NGINX Plus负载均衡Kubernetes服务 【编者的话】此篇文章是Nginx的Michael Pleshakov发表在Nginx官方博客的一篇博文,通过这篇文章概括回顾了Kubernetes暴露服务相关的解决方案,并对最新的Ingreess API进行了说明,最后给出了Kubernetes通过集成NGINX Plus来暴露服务到互联网的解决方案。这个方案解决了目前Kubernetes暴露服务的短板,整个实现过程也比较简单,步骤清晰,具有很强的参考性。我们华三目前也在调研这方面的工作,希望此文能对大家有所帮助。

Kubernetes是由谷歌开发的一个开源系统,用于在集群内运行和管理以容器微服务为基础的应用。使用Kubernetes的人经常需要确保可以从Kubernetes集群外部访问在Kubernetes内创建的服务。

虽然 Kubernetes 提供了内置暴露服务解决方案,正像在下面 Kubernetes内置暴露服务解决方案 中所描述的,这些解决方案会局限你在4层负载均衡或循环HTTP负载平衡。

这篇文章会告诉你如何使用 NGINX Plus 作为高级7层负载均衡解决方案,用于暴露Kubernetes服务到互联网上,无论你是在云服务还是在自有基础设施上运行Kubernetes。

我们假定你对Kubernetes有所了解(pods, services, replication controllers, and labels)并且有一个运行的Kubernetes集群。要了解更多Kubernetes,请访问官方 Kubernetes用户指南

Kubernetes内置暴露服务解决方案

Kubernetes为暴露 服务 提供了多种选择。其中两种是NodePort和负载平衡器,分别对应不同类型的服务。Ingress API在Kubernetes1.1版本开始作为beta测试版供使用,已经成为第三种选择。

NodePort

指定服务类型为 NodePort ,会使得服务在每个Kubernetes节点上在相同的端口可用。为了暴露服务到互联网,你在这个端口上暴露一个或多个节点。为了高可用性,你可以暴露多个节点并使用基于DNS的负载均衡在它们中分布流量,或者你把这些节点放在你选择的负载均衡后。

当传入流量访问端口的一个节点时,它会被在服务的pods之间负载平衡。负载平衡由每个节点上的 Kubernetes代理 完成,并且仅限于TCP/UDP负载均衡。

LoadBalancer

指定服务类型为 负载平衡 会分配用于在服务pods之间分布传入流量的云负载平衡器。

只有特定的云服务供应商和 Google Container Engineand 支持负载均衡器解决方案,如果你在你自己的基础设施上运行Kubernetes,它是不可用的。此外,Kubernetes只允许你配置循环TCP负载均衡,即使云负载均衡器有高级功能,例如会话持久或请求映射。

Ingress API

创建 Ingress 资源使得你可以通过自定义URL(例如,服务A在URL /foo和服务B在URL /bar)和多个虚拟主机名(例如,一组服务是foo.example.com而另一组服务是bar.example.com)暴露服务到互联网。Ingress控制器依赖Ingress资源并建立一个外部负载平衡器。

Ingress控制器不是Kubernetes标准部署的一部分:你需要选择最适合你的控制器或自己实现一个,并把它添加到你的Kubernetes集群。预计很快会出现各种各样的控制器,但目前唯一可用的还是 Google Compute Engine HTTP负载平衡控制器 ,而且是只有当你在 Google Compute Engine 或者 Google Container Engine 中运行Kubernetes时。Ingress API仅支持循环HTTP负载均衡,即使实际负载均衡器支持高级功能。

在撰写本文时,无论是Ingress API还是Google Compute Engine HTTP Load Balancer控制器都还在测试阶段。

尽管上面提到的解决方案配置简单并且马上就可以使用,他们没有提供任何高级功能,特别是7层负载均衡相关的功能。

使用NGINX Plus暴露Kubernetes服务

为了集成NGINX Plus到Kubernetes上,我们需要确保NGINX Plus配置与Kubernetes保持同步,可以反映像pods添加或删除这样的Kubernetes服务变更。 使用开源的NGINX软件,你需要手动修改NGINX配置文件并重新加载配置。使用NGINX Plus,有两种方法 动态 更新配置:
  • With APIs – 此方法使用NGINX Plus的on-the-fly reconfiguration API 添加和删除Kubernetes pods在NGINX Plus配置中的条目,并使用Kubernetes API来获取pods的IP地址。这种方法需要我们写一些代码,这里我们也不进行深入讨论。有关详细信息,可以看Kelsey Hightower的网络研讨会,Bringing Kubernetes to the Edge with NGINX Plus,他在其中探讨了API并新建了利用他们的应用。
  • 通过重新解析DNS名称 -这个方法像在以下章节描述的一样仅仅需要对NGINX Plus的一次恰当配置。

Utilizing DNS-Based Reconfiguration

我们假设你已经有一个正在运行的Kubernetes集群并有一个可以使用kubectl工具的主机用于管理集群;有关说明,请参阅有关你群集类型的 Kubernetes入门指南 。你还需要编译一个NGINX Plus容器镜像,创建的命令就在这篇 博客文章

下面是我们怎么做的一个概括:
  1. 配置一个NGINX Plus pod用于暴露和负载均衡我们在步骤2中创建的服务。
  2. 创建一个提供静态网页的简单服务,。
  3. 扩展或者缩减服务,查看NGINX Plus如何自动重新配置。 > 注:我们使用运行在Google Compute Engine的Kubernetes 1.0.6版本测试了这个博客所描述的解决方案,而我们下面使用的是一个本地配置的Vagrant
    在命令的斜体字中,你Kubernetes设置中的值可能不同。

配置 NGINX Plus Pod

我们把NGINX Plus放在要暴露到互联网节点的Kubernetes pod内。我们的pod通过复制控制器创建,我们同样进行配置。我们Kubernetes相关的NGINX Plus配置文件放在NGINX Plus pod和节点的共享目录内,这样更加方便维护。

选择运行NGINX Plus Pod的节点

为了指定NGINX Plus pod运行的节点,我们添加一个标签到该节点。运行下面命令,查询运行的所有节点列表:
$ kubectl get nodes NAME LABELS STATUS
10.245.1.3 Kubernetes.io/hostname=10.245.1.3 Ready
10.245.1.4 Kubernetes.io/hostname=10.245.1.4 Ready
10.245.1.5 Kubernetes.io/hostname=10.245.1.5 Ready


我们选择第一个节点,并通过下面命令添加一个标签给它:
$ kubectl label node 10.245.1.3 role=nginxplus

为NGINX Plus Pod配置Replication Controller

我们不会直接创建NGINX Plus pod而是通过复制控制器。我们在Kubernetes的nginxplus-rc.yaml文件配置NGINX Plus pod 复制控制器。
  • 我们设置replicas的数量是1,就是说Kubernetes会确保始终有1个NGINX Plus pod在运行:如果pod出现故障,它会被新的pod替换。
  • 在nodeSelector处我们指定NGINX Plus pod在标记角色: nginxplus的节点上创建。
  • 我们的NGINX Plus容器暴露两个端口,80和8080,并且我们配置他们与节点端口80和8080之间的映射。
  • 我们的NGINX Plus容器共享节点的/etc/nginx/conf.d文件夹。作为下面配置NGINX Plus的进一步解释,共享文件夹让我们可以不用重建容器镜像而重新配置NGINX Plus。

apiVersion: v1
kind: ReplicationController
metadata:
name: nginxplus-rc
spec:
replicas: 1
selector:
app: nginxplus
template:
metadata:
  labels:
    app: nginxplus
spec:
  nodeSelector:
    role: nginxplus
  containers:
  - name: nginxplus
    image: nginxplus
    ports:
      - name: http
        containerPort: 80
        hostPort: 80
      - name: http-alt
        containerPort: 8080
        hostPort: 8080
    volumeMounts:
      - mountPath: "/etc/nginx/conf.d"
        name: etc-nginx-confd
  volumes:
    - hostPath:
        path: "/etc/nginx/conf.d"
      name: etc-nginx-confd

使NGINX Plus Docker Image可用

正如我们上面所说,我们已经建立了一个NGINX Plus Docker镜像。 现在我们让它可用。为简单起见,我们不使用私有Docker repository,我们只是手动加载镜像。

在我们编译Docker镜像的主机上,运行以下命令将镜像保存成文件:
$ docker save -o nginxplus.tar nginxplus

我们把nginxplus.tar传送到节点,运行以下命令从文件加载镜像:
$ docker load -i nginxplus.tar

配置NGINX Plus

在NGINX Plus容器的/etc/nginx文件夹中,我们保留随NGINX Plus包默认的主nginx.conf中的配置文件。 在默认文夹include指令读取来自/etc/nginx/conf.d文件夹中的其他配置文件。正向在NGINX Plus复制控制器文件(nginxplus-rc.yaml)中表明的一样,我们与NGINX Plus节点上的容器共享/etc/nginx/conf.d文件夹。 共享意味着我们可以修改存储在文件夹(节点上)中的配置文件,而无需重建NGINX Plus容器镜像,而如果我们直接在容器中创建的文件夹这是我们必须做的。我们把我们的Kubernetes特定配置文件(backend.conf)放在共享目录。

首先,让我们创建/etc/nginx/conf.d文件夹。
$ mkdir /etc/nginx/conf.d

然后,我们创建backend.conf文件,其中包括以下指令:
  • resolver -定义Kubernetes DNS解析的IP地址,使用默认的IP地址,10.0.0.10。valid参数告诉NGINX Plus每五秒钟解析所有DNS名称。 您的Kubernetes DNS服务IP地址可能会有所不同。运行此命令查看: $ kubectl get svc kube-dns --namespace=kube-system
  • upstream -创建一个名为后端的Kubernetes服务,我们揭露上游组。我们确定了服务器在上游组主机名,包括了resolve指令告诉NGINX重新解析主机名在运行时。
  • server (两次) -定义两个虚拟服务器:
  • 第一个服务器监听端口80并且负载均衡在我们服务pods中的/nginx-service传入请求。我们还配置积极的健康检查 。
  • 第二个服务器监听端口8080。这里的我们成立了现场活动的监控NGINX Plus。稍后我们将用它来检查 NGINX Plus 是否被正确地重新配置。

resolver 10.0.0.10 valid=5s;

upstream backend {
zone upstream-backend 64k;
server nginx-service.default.svc.cluster.local resolve;
}

server {
listen 80;

status_zone backend-servers;

location /nginx-service/ {
    proxy_pass http://backend/;
    health_check;
}
}

server {
listen 8080;

root /usr/share/nginx/html;

location = /status.html { }

location /status {
    status;
}
}

创建Replication Controller

现在,我们已经准备好在我们的节点上运行此命令创建复制器:
$ kubectl create -f nginxplus-rc.yaml

为了验证创建NGINX Plus pod,运行:
$ kubectl get pods NAME READY STATUS RESTARTS AGE
nginxplus-rc-0ts5t 1/1 Running 0 17s


我们在本地Vagrant 设定运行Kubernetes,所以我们知道,我们的节点的外部IP地址为10.245.1.3,在这个例子中的剩下部分我们将使用该地址。如果你在一个云服务提供商运行Kubernetes,您可以通过运行下面命令得到您节点的外部IP地址:
$ kubectl get nodes node-name -o json | grep -i externalIP -A 1
            "type": "ExternalIP",
            "address": XXX.XXX.XXX.XXX

如果您在云服务中运行,别忘了设置防火墙规则允许NGINX Plus节点接收传入的流量。请参阅您的云服务提供商文档。

通过查看NGINX Plus实时活动监控仪表板可以检查我们的NGINXPlus pod是否 起来并运行了,它节点的外部IP地址在端口8080上是否可用(在我们的例子中是 http://10.245.1.3:8080/status.html )。 如果我们这时候访问,不过我们是看不到我们服务的任何服务器,因为我们还没有创建它。

创建一个简单Kubernetes Service

现在是时候创建Kubernetes服务了。我们的服务包括两个(开源)NGINX 服务器提供静态web页面。

为服务创建Replication Controller

首先,我们创建一个Replication Controller,这样Kubernetes会确保指定数量的NGINX Web服务器副本(pods)始终在群集中运行。以下是声明文件(nginx-rc.yaml):
apiVersion: v1 kind: ReplicationController
metadata:
name: nginx-rc
spec:
replicas: 2
selector:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80


我们的控制器由两个NGINX Web服务器组成。我们声明一个控制器包含单个NGINX容器pods用于暴露端口80。Nginx的镜像将从Docker Hub下载。

要创建复制控制器,我们运行以下命令:
$ kubectl create -f nginx-rc.yaml

要检查是否已创建pods,我们可以运行下面的命令。我们使用标签选择app=nginx获得仅在上一步的replication controller中创建的pods:
$ kubectl get pods -l app=nginx NAME READY STATUS RESTARTS AGE
nginx-rc-544f1 1/1 Running 0 2m
nginx-rc-uk6pm 1/1 Running 0 2m

创建Service

接下来,我们为replication controller创建的pods创建服务。我们使用下列文件(nginx-service.yaml)创建服务:
apiVersion: v1 kind: Service
metadata:
name: nginx-service
spec:
ClusterIP: None
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: nginx


这里我们通过设置ClusterIP字段为None来声明一个特殊的 headless service 。通过这类服务,不会分配集群的IP地址并且通过kube代理也无法使用服务。DNS查询Kubernetes DNS会返回多个A记录(我们pods的IP地址)。

通过设置selector field为app: nginx,我们声明该pods属于服务,即使用NGINX replication controller 创建的pods(在nginx-rc.yaml中定义)。

我们运行下面的命令创建服务:
$ kubectl create -f nginx-service.yaml

现在,如果我们刷新仪表盘页面,并单击右上角的Upstreams tab,我们可以看到新加的两台服务器。
11.png

我们还可以检查NGINX Plus是否已经在pods的服务间负载均衡流量。如果是,当我们在浏览器中访问 http://10.245.1.3/nginx-service/ 时,我们可以看到默认NGINX的欢迎页面。
22.png

如果我们刷新此页面几次,并查看仪表盘状态,我们可以看到请求是如何分布在两个上游服务器上的。

扩展Kubernetes服务

现在,让我们再添加两个pods到我们的服务并确保NGINX Plus配置会再次自动更新。我们运行此命令扩展replication controller 把pods数量更改为4:
$ kubectl scale rc nginx-rc --replicas=4 scaled

要检查NGINX Plus是否重新配置,我们可以再查看仪表盘,但这次我们使用NGINX Plus状态的API来替代。在我们的节点运行下面的命令,10.245.1.3是我们的NGINX Plus节点外部IP地址。为了格式化JSON输出,我们管道输出到 jq

$ curl -s 10.245.1.3:8080/status/upstreams/backend | jq .
{
"peers": [
{
  "id": 1,
  "server": "10.0.0.1:80",
  "backup": false,
  "weight": 1,
  "state": "unhealthy",
  "active": 0,
  "requests": 1,
  "responses": {
    "1xx": 0,
    "2xx": 0,
    "3xx": 0,
    "4xx": 0,
    "5xx": 0,
    "total": 0
  },
  "sent": 0,
  "received": 0,
  "fails": 0,
  "unavail": 0,
  "health_checks": {
    "checks": 1,
    "fails": 1,
    "unhealthy": 1,
    "last_passed": false
  },
  "downtime": 33965,
  "downstart": 1445378182275,
  "selected": 1445378131000
},
{
  "id": 2,
  "server": "10.246.1.6:80",
  ...
},
{
  "id": 3,
  "server": "10.246.3.2:80",
   ...
{
  "id": 4,
  "server": "10.0.0.2:80",
  ...
}
],
"keepalive": 0
}

在peers中的JSON输出数组正好有四个元素,对应每个NGINX Web服务器。

现在,让我们减少pods的数量从4到1,再次检查NGINX Plus状态:
$ kubectl scale rc nginx-rc --replicas=1 scaled

$ curl -s 10.245.1.3:8080/status/upstreams/backend | jq .

现在peers中的JSON输出数组只包含一个元素。

现在,我们已经把NGINX Plus运行起来,我们就可以开始利用其高级功能,如 会话持久性 SSL终止 请求路由 高级监控 更多

总结

NGINX Plus的on-the-fly reconfiguration让你的Kubernetes集成更轻松:不管是通过API编程还是完全使用DNS的方式。使用NGINX Plus暴露Kubernetes服务到互联网提供了许多当前Kubernetes内置负载均衡解决方案缺乏的功能。

原文链接:Load Balancing Kubernetes Services with NGINX Plus (翻译:朱高校)

原文发布时间为: 2016-01-14
本文作者:zhugaoxiao
本文来自云栖社区合作伙伴DockerOne,了解相关信息可以关注DockerOne。
原文标题:使用NGINX Plus负载均衡Kubernetes服务
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
7天前
|
弹性计算 监控 负载均衡
|
7天前
|
运维 负载均衡 算法
|
30天前
|
Prometheus Kubernetes 监控
k8s部署针对外部服务器的prometheus服务
通过上述步骤,您不仅成功地在Kubernetes集群内部署了Prometheus,还实现了对集群外服务器的有效监控。理解并实施网络配置是关键,确保监控数据的准确无误传输。随着监控需求的增长,您还可以进一步探索Prometheus生态中的其他组件,如Alertmanager、Grafana等,以构建完整的监控与报警体系。
116 60
|
1月前
|
Prometheus Kubernetes 监控
k8s部署针对外部服务器的prometheus服务
通过上述步骤,您不仅成功地在Kubernetes集群内部署了Prometheus,还实现了对集群外服务器的有效监控。理解并实施网络配置是关键,确保监控数据的准确无误传输。随着监控需求的增长,您还可以进一步探索Prometheus生态中的其他组件,如Alertmanager、Grafana等,以构建完整的监控与报警体系。
181 62
|
1月前
|
Kubernetes 应用服务中间件 nginx
k8s学习--YAML资源清单文件托管服务nginx
k8s学习--YAML资源清单文件托管服务nginx
k8s学习--YAML资源清单文件托管服务nginx
|
1月前
|
Kubernetes 监控 测试技术
k8s学习--基于Ingress-nginx实现灰度发布系统
k8s学习--基于Ingress-nginx实现灰度发布系统
k8s学习--基于Ingress-nginx实现灰度发布系统
|
1月前
|
Prometheus Kubernetes 监控
k8s学习--kubernetes服务自动伸缩之水平伸缩(pod副本伸缩)HPA详细解释与案例应用
k8s学习--kubernetes服务自动伸缩之水平伸缩(pod副本伸缩)HPA详细解释与案例应用
k8s学习--kubernetes服务自动伸缩之水平伸缩(pod副本伸缩)HPA详细解释与案例应用
|
1月前
|
Kubernetes 负载均衡 网络协议
在K8S中,负载均衡器有何作用?
在K8S中,负载均衡器有何作用?
|
1月前
|
负载均衡 Kubernetes 区块链
随机密码生成器+阿里k8s负载均衡型服务加证书方法+移动终端设计+ico生成器等
随机密码生成器+阿里k8s负载均衡型服务加证书方法+移动终端设计+ico生成器等
48 1
|
1月前
|
Kubernetes 应用服务中间件 nginx
k8s学习--kubernetes服务自动伸缩之水平收缩(pod副本收缩)VPA策略应用案例
k8s学习--kubernetes服务自动伸缩之水平收缩(pod副本收缩)VPA策略应用案例
下一篇
无影云桌面