本文来说下什么是Istio

文章目录

  • 概述
  • 什么是服务网格
  • 服务网格的特征
    • 流量管理
    • 安全性
    • 可观察性
  • Istio简介
  • 了解Istio组件
    • 数据平面
    • 控制面
  • Istio工作原理
    • 流量管理
    • 安全性
    • 可观察性
  • Istio实战
    • 安装
    • 示例应用
    • 部署
    • 访问应用
  • Istio的常见用例
    • 请求路由
    • 熔断
    • 启用双向TLS
    • 使用JWT进行访问控制
  • 思考
    • 我们应该始终使用服务网格吗
    • Istio的替代品有哪些
  • 本文小结

概述

在本教程中,我们将介绍服务网格的基础知识,并了解它如何实现分布式系统架构。我们将主要关注 Istio,它是服务网格的一种具体实现。在此过程中,我们将介绍 Istio 的核心架构。官方网站:https://istio.io/


什么是服务网格

在过去的几十年中,我们已经看到了单体应用程序开始拆分为较小的应用程序。此外,诸如 Docker 之类的容器化技术和诸如 Kubernetes 之类的编排系统加速了这一变化。

尽管在像 Kubernetes 这样的分布式系统上采用微服务架构有许多优势,但它也具有相当的复杂性。由于分布式服务必须相互通信,因此我们必须考虑发现,路由,重试和故障转移。

还有其他一些问题,例如安全性和可观察性,我们还必须注意以下问题:


现在,在每个服务中建立这些通信功能可能非常繁琐,尤其是当服务范围扩大且通信变得复杂时,更是如此。这正是服务网格可以为我们提供帮助的地方。基本上,服务网格消除了在分布式软件系统中管理所有服务到服务通信的责任。

服务网格能够通过一组网络代理来做到这一点。本质上,服务之间的请求是通过与服务一起运行但位于基础结构层之外的代理路由的:


这些代理基本上为服务创建了一个网状网络—因此,名称为服务网格!通过这些代理,服务网格能够控制服务到服务通信的各个方面。这样,我们可以使用它来解决分布式计算的八个谬误,这是一组断言,描述了我们经常对分布式应用程序做出的错误假设。


服务网格的特征

现在,让我们了解服务网格可以为我们提供的一些功能。请注意,实际功能列表取决于服务网格的实现。但是,总的来说,我们应该在所有实现中都期望其中大多数功能。

我们可以将这些功能大致分为三类:流量管理,安全性和可观察性


流量管理

服务网格的基本特征之一是流量管理。这包括动态服务发现和路由。尤其影子流量和流量拆分功能,这些对于实现金丝雀发布和A/B测试非常有用。

由于所有服务之间的通信都是由服务网格处理的,因此它还启用了一些可靠性功能。例如,服务网格可以提供重试,超时,速率限制和断路器。这些现成的故障恢复功能使通信更加可靠。


安全性

服务网格通常还处理服务到服务通信的安全性方面。这包括通过双向TLS(mTLS)强制进行流量加密,通过证书验证提供身份验证以及通过访问策略确保授权。

服务网格中还可能存在一些有趣的安全用例。例如,我们可以实现网络分段,从而允许某些服务进行通信而禁止其他服务。而且,服务网格可以为审核需求提供精确的历史信息。


可观察性

强大的可观察性是处理分布式系统复杂性的基本要求。由于服务网格可以处理所有通信,因此正确放置了它可以提供可观察性的功能。例如,它可以提供有关分布式追踪的信息。

服务网格可以生成许多指标,例如延迟,流量,错误和饱和度。此外,服务网格还可以生成访问日志,为每个请求提供完整记录。这些对于理解单个服务以及整个系统的行为非常有用。


Istio简介

Istio是最初由IBM,Google和Lyft开发的服务网格的开源实现。它可以透明地分层到分布式应用程序上,并提供服务网格的所有优点,例如流量管理,安全性和可观察性。

它旨在与各种部署配合使用,例如本地部署,云托管,Kubernetes容器以及虚拟机上运行的服务程序。尽管 Istio 与平台无关,但它经常与Kubernetes平台上部署的微服务一起使用。

从根本上讲,Istio的工作原理是以Sidcar的形式将Envoy的扩展版本作为代理布署到每个微服务中:

