Istio流量管理实践之(1): 通过Istio规则来实现TCP入口流量路由的统一管理

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 本文通过一个示例来讲述如何通过一个简单且标准的Istio规则来控制TCP入口流量的路由,从而实现TCP入口流量路由的统一管理。

概述

使用Istio的流量管理模型,本质上是将流量与基础设施扩容进行解耦,让运维人员可以通过Pilot指定流量遵循什么规则,而不是指定哪些pods/VM应该接收流量。通过将流量从基础设施扩展中解耦,就可以让 Istio 提供各种独立于应用程序代码之外的流量管理功能。 这些功能都是通过部署的Envoy sidecar代理来实现的。

在一个典型的网格中,通常有一个或多个用于终结外部 TLS 链接,将流量引入网格的负载均衡器(我们称之为 gateway),然后流量通过sidecar gateway流经内部服务。下图描绘了网关在网格中的使用情况:
图片.png

Istio Gateway 为 HTTP/TCP 流量配置了一个负载均衡,多数情况下在网格边缘进行操作,用于启用一个服务的入口(ingress)流量。网格中可以存在任意数量的 Gateway,并且多个不同的 Gateway 实现可以共存。 对于入口流量管理,可能会问为什么不直接使用 Kubernetes Ingress API ? 原因是 Ingress API 无法表达 Istio 的路由需求。 Ingress 试图在不同的 HTTP 代理之间取一个公共的交集,因此只能支持最基本的 HTTP 路由,最终导致需要将代理的其他高级功能放入到注解(annotation)中,而注解的方式在多个代理之间是不兼容的,无法移植。

此外,Kubernetes Ingress本身不支持TCP协议。因此,即使TCP不是NGINX的限制,也无法通过Ingress创建来配置NGINX Ingress Controller以进行TCP负载均衡。当然可以通过创建一个Kubernetes ConfigMap,来使用NGINX的TCP负载均衡功能,具体可参阅这里:Support for TCP/UDP Load Balancing 。可想而知,这种配置在多个代理中无法兼容与移植。

与Kubernetes Ingress 不同,Istio Gateway 通过将 L4-L6 配置与L7配置分离的方式克服了 Ingress 的上述缺点。 Gateway 只用于配置 L4-L6 功能(例如,对外公开的端口、TLS 配置),所有主流的代理均以统一的方式实现了这些功能。 然后,通过在 Gateway 上绑定 VirtualService 的方式,可以使用标准的 Istio 规则来控制进入 Gateway 的 HTTP 和 TCP 流量。

本文通过一个示例来讲述如何通过一个简单且标准的Istio规则来控制TCP入口流量的路由,从而实现TCP入口流量路由的统一管理。

准备Kubernetes集群

阿里云容器服务Kubernetes 1.11.2目前已经上线,可以通过容器服务管理控制台非常方便地快速创建 Kubernetes 集群。

确保安装配置kubectl 能够连接上Kubernetes 集群。

部署Istio

打开容器服务控制台,在左侧导航栏中选中集群,右侧点击更多,在弹出的菜单中选中 部署Istio。

图片.png

在打开的页面中可以看到Istio默认安装的命名空间、发布名称;
通过勾选来确认是否安装相应的模块,默认是勾选前四项;
第5项是提供基于日志服务的分布式跟踪能力,本示例中不启用。
图片.png

点击 部署Istio 按钮,几十秒钟之后即可完成部署。

自动 Sidecar 注入

Istio就是充分利用了Kubernets Webhook机制实现Envoy Proxy Sidecar的自动注入。执行以下命令可以为命令空间default增加标签istio-injection且值设为enabled。

查看namespace:

图片.png

点击编辑,为 default 命名空间打上标签 istio-injection=enabled

图片.png

TCP Server镜像

你可以直接使用已经构建好的镜像文件:
registry.cn-hangzhou.aliyuncs.com/wangxining/tcptest:0.1

或者按照以下步骤自行构建。

从以下地址克隆代码库:

https://github.com/osswangxining/Istio-TCPRoute-Sample

切换到代码目录可以看到一个Dockerfile:
图片.png

运行以下命令构建镜像,例如:

docker build -t {镜像仓库地址} .

之后推送到你自己的镜像仓库地址。

部署应用

  • 使用 kubectl 部署服务
    cd k8s
    kubectl apply -f deployment.yml
    kubectl apply -f service.yml
    

上面的命令会创建1个Service(tcp-echo)与2个Deployment(tcp-echo-v1tcp-echo-v2),其中这2个Deployment都包含了标签app: tcp-echo,并且Service(tcp-echo)对应到上述2个Deployment:

