微服务边车模式深度解析:赋能云原生应用的终极指南(自己搞一个简单SideCar?)

9 篇文章 0 订阅
7 篇文章 0 订阅

什么是SideCar?

file

Sidecar模式定义:

Sidecar 模式是一种常用于微服务架构中的设计模式,该模式允许将应用程序的核心功能与辅助功能(如日志记录、监控、配置管理、网络通信等)分离开来。在这种设计模式中,每个微服务主容器旁边都有一个“边车”(Sidecar)容器运行辅助功能,就像摩托车旁的边车一样,Sidecar 容器和主容器共享同一个生命周期和网络空间。

你专心开车,其他交给我。

file

整体Sidecar就是这样:

file

总结:把非核心业务杂七杂八的东西分离出来,微服务的关注点尽可能只在业务上面,减少业务开发的复杂度。

Sidecar主要干啥?

Sidecar模式通常会处理以下范围的功能:

  1. 网络通信

    • 代理和管理微服务之间的通信,例如用来处理进出的网络流量、服务发现、负载均衡、断路、重试和超时。
  2. 安全性

    • 实现安全协议,如TLS加密、认证、授权和密钥管理。
  3. 监控与日志记录

    • 收集和导出日志、性能度量指标和追踪信息,以供监控系统使用。
  4. 配置管理

    • 动态加载和管理配置数据,而无需重启应用程序。
  5. 故障处理和调试

    • 提供调试支持,记录崩溃报告和性能瓶颈。
  6. 健康检查

    • 周期性地检查主服务的健康,并可实施自我修复措施。
  7. API 网关或接口转换

    • 处理服务的REST或gRPC API,提供API网关功能,或者对老旧系统进行接口转换。
  8. 服务依赖抽象

    • 管理服务间的数据库连接、队列等系统资源的访问。
  9. 请求/响应转换

    • 对进出的请求或响应数据进行转换或扩展。

Sidecar有哪些实现?

Sidecar在容器化和微服务领域有很多实现:

1. Envoy

Envoy是一个开源的、高性能的边缘和服务代理,专门设计用于云原生应用环境。由Lyft公司首次开发发布,后来成为了Cloud Native Computing Foundation(CNCF)的一部分。它的设计允许它同时在应用程序的边缘和内部使用,作为边缘网关、负载均衡器或服务网格的一部分,以提高微服务之间的通信质量和效率。

file

  1. Istio
    Istio是一个开源的服务网格,用于连接、保护、控制和观察在Kubernetes集群中运行的服务。它为微服务提供一种统一的方式来管理网络通信,安全性,策略和观察性,无需改变应用本身的代码。Istio利用了Envoy代理,它作为Sidecar部署在每个服务的Pod中,拦截所有进出Pod的网络通信。
     

    file

    file

  2. Linkerd
    Linkerd是一个开源的服务网格,专门为云原生应用设计,用以在微服务架构中提供可靠的服务间通信。它提供关键功能,如服务发现、负载均衡、故障处理、请求路由和安全性,在不改动服务代码的情况下,使得服务更容易监控、管理和控制。Linkerd是由Buoyant公司开源的,并且是Cloud Native Computing Foundation(CNCF)的一部分。

    file

自己搞一个简单的?

我们个人势单力薄,搞一个像他们这么有高级功能的组件还是挺费时间的,况且我们还在温饱线上挣扎。

但是又想在这块搞点小事情,那么整个简单的。

先来个简单的需求

一个业务系统部署在k8s集群中,每个服务采用一个Pod一个服务的方式部署,每个Pod都有一个Service。

file


就这么简单来一下就可以了,Service关联Pod提供统一访问入口。

那根据SideCar的拓扑,我们可以在Service和Pod中容器之间加一个Sidecar来管理流量,像这样:

file

在这个拓扑中,所有流量先进SVC(逻辑上哈),然后转发给车最后转发给Pod。

车的具体需求?

  1. 管理HTTP流量(TCP的暂时不支持):只开发一个IP白名单规则。如果请求这个服务的IP不在这个白名单中,则返回404,否则转发该请求。
  2. 白名单规则配置:支持单个IP地址,支持CIDR地址。

