当前位置: 首页 > news >正文

一文学习 Spring 声明式事务源码全流程总结脊

在之前的文章中,我们花了大量的篇幅,从记录后端pod真实ip开始说起,然后引入envoy,再解决了各种各样的需求:配置自动重载、流量劫持、sidecar自动注入,到envoy的各种能力:熔断、流控、分流、透明代理、可观测性等等,已经可以支撑起一个完整的服务治理框架了

而今天介绍的istio,正是前面提到的这些所有功能的集大成者,从本文开始,我们将详细介绍istio,并且与之前手搓的功能做一个详细的对比,为大家以后选择服务治理的某个功能提供参考

istio架构

┌──────────────┐

│ istiod │ ← 控制面

│ (Pilot+CA) │

└──────┬───────┘

│ xDS (gRPC / TLS)

┌────────────┐ │ ┌────────────┐

│ Envoy │?───┼───?│ Envoy │ ← 数据面

│ (Sidecar) │ │ (Sidecar) │

└─────▲──────┘ └─────▲──────┘

│ iptables │

│ │

App Pod App Pod

数据面就是之前一直在研究的envoy,包括4/7代理、熔断、限流、可观测性等等,envoy就是执行由控制面下发的配置

控制面istiod主要的职责:将配置下发到每一个envoy去。由于istio中配置以crd的形式成为了k8s的资源,所以要不断的监听k8s apiserver,将资源的变化翻译成envoy看得懂的配置,并且下发到envoy去

至于其余istio的资源,我们后面详细介绍

istio安装

不说废话,先把istio安装上去再说

首先准备好k8s集群,其次下载istio(这一步有可能需要上网)

curl -L https://istio.io/downloadIstio | sh -

cd istio-*

sudo ln -s $PWD/istioctl /usr/local/bin/istioctl

验证兼容性

istioctl x precheck

开始安装

istioctl install --set profile=default -y

由于镜像仓库没法直接使用,所以需要一些特殊的方法,具体可以看这篇文章: 快速拉取docker镜像

需要的镜像有:

docker.io/istio/pilot:1.28.2

docker.io/istio/proxyv2:1.28.2

安装完成:

? kubectl -n istio-system get pod

NAME READY STATUS RESTARTS AGE

istio-ingressgateway-865c448856-qs8s2 1/1 Running 0 8s

istiod-86c75775bb-j7qbg 1/1 Running 0 12s

安装完成,要从哪儿开始呢?

istio的自动注入

kubectl label namespace default istio-injection=enabled

同之前envoy一样,给namespace打上标签之后,重启服务即可

kubectl rollout restart deploy nginx-test

重启之后sidecar已经注入进去了,我们来观察一下istio注入到底做了什么事情

先describe看看events

Events:

Type Reason Age From Message

---- ------ ---- ---- -------

Normal Scheduled 8s default-scheduler Successfully assigned default/nginx-test-6f855b9bb9-9phsv to wilson

Normal Pulled 8s kubelet Container image "docker.io/istio/proxyv2:1.28.2" already present on machine

Normal Created 8s kubelet Created container: istio-init

Normal Started 8s kubelet Started container istio-init

Normal Pulled 8s kubelet Container image "docker.io/istio/proxyv2:1.28.2" already present on machine

Normal Created 8s kubelet Created container: istio-proxy

Normal Started 8s kubelet Started container istio-proxy

Normal Pulled 6s kubelet Container image "registry.cn-beijing.aliyuncs.com/wilsonchai/nginx:latest" already present on machine

Normal Created 6s kubelet Created container: nginx-test

Normal Started 5s kubelet Started container nginx-test

1个initContainer,1个业务container和1个sidecar

其中initContainer:

Init Containers:

istio-init:

Container ID: containerd://2bf56cd37703d82a2a43e94e8c8d683ed66b0afe22bf7148a597d67b89a727a8

Image: docker.io/istio/proxyv2:1.28.2

Image ID: docker.m.daocloud.io/istio/proxyv2@sha256:39065152d6bd3e7fbf6bb04be43c7a8bbd16b5c7181c84e3d78fa164a945ae7f

Port:

Host Port:

Args:

istio-iptables

-p

15001

-z

15006

-u

1337

-m

REDIRECT

-i

*

-x

-b

*

-d

15090,15021,15020

--log_output_level=default:info

...

和之前envoy中劫持流量的做法一样,istio依然是使用iptables将端口流量导入到代理之中处理

尝试访问一下:

? curl 10.22.12.178:30785/test

i am backend in backend-6d76f54494-g6srz