该代理网络构成了Istio架构的数据平面。这些代理的配置和管理是从控制平面完成的:

控制平面基本上是服务网格的大脑。它为数据平面中的 Envoy 代理提供发现,配置和证书管理。

当然,只有在拥有大量相互通信的微服务时,我们才能体现Istio的优势。在这里,sidecar代理在专用的基础架构层中形成一个复杂的服务网格:


Istio在与外部库和平台集成方面非常灵活。例如,我们可以将Istio与外部日志记录平台,遥测或策略系统集成。


了解Istio组件

我们已经看到,Istio体系结构由数据平面和控制平面组成。此外,还有几个使Istio起作用的核心组件。

在本节中,我们将详细介绍这些核心组件。


数据平面

Istio 的数据平面主要包括 Envoy 代理的扩展版本。Envoy 是一个开源边缘和服务代理,可帮助将网络问题与底层应用程序分离开来。应用程序仅向 localhost 发送消息或从localhost 接收消息,而无需了解网络拓扑。

Envoy 的核心是在 OSI 模型的 L3 和 L4 层运行的网络代理。它通过使用可插入网络过滤器链来执行连接处理。此外,Envoy 支持用于基于HTTP的流量的附加L7层过滤器。而且,Envoy 对 HTTP/2 和 gRPC 传输具有一流的支持。

Istio 作为服务网格提供的许多功能实际上是由 Envoy 代理的基础内置功能启用的:

  • 流量控制:Envoy 通过 HTTP,gRPC,WebSocket 和 TCP 流量的丰富路由规则启用细粒度的流量控制应用
  • 网络弹性:Envoy 包括对自动重试,断路和故障注入的开箱即用支持
  • 安全性:Envoy 还可以实施安全策略,并对基础服务之间的通信应用访问控制和速率限制

Envoy 在 Istio 上表现出色的另一个原因之一是它的可扩展性。Envoy 提供了基于 WebAssembly 的可插拔扩展模型。这在定制策略执行和遥测生成中非常有用。此外,我们还可以使用基于 Proxy-Wasm 沙箱 API 的Istio扩展在Istio中扩展Envoy代理。


控制面

如上所述,控制平面负责管理和配置数据平面中的Envoy代理。在Istio架构中,控制面核心组件是 istiod,Istiod负责将高级路由规则和流量控制行为转换为特定于 Envoy 的配置,并在运行时将其传播到 Sidercar。

如果我们回顾一下 Istio 控制平面的架构,将会注意到它曾经是一组相互协作的独立组件。它包括诸如用于服务发现的 Pilot,用于配置的 Galley,用于证书生成的 Citadel 以及用于可扩展性的 Mixer 之类的组件。由于复杂性,这些单独的组件被合并为一个称为istiod 的单个组件。

从根本上来说,istiod 仍使用与先前各个组件相同的代码和 API。例如,Pilot 负责抽象特定于平台的服务发现机制,并将其合成为Sidecar可以使用的标准格式。因此,Istio 可以支持针对多个环境(例如 Kubernetes 或虚拟机)的发现。

此外,istiod 还提供安全性,通过内置的身份和凭据管理实现强大的服务到服务和最终用户身份验证。此外,借助 istiod,我们可以基于服务身份来实施安全策略。该过程也充当证书颁发机构(CA)并生成证书,以促进数据平面中的相互 TLS(MTLS)通信。


Istio工作原理

我们已经了解了服务网格的典型特征是什么。此外,我们介绍了Istio架构及其核心组件的基础。现在,是时候了解 Istio 如何通过其架构中的核心组件提供这些功能了。

我们将专注于我们之前经历过的相同类别的功能。


流量管理

我们可以使用 Istio 流量管理 API 对服务网格中的流量进行精细控制。我们可以使用这些API 将自己的流量配置添加到 Istio。此外,我们可以使用 Kubernetes 自定义资源定义(CRD)定义API资源。帮助我们控制流量路由的关键API资源是虚拟服务和目标规则:


基本上,虚拟服务使我们可以配置如何将请求路由到 Istio 服务网格中的服务。因此,虚拟服务由一个或多个按顺序评估的路由规则组成。评估虚拟服务的路由规则后,将应用目标规则。目标规则有助于我们控制到达目标的流量,例如,按版本对服务实例进行分组。


