原文

在学习像 Istio 这样的新技术时,看一下示例应用程序总是一个好主意。 Istio repo 有一些示例应用程序,但它们似乎有各种不足。 文档中的 BookInfo 是一个很好的示例。 但是,对于我而言,它太冗长,服务太多,而且文档似乎专注于管理 BookInfo 应用程序,而不是从头开始构建。 有一个较小的 hellohttp 例子,但它更多的是关于自动伸缩而不是其他。

在这篇文章中,我想介绍一下基础知识,并向您展示如何从头开始构建支持 Istio 的“hellohttp”应用程序。 要记住的一点是,Istio 只管理您应用的流量。 在这种情况下,应用程序生命周期由底层平台 Kubernetes 管理。 因此,您需要了解容器和 Kubernetes 基础知识,并且需要了解 Istio Routing 原语,例如 Gateway,VirtualService,DestinationRule。 我假设大多数人都知道容器和 Kubernetes 基础知识。 我将在本文中专注于 Istio Routing。

基础步骤

以下这些大致就是您需要遵循的,以获得 Istio 的“hellohttp”应用程序的步骤:

  1. 创建一个 Kubernetes 集群并安装带有 sidecare 自动注入的 Istio。
  2. 使用您选择的语言创建 Hellohttp 应用程序,创建 Docker 镜像并将其推送到公共镜像仓库。
  3. 为你的容器创建 Kubernetes deployment 和 service。
  4. 创建 Gateway 以启用到群集的 HTTP(S)流量。
  5. 创建 VirtualService,通过 Gateway 公开 Kubernetes 服务。
  6. (可选)如果要创建多个版本应用程序,请创建 DestinationRule 以定义可从 VirtualService 引用的 subsets。
  7. (可选)如果要在服务网格外部调用其他外部服务,请创建 ServiceEntry。

我不会在本文中介绍步骤 1 和 2,因为它们不是特定于 Istio 的。 如果您需要有关这些步骤的帮助,可以查看我在本文末尾提到的文章。 第 3 步也不是 Istio 特定的,但它是其他一切的先决条件,所以让我们从那开始。

Deployment 和 Service

正如我所提到的,应用程序生命周期由 Kubernetes 管理。 因此,您需要从创建 Kubernetes deployment 和 service 开始。 我的情况如下,我有一个容器化的 ASP.NET 核心应用程序,其镜像我已经推送到谷歌镜像仓库。 让我们从创建一个hellohttp-deploy.yaml.yaml文件开始:

apiVersion: v1
kind: Service
metadata:
name: hellohttp-service
labels:
app: hellohttp
spec:
ports:
- port: 80
name: http
selector:
app: hellohttp
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hellohttp-v1
spec:
replicas: 1
selector:
matchLabels:
app: hellohttp
version: v1
template:
metadata:
labels:
app: hellohttp
version: v1
spec:
containers:
- name: hellohttp
image: busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c", "echo 'hello httpd v1' > /var/www/index.html; httpd -f -p 80 -h /var/www/"]
ports:
- containerPort: 80

创建 Deployment 和 Service:

$ kubectl apply -f hellohttp-deploy.yaml
service "hellohttp-service" created
deployment.extensions "hellohttp-v1" created

到目前为止没有任何特定的针对 Istio 的内容。

Gateway

我们现在可以开始研究 Istio Routing。 首先,我们需要为服务网格启用 HTTP/HTTPS 流量。 为此,我们需要创建一个网关。 Gateway 描述了在边缘运行的负载均衡,用于接收传入或传出的 HTTP/TCP 连接。

让我们创建一个hellohttp-gateway.yaml文件:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: hellohttp-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "hellohttp.com"

创建 Gateway:

$ kubectl apply -f hellohttp-gateway.yaml
gateway.networking.istio.io "hellohttp-gateway" created

此时,我们为集群启用了 HTTP 流量。 我们需要将之前创建的 Kubernetes 服务映射到 Gateway。 我们将使用 VirtualService 执行此操作。

VirtualService

VirtualService 实际上将 Kubernetes 服务连接到 Istio 网关。 它还可以执行更多操作,例如定义一组流量路由规则,以便在主机被寻址时应用,但我们不会深入了解这些细节。

让我们创建一个hellohttp-virtualservice.yaml文件:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: hellohttp-virtualservice
spec:
hosts:
- "hellohttp.com"
gateways:
- hellohttp-gateway
http:
- route:
- destination:
host: hellohttp-service

请注意,VirtualService 与特定网关绑定,并定义引用 Kubernetes 服务的主机。

创建 VirtualService:

$ kubectl apply -f hellohttp-virtualservice.yaml
virtualservice.networking.istio.io "hellohttp-virtualservice" created

测试 V1 版本 APP

我们准备测试我们的应用程序了。 我们需要获取 Istio Ingress Gateway 的 IP 地址:

$ istio-ingressgateway   NodePort   10.109.111.38   <none>        15020:32105/TCP,80:30824/TCP,443:32478/TCP,31400:32419/TCP,15443:30884/TCP   4d