成功,再次查看istio-proxy日志。空的?为了调试方便,将其打开并且输出至控制台

kubectl -n istio-system edit cm istio

apiVersion: v1

data:

mesh: |-

accessLogFile: /dev/stdout

...

至此,istio的第一个功能探索完毕,自动注入sidecar container并且完成了流量劫持

Upgrade Required 426 的问题

当前的架构是左图,现在要前进到右图

watermarked-istio_1

其实就是在backend注入istio-proxy,直接重启就好

? kubectl get pod -owide

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES

backend-5d4d7b598c-f7852 2/2 Running 0 13s 10.244.0.49 wilson

nginx-test-6f855b9bb9-9phsv 2/2 Running 0 58m 10.244.0.48 wilson

注入完成,测试一下

? curl 10.22.12.178:30785/test

Upgrade Required

? kubectl logs -f -l app=nginx-test -c istio-proxy

[2026-01-26T07:54:42.977Z] "GET /test HTTP/1.1" 426 - upstream=10.244.0.48:80 duration=6ms route=default

[2026-01-26T07:54:42.978Z] "- - -" 0 - upstream=10.105.148.194:10000 duration=9ms route=-

在nginx注入istio-proxy,backend没有注入的时候并没有报错。而一旦nginx与backend都注入的时候就会出现Upgrade Required (426)错误,Nginx Sidecar 发现目标(Backend)是一个纯文本服务,它会回退到“透明代理”模式,简单地把 Nginx 发出的流量透传出去

Nginx Sidecar 发现目标也有 Sidecar,它会尝试建立一个高度优化的、基于 mTLS 的隧道(关于mTLS后面会详细介绍)。如果此时 Nginx 发出的请求头(比如缺少 Host 字段,或者使用了 HTTP/1.0)不符合 Envoy 对这种隧道

协议的预期,Envoy 可能会向 Nginx 发送一个特殊的响应,或者 Nginx 在尝试通过这种隧道通信时,因为某些 Header 冲突(如 Connection: close)自发产生了 426 错误

想要解决这个问题有两种方法

改造nginx中加入标记

location /test {

proxy_http_version 1.1; # 必须添加这一行

proxy_set_header Host $host; # 这一行也是必须的

proxy_pass http://backend_ups;

}

Nginx 的 proxy_pass 默认使用 HTTP/1.0。在 Istio 环境中,HTTP/1.0 不支持长连接(Keep-Alive)以及一些现代的协议协商,这与 Istio Sidecar(Envoy)默认的 L7 代理行为冲突,Istio 需要 HTTP/1.1 来支持复杂连接管理问题

改造backend service

如果nginx改造有难度,那也可以尝试改造backend-service

apiVersion: v1

kind: Service

metadata:

name: backend-service

namespace: default

spec:

ports:

- name: tcp-80 # 原为 http-80 改为 tcp-80

port: 10000

protocol: TCP

targetPort: 10000

selector:

app: backend

Istio 只有在识别到流量是 HTTP 时才会进行深度的协议检查和转换。如果你把这个服务声明为 TCP,Istio 就会将其视为原始字节流进行透传,不再关心它是 HTTP/1.0 还是 1.1。优点就是彻底解决 426 问题,无需改 Nginx。

缺点则是你会失去 Istio 针对该服务的 HTTP 监控指标(如请求数、4xx/5xx 统计)、分布式追踪以及基于路径的路由功能

http 1.0 与 http 1.1

这里再简单介绍一下两个协议版本的区别

连接管理(最显著的区别)

HTTP 1.0:短连接 (Short-lived),默认情况下,客户端每发起一个请求,都要与服务器建立一次 TCP 三次握手。请求结束并收到响应后,TCP 连接立即关闭。如果页面有 10 张图片,浏览器就要建立 10 次 TCP 连接。这带来了极高的延迟和资源开销。

HTTP 1.1:持久连接 (Persistent Connection / Keep-Alive)。默认开启 Connection: keep-alive。一个 TCP 连接可以被多个请求复用。只有在明确声明 Connection: close 或连接超时后才会关闭。

在 Istio 中: Envoy 极度依赖持久连接来维持高性能的 Sidecar 间隧道。HTTP 1.0 的频繁断开会让 Envoy 感到“压力山大”,甚至认为这是一种非标准的协议行为。

Host Header

HTTP 1.0:人们认为一个 IP 对应一个网站,所以请求头里不需要带域名信息。

HTTP 1.1:随着虚拟主机(一个 IP 跑多个网站)的流行,HTTP 1.1 规定请求头必须包含 Host 字段。