安全性

Istio为每个服务提供身份。与每个Envoy代理一起运行的Istio代理与istiod一起使用以自动进行密钥和证书轮换:


Istio提供两种身份验证—对等身份验证和请求身份验证。对等身份验证用于服务到服务的身份验证,其中Istio提供双向TLS作为全栈解决方案。请求身份验证用于最终用户身份验证,其中Istio使用自定义身份验证提供程序或OpenID Connect(OIDC)提供程序提供JSON Web令牌(JWT)验证。

Istio还允许我们通过简单地将授权策略应用于服务来实施对服务的访问控制。授权策略对Envoy代理中的入站流量实施访问控制。这样,我们就可以在各种级别上应用访问控制:网格,命名空间和服务范围。


可观察性

Istio为网格网络内的所有服务通信生成详细的遥测,例如度量,分布式跟踪和访问日志。Istio生成一组丰富的代理级指标,面向服务的指标和控制平面指标。

之前,Istio遥测体系结构将Mixer作为核心组件。但是从Telemetry v2开始,混音器提供的功能已替换为Envoy代理插件:


此外,Istio 通过 Envoy 代理生成分布式跟踪。Istio支持许多跟踪后端,例如 Zipkin,Jaeger,Lightstep 和 Datadog。我们还可以控制跟踪速率的采样率。此外,Istio 还以一组可配置的格式生成服务流量的访问日志。


Istio实战

上面我们已经讲述了Istio原理和架构,接下来我们开始实战部分。首先,我们将在Kubernetes 集群中安装 Istio。此外,我们将使用一个简单的基于微服务的应用程序来演示 Istio 在 Kubernetes 上的功能。


安装

有多种安装Istio的方法,但最简单的方法是下载并解压缩特定操作系统(例如Windows)的最新版本。提取的软件包在 bin 目录中包含 istioctl 客户端二进制文件。我们可以使用 istioctl 在目标 Kubernetes 集群上安装 Istio:

istioctl install --set profile=demo -y

这会使用演示配置文件将 Istio 组件安装在默认的 Kubernetes 集群上。我们还可以使用任何其他特定于供应商的配置文件来代替演示。

最后,当我们在此 Kubernetes 集群上部署任何应用程序时,我们需要指示 Istio 自动注入 Envoy sidecar 代理:

kubectl label namespace default istio-injection=enabled

我们在这里使用 kubectl 的前提是,我们的机器上已经有像 Minikube 这样的Kubernetes 集群和 Kubernetes CLI kubectl。


示例应用

为了演示,我们将想象一个非常简单的在线下订单应用程序。该应用程序包含三个微服务,它们相互交互以满足最终用户的订购请求:

我们没有讨论这些微服务的细节,但是使用Spring Boot和REST API可以很简单地创建它们。最重要的是,我们为这些微服务创建了一个Docker镜像,以便我们可以将它们部署在Kubernetes上。


部署

在像 Minikube 这样的 Kubernetes 集群上部署容器化的工作负载非常简单。我们将使用Deployment和Service资源类型来声明和访问工作负载。通常,我们在YAML文件中定义它们:

apiVersion: apps/v1beta1
kind: Deployment
metadata:name: order-servicenamespace: default
spec:replicas: 1template:metadata:labels:app: order-serviceversion: v1spec:containers:- name: order-serviceimage: kchandrakant/order-service:v1resources:requests:cpu: 0.1memory: 200
---
apiVersion: v1
kind: Service
metadata:name: order-service
spec:ports:- port: 80targetPort: 80protocol: TCPname: httpselector:app: order-service

对于订单服务的“部署和服务”,这是一个非常简单的定义。同样,我们可以为库存服务和运输服务定义 YAML 文件。

使用kubectl部署这些资源也非常简单:

kubectl apply -f booking-service.yaml -f inventory-service.yaml -f shipping-service.yaml

由于我们已经为默认命名空间启用了自动注入 Envoy sidecar 代理,因此一切都会由istiod 来处理。或者,我们可以使用 istioctl 的 kube-inject 命令手动注入 Envoy sidecar代理。


访问应用