selector:
    app: "tcp-echo"
  • 确认TCPServer的POD启动:

    kubectl get pods --selector=app=tcp-echo
    NAME                           READY     STATUS    RESTARTS   AGE
    tcp-echo-v1-7c775f57c9-frprp   2/2       Running   0          1m
    tcp-echo-v2-6bcfd7dcf4-2sqhf   2/2       Running   0          1m
    
  • 确认TCPServer的服务:

    kubectl get service --selector=app=tcp-echo
    NAME       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    tcp-echo   ClusterIP   172.19.46.255   <none>        3333/TCP   17h
    

定义 gateway

使用如下命令创建2个Gateway,其中一个Gateway监听31400端口,另一个Gateway监听31401端口。

kubectl apply -f gateway.yaml

gateway.yaml代码如下:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: tcp-echo-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 31400
      name: tcp
      protocol: TCP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: tcp-echo-gateway-v2
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 31401
      name: tcp
      protocol: TCP
    hosts:
    - "*"

如下所示,这2个Gateway共用了一个ingressgateway服务,该ingressgateway使用了Loadbalancer方式暴露,可提供对外使用的IP地址。
图片.png

创建Istio规则

kubectl apply -f destination-rule-all.yaml
kubectl apply -f virtualservice.yaml

该示例规则中定义了2个subset(或者称之为版本),第一个Gateway会把请求到端口31400的TCP流量进行转发到版本v1的POD,第二个Gateway会把请求到端口31401的TCP流量进行转发到版本v2的POD。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: tcp-echo
spec:
  hosts:
  - "*"
  gateways:
  - tcp-echo-gateway
  - tcp-echo-gateway-v2
  tcp:
  - match:
    - port: 31400
      gateways:
        - tcp-echo-gateway
    route:
    - destination:
        host: tcp-echo.default.svc.cluster.local
        subset: v1
        port:
          number: 3333
  - match:
    - port: 31401
      gateways:
        - tcp-echo-gateway-v2
    route:
    - destination:
        host: tcp-echo.default.svc.cluster.local
        subset: v2
        port:
          number: 3333

体验TCP路由功能

  • 查看Ingress Gateway的地址
    点击左侧导航栏中的服务,在右侧上方选择对应的集群和命名空间,在列表中找到istio-ingressgateway的外部端点地址。

  • 打开终端,运行以下命令(前提是安装了nc):

    nc INGRESSGATEWAY_IP 31400
    
  • 输入文字进行如下交互,可以看到该端口的TCP流量转发到了版本v1对应的POD:

    Welcome, you are connected to node cn-beijing.i-2zeij4aznsu1dvd4mj5c.
    Running on Pod tcp-echo-v1-7c775f57c9-frprp.
    In namespace default.
    With IP address 172.16.2.90.
    Service default.
    hello, app1
    hello, app1
    continue..
    continue..
    
  • 查看版本v1的POD的日志:

    kubectl logs -f tcp-echo-v1-7c775f57c9-frprp -c tcp-echo-container | grep Received
    2018/10/17 07:32:29 6c7f4971-40f1-4f72-54c4-e1462a846189 - Received Raw Data: [104 101 108 108 111 44 32 97 112 112 49 10]
    2018/10/17 07:32:29 6c7f4971-40f1-4f72-54c4-e1462a846189 - Received Data (converted to string): hello, app1
    2018/10/17 07:34:40 6c7f4971-40f1-4f72-54c4-e1462a846189 - Received Raw Data: [99 111 110 116 105 110 117 101 46 46 10]
    2018/10/17 07:34:40 6c7f4971-40f1-4f72-54c4-e1462a846189 - Received Data (converted to string): continue..
    
  • 打开另外一个终端,运行以下命令:

    nc INGRESSGATEWAY_IP 31401
    
  • 输入文字进行如下交互,可以看到该端口的TCP流量转发到了版本v2对应的POD:

    Welcome, you are connected to node cn-beijing.i-2zeij4aznsu1dvd4mj5b.
    Running on Pod tcp-echo-v2-6bcfd7dcf4-2sqhf.
    In namespace default.
    With IP address 172.16.1.95.
    Service default.
    hello, app2
    hello, app2
    yes,this is app2
    yes,this is app2
    
  • 查看版本v2的POD的日志:

    kubectl logs -f tcp-echo-v2-6bcfd7dcf4-2sqhf -c tcp-echo-container | grep Received
    2018/10/17 07:36:29 1a70b9d4-bbc7-471d-4686-89b9234c8f87 - Received Raw Data: [104 101 108 108 111 44 32 97 112 112 50 10]
    2018/10/17 07:36:29 1a70b9d4-bbc7-471d-4686-89b9234c8f87 - Received Data (converted to string): hello, app2
    2018/10/17 07:36:37 1a70b9d4-bbc7-471d-4686-89b9234c8f87 - Received Raw Data: [121 101 115 44 116 104 105 115 32 105 115 32 97 112 112 50 10]
    2018/10/17 07:36:37 1a70b9d4-bbc7-471d-4686-89b9234c8f87 - Received Data (converted to string): yes,this is app2
    

