Go微服务架构实战 中篇:4. 基于ingress的限流,路径匹配和重写实战

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: Go微服务架构实战 中篇:4. 基于ingress的限流,路径匹配和重写实战

4. 基于k8s的ingress实战



到现在为止我们的服务都是跑在集群内部的,为了让集群外部也能访问,那么我们需要让服务外化,但是因为minikube在mac上是网络不通的,所以我们我们直接就在minikube环境中测试(minikube ssh进入即可)。


1. 创建Pod的service


创建pod的service,类型是NodePort,我们看下svc.yaml:


apiVersion: v1
kind: Service
metadata:
  name: k8sdemo-svc # service的服务名称
spec:
  ports:
    - name: k8sdemo-svc
      port: 8000 # service的端口
      targetPort: 60001 # 容器服务的端口
  selector:
    app: k8sdemo # 关联pod
  type: NodePort # 对外暴露

创建完成之后,我们可以kubectl get svc查看是否创建成功

640.png


通过上图可以知道service是创建成功的,接下来看下架构图:

640.png


随便拿一台机器的公网IP+NodePort就可以访问了,我们这里可以在minikube中验证下:http://$(minikube ip):NodePort


docker@minikube:~$ curl -X POST  http://192.168.49.2:30143/hello -d '{"name": "fromGW"}'
{"message":"Hello fromGW from 172.17.0.16:50009"}


可以看到是没有问题的。我们从图中可以看出service是pod的更高一层抽象,负责服务发现和负载均衡,当某个Pod挂掉的时候,service会发现这个问题然后把请求打到别的Pod上。同样当在创建一个带有相同标签的Pod的时候,它会自动加入到service中,然后service会把流量按照某种负载均衡算法分发到各个Pod中。


2. 创建ingress


先安装ingress-nginx,我们先把ingress-nginx下载到本地,然后把镜像地址替换下,防止下载速度慢。


wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.0/deploy/static/provider/baremetal/deploy.yaml
sed -i 's@k8s.gcr.io/ingress-nginx/controller:v1.0.0\(.*\)@cnsre/ingress-nginx-controller:v1.0.0@' deploy.yaml
sed -i 's@k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.0\(.*\)$@cnsre/ingress-nginx-kube-webhook-certgen:v1.0@' deploy.yaml

通过kubectl apply -f deploy.yaml安装。

可以看下是否安装成功:


640.png

目前来看是安装成功的。


接下来创建我们自己的ingress,这个ingress实现的功能就是路径匹配,重写以及限流,这个yam文件内容如下,ingress.yaml:


apiVersion: networking.k8s.io/v1
kind: Ingress # ingress对象
metadata:
  name: k8sdemo-ingress-prefix # 验证前缀匹配的
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
    - host: hi.k8sdemo.com # 域名
      http:
        paths:
          - path: "/hello" # 前缀匹配
            pathType: Prefix
            backend:
              service:
                name: k8sdemo-svc
                port:
                  number: 8000 # service的端口
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: k8sdemo-ingress-rewrite # 这个ingress是关于验证重写的
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /$2 # 重写注解
spec:
  rules:
    - host: hello.k8sdemo.com
      http:
        paths:
          - pathType: Prefix
            path: "/api(/|$)(.*)"  # 把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404
            backend:
              service:
                name: k8sdemo-svc  # 如果是/api/hello 去掉前缀api 用/hello访问服务 网关一般这么搞
                port:
                  number: 8000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: k8sdemo-ingress-limit-rate
  annotations:
    nginx.ingress.kubernetes.io/limit-rps: "1" # rps:每秒多少请求 超过之后就报错 https status: 503
spec:
  ingressClassName: nginx
  rules:
    - host: hi.k8sdemo.com
      http:
        paths:
          - pathType: Exact # 精确匹配
            path: "/hello" # 针对这个路径限流
            backend:
              service:
                name: k8sdemo-svc
                port:
                  number: 8000

通过kubectl apply -f deploy.yaml创建。可以查看下是否创建成功:

640.png


可以看到这三个ingress绑定了两个host,接下来申请域名绑定ingress的ip地址,即上图中的192.168.49.2。但因为我们是minikube本地测试,所以绑定hosts就可以了。修改/etc/hosts:

192.168.49.2 hello.k8sdemo.com
192.168.49.2 hi.k8sdemo.com

保存之后我们就可以验证测试了。大致架构图就是:


640.png


3. 验证ingress


我们再次看下ingress的svc对外暴露的端口是:

640.png

可以看到是31721,接下来我们通过域名+端口来访问后端服务。

  1. 首先验证通过正常路径匹配访问
docker@minikube:~$ curl -X POST  http://hi.k8sdemo.com:31721/hello -d '{"name": "fromGW"}'
{"message":"Hello fromGW from 172.17.0.16:50009"}


发现是成功的。

  1. 验证路径重写
docker@minikube:~$ curl -X POST  http://hello.k8sdemo.com:31721/api/hello -d '{"name": "fromGW"}'
{"message":"Hello fromGW from 172.17.0.16:50009"}

发现是成功的。


4. ingress限流