现在,Istio 主要负责处理所有的网状网络流量。因此,默认情况下,不允许进出网格的任何流量。Istio 使用网关来管理来自网格的入站和出站流量。这样,我们可以精确地控制进入或离开网格的流量。Istio提供了一些预配置的网关代理部署:istio-ingressgateway 和 istio-egressgateway。

我们将为我们的应用程序创建一个网关和一个虚拟服务来实现此目的:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:name: booking-gateway
spec:selector:istio: ingressgatewayservers:- port:number: 80name: httpprotocol: HTTPhosts:- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: booking
spec:hosts:- "*"gateways:- booking-gatewayhttp:- match:- uri:prefix: /api/v1/bookingroute:- destination:host: booking-serviceport:number: 8080

在这里,我们利用了Istio 提供的默认入口控制器。此外,我们已经定义了一个虚拟服务,将我们的请求路由到预订服务。同样,我们也可以为来自网格的出站流量定义出口网关。


Istio的常见用例

现在,我们已经看到了如何使用 Istio 在 Kubernetes 上部署一个简单的应用程序。但是,我们仍然没有利用 Istio 为我们启用的任何有趣功能。在本节中,我们将介绍服务网格的一些常见用例,并了解如何使用Istio为我们的简单应用程序实现它们。


请求路由

我们可能要以特定方式处理请求路由的原因有多个。例如,我们可能会部署微服务的多个版本,例如运输服务,并希望仅将一小部分请求路由到新版本。

我们可以使用虚拟服务的路由规则来实现这一点:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: shipping-service
spec:hosts:- shipping-servicehttp:- route:- destination:host: shipping-servicesubset: v1weight: 90- destination:host: shipping-servicesubset: v2weight: 10
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: shipping-service
spec:host: shipping-servicesubsets:- name: v1labels:version: v1- name: v2labels:version: v2

路由规则还允许我们基于诸如 header 参数之类的属性来定义匹配条件。此外,目的地字段指定与条件匹配的流量的实际目的地。


熔断

熔断器基本上是一种软件设计模式,用于检测故障并封装防止故障进一步级联的逻辑。这有助于创建有弹性的微服务应用程序,以限制故障和延迟尖峰的影响。

在 Istio 中,我们可以使用 DestinationRule 中的 trafficPolicy 配置在调用诸如清单服务之类的服务时应用熔断:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: inventory-service
spec:host: inventory-servicetrafficPolicy:connectionPool:tcp:maxConnections: 1http:http1MaxPendingRequests: 1maxRequestsPerConnection: 1outlierDetection:consecutive5xxErrors: 1interval: 1sbaseEjectionTime: 3mmaxEjectionPercent: 100

在这里,我们将DestinationRule配置为 maxConnections为1,httpMaxPendingRequests 为1,maxRequestsPerConnection 为1。这实际上意味着,如果我们将并发请求数超过1,熔断器将开始trap一些请求。


启用双向TLS

双向身份验证是指双方在诸如TLS之类的身份验证协议中同时相互进行身份验证的情况。默认情况下,具有代理的服务之间的所有流量在Istio中都使用相互TLS。但是,没有代理的服务仍继续以纯文本格式接收流量。

虽然Istio将具有代理的服务之间的所有流量自动升级为双向TLS,但这些服务仍可以接收纯文本流量。我们可以选择使用 PeerAuthentication 策略在整个网格范围内实施双向TLS:

apiVersion: "security.istio.io/v1beta1"
kind: "PeerAuthentication"
metadata:name: "default"namespace: "istio-system"
spec:mtls:mode: STRICT

我们还提供了对每个命名空间或服务而不是在网格范围内强制实施双向TLS的选项。但是,特定于服务的PeerAuthentication策略优先于命名空间范围的策略。


使用JWT进行访问控制

JSON Web令牌(JWT)是用于创建数据的标准,该数据的有效载荷中包含声明许多声明的JSON。为了在身份提供者和服务提供者之间传递经过身份验证的用户的身份和标准或自定义声明,这一点已被广泛接受。

我们可以在Istio中启用授权策略,以允许访问基于JWT的预订服务之类的服务:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: require-jwtnamespace: default
spec:selector:matchLabels:app: booking-serviceaction: ALLOWrules:- from:- source:requestPrincipals: ["testing@baeldung.com/testing@baeldung.io"]

