2024-11-21 14:43:02
多年来,我尝试过多款笔记和 Markdown 编辑工具,包括 Typora、Notion 和 Obsidian。每一款工具都有它的优缺点,但最终我决定将笔记迁移到 Obsidian。这篇文章将详细记录我的思考过程、对比分析,以及迁移的原因。
最初,我使用 Typora 作为主要的 Markdown 编辑工具。Typora 简洁优雅,支持多种文档格式导出,是一款极具吸引力的软件。然而,随着我管理的文档和笔记日益增多,Typora 的缺点也逐渐暴露:
在发现 Typora 的局限性后,我转而使用 Notion。Notion 提供了强大的笔记管理能力,其数据库功能让我能够轻松归档和分类文档,并支持跨平台协作。这一阶段,我还利用 Notion 构建了家庭账本和知识库。然而,随着时间推移,Notion 的一些问题让我逐渐感到不满:
最近阅读了 全面提升 Obsidian 体验:插件与日常技巧分享,让我重新审视 Obsidian 的潜力。早年试用时,我觉得 Obsidian 界面“丑陋”,文件组织方式也不够直观。然而,现在的 Obsidian 已今非昔比,丰富的插件生态、灵活的文件管理能力,以及对开源社区的支持,让我再次尝试并最终选择了它。
在迁移到 Obsidian 之前,我仔细对比了 Typora、Notion 和 Obsidian 的优缺点。以下是对比表:
特性 | Typora | Notion | Obsidian |
---|---|---|---|
价格 | 商业软件,需要购买 | 个人用户免费,AI 功能 $10/月 | 免费,开源软件 |
优点 | 界面简洁,导出多种文档格式 | 功能强大,适合协作,数据库功能优秀 | 丰富的插件生态,灵活的文档管理,开源透明 |
缺点 | 无文件管理,无插件支持 | 在线依赖,不支持本地管理,文件导出问题 | 插件功能复杂,需要手动调整,入门稍陡 |
适用场景 | 单文档编辑 | 知识库管理与协作 | 高度定制化的本地知识管理和 Markdown 编辑 |
在使用 Typora 和 Notion 后,我发现自己的需求更倾向于 Obsidian 所提供的功能:
尽管 Obsidian 非常适合我的需求,但仍存在一些小问题:
以下是我最常用的插件清单:
通过这些插件,我将 Obsidian 打造成了一个功能强大的笔记工具,既满足了个人知识管理需求,又能够支持博客写作。
从 Typora 到 Notion,再到最终的 Obsidian,是我对笔记工具需求不断变化的结果。Typora 的简洁、Notion 的强大都吸引过我,但 Obsidian 开源、可扩展、本地化的特性,真正让我感受到自由和高效。虽然使用中仍有一些问题,但通过插件和社区支持,我已经完全适应了 Obsidian 的生态。
如果你也在寻找一款强大的 Markdown 笔记工具,不妨试试 Obsidian。或许它也能成为你的最终选择!
2024-11-18 11:48:39
这是我关于 Istio ambient 模式系列文章的第一篇。在接下来的几篇中,我将深入探讨 ambient 模式的关键组件及其工作原理,包括 ztunnel 如何将流量转发到 waypoint proxy,waypoint proxy 如何处理流量,以及通过 bookinfo 示例完整理解流量路径的操作。由于流量拦截是服务网格的基础功能,因此我选择从它开始,为大家提供扎实的理解基础。
Istio ambient 模式是一种无需在每个 pod 中注入 sidecar 的服务网格实现方式。它通过在 pod 的网络命名空间内配置透明流量拦截和重定向,使应用程序无需修改即可享受服务网格的功能。以下内容将详细解析透明流量拦截的实现过程,涉及组件如 Istio CNI Node Agent、ztunnel、网络命名空间 和 iptables 规则,并通过流程图和示意图进行说明。
网络命名空间(Network Namespace) 是 Linux 内核的功能,用于隔离不同进程的网络环境。每个网络命名空间都有独立的网络设备、IP 地址、路由表和 iptables 规则。容器技术(如 Docker、Kubernetes)利用网络命名空间为每个容器(或 pod)提供独立的网络栈。
Istio CNI Node Agent 是 ambient 模式中的核心组件之一,负责在 Kubernetes 节点上检测加入 ambient 网格的 pod,并为这些 pod 配置流量重定向规则。需要注意的是,这里使用的是 Istio CNI Node Agent,而非传统的 Istio CNI 插件。Node Agent 是一个守护进程,与 ztunnel 协同工作,而不是直接参与网络插件的工作。
ztunnel 是 ambient 模式中的重要组件,以 DaemonSet 的形式运行在每个节点上,负责:
HBONE(HTTP-Based Overlay Network Encapsulation) 是 Istio 引入的协议,用于在 ztunnel 和 waypoint proxy 之间传输任意 TCP 流量。HBONE 利用 HTTP/2 和 HTTP/3 的多路复用及加密特性,提高通信效率和安全性。
在 ambient 模式下,应用程序 pod 无需修改代码,也不需要注入 sidecar。流量拦截和重定向的主要过程发生在 pod 的网络命名空间 内部,这种方式避免了与底层 CNI 的冲突。以下是其步骤概览:
istio.io/dataplane-mode=ambient
)。想了解更多关于 Istio CNI 处理 iptables 的细节请见我的另一篇博客 Istio ambient 模式中的 iptables 规则解析。
你可以通过下面的命令查看所有 ztunnel 日志中有关流量拦截的记录,可以帮助你理解 ztunnel 的运行原理:
kubectl -n istio-system logs -l app=ztunnel | grep -E "inbound|outbound"
你将看到例如下面的输出,注意里面的 inbound
和 outbound
是相对于 ztunnel 而言的。
入站流量示例
2024-11-16T10:33:01.410751Z info access connection complete src.addr=10.28.2.19:58000 src.workload="bookinfo-gateway-istio-64fc6d75d6-s442s" src.namespace="default" src.identity="spiffe://cluster.local/ns/default/sa/bookinfo-gateway-istio" dst.addr=10.28.2.18:15008 dst.hbone_addr=10.28.2.18:9080 dst.service="productpage.default.svc.cluster.local" dst.workload="productpage-v1-57ffb6658c-tgbjs" dst.namespace="default" dst.identity="spiffe://cluster.local/ns/default/sa/bookinfo-productpage" direction="inbound" bytes_sent=9603 bytes_recv=2052 duration="2110ms"
该日志描述了从 bookinfo-gateway-istio
到 productpage
的入站流量。流量经过 ztunnel 的 15008 端口,使用了 HBONE 隧道加密,身份通过 SPIFFE 确认。
出站流量示例
2024-11-16T10:32:59.360677Z info access connection complete src.addr=10.28.2.18:51960 src.workload="productpage-v1-57ffb6658c-tgbjs" src.namespace="default" src.identity="spiffe://cluster.local/ns/default/sa/bookinfo-productpage" dst.addr=10.28.2.14:15008 dst.hbone_addr=34.118.226.6:9080 dst.service="details.default.svc.cluster.local" dst.workload="waypoint-7594b5b786-vgjwz" dst.namespace="default" dst.identity="spiffe://cluster.local/ns/default/sa/waypoint" direction="outbound" bytes_sent=794 bytes_recv=414 duration="40ms"
此日志描述了 productpage
pod 访问 details
服务时的出站流量。流量由 ztunnel 使用 HBONE 隧道转发到 waypoint pod(15008
端口)。
Istio ambient 模式通过 Istio CNI Node Agent 和 ztunnel 的协作,实现了无需 sidecar 的透明流量拦截。其关键特性包括:
后续文章中,我将进一步探讨 Istio ambient 模式的高级功能,包括 L7 流量路径分析和网络拓扑构建过程,敬请期待。
2024-11-18 11:47:02
在 上一篇博客 中,我概述了 Istio ambient 模式中 pod 网络命名空间内注入的 iptables 规则。本文将深入解析这些规则,探讨它们是如何在 pod 内实现透明流量拦截和重定向的。
在 pod 的网络命名空间内,Istio CNI node agent 会设置一系列 iptables 规则,以实现流量的透明拦截与重定向。下面的规则展示了 Istio 在 mangle 和 nat 表中注入的内容,确保入站和出站流量经过适当的处理。
# Generated by iptables-save v1.8.9 (nf_tables) on Thu Nov 14 08:43:17 2024
*mangle
:PREROUTING ACCEPT [99138:22880045] # mangle 表中的 PREROUTING 链,默认策略为 ACCEPT。
:INPUT ACCEPT [0:0] # mangle 表中的 INPUT 链,默认策略为 ACCEPT。
:FORWARD ACCEPT [0:0] # mangle 表中的 FORWARD 链,默认策略为 ACCEPT。
:OUTPUT ACCEPT [100900:34940164] # mangle 表中的 OUTPUT 链,默认策略为 ACCEPT。
:POSTROUTING ACCEPT [0:0] # mangle 表中的 POSTROUTING 链,默认策略为 ACCEPT。
:ISTIO_OUTPUT - [0:0] # 自定义的 ISTIO_OUTPUT 链,用于处理 Istio 的出站流量。
:ISTIO_PRERT - [0:0] # 自定义的 ISTIO_PRERT 链,用于处理 Istio 的预路由流量。
-A PREROUTING -j ISTIO_PRERT # 将所有 PREROUTING 流量跳转到 ISTIO_PRERT 链。
-A OUTPUT -j ISTIO_OUTPUT # 将所有 OUTPUT 流量跳转到 ISTIO_OUTPUT 链。
-A ISTIO_OUTPUT -m connmark --mark 0x111/0xfff -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff
# 如果连接标记为 0x111/0xfff,则恢复连接标记,用于连接追踪的一致性。
-A ISTIO_PRERT -m mark --mark 0x539/0xfff -j CONNMARK --set-xmark 0x111/0xfff
# 如果数据包标记为 0x539/0xfff,在 PREROUTING 链中将其连接标记设置为 0x111/0xfff。
COMMIT # 应用 mangle 表规则。
# Completed on Thu Nov 14 08:43:17 2024
# Generated by iptables-save v1.8.9 (nf_tables) on Thu Nov 14 08:43:17 2024
*nat
:PREROUTING ACCEPT [2:120] # nat 表中的 PREROUTING 链,默认策略为 ACCEPT。
:INPUT ACCEPT [0:0] # nat 表中的 INPUT 链,默认策略为 ACCEPT。
:OUTPUT ACCEPT [119:9344] # nat 表中的 OUTPUT 链,默认策略为 ACCEPT。
:POSTROUTING ACCEPT [0:0] # nat 表中的 POSTROUTING 链,默认策略为 ACCEPT。
:ISTIO_OUTPUT - [0:0] # 自定义的 ISTIO_OUTPUT 链,用于处理 Istio 的出站 NAT 流量。
:ISTIO_PRERT - [0:0] # 自定义的 ISTIO_PRERT 链,用于处理 Istio 的预路由 NAT 流量。
-A PREROUTING -j ISTIO_PRERT # 将所有 PREROUTING 流量跳转到 ISTIO_PRERT 链。
-A OUTPUT -j ISTIO_OUTPUT # 将所有 OUTPUT 流量跳转到 ISTIO_OUTPUT 链。
-A ISTIO_OUTPUT -d 169.254.7.127/32 -p tcp -m tcp -j ACCEPT
# 如果目标地址为 169.254.7.127(可能是 Istio 内部地址),允许 TCP 流量通过。
-A ISTIO_OUTPUT -p tcp -m mark --mark 0x111/0xfff -j ACCEPT
# 如果数据包标记为 0x111/0xfff,允许 TCP 流量通过。
-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -j ACCEPT
# 允许发往本地回环接口(但不包括 127.0.0.1)的流量通过。
-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -p tcp -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15001
# 将发往非 127.0.0.1 的出站 TCP 流量(且标记不是 0x539/0xfff)重定向到端口 15001(Istio 出站流量入口)。
-A ISTIO_PRERT -s 169.254.7.127/32 -p tcp -m tcp -j ACCEPT
# 如果源地址为 169.254.7.127,允许 TCP 流量通过 PREROUTING 链。
-A ISTIO_PRERT ! -d 127.0.0.1/32 -p tcp -m tcp ! --dport 15008 -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15006
# 将非 127.0.0.1 且目标端口不是 15008 的入站 TCP 流量(标记不是 0x539/0xfff)重定向到端口 15006(Istio 入站流量入口)。
COMMIT # 应用 nat 表规则。
# Completed on Thu Nov 14 08:43:17 2024
这些 iptables 规则通过特定的端口号来区分并处理不同类型的流量:
这些端口使得 Istio 能够对入站、出站及内部流量进行透明的管理与控制,从而实现细粒度的安全策略与流量控制。更多关于端口号的使用请参考 Istio 应用要求。
0x539
的作用0x539
是用于标识 Istio 代理发出的流量的标记。这一标记在流量进入 iptables 规则时被设置,用于区分由代理(如 ztunnel)处理过的数据包,防止其被重复代理或误处理。
0x111
的作用0x111
用于连接级别的标记管理,在 Istio 网格中标识已由代理处理过的整个连接。通过 iptables 的 CONNMARK
模块,0x111
标记能够从单个数据包扩展到整个连接的生命周期,从而加速后续数据包的匹配。
下图展示了流量在 iptables 规则中的执行路径,帮助理解流量的匹配和重定向过程:
想进一步了解 Istio CNI 如何处理 iptables,请参考代码 istio/cni/pkg/iptables/iptables.go at master · istio/istio · GitHub。
以下是同节点与跨节点的加密和明文流量路径的可视化图示:
跨节点的加密流量路径
跨节点的明文流量路径
同节点的加密流量路径
同节点的明文流量路径
OUTPUT
链中被匹配,符合条件的流量被重定向到 ISTIO_OUTPUT
链。ISTIO_OUTPUT
链中,流量被标记并被接受。通过解析 Istio ambient 模式下的 iptables 规则,我们可以看到,Istio 通过 CNI 插件在 pod 内设置了一系列透明的流量拦截规则。这些规则确保了流量在进出 pod 时能够按预期被 ztunnel 代理处理,从而实现更细粒度的流量管理和安全策略应用。未来我们将继续探索更多关于 Istio ambient 模式下的网络细节,敬请关注。
2024-11-07 16:48:08
最近我在研究 Istio Ambient 模式中的透明流量劫持,过程中涉及了跨网络命名空间管理套接字的功能。在 Istio 官方的博客 Maturing Istio Ambient: Compatibility Across Various Kubernetes Providers and CNIs 中也提到了这一点,让我对 Linux 套接字 API 的这个功能产生了浓厚的兴趣。所以,我决定写下这篇博客,分享如何在 Linux 系统中跨网络命名空间管理套接字的细节。
网络命名空间是一种 Linux 内核特性,可以把系统的网络资源(例如 IP 地址、路由表等)分割成多个独立的实例。这样每个实例就可以为不同的进程提供独立的网络环境。比如,Docker 使用网络命名空间为每个容器提供独立的网络栈,让它们之间的网络资源互相隔离。
通过网络命名空间,不同的进程可以有独立的网络配置,比如不同的 IP 地址和路由设置。但即使网络命名空间实现了隔离,Linux 的套接字 API 仍然可以让进程跨网络命名空间操作套接字。
在一个命名空间中运行的进程可以创建一个套接字,并将它放到另一个网络命名空间中,这让我们可以实现非常灵活的网络通信。比如,可以在一个特定的网络命名空间中创建监听套接字,让其他命名空间中的进程共享这个套接字。这种功能在容器编排和微服务架构中非常有用。
下面是一个简单的例子,使用 nc
命令创建套接字,使其绑定到指定的网络设备或命名空间。
因为我使用的 macOS 不支持 Linux 的网络命名空间,但可以使用 Docker Desktop 模拟相应的环境。下面是在 macOS 上使用 Docker 来演示的方法:
安装 Docker Desktop
配置虚拟网络
docker network create --driver bridge my_bridge
创建网络命名空间(使用 Docker 容器模拟)
使用 Docker 创建两个容器,分别模拟两个网络命名空间:
docker run -d --name ns1 --network my_bridge --privileged alpine sleep infinity
docker run -d --name ns2 --network my_bridge --privileged alpine sleep infinity
创建容器时直接将它们连接到这个虚拟网络,以便它们可以相互通信。
跨命名空间创建套接字
使用 docker exec
命令进入容器并配置网络接口:
在 ns1
容器中运行一个监听套接字:
docker exec ns1 sh -c "nc -l -k -p 8080"
获取 ns1
容器的 IP 地址:
export NS1_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ns1)
在 ns2
容器中,使用 nc
命令访问 ns1
容器中的套接字:
docker exec ns2 sh -c "echo 'Hello from ns2' | nc $NS1_IP 8080"
此时,我们可以在 ns1
容器的界面中看到来自 ns2
容器的 Hello from ns2
字符串。尽管 ns1
和 ns2
属于不同的容器,但通过正确的配置,ns2
仍然可以访问 ns1
中的套接字。
可以理解为通过在 ns2
监听 ns1
的套接字,类似于建立了一个“隧道”来实现通信。这种方式实际上是建立了一条直接的通信通道,使得两个容器之间能够进行数据交换。虽然它没有真正构建 VPN 那样复杂的隧道,但从逻辑上来说,ns2
和 ns1
之间可以通过这个套接字来传递数据,相当于建立了一个轻量级的点对点连接通道。
这种“隧道”式的通信在许多实际场景中非常有用,以下是一些例子:
跨网络命名空间管理套接字在容器管理、调度系统和微服务架构中有很多应用。例如,可以用这种方式实现服务的透明负载均衡,建立隧道或进行网络流量调试。但这种灵活性也要求我们在设计网络安全策略时更加谨慎,以防止不同命名空间之间的潜在通信带来的安全问题。
2024-10-30 14:20:22
随着 AWS 宣布将在 2026 年 9 月 30 日停用 AWS App Mesh,许多企业正在评估继续使用服务网格的替代方案。如果您也在寻找替代方案,Istio 将是一个强大且功能丰富的选项,尤其适合 Kubernetes 原生环境。在本文中,我将介绍从 AWS App Mesh 迁移到 Istio 的过程,对比这两种服务网格,并介绍我们开发的 Tetrate Istio 迁移工具,帮助简化这一迁移过程。
由于 AWS App Mesh 即将停用,了解 App Mesh 和 Istio 之间的相似性和差异对于成功迁移至关重要。以下是一些关键比较点,帮助您将当前的基础设施与 Istio 提供的功能对齐:
AWS 建议 ECS 客户迁移到 Service Connect 而 EKS 客户迁移到 VPC Lattice。对于一个功能丰富的开源解决方案,Istio 是一个很有吸引力的选择。接下来,让我们深入了解从 AWS App Mesh 迁移到 Istio 的过程,并使用 Tetrate 的迁移工具进行支持。
在开始迁移之前,了解 AWS App Mesh、Service Connect、VPC Lattice 和 Istio 之间的关键区别非常重要:
功能 | App Mesh | Service Connect | VPC Lattice | Istio |
---|---|---|---|---|
网络可靠性 | 使用 Envoy 作为 Sidecar 代理,进行异常检测、健康检查和重试,支持精细调整。 | 使用 Envoy 作为 Sidecar 代理,仅支持超时调整。 | 内置健康检查和重试,由 AWS 管理的可靠性,不需要 Sidecar 代理。 | 支持 Sidecar 和 Ambient 模式,使用 Envoy 并完全支持精细化调整。 |
高级流量路由 | 支持高级流量路由,如 A/B 测试和金丝雀发布。 | 不支持高级流量路由。 | 支持基本的流量路由和负载均衡。 | 支持包括 A/B 测试和金丝雀发布在内的高级流量控制。 |
可观测性 | 需要手动收集和监控指标。 | 自动将指标发送到 Amazon CloudWatch。 | 集成 AWS CloudWatch 和 X-Ray 监控。 | 开箱即用的可观测性,支持 Prometheus、Grafana 和 Jaeger。 |
服务发现 | 集成 AWS Cloud Map。 | 使用 AWS Cloud Map。 | 使用 AWS 服务发现机制。 | 使用 Kubernetes 原生的服务发现机制。 |
安全性 | 支持与 AWS PCA 的 TLS 和双向 TLS(mTLS)。 | 支持 TLS,不支持 mTLS。 | 支持 mTLS。 | 支持 mTLS 和细粒度的安全策略。 |
资源共享 | 可以跨多个 AWS 账户共享网格。 | 不支持跨账户共享命名空间。 | 可以跨多个 AWS 账户共享资源。 | 可以跨多个集群和云部署。 |
为了使迁移过程更加顺利,Tetrate 开发了一个 Istio 迁移工具包,目前处于私有状态,但可供内部或经过批准的客户通过 此表单 申请使用。该工具包帮助自动转换 AWS App Mesh 配置为 Istio 的等效配置,包括 Virtual Nodes、Virtual Routers 和其他网络结构。
关键考量
下面是使用此工具的有效步骤:
开始迁移之前,确保已安装以下工具:
确保在 EKS 集群上正确安装和配置 AWS App Mesh。您还需要一个名为 tetrate-tis-creds 的 Kubernetes secret,用于 Istio 安装,详见工具文档。
该工具还提供预检查命令,以识别迁移前的任何潜在阻碍因素。
为确保设置准备就绪,运行以下命令:
tim precheck
此命令将扫描 App Mesh 环境,标出任何需要调整的项,以确保成功迁移。
安装 Istio
使用 Istio 迁移工具包生成 IstioOperator 配置并安装 Istio:
tim generate iop | istioctl install –skip-confirmation -f –
应用 Istio 网络规则
接下来,生成并应用 Istio 网络规则:
tim generate networking | kubectl apply -f –
移除 AWS App Mesh 标签
从命名空间中移除现有的 App Mesh 标签。例如,对于 default 命名空间:
kubectl label namespace default "appmesh.k8s.aws/sidecarInjectorWebhook-"
启用 Istio Sidecar 注入
添加标签以启用 Istio 的自动 Sidecar 注入:
kubectl label namespace default istio-injection=enabled
重启部署
为应用更改并启动新的 Envoy Sidecar 注入,重启部署:
kubectl rollout restart deployment <deployment-name> -n <deployment-namespace>
从 AWS App Mesh 迁移到 Istio 时,可以使用如原地迁移、金丝雀发布、蓝绿部署等策略,这些策略与迁移到 VPC Lattice 的策略相似。合适的策略取决于应用需求,如是否需要零停机或安排维护窗口。
原地迁移:用配置为 Istio 的新 Pods 替换当前 App Mesh 的 Kubernetes Pods,适合可容忍迁移过程中的停机的应用。
蓝绿部署:在新命名空间中配置为 Istio 的应用副本,而原始部署继续运行 App Mesh,无停机地逐步将流量从 App Mesh 迁移到 Istio。
金丝雀发布:与 App Mesh 并行部署 Istio,逐步将少量流量转移到 Istio,监控性能和稳定性,逐步增加流量。
分阶段迁移:逐步迁移组件或服务,而非一次性迁移,以减少风险并帮助识别潜在问题。
测试和验证:在完全切换前,进行全面测试,验证服务功能、安全性和性能指标符合或超出预期。
从 AWS App Mesh 迁移到 Istio 可以解锁流量管理、可观测性和安全方面的新功能。Tetrate 的 Istio 迁移工具简化了过程,提供了分步骤方法,减少手动配置,确保平稳过渡。
如果您有兴趣试用 Tetrate 的 Istio 迁移工具,欢迎联系我们——该工具目前可私密使用,我们将很乐意讨论访问权限。
此次迁移不仅是采用新的服务网格,更是一个充分利用 Istio 全面功能、支持多云部署、增强基础设施弹性的机会。
本文最初发表于 tetrate.io。