需求就是这么简单,我们让SVC把流量先转给车,车处理了一下以后再转发给业务服务。

准备开干

首先开发一个HTTP服务器

使用Go built-in API就可以很简单开发实现一个HTTP服务器,就是使用net包:


    http.HandleFunc("/", handler)
    err = http.ListenAndServe(conf.Server.Addr, nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }

COPY

几行代码搞定,额,这还是有点快,让人猝不及防。那这样我们的HTTP服务器就搞定了

其次 读取配置文件

我们用yaml来定义白名单配置,白名单中有IP和CIDR地址。


whitelist:
  - 192.168.1.1
  - 192.168.1.2
  - 10.22.81.0/24
  - ::1

COPY

然后我们使用yaml解析库来读取它。

先来下载一下依赖库:


go get gopkg.in/yaml.v2

COPY

然后使用库提供的api来读取yaml文件:


type Conf struct {
    Server     Server     `yaml:"server"`
    Downstream Downstream `yaml:"downstream"`
    Whitelist  []string   `yaml:"whitelist"`
}

err = yaml.Unmarshal(source, &conf)
    if err != nil {
        log.Panic(err)
    }

COPY

设置HTTP的请求处理函数

我们请求处理函数从X-FORWARDED-FOR协议头来获取请求的Ip列表字符串,字符串以ip1,ip2,ip3,...来组成的。

我们只取第一个,就是上面示例的ip1,因为只有这个IP才表示请求方的IP,其他都是代理方的。

func handler(w http.ResponseWriter, r *http.Request) {
    ipStr := r.Header.Get("X-FORWARDED-FOR")
    if ipStr == "" {
        ipStr = strings.Split(r.RemoteAddr, ":")[0]
    } else {
        ipStr = strings.TrimSpace(strings.Split(ipStr, ",")[0])
    }

    // 如果IP地址在白名单中,那么就转发请求
    if ipInWhitelist(ipStr, conf.Whitelist) {
        serveReverseProxy(conf.Downstream.URL, w, r)
        return
    }

    // 否则返回404
    http.NotFound(w, r)
}

COPY

转发请求

Go内建包net实现了ReverseProxy,我们直接使用httputil.NewSingleHostReverseProxy就可以直接转发HTTP请求,很快~。


func serveReverseProxy(target string, w http.ResponseWriter, r *http.Request) {
    url, _ := url.Parse(target)

    proxy := httputil.NewSingleHostReverseProxy(url)

    r.URL.Host = url.Host
    r.URL.Scheme = url.Scheme
    r.Header.Set("X-Forwarded-Host", r.Header.Get("Host"))
    r.Host = url.Host

    proxy.ServeHTTP(w, r)
}

COPY

这样我们的核心功能就实现了。

一点小细节

实现了核心流程以后,我们还得关注配置中IP的解析。
Go的net 包也提供了IP地址和CIDR地址的解析,我们只需要调用一下

  1. net.ParseIP
  2. net.ParseCIDR
    就可以实现IP解析了。

transformToCIDR 这个函数就给IP地址增加/32转换成CIDR形式,大家可以不用太关注。


func ipInWhitelist(ipStr string, whitelist []string) bool {

    ip := net.ParseIP(ipStr)
    for _, cidr := range whitelist {
        _, ipNet, err := net.ParseCIDR(transformToCIDR(cidr))
        if err != nil {
            return false
        }
        if ipNet.Contains(ip) {
            return true
        }
    }
    return false
}

COPY

部署

开发这个简单的需求一百多行代码就可以搞定了,但是部署怎么办?

我们在k8s中不是有Service嘛,我们Service在配置流量转发规则的时候先转到我们的HTTP Server,然后我们HTTP再转发给业务服务。

Pod改造

原来我们的拓扑是这样的:

file

加上我们自己的sidecar就变成这样了:

file

随之而来的改造

k8s Pod支持一个Pod多个Container,所以我们可以直接在Pod中增加一个Container:
比如:原来我们的Pod定义是这样的:


        - name: my-order-app
          image: my-registry-domain-name/ my-order-app:${my-order-app-version}
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080

COPY