总结

本文通过一个示例来讲述如何通过一个简单且标准的Istio规则来控制TCP入口流量的路由,从而实现TCP入口流量路由的统一管理。

欢迎大家使用阿里云上的容器服务,快速搭建微服务的开放治理平台Istio,比较简单地集成到自己项目的微服务开发中。

相关实践学习
使用ACS算力快速搭建生成式会话应用
阿里云容器计算服务 ACS(Container Compute Service)以Kubernetes为使用界面,采用Serverless形态提供弹性的算力资源,使您轻松高效运行容器应用。本文将指导您如何通过ACS控制台及ACS集群证书在ACS集群中快速部署并公开一个容器化生成式AI会话应用,并监控应用的运行情况。
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
安全 Linux 网络安全
/var/log/secure日志详解
Linux系统的 `/var/log/secure` 文件记录安全相关消息,包括身份验证和授权尝试。它涵盖用户登录(成功或失败)、`sudo` 使用、账户锁定解锁及其他安全事件和PAM错误。例如,SSH登录成功会显示&quot;Accepted password&quot;,失败则显示&quot;Failed password&quot;。查看此文件可使用 `tail -f /var/log/secure`,但通常只有root用户有权访问。
3679 4
|
缓存 运维 Kubernetes
NVIDIA GPU Operator分析一:NVIDIA驱动安装
背景我们知道,如果在Kubernetes中支持GPU设备调度,需要做如下的工作:节点上安装nvidia驱动节点上安装nvidia-docker集群部署gpu device plugin,用于为调度到该节点的pod分配GPU设备。除此之外,如果你需要监控集群GPU资源使用情况,你可能还需要安装DCCM exporter结合Prometheus输出GPU资源监控信息。要安装和管理这么多的组件,对于运维
5417 0
NVIDIA GPU Operator分析一:NVIDIA驱动安装
|
弹性计算 容器 RDMA
在Kubernetes上使用RDMA
### RDMA RDMA(全称RemoteDirect Memory Access) 它为了解决网络传输中服务器端数据处理的延迟而产生。 它的原理是将待传输的数据从一台计算机的内存,直接传输到另一台计算机的内存,整个传输过程无需操作系统和协议栈的介入。
10392 0
|
运维 Kubernetes API
k8s集群新增master 、work节点重新生成token、certificate-key等操作
k8s集群运维中通常会存在新增和删除节点,一些token、certificate-key信息 会被遗忘,怎么去重生成了 可以按照以下方式
5057 0
|
Kubernetes 搜索推荐 前端开发
containerd 镜像构建工具 -- nerdctl 和 buildkit
containerd 镜像构建工具 -- nerdctl 和 buildkit
7875 0
|
12月前
|
机器学习/深度学习 人工智能 自然语言处理
深入理解深度学习:从基础到前沿
本文将带你走进深度学习的世界,从基础概念到前沿应用,让你对深度学习有更深入的理解。我们将通过简单易懂的语言和生动的比喻,让你轻松掌握深度学习的核心知识。同时,我们还会分享一些实用的技巧和方法,帮助你更好地运用深度学习解决实际问题。无论你是初学者还是有一定基础的学习者,这篇文章都将为你提供有价值的参考和启示。让我们一起探索深度学习的奥秘吧!
403 1
|
存储 容灾 NoSQL
同城双活的必修课 - 落地经验与关键挑战解析
同城双活作为一种容灾架构,通过在同一城市建立两个数据中心,以确保在一个数据中心发生故障时,系统能够快速切换到另一个数据中心,从而提高系统的可用性
1593 2
同城双活的必修课 - 落地经验与关键挑战解析
|
存储 Kubernetes 调度
|
Kubernetes 网络协议 微服务
Istio的流量管理(实操一)
Istio的流量管理(实操一)
230 3
|
11月前
|
API
Istio 使用ingress和gateway两种方式公开服务
本文档指导您完成Istio网关的部署与配置。首先安装`istiod`(步骤略过)。接着,创建`ingress.yaml`文件,定义Istio入口网关的服务、部署及权限设置,通过`kubectl apply -f ingress.yaml`命令应用。最后,创建Ingress资源,指定主机名、后端服务及TLS配置,实现对外部请求的路由管理。
970 1