在 K8s/Istio 中: Istio 的路由决策、Service 的匹配完全依赖 Host 头。这也是为什么 Nginx 使用 HTTP 1.0 转发时,如果不手动补全 Host 头,后端往往会返回 404 或协议错误。

以上是istio必须要求HTTP 1.1最主要的两个因素,当然还有其他非常重要的区别

特性 HTTP 1.0 HTTP 1.1

连接模型 默认短连接,每次请求新开 TCP 默认持久连接 (Keep-Alive),复用 TCP

Host 头部 可选 (导致无法支持虚拟主机) 必须 (支持一 IP 多域名)

流水线 (Pipelining) 不支持 支持 (但在实际应用中受限)

断点续传 不支持 支持 (通过 Range 头部)

缓存控制 简单 (Expires) 复杂且强大 (Cache-Control, ETag)

默认协议版本 许多旧软件(如 Nginx proxy)的默认值 现代 Web 应用的基石标准

小结

本章内容算是一个开胃小菜,成功安装了istio,并且解决了一个非常常见的426问题,至于怎么把之前在envoy的那些最佳实践搬迁到istio,那就是后面的内容了,敬请期待

后记

如果整个namespace都已经有了注入标签istio-injection=enabled,但是某个deployment不想让istio注入

kubectl patch deployment nginx -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/inject":"false"}}}}}'铝秦秃欠

http://www.jsqmd.com/news/632732/

相关文章:

  • 2026年质量好的长春钝化处理工艺/汽车零部件钝化处理/铝合金钝化处理/压铸件钝化处理行业内知名厂家推荐 - 品牌宣传支持者
  • 锂电池测试规范MSDS与UN38.3认证的关系
  • 训练阶段未对齐,推理必然崩塌!,SITS2026首次公开长上下文预训练数据配比黄金公式(含Python验证脚本)
  • 翻译模型Hunyuan-MT-7B体验分享:开箱即用,38种语言互译效果超预期
  • 立知-多模态重排序模型lychee-rerank-mm实战:基于LangChain的智能文档处理系统
  • OpenCV多线程编程:从单线程到多线程的视频处理方
  • 5秒克隆声音!IndexTTS 2.0零基础教程:手把手教你制作专属配音
  • Graphormer模型在IDE中高效开发:IntelliJ IDEA集成与调试技巧
  • 2026年热门的铝铸件五轴机械加工/铸件机械加工/长春铝合金机械加工/结构件机械加工厂家选购参考建议 - 行业平台推荐
  • Eleventy 变身 Build Awesome:开源静态网站生成器商业化困境凸显
  • Coze-Loop与IntelliJ IDEA插件开发实战
  • 2026年太空舱民宿公司技术实力拆解:成都太空舱民宿公司、成都景区规划推荐、成都木屋民宿公司、成都民宿规划设计选择指南 - 优质品牌商家
  • Vue + Iframe 实战:打造企业级流程配置中心先
  • Wan2.1-UMT5智能体(Agent)应用:自主脚本编写与视频生成
  • 造相-Z-Image文生图引擎:5分钟上手,用中文描述生成高清写实图片
  • Agent-Sandbox UI 上线,来看看有哪些的功能是你经常使用的?嘏
  • 存储文件操作
  • intv_ai_mk11镜像免配置:开箱即用网页界面+独立venv环境部署解析
  • Lychee-Rerank快速部署:Windows/Mac/Linux三平台Streamlit启动指南
  • 不满意Oh My Zsh启动卡顿,来试试Starship吧燎
  • 2026年知名的化工厂酸原料/工业盐酸原料/氢氧化钠酸原料厂家推荐与选择指南 - 行业平台推荐
  • lora-scripts详细使用手册:图文并茂,带你完成LoRA训练全流程
  • 2026年评价高的北京办公室装修设计/北京办公室装修工程高评分公司推荐 - 行业平台推荐
  • 别再踩坑了!SQL Server数据类型那点事儿,看懂这篇少背三个锅型
  • 前端代码质量检查
  • Qwen3-Reranker实战案例:构建带反馈机制的迭代式RAG重排系统
  • 5分钟搞定:DeepSeek-R1-Distill-Qwen-1.5B网页版对话机器人搭建
  • 【实战部署+模型优化】YOLOv8花卉分类检测系统:从数据集构建到Web端应用全流程解析
  • 2026年比较好的卷材珍珠棉/护角珍珠棉/定制珍珠棉厂家最新推荐 - 品牌宣传支持者
  • Qwen Pixel Art新手指南:如何用Gradio界面实时调整prompt并预览变化