docker@minikube:~$ curl -X POST  http://hi.k8sdemo.com:31721/hello -d '{"name": "fromGW"}'
<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>nginx</center>
</body>
</html>

当我们一秒请求的/hello次数大于1的时候报错,nginx返回503,这样就验证了我们的ingress的限流功能。


5. 总结


本小节算是重点,我们要了解ingress如何暴露服务,如何重写路径以及如何限流等。路径重写很重要,比如接口地址是:http://example.gateway.com/user-center/userinfohttp://example.gateway.com/user-center/userprofile,网关地址是http://example.gateway.com,路由到后端服务是userinfo,那么在网关层为了区分我们的服务,会统一加一层user-center,这样就可以区分不同业务了,但是user-center不是我们想要的,我们用它只是区分业务,所以需要在ingress层做下路径重写,这样到后端的服务就没有了user-center了。


还有基于ingress的限流功能也非常简单,大家可以尝试用起来。


参考:

https://kubernetes.github.io/ingress-nginx/

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
6天前
|
安全 大数据 Go
深入探索Go语言并发编程:Goroutines与Channels的实战应用
在当今高性能、高并发的应用需求下,Go语言以其独特的并发模型——Goroutines和Channels,成为了众多开发者眼中的璀璨明星。本文不仅阐述了Goroutines作为轻量级线程的优势,还深入剖析了Channels作为Goroutines间通信的桥梁,如何优雅地解决并发编程中的复杂问题。通过实战案例,我们将展示如何利用这些特性构建高效、可扩展的并发系统,同时探讨并发编程中常见的陷阱与最佳实践,为读者打开Go语言并发编程的广阔视野。
|
6天前
|
运维 监控 持续交付
深入浅出:微服务架构的设计与实战
微服务,一个在软件开发领域如雷贯耳的名词,它代表着一种现代软件架构的风格。本文将通过浅显易懂的语言,带领读者从零开始了解微服务的概念、设计原则及其在实际项目中的运用。我们将一起探讨如何将一个庞大的单体应用拆分为灵活、独立、可扩展的微服务,并分享一些实践中的经验和技巧。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和深入的理解。
31 3
|
10天前
|
缓存 安全 Java
如何利用Go语言提升微服务架构的性能
在当今的软件开发中,微服务架构逐渐成为主流选择,它通过将应用程序拆分为多个小服务来提升灵活性和可维护性。然而,如何确保这些微服务高效且稳定地运行是一个关键问题。Go语言,以其高效的并发处理能力和简洁的语法,成为解决这一问题的理想工具。本文将探讨如何通过Go语言优化微服务架构的性能,包括高效的并发编程、内存管理技巧以及如何利用Go生态系统中的工具来提升服务的响应速度和资源利用率。
|
16天前
|
消息中间件 缓存 Kafka
go-zero微服务实战系列(八、如何处理每秒上万次的下单请求)
go-zero微服务实战系列(八、如何处理每秒上万次的下单请求)
|
16天前
|
缓存 NoSQL Redis
go-zero微服务实战系列(七、请求量这么高该如何优化)
go-zero微服务实战系列(七、请求量这么高该如何优化)
|
11天前
|
前端开发 开发者 C#
WPF开发者必读:MVVM模式实战,轻松实现现代桌面应用架构,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,MVVM(Model-View-ViewModel)模式通过分离应用程序的逻辑和界面,提高了代码的可维护性和可扩展性。本文介绍了MVVM模式的三个核心组件:Model(数据模型)、View(用户界面)和ViewModel(处理数据绑定和逻辑),并通过示例代码展示了如何在WPF项目中实现MVVM模式。通过这种方式,开发者可以构建更加高效和可扩展的桌面应用程序。
32 0
|
16天前
|
消息中间件 SQL 关系型数据库
go-zero微服务实战系列(十、分布式事务如何实现)
go-zero微服务实战系列(十、分布式事务如何实现)
|
16天前
|
消息中间件 NoSQL Kafka
go-zero微服务实战系列(九、极致优化秒杀性能)
go-zero微服务实战系列(九、极致优化秒杀性能)
|
14天前
|
Kubernetes Cloud Native Docker
云原生之旅:从容器到微服务的架构演变
【8月更文挑战第29天】在数字化时代的浪潮下,云原生技术以其灵活性、可扩展性和弹性管理成为企业数字化转型的关键。本文将通过浅显易懂的语言和生动的比喻,带领读者了解云原生的基本概念,探索容器化技术的奥秘,并深入微服务架构的世界。我们将一起见证代码如何转化为现实中的服务,实现快速迭代和高效部署。无论你是初学者还是有经验的开发者,这篇文章都会为你打开一扇通往云原生世界的大门。
|
3天前
|
监控 负载均衡 应用服务中间件
探索微服务架构下的API网关设计与实践
在数字化浪潮中,微服务架构以其灵活性和可扩展性成为企业IT架构的宠儿。本文将深入浅出地介绍微服务架构下API网关的关键作用,探讨其设计原则与实践要点,旨在帮助读者更好地理解和应用API网关,优化微服务间的通信效率和安全性,实现服务的高可用性和伸缩性。
13 3