在这里,AuthorizationPolicy 强制所有请求具有有效的 JWT,并将 requestPrincipal 设置为特定值。Istio 通过组合声明JWT的iss和sub来创建requestPrincipal属性。


思考

因此,到目前为止,我们已经看到像Istio这样的服务网格如何使我们更轻松地处理诸如微服务之类的分布式架构中的许多常见问题。但是尽管如此,Istio还是一个复杂的系统,会增加最终部署的复杂性。与其他所有技术一样,Istio并非灵丹妙药,必须谨慎使用。


我们应该始终使用服务网格吗

尽管我们已经看到了使用服务网格的足够理由,但下面列举了一些可能促使我们不使用它的原因:

  • 服务网格处理所有服务到服务的通信,而部署和操作服务网格则需要支付额外的费用。对于较简单的应用程序,这可能是不合理的
  • 由于我们已经习惯于处理一些此类问题,例如应用程序代码中的熔断,因此可能导致服务网格中的重复处理
  • 越来越依赖于诸如服务网格之类的外部系统可能会损害应用程序的可移植性,尤其是因为没有针对服务网格的行业标准
  • 由于服务网格通常通过拦截通过代理的网格流量来工作,因此它可能会给请求增加不希望的延迟
  • 服务网格增加了许多其他组件和配置,需要精确处理。这需要专业知识,并增加了学习曲线
  • 最后,我们可能最终将操作逻辑(应在服务网格中存在)与业务逻辑(不应在服务网格中)混合在一起

因此,正如我们所看到的,服务网格的故事不仅仅涉及好处,但这并不意味着它们不是真的。对我们来说,重要的是要仔细评估我们的需求和应用程序的复杂性,然后权衡服务网格的好处和它们所增加的复杂性。


Istio的替代品有哪些

尽管 Istio 非常受欢迎,并得到了业内一些领导者的支持,但它当然不是唯一的选择。尽管我们在这里无法进行全面的比较,但让我们看一下 Linkerd 和Consul 这两个选项。

Linkerd 是已为 Kubernetes 平台创建的开源服务网格。它也很受欢迎,目前在 CNCF 中具有孵化项目的地位。它的工作原理类似于 Istio 等任何其他服务网格。它还利用 TCP 代理来处理网格流量。Linkerd 使用用 Rust 编写的微型代理,称为 Linkerd 代理。

总体而言,Linkerd并不比Istio复杂,因为它仅支持 Kubernetes。但是,除此之外,Linkerd中可用的功能列表与Istio中可用的功能非常相似。Linkerd的核心架构也非常类似于Istio。基本上,Linkerd包含三个主要组件:用户界面,数据平面和控制平面。

Consul是HashiCorp的服务网格的开源实现。它的好处是可以与HashiCorp的其他基础架构管理产品套件很好地集成,以提供更广泛的功能。Consul中的数据平面可以灵活地支持代理以及本机集成模型。它带有内置代理,但也可以与Envoy一起使用。

除了Kubernetes,Consul还可以与Nomad等其他平台一起使用。Consul通过在每个节点上运行Consul代理以执行运行状况检查来工作。这些代理与一台或多台存储和复制数据的Consul服务器通信。尽管它提供了服务网格(如Istio)的所有标准功能,但它是部署和管理的更复杂的系统。


本文小结

总而言之,在本教程中,我们介绍了服务网格模式的基本概念以及它提供给我们的功能。特别是,我们详细介绍了Istio。这涵盖了Istio的核心架构及其基本组件。此外,我们详细介绍了一些常见用例的安装和使用Istio的细节。

