使用Ingress来负载分发微服务 html
Demo规划 前端
准备Demo并完成部署 node
建立部署(Deployment)资源 nginx
建立服务(Service)资源 docker
建立Ingress资源并配置转发规则 编程
NodePort Service存在太多缺陷,不适合生产环境。LoadBlancer Service则不太灵活,好比针对微服务架构,那么不一样服务是否须要多个负载均衡服务呢?那么,咱们还有其余选择么?那就是Ingress。后端
Ingress将集群外部的HTTP和HTTPS路由暴露给集群中的Service,至关于集群的入口,而入口规则则由Ingress定义的规则来控制。在使用Ingress以前,咱们先须要有一个Ingress Controller(入口控制器),例如ingress-nginx。Ingress负责定义抽象的规则,而Ingress Controller负责具体实现。一般状况下,Ingress搭配负载均衡一块儿使用。接下来,笔者结合一个简单的微服务Demo来使用Ingress进行负载分发。因为须要使用到负载均衡服务,本教程使用腾讯云容器服务进行讲解。api
为了便于你们理解,咱们先作一个简单的规划。总体规划图以下所示:架构
如图所示,总体步骤以下所示:app
咱们须要开发两个应用,分别为apidemo1和apidemo2,并提供不一样的接口服务;
而后须要将两个应用分别部署到k8s集群,而且分别建立不一样的Service;
接下来,咱们须要建立Ingress,配置不一样的转发规则;
最后,为了访问方便,咱们须要配置域名映射。
如上所述,接下来咱们进入开发环节。
为了完成咱们上述的目标,咱们须要提供如下两个demo(不限编程语言):
apidemo1
以下图所示,apidemo1的访问路径为https://{hostname}:{port}/api/demo1,输出JSON“["value1","value2"]”。
注意:apidemo1和apidemo2均需支持80端口和443端口访问。
apidemo2
以下图所示,apidemo2的访问路径为https://{hostname}:{port}/api/demo2,输出JSON“["value3","value4"]”。
因为Demo比较简单,这里咱们就不贴代码了。Demo准备完成后,咱们须要推送docker镜像到目标仓储,而后建立部署(Deployment)以及服务(Service)。
整个过程在前面的章节咱们均有详细讲述,所以这里就不赘述了,这里咱们仅提供参考的YAML定义文件:
apiVersion: apps/v1beta2 #api版本 kind: Deployment #使用部署对象 metadata: labels: #标签列表 app: apidemo1 name: apidemo1 #部署名称 namespace: default #命名空间 spec: replicas: 1 #副本数 selector: #选择器 matchLabels: app: apidemo1 template: #Pod模板 metadata: labels: app: apidemo1 spec: containers: #容器列表 - env: #环境变量设置 - name: PATH value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - name: ASPNETCORE_URLS value: http://+:80 - name: DOTNET_RUNNING_IN_CONTAINER value: "true" - name: ASPNETCORE_VERSION value: 2.2.6 image: ccr.ccs.tencentyun.com/magicodes/apidemo1:latest #镜像地址 imagePullPolicy: Always #镜像拉取策略,Always表示老是拉取最新镜像,IfNotPresent表示若是本地存在则不拉取,Never则表示只使用本地镜像 name: apidemo1 #容器名称 resources: #资源限制 limits: #最高限制 cpu: 500m memory: 256Mi requests: #预分配 cpu: 250m memory: 64Mi workingDir: /app #工做目录 dnsPolicy: ClusterFirst #DNS策略 restartPolicy: Always #重启策略 terminationGracePeriodSeconds: 30 #删除须要时间
镜像是公开的,基于以上YAML定义,各位能够直接基于腾讯云的容器服务的【YAML建立资源】进行建立,步骤以下:
进入容器服务,选择已有集群进入
进入工做负载面板,选择【Deployment】,点击右上角的【YAML建立资源】按钮
贴入刚刚定义的YAML,以下图所示,而后点击建立
4.接下来,须要确保建立成功。咱们使用上述参考的YAML分别建立Deployment“apidemo1”和“apidemo2”以下图所示:
接下来,咱们来分别建立“apidemo1”和“apidemo2”Service资源。参考YAML以下所示:
apiVersion: v1 kind: Service #资源类型 metadata: name: apidemo1 #服务名称 namespace: default spec: ports: #端口列表 - name: tcp-80-80 nodePort: 31010 #节点端口 port: 80 #当前端口 protocol: TCP #协议 targetPort: 80 #目标端口 selector: #标签选择器 app: apidemo1 type: NodePort #NodePort 类型的Service
注意:由于Ingress不会暴露任意端口或协议,所以用于外部访问时,Service类型必须为NodePort或者LoadBalancer类型。
使用上述相似的“YAML建立资源”的步骤建立Service以下图所示:
咱们建立的Service类型为NodePort,所以能够经过节点公网IP和上述定义的nodePort访问,以下图所示:
接下来咱们须要建立Ingress并配置好转发规则达成以下目标:
使用同一个IP访问多个API服务,这里咱们对应的是“apidemo1”和“apidemo2”
地址http://{IP}/api/demo1将访问应用“apidemo1”
地址http://{IP}/api/demo2将访问应用“apidemo2”
根据以上目标,咱们定义YAML以下所示:
apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: qcloud #注释,不一样的Ingress控制器支持不一样的注释 name: demo-ip namespace: default spec: rules: #规则列表 - http: #HTTP规则 paths: #路径列表 - backend: #后端配置 serviceName: apidemo1 #后端服务名称 servicePort: 80 #服务端口 path: /api/demo1 #路径,同一个域名路径需不一样 - http: paths: - backend: serviceName: apidemo2 #后端服务名称 servicePort: 80 #服务端口 path: /api/demo2 #路径,同一个域名路径需不一样
使用以上YAML建立资源,腾讯云会自动建立负载均衡服务而且提供负载均衡IP,以下图所示:
咱们来验证下经过此IP访问是否可以达到预期结果,测试分别以下图所示:
虽然咱们达成了目标,可是经过IP访问体验并不友好,如何经过域名访问呢?YAML定义定义以下所示:
apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: qcloud #注释,不一样的Ingress控制器支持不一样的注释 kubernetes.io/ingress.http-rules: '[{"host":"demo.xin-lai.com","path":"/api/demo1","backend":{"serviceName":"apidemo1","servicePort":80}},{"host":"demo.xin-lai.com","path":"/api/demo2","backend":{"serviceName":"apidemo2","servicePort":80}}]' #HTTP转发规则 kubernetes.io/ingress.https-rules: "null" kubernetes.io/ingress.rule-mix: "true" random: "7778255514276773869" name: demo namespace: default spec: rules: #规则列表 - host: demo.xin-lai.com #主机名,可选。如不填写,则使用IP地址。 http: #HTTP规则 paths: #路径列表 - backend: #后端配置 serviceName: apidemo1 #后端服务名称 servicePort: 80 #服务端口 path: /api/demo1 #路径,同一个域名路径需不一样 - host: demo.xin-lai.com #主机名,可选。如不填写,则使用IP地址。 http: paths: - backend: serviceName: apidemo2 #后端服务名称 servicePort: 80 #服务端口 path: /api/demo2 #路径,同一个域名路径需不一样
值得注意的是,不一样的Ingress控制器支持不一样的注释,所以注释的编写请参阅所使用的Ingress控制器的说明。转发规则中,host为空则使用IP。
建立完成以后,腾讯云一样会自动建立负载均衡服务而且提供负载均衡IP,以下图所示,接下来咱们须要将域名“demo.xin-lai.com”解析到该负载均衡IP“193.112.232.48”:
解析完成后,咱们一样进行验证:
如上图所示,咱们使用域名完成了如下目标:
使用同一个域名“demo.xin-lai.com”访问了“apidemo1”和“apidemo2”
地址http://demo.xin-lai.com/api/demo1将访问应用“apidemo1”
地址http://demo.xin-lai.com/api/demo2将访问应用“apidemo2”
至此,一个简单的使用Ingress来负载分发微服务的Demo完成。固然这仅仅是微服务架构的万里长征第一步,毕竟Nginx Ingress控制器仅仅解决了服务的分发,并不具有完整的接口网关功能,对于这块,笔者推荐你们使用Kong+Kong Ingress Controller,架构以下图所示:
接下来,咱们再谈谈微服务应用服务的管理问题。微服务每每有许多小服务,每一个微服务都可以独立进行部署和扩展,那么必然提升了应用管理的复杂度,它们的配置、分发、版本管理等等都是一个管理的难题。在这块,有什么更好的解决方案吗?那就Helm。