改造后:


      containers:
        - name: sidecar
          image: my-registry-domain-name/my-custom-sidecar:latest
          imagePullPolicy: Always
          ports:
            - containerPort: 8081
        - name: my-order-app
          image: my-registry-domain-name/ my-order-app:${my-order-app-version}
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080

COPY

Pod的改造就完成了,接下来就是Service改造了。

Service改造

我们要把Service的目标端口改成我们自己的Sidecar应用才可以。

比如:原来我们的Service是这样的:
Service端口为8080,转发到app的8080端口中。


apiVersion: v1
kind: Service
metadata:
  name: my-order-app-service
  namespace: my-app
  labels:
    app: my-order-app
spec:
  ports:
    - name: my-order-http
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: my-order-app
  type: ClusterIP

COPY

现在我们要把Target改成8081,也就是我们的Sidecar HTTP服务器端口。


apiVersion: v1
kind: Service
metadata:
  name: my-order-app-service
  namespace: my-app
  labels:
    app: my-order-app
spec:
  ports:
    - name: my-order-http
      port: 8080
      protocol: TCP
      targetPort: 8081
  selector:
    app: my-order-app
  type: ClusterIP

COPY

这样我们的Sidecar就搞定了。

总结

通过使用Sidecar模式,我们能够实现对微服务架构的强化,也就是关注点分离,让你专注于开车,开好车,开快车。
它提供了一种有效的方式去分摊微服务的辅助功能(如日志记录、监控、配置管理、网络通信等),而无需改动微服务的核心业务逻辑。这带来了显著的优点,包括简化开发复杂度、增强服务的可维护性和可伸缩性,以及提供了横切关注点(cross-cutting concerns)的统一管理。

优点

关注点分离:通过将非核心功能从应用程序逻辑中分离出来,开发者可以更专注于业务逻辑。
可插拔性:Sidecar可以独立于应用程序部署和更新,使得维护工作更加灵活。
一致性:在多个服务中应用相同的配置和策略,不需要在每个服务上单独配置。
扩展性:新增功能时,可以在不影响现有服务的情况下,在Sidecar中添加新的组件。
增强的能力:例如,集中日志处理、安全性控制、以及动态路由等。

缺点(Sidecar的通病):

资源使用:每个Sidecar都会消耗额外的计算和内存资源,这可能导致资源的浪费。
复杂性:虽然单个服务的复杂性降低了,但整体架构可能会因为增加的组件而变得复杂。
调试困难:由于Sidecar模式涉及多个容器协同工作,调试和追踪问题可能比传统单体应用更加困难。
网络延迟:每个请求都要通过Sidecar代理,可能会增加网络延迟。

参考

微服务侧车模式深度解析:赋能云原生应用的终极指南(自己搞一个简单SideCar?) – 小厂程序员

  • 46
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GSMA是全球移动通信运营商协会,其在人工智能行业中推动着人工智能与安全应用的结合。人工智能作为一种新兴技术,为安全应用提供了全新的解决方案和创新思路。 在人工智能赋能安全应用案例集中,GSMA提供了一些典型的应用场景和案例,来展示人工智能如何改善和增强安全性。其中包括以下几个方面: 首先,人工智能在安全监控领域的应用。通过人工智能技术,可以实现对大量视频监控画面的自动分析和识别,从而快速发现异常行为和威胁。例如,人工智能可以检测图像中的人脸、车牌等信息,并与数据库进行比对,实现实时监控和安全报警。 其次,人工智能在网络安全领域的应用。通过使用机器学习和深度学习算法,人工智能可以自动分析网络流量和数据,并识别出潜在的网络攻击和漏洞。这种能力可以帮助企业和个人及时发现和应对网络安全威胁,并提升网络安全防护的效率和准确性。 另外,人工智能还可以在移动应用和物联网设备的安全保护方面发挥作用。通过人工智能技术,移动设备和物联网设备可以进行行为分析和异常检测,从而防止设备被非法控制或者被入侵。同时,人工智能还可以实现对移动应用和物联网设备的风险评估和防护策略的优化,提升设备和数据的安全性。 总而言之,人工智能在安全应用领域有着广阔的前景和潜力。GSMA通过推动人工智能与安全应用的结合,致力于提高安全防护的效率和准确性,保障用户的个人和信息安全。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值