一文弄懂什么是Istio相关推荐

  1. 一文弄懂元学习 (Meta Learing)(附代码实战)《繁凡的深度学习笔记》第 15 章 元学习详解 (上)万字中文综述

    <繁凡的深度学习笔记>第 15 章 元学习详解 (上)万字中文综述(DL笔记整理系列) 3043331995@qq.com https://fanfansann.blog.csdn.net ...

  2. 一文弄懂神经网络中的反向传播法

    最近在看深度学习的东西,一开始看的吴恩达的UFLDL教程,有中文版就直接看了,后来发现有些地方总是不是很明确,又去看英文版,然后又找了些资料看,才发现,中文版的译者在翻译的时候会对省略的公式推导过程进 ...

  3. 一文弄懂各种loss function

    有模型就要定义损失函数(又叫目标函数),没有损失函数,模型就失去了优化的方向.大家往往接触的损失函数比较少,比如回归就是MSE,MAE,分类就是log loss,交叉熵.在各个模型中,目标函数往往都是 ...

  4. 一文弄懂神经网络中的反向传播法——BackPropagation【转】

    本文转载自:https://www.cnblogs.com/charlotte77/p/5629865.html 一文弄懂神经网络中的反向传播法--BackPropagation 最近在看深度学习的东 ...

  5. 一文弄懂String的所有小秘密

    文章目录 简介 String是不可变的 传值还是传引用 substring() 导致的内存泄露 总结 一文弄懂String的所有小秘密 简介 String是java中非常常用的一个对象类型.可以说ja ...

  6. 一文弄懂EnumMap和EnumSet

    文章目录 简介 EnumMap 什么时候使用EnumMap EnumSet 总结 一文弄懂EnumMap和EnumSet 简介 一般来说我们会选择使用HashMap来存储key-value格式的数据, ...

  7. CAD2010 为了保护_一文弄懂,锂电池的充电电路,以及它的保护电路方案设计

    原标题:一文弄懂,锂电池的充电电路,以及它的保护电路方案设计 锂电池特性 首先,芯片哥问一句简单的问题,为什么很多电池都是锂电池? 锂电池,工程师对它都不会感到陌生.在电子产品项目开发的过程中,尤其是 ...

  8. deque stack java_一文弄懂java中的Queue家族

    简介 java中Collection集合有三大家族List,Set和Queue.当然Map也算是一种集合类,但Map并不继承Collection接口. List,Set在我们的工作中会经常使用,通常用 ...

  9. 一文弄懂Flink网络流控及反压

    一文弄懂Flink网络流控及反压 1. 为什么需要网络流控? 2. 网络流控的实现:静态限速 3. 网络流控的实现:动态反馈/自动反压 3.1 案例一:Storm 反压实现 3.2 案例二:Spark ...

最新文章

  1. 《转》十种更好的表达“你的代码写的很烂”的方法
  2. 鸿蒙2.0操作体验,鸿蒙2.0操作系统正式版-华为鸿蒙2.0操作系统正式版官方预约 v1.0.0-优盘手机站...
  3. 学生成绩管理系统设计报告python_python实现简易版学生成绩管理系统
  4. MVC+JSON 无限滚动翻页
  5. 数字图像处理之图像几何变换
  6. SpringBoot:搭建第一个Web程序
  7. 51.com庞升东:其实我认为自己比较像唐僧
  8. jQuery中的.bind()、.live()和.delegate()之间区别分析,学习jquery
  9. html 链接 id属性_HTML id属性
  10. php-cms,GitHub - lovelife10000/L-php-cms: 基于laravel框架开发的一款php CMS内容管理系统,前端采用angular、jquery技术...
  11. 在线工具:找到神器,助你轻松应对各种职场难题
  12. 算法分析与设计-线性时间选择详解(通俗易懂,含图解,附源码)(c++)
  13. ffmpeg推流到流媒体服务器
  14. python langid 语种检测以及语种对应表
  15. 微信小程序使用阿里字体图标库的方法
  16. 计算机x线成像检查,计算机X线成像(X光机成像)简述
  17. python统计大写字符个数和小写英文字符_统计一个字符串中大写字母字符和小写字母字符,数字字符出现的次数...
  18. SQL Server 数据库中添加文件组和数据文件
  19. 定时任务:springboot集成Quartz实现多任务多触发的动态管理
  20. 【IDEA保姆级教程】快捷键

热门文章

  1. 国内开源社区软件 PHPWind 团队已解散
  2. jQuery 属性操作 - toggleClass() 方法
  3. .NET平台4.0 发布网站流程及出错总结
  4. 99%学习前端开发都会遇到的问题,百分之百都没绝对意识
  5. CSS(一)sytle
  6. 自动化运维-Ansible (第三部:Playbook 介绍)
  7. 如何使用Spring优雅地处理REST异常
  8. OEA 2.11 支持单机版数据库 - SQLite与SQLCE对比
  9. RHEL 7.0已发布 CentOS 7 即将到来
  10. 用DOS命令快把系统看透