当我们在浏览器中打开NodePort-IP时,我们应该看到 hellohttp ASP.NET Core 应用程序:

DestinationRule

在某些时候,您希望将应用更新为新版本。 也许你想分割两个版本之间的流量。 您需要创建一个 DestinationRule 来定义是哪些版本,在 Istio 中称为 subset。

首先,更新 hellohttp-deploy.yaml 文件以使用 v2 版本的容器定义 v2 的 deployment:

apiVersion: v1
kind: Service
metadata:
name: hellohttp-service
labels:
app: hellohttp
spec:
ports:
- port: 80
name: http
selector:
app: hellohttp
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hellohttp-v1
spec:
replicas: 1
selector:
matchLabels:
app: hellohttp
version: v1
template:
metadata:
labels:
app: hellohttp
version: v1
spec:
containers:
- name: hellohttp
image: busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c", "echo 'hello httpd v1' > /var/www/index.html; httpd -f -p 80 -h /var/www/"]
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hellohttp-v2
spec:
replicas: 1
selector:
matchLabels:
app: hellohttp
version: v2
template:
metadata:
labels:
app: hellohttp
version: v2
spec:
containers:
- name: hellohttp
image: busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c", "echo 'hello httpd v2' > /var/www/index.html; httpd -f -p 80 -h /var/www/"]
ports:
- containerPort: 80

创建新的 Deployment:

$ kubectl apply -f hellohttp-deploy.yaml
service "hellohttp-service" unchanged
deployment.extensions "hellohttp-v1" unchanged
deployment.extensions "hellohttp-v2" created

如果使用 EXTERNAL-IP 刷新浏览器,您将看到应用程序的 v1 和 v2 版本交替出现:

这是符合预期的,因为两个版本都暴露在相同的 Kubernetes 服务之后:hellohttp-service。

如果您想将服务仅指向 v2,该怎么办? 这可以通过在 VirtualService 中指定 subset 来完成,但我们需要首先在 DestinationRules 中定义这些 subset。 DestinationRule 本质上是将标签映射到 Istio 的 subset。

创建一个hellohttp-destinationrule.yaml文件:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: hellohttp-destinationrule
spec:
host: hellohttp-service
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2

创建 DestinationRule:

$ kubectl apply -f hellohttp-destinationrule.yaml
destinationrule.networking.istio.io "hellohttp-destinationrule" created

现在你可以从 VirtualService 来引用 v2 subset:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: hellohttp-virtualservice
spec:
hosts:
- "hellohttp.com"
gateways:
- hellohttp-gateway
http:
- route:
- destination:
host: hellohttp-service
subset: v2

更新 VirtualService:

$ kubectl apply -f hellohttp-virtualservice.yaml
virtualservice.networking.istio.io "hellohttp-virtualservice" configured

如果您现在继续浏览 EXTERNAL-IP,您现在应该只能看到应用程序的 v2 版本。

测试AB版本更新

可以从 VirtualService 来引用v2 subset和v1 subset

[root@localhost hello-world]# cat hellohttp-virtualservice.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: hellohttp-virtualservice
spec:
hosts:
- "hellohttp.com"
gateways:
- hellohttp-gateway
http:
- route:
- destination:
host: hellohttp-service
subset: v1
weight: 75
- destination:
host: hellohttp-service
subset: v2
weight: 25

上面的配置就是通过VirtualService 调用DestinationRule 里面定义的host分类,来进行AB 版本的流量分离,进行AB 版本更新。

对于生产环境里面的版本更新可以进行header 主机头匹配,进行版本区分,基础的金丝雀发布更新版本就是这样实现的。

ServiceEntry

我想在 Istio Routing 中提到的最后一件事是 ServiceEntry。 默认情况下,Istio 中的所有外部流量都被阻止。 如果要启用外部流量,则需要创建 ServiceEntry 以列出为外部流量启用的协议和主机。 我不会在这篇文章中展示一个例子,但你可以在这里阅读更多相关内容。

希望这篇文章对你有用! 如果您想了解更多信息,可以使用 codelab 系列以下两部分,其中所有这些概念和更多内容将在逐步的详细教程中进行说明:

Istio Routing 实践掌握virtualservice/gateway/destinationrule/AB版本发布/金丝雀发布的更多相关文章

  1. Istio Routing极简教程

    官网文档: https://istio.io/docs/reference/config/networking/#VirtualService 在学习像Istio这样的新技术时,看一下示例应用程序总是 ...

  2. 灵雀云Istio技术实践专题整理

    Istio技术实践专题(1) Service Mesh Istio 基本概念和架构基础 Istio被称作Kubernetes的最佳云原生拍档.从今天起,我们推出"Istio技术实践" ...

  3. 【从小白到专家】Istio技术实践专题(四):应用接入Istio的正确姿势

    上一篇文章中,我们介绍了Istio针对单集群的三种主流部署安装方式:使用Istioctl安装.使用Helm自定义安装.独立Operator安装.本文将向大家介绍kubernetes中的应用接入Isti ...

  4. Istio流量管理实践之(3): 基于Istio实现流量对比分析

    流量镜像 流量镜像,也称为影子流量,流量镜像提供一种尽可能低的风险为生产带来变化的强大功能.镜像会将实时流量的副本发送到镜像服务.镜像流量发生在主服务的关键请求路径之外. 在非生产或者测试环境中,尝试 ...

  5. 【从小白到专家】收官!Istio技术实践之九:路由控制与灰度发布

    本期是Istio技术实践专题的最后一个模块,主题是Istio的路由控制与灰度发布.上一期我们讲到,虚拟服务(Virtual Service)以及目标规则(Destination Rule)是 Isti ...

  6. 蓝绿部署、红黑部署、AB测试、灰度发布、金丝雀发布、滚动发布的概念与区别(转)

    出处:https://www.baidu.com/link?url=QjboallwNm_jxcL3fHG57wEakiBfAs_3-TChTGu1eBXstlHEsGBc-NDA7AKTqsiroB ...

  7. Istio最佳实践:在K8s上通过Istio服务网格进行灰度发布

    Istio是什么? Istio是Google继Kubernetes之后的又一开源力作,主要参与的公司包括Google,IBM,Lyft等公司.它提供了完整的非侵入式的微服务治理解决方案,包含微服务的管 ...

  8. Istio最佳实践系列:如何实现方法级调用跟踪?

    赵化冰,腾讯云高级工程师,Istio Member,ServiceMesher 管理委员,Istio 项目贡献者,热衷于开源.网络和云计算.目前主要从事服务网格的开源和研发工作. 引言 TCM(Ten ...

  9. Webservice实践(七)CXF 与Spring结合+tomcat发布

    上一节介绍了如何使用CXF 来发布服务,但是没有介绍使用web 容器来发布,很多项目需要用tomcat 这样的容器来发布.另外本节将介绍CXF 与spring 结合的方法. 一 目标: 1.利用spi ...

随机推荐

  1. 题解 洛谷 P5311 【[Ynoi2011]成都七中】

    每次询问是关于 \(x\) 所在的连通块,所以考虑用点分树来解决本题. 点分树上每个节点所对应的子树,都是原树中的一个连通块.询问中给定 \(x\) 和区间 \([l,r]\),其就已经确定了原树的一 ...

  2. css的一些小技巧。修改input样式

    在第一次正式写项目的时候,遇到了几个布局的小技巧.记录一下. 我们常常会遇到图片和文字对齐的一种样式.比如 这样的样式,我们写的时候有时候会出现不对齐的情况.我们有俩种方法 一种就是flex的布局,还 ...

  3. anaconda一站式环境的搭建(anaconda、tensorflow、opencv)

    搭建人工智能图像处理环境 Anaconda一站式开发环境搭建. 工欲善其事必先利其器,在我们学习之前,我们先要搭建一个属于我们自己的开发环境.我们开发的环境是有anaconda.testflow.op ...

  4. 关闭,centos yum的自动更新

    今天我虚拟机提示我满了,,,打开磁盘分析器一看,yum的更新目录满了,本地虚拟跟生产环境的版本完全一致,所以我也不打算更新,找一下命令,得先安装yum-cron ,然后再禁止更新 [root@loca ...

  5. 《Python金融大数据分析》高清PDF版|百度网盘免费下载|Python数据分析

    <Python金融大数据分析>高清PDF版|百度网盘免费下载|Python数据分析 提取码:mfku 内容简介 唯一一本详细讲解使用Python分析处理金融大数据的专业图书:金融应用开发领 ...

  6. 让你的GitHub下载飞速提升到2M/s以上

    2020年7月27日整理发布多种GitHub加速方式! 转载自:https://code.pingbook.top/blog/2020/How-To-Speed-Github.html 1. GitH ...

  7. UDP 绑定信息

    """ 建立->绑定本地ip地址和端口号->接收数据->转码输出->关闭客户端 """ from socket im ...

  8. 1-Numpy的通用函数(ufunc)

    一.numpy“通用函数”(ufunc)包括以下几种: 元素级函数(一元函数):对数组中的每个元素进行运算 数组级函数:统计函数,像聚合函数(例如:求和.求平均) 矩阵运算 随机生成函数 常用一元通用 ...

  9. PHP curl_strerror函数

    (PHP 5 >= 5.5.0) curl_strerror — 返回错误码的描述. 说明 string curl_strerror ( int $errornum ) 返回错误码的文本描述信息 ...

  10. luogu P4948 数列求和 推式子 简单数学推导 二项式 拉格朗日插值

    LINK:数列求和 每次遇到这种题目都不太会写.但是做法很简单. 终有一天我会成功的. 考虑类似等比数列求和的东西 帽子戏法一下. 设\(f(k)=\sum_{i=1}^ni^ka^i\) 考虑\(a ...