Tetrate 布道师,云原生社区 创始人,CNCF Ambassador,云原生技术专家。
2024-09-06 19:14:52
上个月,因为参加 KubeCon China,我第一次前往香港,这让我有机会近距离审视这颗“东方明珠”。
我不记得之前在哪里看到一个说法,说是“香港是中国内地的一面镜子”。香港因其特殊的历史背景、经济发展轨迹以及在回归后的一系列表现等,许多人都在分析研究过程中会将香港的发展情况、社会治理经验教训等与内地进行关联和比较,认为其在某些方面可以为内地提供参考借鉴,就如同镜子一样反映出一些现象和问题的不同侧面及解决路径的可能性等。比如一些研究区域发展和社会治理的专家学者在相关论述中可能就会涉及到类似的观点表达。
香港与内地存在着诸多不同,这些不同不光是表面上的:
维度 | 香港 | 内地 |
---|---|---|
政治制度 | 资本主义制度,行政长官是特别行政区首长。 | 社会主义制度,人民代表大会制度。 |
法律体系 | 英美法系,判例法重要。 | 大陆法系,以成文法为主。 |
经济体制 | 自由市场经济,服务业和金融为主。 | 社会主义市场经济,公有制为主体,多种所有制发展。 |
文化方面 | 中西文化交融,保留大量中华传统文化。 | 以中华文化为主,地域文化多样。 |
教育体系 | 推行“三三四”学制,多语言教学,注重素质教育。 | 国家指导,地方负责,应试教育为主,统一教材。 |
医疗体系 | 公立私立并存,谨慎用药,社区医院为主。 | 医疗体系多元,大医院资源紧张,用药依据病情。 |
税收制度 | 地域来源征税,税种少,税率低。 | 居民身份征税,税种多,税负较高。 |
养老保障 | 强积金制度,雇主和雇员共同供款。 | 职工和居民基本养老保险,缴费比例不同。 |
语言使用 | 粤语为主,英语广泛使用。 | 普通话为主,各地方言众多。 |
文字形式 | 使用繁体中文。 | 使用简体中文。 |
生活习惯 | 饮食清淡,煲汤文化,部分西方生活习惯。 | 饮食丰富多样,生活习惯因地域文化不同。 |
消费观念 | 消费多元化,注重品质,高端品牌接受度高。 | 消费观念多样化,与经济水平有关。 |
交通规则 | 靠左行驶,驾驶位在右侧。 | 靠右行驶,驾驶位在左侧。 |
住房情况 | 土地少,房价高,公屋制度完善。 | 住房类型多样,房价差异大。 |
电影分级 | 有明确的电影分级制度。 | 无明确电影分级,审查严格。 |
新闻出版审查 | 新闻出版较自由,但有监管。 | 严格的新闻出版审查制度。 |
网络开放度 | 互联网相对开放,全球大多数网站可访问。 | 互联网监管严格,部分国外网站被屏蔽。 |
护照含金量 | 可免签或落地签前往约 170 个国家和地区。 | 可免签或落地签前往约 80 个国家和地区。 |
计量单位使用 | 使用英制和公制单位。 | 主要使用公制单位。 |
电压和插座类型 | 220V,英式三插(G 型)。 | 220V,双孔和三孔插座(A 型、I 型)。 |
手机支付普及度 | 现金和信用卡普及,八达通卡使用广泛。 | 手机支付非常普及,微信支付和支付宝常用。 |
购物和零售模式 | 国际品牌与本地品牌并存,夜市和街边小店常见。 | 大型购物中心、超市、夜市、电商平台多样。 |
社交习惯 | 英语使用普遍,西方社交礼仪。 | 普通话为主,传统社交礼仪。 |
宗教信仰 | 多元宗教环境,宗教自由。 | 宗教信仰有限制,信仰自由受法律保护。 |
食品安全标准 | 食品进口和监控严格,国际标准。 | 标准逐渐完善,偶有问题。 |
工作时间和假期 | 每周 44 小时,公共假期多。 | 每周 40 小时,法定节假日较少。 |
香港岛是香港最繁华的地方,面积约 78.10 平方公里,这里集中了大量的商业、办公和住宅区域,吸引了众多人口和车辆,交通压力较大。在香港岛上,有一种极具特色的交通工具——叮当车,它也被称为有轨电车。叮当车全部分布在港岛北部狭长的地带,共有 6 条线路,全都经过港岛繁华热闹的地区,如铜锣湾、跑马地、中环等。它的车身通常为双层,造型古朴,当司机踩到踏脚时,车子会发出“叮当、叮当”的声响,故而得名。
在香港旺角的街头,人群如潮水般涌动。这里是繁华都市的缩影,喧嚣与热闹交织成一幅独特的画卷。摩肩接踵的人们,怀揣着各自的梦想与故事,在这个充满活力的地方穿梭。时尚的店铺、美味的小吃、璀璨的灯光,共同构成了旺角的魅力。每一个匆忙的脚步,每一张洋溢着笑容的脸庞,都在诉说着这座城市的无限可能。旺角,一个让人感受香港脉搏跳动的地方,永远充满着生机与活力。
香港岛地形以山地为主,地势较高,自北向南地势渐缓,环岛沿岸曲折,多美景港湾。岛上的主要山峰包括太平山、柏架山、奇力山等,其中太平山是香港岛的最高峰,海拔 554 米。
兰桂坊位于香港岛中西区中环,是一个聚集大小酒吧与餐馆的中高档消费区。它由德己立街、威灵顿街、云咸街、和安里、仁寿里及荣华里构成,宽约 20 米,长约 300 米。20 世纪中期,香港经济腾飞,商业高速发展,夜总会文化开始在香港流行,很多在香港工作或暂居的外国人渴求适合他们品味和要求的娱乐场所,兰桂坊便应运而生。每当夜幕降临,这里便会灯红酒绿,觥筹交错,置身这里让我仿佛置身东南亚,感觉跟泰国很像。
我在香港 City walk 的时候发现的一些本地特色。
我发现很多建筑使用竹子搭建的脚手架,现在竹子脚手架在大城市中很少见到了。
我还在庙街看到算命一条街,还有一家店代客烧香。
最后本地的粤菜真的很好吃,我吃了一道炸猪排,外焦里嫩,口水直流。
在香港的这次旅行中,我不仅领略了这座城市的繁华与多样性,还感受到了它作为一面“镜子”所带来的思考。香港的独特之处在于它东西方文化的交融、现代与传统的结合,以及其与内地在政治、经济、文化等方面的显著差异。无论是乘坐叮当车穿行在港岛繁华的街道,还是漫步在兰桂坊体验夜生活的丰富多彩,亦或是在街头巷尾发现本地的特色文化,这一切都让我更加理解为什么有人说香港是中国内地的一面镜子。通过这面镜子,我们可以看到一个不同的视角,这不仅让我们更好地理解香港,也能反思内地的许多方面,为未来的社会和经济发展提供更多的借鉴和启示。
2024-08-27 10:23:48
今年的KubeCon China是首次在香港举办的盛会,持续了三天。作为会议的参与者及一个论坛的主持人,我在这篇文章中将分享会议的精彩内容和对服务网格及网关技术的深入讨论。
本次 KubeCon 新增了 AI 与开发者主题,以下是部分重点内容:
云原生技术在行业中的实际应用:特别是电动汽车和网络安全领域,如 Huawei 和 NIO 的共同探讨云原生技术如何加速电动汽车创新。
Kubernetes 社区的力量:详细讨论了中国 Kubernetes 社区的影响力及其在推动区域云原生活动中的角色。
开源技术与人工智能的融合:探讨了中国及香港在开源与 AI 技术领域的先进地位及对区域技术创新的推动。
服务网格与 API 网关的最新进展:包括服务网格的最新技术更新及其与 Kubernetes 调度器的协同工作提高系统吞吐量的策略。
供应链安全的新策略:关注保障供应链安全的最新动态,特别是 SLSA 合规性的实践指南。
多集群管理与边缘计算:探讨了在不同架构下进行有效管理与创新的策略。
AI 大模型的推理性能优化:讨论了无服务器架构下的 AI 大模型推理性能优化及相关技术进展。
我与来自 Tetrate、阿里云和 Kong Inc.的行业领袖共同参与的圆桌讨论,深入探讨了 Istio 和 API 网关的最新进展及其融合带来的革新。
Istio 的革新:介绍了 Istio 1.123 版本中的 Ambient 模式优化,此模式作为新的架构选择,减少资源消耗同时提升性能。
Ambient 模式与 Sidecar 模式的实用对比:
Ambient 模式的发展挑战:尽管有诸多优势,Ambient 模式在复杂流量管理与多租户环境中仍面临挑战。
服务网格优化策略:讨论了服务网格的优化方法,如何提升云应用的性能与效率。
服务网格与 API 网关的整合:展示了这两大技术如何共同作用,支持更复杂的部署与运维模式。
在徐中虎和何建鹏的分享中,我们了解到了 Istio 未来的可能发展方向:
双模驱动:Istio 将同时支持 Ambient 模式和传统的 Sidecar 模式。Ambient 模式适合追求性能和资源成本优化的用户,而 Sidecar 模式将为需要更全面功能的用户长期支持。
Gateway API 的支持:Istio 对 Gateway API 的支持,为用户提供了更灵活的路由与策略配置选项。
Waypoints 的策略应用:Waypoints 不必局限于 Istio 或 Envoy。通过使用 Gateway API 和 GAMMA,任何符合标准的实现都可以作为 Waypoint,这为服务网格提供了更大的灵活性和扩展性。
他们着重介绍了 Sandwich Waypoint,这是一种在 Istio 内管理和引导流量的复杂方法,特别是在环境模式下。这种 Waypoint 代理模式旨在通过充当处理、转换和转发客户端和服务器之间流量的中介层来简化和提高流量路由的效率。它利用了双 zTunnel 设置,其中位于通信通道两端的每个 zTunnel 协作封装和解码流量。Waypoint 本身负责执行额外的功能,如流量整形、安全检查和协议转换,从而在没有传统边车开销的情况下丰富服务网格功能。这种方法允许 Istio 保持强大的流量管理和安全功能,同时优化资源利用率并减少延迟。
Sandwich Waypoint 支持:
istio.io/use-waypoint: {namespace}/{gateway-name}
注解,将目标服务、Pod 或命名空间内的流量重定向到同一个 Waypoint。这是一种 Istio Ambient 模式中捕获七层流量模式,如下图所示。
Istio Sandwich Waypoint 捕获七层流量的步骤如下:
赵化冰在 KubeCon 上介绍了 Envoy Gateway 如何通过扩展 Kubernetes Gateway API 来增强功能与灵活性的演讲,涵盖了多种匹配与路由能力的扩展、新的资源和策略模型以及安全策略的细节。
ClientTrafficPolicy
和 BackendTrafficPolicy
为用户提供了更细粒度的流量管理控制,适用于上游和下游连接,包括如限速、重试、负载均衡、断路器等功能。SecurityPolicy
支持 CORS、HTTP 基础认证、OIDC、JWT 认证,并能与各种身份提供商集成。它还提供了详细的访问控制,允许根据请求者的原始 IP、JWT 声明等进行授权。通过本次会议我们了解了 Istio 的 Ambient 模式和 Envoy Gateway 的进展。这些技术的讨论不仅展望了未来趋势,也提供了实用的洞察,助力技术实施与创新。
2024-08-23 14:47:39
随着 8 月 20 日《黑神话:悟空》的正式发售,瞬间点燃了玩家们对 3A 游戏无尽的热情与讨论。在这篇随笔中,我将漫步于记忆的长廊,从孩提时代的掌中世界到今日的次世代主机,细数那些陪伴我的游戏时光,并深入探讨我心目中 3A 大作的独特魅力。
在中国,游戏曾一度被视为教育的绊脚石,是家长眼中的洪水猛兽。然而,正是这些看似微不足道的游戏机,悄然开启了我探索未知世界的奇妙之旅。
在我十岁左右,我获得了一个第一台游戏机,一台类似 Gameboy 的掌上游戏机。
这是我最早接触的游戏机,还有我最早接触的游戏《俄罗斯方块》。
也进过游戏机厅,小学时每年寒暑假前都要写保证书,名叫《暑/寒假公约》,其中一定会有一条——“不去游戏机厅”。我只去过一两次,这些游戏机需要投币。
这类游戏机上常玩的游戏是《街头霸王(Street Fighters)》。
小霸王学习机,可以更换卡带,接上电视就能玩,那时候经常用它玩高桥名人的《冒险岛》。
虽然号称是学习机,但是我没有见过有谁用它来学习的。
世纪之交的时候,网吧开始兴起,2000 年的时候我才第一次接触电脑,暑期的时候还参加电脑培训,练习过五笔打字,那时候也没学会,光顾着玩游戏了,我记得那时候还使用的是 3.5 英寸软盘,操作系统还是 Windows 98,使用的是笨重的 CRT 显示器。
2000 年左右,电脑上的游戏有《红色警戒》、《暴力摩托》、《三角洲部队》、《拳皇》,但是我最喜欢的还是《红色警戒 2》,从 2000 年一直到 2008 年。
最开始玩红警的时候年纪还小,是我自己一个人探索着玩,一开始做任务,甚至不知道怎样展开基地车,因为游戏是繁体字,很多我还看不懂。
除了红色警戒之外,我玩过的游戏还有《反恐精英》、《半条命》、《暗黑破坏神》、《仙剑奇侠传》、《魔兽争霸》,但这些游戏都不是我的菜,大多也玩不好,我还是钟情于红警,还有它的各种 mod。
在开始玩网络游戏之前,从来没有为玩游戏花过钱,因为中国的各种盗版游戏泛滥,网上到处都可以下载到。
在此之后就是网游的时代了,什么《传奇》、《大话西游》,腾讯的各种游戏比如《泡泡堂》、《劲舞团》、《地下城与勇士》、《QQ 飞车》这些我都玩过。
曾经有一段时间,大概 2008 到 2013 年,校友网、QQ 空间上诞生的网页游戏,比如《抢车位》、《开心农场》等火爆一时,很多人定闹钟偷菜,也诞生了一些做网页游戏的网站。
还有一些流行的休闲游戏,比如《植物大战僵尸》也是我特别喜欢的一款游戏。跟它同时期的一些游戏也不错。
《开心消消乐》、《原神》、《辐射:避难所》。不过很多流行的手机游戏比如《绝地求生》、《穿越火线》我都没有玩过。
从 2009 年到 2023 年可以说我就没有再接触主机游戏和网游了,平时也很少玩游戏,直到 2023 年 12 月,我获得了我的第一台游戏主机 PS5,情况才发生了改变。
在此之前我曾玩过朋友的任天堂主机,但是并不是很喜欢任天堂主机的游戏,画面质量,游戏类型都不是我喜爱的。
但是从我接触的第一个 PS5 主机游戏《双人成行》开始,我对主机游戏甚至说对电子游戏的看法大大改观了。一起我对大部分游戏都提不起兴趣,感觉那些游戏就是打发打发时间,玩久了就很无聊,但是接下来的几款游戏让我体验到了什么是 3A 大作。
在拥有了 PS5 之后,玩什么游戏就是一个问题了。我订阅了二挡会员,所以起初我下载和玩了一些游戏库里的游戏。
《双人成行》这是一个必须两个人配合才能完成的游戏,通过 PS5 的手柄来操控,终于让我体会到玩游戏的快感。这也是我第一次购买的实体游戏,我购买了游戏光盘。
《地平线:西之绝境》在 PlayStation 的二挡会员库里,所以我也下载和游玩了这款游戏。这款游戏以废土世界的旧金山为背景,里面有很多奇思妙想的未来机械生物。但是我对它的剧情和部落完全不感兴趣,只是享受其中打斗的乐趣,因为主角可以使用的武器和技能有很多。
《对马岛之魂》,故事发生在古代日本的对马岛,虽然景色很美,但是打斗风格及剧情让我提不起兴趣,一个日本人反抗蒙古侵略者的故事,我只玩了几个小时就卸载了游戏。
《蜘蛛侠:Miles Morales》,以纽约为背景,化身蜘蛛侠在纽约的城市上空飞来飞去,还有爽快的打斗,确实是一款很刺激的游戏,但是我对漫画人物为主角的游戏也不是特别喜欢,这款游戏的故事也比较简单,很快就通关了。
《极地战嚎 6》,是一个虚构的现代国家 Yara 为背景(实际上是映射古巴)的游击队反抗政府军的故事,这是育碧旗下的游戏,已经出到第六代,有点像罐头游戏,完成主线任务也很快,我喜欢里面的各种枪械和野路子武器,剧情能够发人深省。
《荒野大镖客 2》是以 19 世纪末的美国西部为背景,玩了不到 1 个小时,实在无法带入剧情,对这个的故事和背景也不感兴趣,索性不玩了。
我玩过的最后一个 3A 大作是《艾尔登法环》,这是我第一次玩魂系游戏,其中的世界观,复杂的技能点加成,庞大的地图,开放世界都给我造成很大的困惑,尤其是强大的怪物,我一开始玩了几个小时,就死过无数次,被大树守卫很轻易就秒杀,甚至一个普通怪物三两下就把我干掉,我感觉玩这个游戏很痛苦,完全无法体会其中的乐趣,直到我了解可以购买卢恩,将角色升级到满级,然后玩这个游戏就可以轻松很多。
不过这个游戏偶尔还是会让人感觉很不适,尤其是各种迷宫一样的墓地,阴暗的环境,下水道,恶心的怪物。但是面对那些强大的怪物,当时死亡无数次后将其打败,可以体会到其中的快感,以及游戏庞大的地图,琳琅满目的武器,是我坚持玩下去的动力。
在《黑神话:悟空》诞生之前,并没有一个让我眼前一亮的 3A 大作,它的出现就像一颗闪耀的新星。下面我将谈谈什么是我心目中的 3A 大作。
我心目中的 3A 大作,首先必须拥有一段深入人心的故事。它应当如同一部宏大的史诗,让玩家在跌宕起伏的剧情中与角色同悲共喜,体验一段段难忘的旅程。《黑神话:悟空》以其独特的中国神话背景,正是我所期待的那一抹亮色。
高质量的美术与音乐是 3A 大作的另一大亮点。精美的画面、逼真的场景、细腻的角色设计,以及动人心弦的背景音乐和音效,共同构建了一个令人向往的虚拟世界。《黑神话:悟空》的预告片已经展现出了其在这方面的非凡实力。
流畅的操作手感与丰富的游戏玩法是 3A 大作的基石。无论是战斗系统的爽快感、解谜机制的巧妙设计,还是探索元素的无限可能,都应让玩家在享受游戏的过程中感受到无尽的乐趣与挑战。《黑神话:悟空》作为动作冒险游戏,其在这方面的表现无疑值得期待。
对于国内玩家而言,游戏中融入的文化内涵往往能引发更深的共鸣与认同。《黑神话:悟空》以中国神话为背景,不仅展现了丰富的传统文化元素,更通过游戏这一载体将中华文化的魅力传播至世界各地。
一款优秀的 3A 大作不仅需要在发布时惊艳四座,更需要在后续的开发与运营中保持活力与创新。持续的更新与支持不仅能够为玩家带来新鲜感与惊喜,更是游戏生命力的体现。《黑神话:悟空》作为国产 3A 的佼佼者,其后续的更新与支持同样值得我们期待。
《黑神话:悟空》的发布不仅是对国产游戏的一次重大突破,更是对全球游戏界的一次震撼宣言。它让我看到了国产 3A 大作的无限可能。
今天我就购入了《黑神话:悟空》,在游玩一段时间后我会发布新的博客谈谈我的游玩体验。
2024-08-13 13:43:16
Istio 提供了对入口网关的强大而灵活的支持,利用 Envoy 代理在其 sidecar 模式下运行。尽管 Istio 专注于管理集群内服务之间的通信,Envoy Gateway 旨在将应用程序暴露给外部世界,处理用户请求,并支持高级功能,如 OIDC 单点登录。通过结合 Istio 服务网格的功能和 Envoy Gateway 的高级网关功能,可以增强整体应用程序的可访问性和安全性。
下图显示了 Istio 网格中入口网关的流量路径。
下一个图表显示了在引入 Envoy Gateway 后,流量如何从 Istio 网格的边缘流入内部网络。
要将 Envoy Gateway 用作 Istio 的入口网关,请考虑以下关键点:
Service
而不是 Endpoint
,以确保正确路由。按照 快速启动文档 安装 Envoy Gateway。标记 Envoy Gateway 的命名空间以确保数据平面获得 Istio sidecar 注入:
kubectl label namespace envoy-gateway-system --overwrite=true istio-injection=enabled
配置 Envoy Gateway 的 sidecar 以不拦截进入网关的流量。注入的 sidecar 确保 Envoy Gateway 的组件及其创建的代理被包含在 Istio 网格中,并安装正确的证书以进行安全通信。
spec:
ports:
- port: 18000
appProtocol: tls
应用补丁:
kubectl patch service -n envoy-gateway-system envoy-gateway --type strategic --patch-file control-plane-tls.yaml
配置 Envoy Gateway 不拦截入站流量:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: data-plane-sidecars
namespace: envoy-gateway-system
spec:
provider:
type: Kubernetes
kubernetes:
envoyDeployment:
pod:
annotations:
traffic.sidecar.istio.io/includeInboundPorts: ""
routingType: Service
应用配置:
kubectl apply -f teg-sidecars-no-inbound.yaml
修改 GatewayClass 配置以将 sidecar 配置应用于 Envoy Gateway 数据平面中的所有 EnvoyProxy
:
spec:
parametersRef:
group: gateway.envoyproxy.io
kind: EnvoyProxy
namespace: envoy-gateway-system
name: data-plane-sidecars
应用补丁:
kubectl patch gatewayclass teg --patch-file gtwcls-use-envoyproxy.yaml --type merge
使用 minimal 配置文件部署 Istio 以避免部署入口网关:
istioctl install --set profile=minimal -y
在 Istio 的 sidecar 注入准备好后,重启所有 Envoy Gateway 控制平面的 pod:
for d in envoy-gateway envoy-ratelimit teg-envoy-gateway teg-redis;
do kubectl rollout restart deployment -n envoy-gateway-system $d;
done
在安装 Istio 后部署测试应用程序,以确保它们也接收到 sidecar 注入:
kubectl create namespace httpbin
kubectl label namespace httpbin --overwrite=true istio-injection=enabled
kubectl apply -n httpbin -f https://raw.githubusercontent.com/istio/istio/master/samples/httpbin/httpbin.yaml
现在配置 Envoy Gateway 以处理边缘流量:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: apps
namespace: httpbin
spec:
gatewayClassName: teg
listeners:
- name: http
protocol: HTTP
port: 80
应用配置:
kubectl apply -f apps-gateway.yaml
部署应用网关,包括以下容器:
istio-init
:由 Istio 注入以修改 pod iptables。envoy
:由 Envoy Gateway 控制,充当入口网关。istio-proxy
:由 Istio 注入,负责与内部集群 pod 的通信。shutdown-manager
:由 Envoy Gateway 控制,负责 pod 生命周期管理。创建一个 HTTP 路由:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin
namespace: httpbin
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: apps
hostnames:
- "www.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /httpbin/
filters:
- type: URLRewrite
urlRewrite:
hostname: httpbin.httpbin.svc.cluster.local
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- kind: Service
name: httpbin
port: 8000
应用路由配置:
kubectl apply -f httpbin-route.yaml
获取网关的负载平衡器 IP 地址并发送测试请求:
export GATEWAY_URL=$(kubectl get svc -n envoy-gateway-system -l gateway.envoyproxy.io/owning-gateway-name=apps -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')
curl -v -H Host:www.example.com http://$GATEWAY_URL/httpbin/get
你应该能看到来自 httpbin
服务的正确响应:
* Trying 34.41.0.90:80...
* Connected to 34.41.0.90 (34.41.0.90) port 80
> GET /httpbin/get HTTP/1.1
> Host:www.example.com
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< server: envoy
< date: Wed, 31 Jul 2024 08:21:58 GMT
< content-type: application/json
< content-length: 282
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-envoy-upstream-service-time: 11
<
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "www.example.com",
"User-Agent": "curl/8.7.1",
"X-Envoy-Attempt-Count": "1",
"X-Envoy-External-Address": "123.120.227.173"
},
"origin": "123.120.227.173",
"url": "http://www.example.com/get"
}
* Connection #0 to host 34.41.0.90 left intact
通过应用以下配置启用严格 mTLS:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: "default"
namespace: "istio-system"
spec:
mtls:
mode: STRICT
应用配置:
kubectl apply -f strict-mtls.yaml
创建服务签名的根证书和私钥:
mkdir example_certs
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example_certs/example.com.key -out example_certs/example.com.crt
为 www.example.com
创建证书和私钥:
openssl req -out example_certs/www.example.com.csr -newkey rsa:2048 -nodes -keyout example_certs/www.example.com.key -subj "/CN=www.example.com/O=www organization"
openssl x509 -req -sha256 -days 365 -CA example_certs/example.com.crt -CAkey example_certs/example.com.key -set_serial 0 -in example_certs/www.example.com.csr -out example_certs/www.example.com.crt
为入口网关创建一个密钥:
kubectl create -n httpbin secret tls httpbin-credential --key=example_certs/www.example.com.key --cert=example_certs/www.example.com.crt
配置入口网关:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: apps
namespace: httpbin
spec:
gatewayClassName: teg
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: httpbin-credential
应用配置:
kubectl apply -f tls-apps-gateway.yaml
发送测试请求:
curl -v -H Host:www.example.com --resolve "www.example.com:443:$GATEWAY_URL" --cacert example_certs/example.com.crt "https://www.example.com:443/httpbin/get"
你应该可以通过 HTTPS 在网格内访问 httpbin
服务。
通过将 Envoy Gateway 集成为 Istio 服务网格中的入口网关,你可以利用两者的优势:Istio 的强大服务网格能力和 Envoy Gateway 的高级网关功能。这种设置增强了你的应用程序的安全性、可扩展性和灵活性,提供了无缝且安全的用户体验。通过仔细的配置和正确的工具,管理服务网格内外的流量变得更加高效和有效,确保你的应用程序始终可访问并且安全。
2024-08-06 11:03:02
Istio 是一个功能强大的服务网格解决方案,提供零信任安全性、可观测性和高级流量管理等功能,且无需修改代码即可实现。然而,由于配置错误,我们经常会遇到意料之外的行为。本文将介绍几种常见的 Istio 配置错误,解析其背后的原理,并通过示意图展示如何识别和解决这些问题。我们还将介绍 Tetrate 提供的工具——TIS Config Analyzer,这是一种优化 Istio 操作效率和安全性的工具。
以下是两个由于配置错误导致的典型事故案例:
Amazon Web Services 2017 年停机事件:一次简单的输入错误导致了广泛的服务中断,影响了数千个在线服务和应用,突显了即使在成熟的云基础设施中,一个小小的配置错误也会引发严重后果。
GitLab 2017 年数据丢失事故:由于配置错误,GitLab 在进行数据库维护时误删除了大量生产数据。尽管备份机制被配置好,但错误的配置阻止了数据的及时恢复。
这些案例表明,正确的配置管理对于防止服务中断和数据丢失至关重要。
Istio 配置错误主要分为以下几大类:
在 Istio 的日常使用中,以下是一些最常见的配置错误:
虚拟服务指向不存在的网关:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: details
namespace: bookinfo
spec:
hosts:
- details
gateways:
- non-existent-gateway
在这种情况下,details
虚拟服务试图通过一个不存在的 non-existent-gateway
进行路由,导致流量管理失败。
虚拟服务引用不存在的服务子集:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: details
namespace: bookinfo
spec:
hosts:
- details
如果 details
服务没有定义相应的子集,请求将因无法找到正确的服务实例而被拒绝。
网关找不到指定的服务器凭证:
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: cert-not-found-gateway
namespace: bookinfo
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: "not-exist"
这会导致 TLS 握手失败,因为指定的凭证 not-exist
不存在。
为了减少由于配置错误而导致的服务中断风险,配置验证成为了一个不可或缺的步骤。配置验证可以分为以下两种:
istioctl validate
istioctl validate
用于验证 Istio 配置文件(如 YAML 文件)的语法和基本结构,确保配置文件符合 Istio API 的规范。它可以在配置应用到集群之前检测出语法错误和格式问题,是一个静态分析工具,通常结合 CI 流程使用,防止无效配置文件应用到集群中。
istioctl analyze
istioctl analyze
是一个强大的诊断工具,用于分析 Istio 集群的运行状态和配置一致性。它不仅检查配置文件的语法,还可以检查集群中实际应用的配置,找出潜在的问题和冲突。istioctl analyze
提供动态分析功能,能够识别集群运行时的配置错误和潜在问题。
istioctl analyze
的配置流程如下:
istioctl analyze
收集来自指定源的 Istio 配置数据。这些源可以是活动的 Kubernetes 集群,也可以是本地的配置文件。istioctl analyze
输出一个包含所有发现问题的详细报告。如果没有发现问题,它会通知用户配置看起来没有问题。下面是 istioctl analyze
的工作流程图:
Kiali 是管理和可视化 Istio 服务网格的重要工具,提供对网格健康状况、性能和配置状态的实时洞察。通过将 Kiali 集成到 Istio 环境中,可以通过以下方式增强配置安全性:
将 Kiali 与 istioctl validate
和 istioctl analyze
等工具结合使用,能确保更为稳健的方法来预防和解决 Istio 配置错误,进而提升服务网格的安全性和效率。
为了帮助开发者和运维人员避免常见的配置失误,Tetrate 开发了 TIS Dashboard 中的 Config Analyzer 工具。该工具能够自动验证 Istio 的配置,根据最佳实践分析服务网格的配置问题,并提供优化建议。Config Analyzer 可以自动检测 Istio 服务网格中的配置问题,提供解释及解决方案,支持按需检测配置中的错误。
正确配置 Istio 是确保服务网格健康运行的关键。通过了解和避免常见配置错误,以及利用如 Tetrate 的 TIS Config Analyzer 这样的高级工具,您可以确保 Istio 环境的稳定性和安全性。记住,一个小小的配置错误可能导致整个服务网格的故障,因此持续监控和审核配置是非常必要的。
2024-07-25 14:09:37
近期,Wiz 研究团队发布了博客,揭示了 AI 服务中的租户隔离漏洞,引起了广泛关注。该研究详细阐述了多个 AI 服务供应商存在的安全缺陷,特别是 SAP AI Core 平台。通过合法的 AI 训练过程,研究人员能够绕过 Istio 服务网格中的流量劫持,进而横向移动并接管服务,获取客户的私人文件和云环境凭证。这些发现凸显了当今云服务和管理平台在确保隔离和沙盒环境方面面临的挑战。
istio-proxy
容器中的用户 ID 是为了便于配置并避免权限冲突。这个数字在技术和游戏文化中象征“精英”(elite),有助于防止与其他常规用户 ID 冲突,确保流量管理操作不受权限问题干扰。
在这个背景下,Istio 作为一个重要的服务网格解决方案,同样面临着类似的安全问题,尤其是在 sidecar 注入和流量管理等关键功能上。这篇博客旨在探讨如何保护 Istio 服务网格的安全,并提供一套全面的缓解措施。我们还将讨论多层安全策略如何有效增强 Istio 的安全性,以应对类似 Wiz 报告中提到的挑战。
Istio 主要用于管理 Kubernetes 中的东西向流量,提供详细的流量管理功能,如请求路由、负载均衡和故障恢复策略。虽然 Istio 提供了流量加密、认证和授权等安全功能,但它本身不应被视为防火墙。为了确保 Istio 网格中的服务安全,除了使用 Istio 自身的安全功能,还需要结合底层网络和基础设施的安全措施,比如 CNI 和安全容器。此外,微分段技术可以用来实现更细粒度的隔离,提高安全性。
不论是 Sidecar 模式还是 Ambient 模式,都是通过劫持应用程序 Pod 的流量到数据平面代理中进行处理和转发的。如果没有成功拦截到应用程序流量或者被仿冒程序冒充了 Istio 而执行操作,就会有安全漏洞出现。
下图展示了通过绕过或仿冒 Istio 系统用户而造成的安全漏洞存在的位置。
接下来,我们将探讨“安全漏洞”产生的具体情况及应对策略。
outboundTrafficPolicy
字段设置为 ALLOW_ANY
(覆盖可能的全局值 REGISTRY_ONLY
)。服务网格被描述为现有安全模型的一个补充层,通过在传统安全控制之上添加更细粒度的安全策略来增强微服务的安全性。然而,文章强调了服务网格无法独立保障微服务的全面安全,而是应当作为整体安全策略的一部分。
服务网格主要通过在每个服务实例旁部署一个轻量级的代理(sidecar),来管理和控制网络流量。这使得它能够在网络层面上实现精细的流量控制和策略执行,如流量加密、身份认证和授权。尽管服务网格能够提供诸如流量控制、服务发现和断路器等功能,这些功能本质上是对网络流量的管理,无法解决所有安全问题。例如,它不能替代应用层防火墙、入侵检测系统和数据安全等更传统的安全措施。
此外,服务网格依赖于正确的配置和管理,配置不当可能导致安全漏洞。因此,尽管服务网格是现代微服务架构中不可或缺的一部分,它应该与传统的安全措施相结合,共同构成一个全面的、多层次的安全策略框架。参考如何通过服务网格增强微服务的安全性以进一步了解如何加强服务网格的安全。
Istio 社区每年都会进行一次安全审计,见 2021 年、2022 年 的安全审计结果。从结果中我们可以看到,Istio 的安全态势有了很大的提升。确保你的 Istio 服务网格符合安全最佳实践。另外,你还需要关注 Istio CVE 公告栏,或者使用如 Tetrate Istio Subscription 这类工具来扫描 Istio 服务网格的各种 CVE,部署符合 FIPS 并经过 FIPS 验证的 Istio 发行版。
服务网格通过在应用程序外部管理控制流,为微服务架构提供了额外的安全层。这允许在不影响应用程序性能的前提下,加强服务之间的通信安全。在部署服务网格时,推荐使用 Istio 的 Egress Gateway 来管理出口流量,结合 Kubernetes 的 NetworkPolicy,确保所有出口流量都必须经过网关,从而防止潜在的数据泄露和其他安全威胁。
2024-07-23 15:24:08
上个周末,我从北京自驾前往乌兰察布,经历了一段全程 995 公里的旅程。周五晚上,我从北京东四环出发,驶过 295 公里,抵达乌兰察布兴和县,暂住一晚。清晨,我们满怀期待地出发,迎接乌兰哈达火山的壮丽景观。
乌兰哈达火山地质公园是一个免费开放的景区,景区公路和一些配套设施还在建设中。我从北面进入公园,首先到达的是 3 号火山。
当天虽然温度只有 31°C,但紫外线格外强烈。11 点钟,我们开始攀登 3 号火山。烈日当空,紫外线炙热,我穿着防晒服,T 恤已经被汗水浸湿,汗珠如豆粒般大小不断滴落,仿佛在与这片广袤的天地进行一场激烈的对抗。当地的海拔达到了 1600 米,空气清新而稀薄。
乌兰哈达火山地质公园位于内蒙古乌兰察布市,这里保存着一片完好的火山群,展现着大自然的鬼斧神工和地质变迁的壮丽画卷。火山群由多座火山组成,其中最著名的 3 号和 6 号火山,被分别称为“北炼丹炉”和“南炼丹炉”。
我们首先攀登了 3 号火山,从山顶俯瞰,火山口清晰可见,周围的火山岩石展现出奇特的地质构造,仿佛在诉说着那段遥远而神秘的历史。随后,我们自驾途径 6 号火山,由于交通堵塞,不得不掉头返回。3 号火山的南面已经被挖得面目全非,只有从北面看才能看出完整的火山形状。
夜晚,我们住在现代化的“蒙古包”里。蒙古包的构造独特,圆形设计不仅抵御风沙,还能保持内部温暖。现代蒙古包则在传统基础上融合了现代元素,提供了更为舒适的居住体验。
火山岩石具有独特的地质特征,这些岩石形成于数百万年前火山喷发的熔岩冷却后。它们质地坚硬,颜色多样,从黑色到红色不等。这些岩石不仅是大自然的杰作,也是地质学研究的宝贵材料。
生态保护红线是为了保护生态系统、维护生态安全而划定的严格保护区域。乌兰察布地区的生态保护红线确保了火山地质公园和周边生态环境的原始风貌得以保存。这片大地上的生态保护红线,像是一道无形的屏障,守护着这片古老而神秘的土地。
卓资县,位于乌兰察布的偏远角落。由于经济发展滞后,人口逐年减少,许多村庄因此被废弃。这些废弃的村庄见证了人口迁移和城镇化的历史变迁,仿佛在无声地诉说着一个个时代的故事。
上图中上方左二为战国赵长城遗址,公元前 300 年,赵武灵王修建的长城,今复何在?
赵长城,为赵武灵王时所筑,故也称赵武灵王长城。据《史记·匈奴列传》记载:“赵武灵王变俗,胡服,习骑射,北破林胡、楼烦,筑长城,自代并阴山下,至高阙为塞。”
拍摄于乌兰察布市察哈尔右翼后旗四胜路马房沟附近的树林里,成百上千只鸟时而隐藏在树林里,时而飞到远处的山坡上,蔚为壮观。
我们在生态保护红线的地图上采用投飞镖的方式随机造访一个村子,投中了胜利村。几经辗转,我们发现胜利村在手机地图上甚至没有路线指引。最终到达的村子已经不复存在,只留下一些荒废的房子,静静地伫立在这片广袤的土地上。
这次乌兰察布之旅让我深刻感受到了内蒙古独特的自然景观和人文历史。从壮丽的火山地质公园到失落的乡村,每一处景点都给我留下了深刻的印象。这次旅程不仅让我放松了身心,也让我对生态保护和人口流动有了更多的思考。在这片辽阔的土地上,我看到了自然的壮丽与人类历史的沉浮,内心也随之变得更加丰盈和宁静。
2024-07-22 16:43:16
Tetrate Enterprise Gateway(TEG)是基于 Envoy Gateway (EG) 的企业级解决方案,专门针对 Envoy Proxy 设计,通过 Kubernetes Gateway API 提供更易于消费的 Envoy 代理配置和管理包。TEG 结合了 Kubernetes Gateway API 的特性,支持在 Kubernetes 中轻松暴露服务和应用程序。
TEG 相对于 Envoy Gateway 的主要新增特性包括:
mod_security
兼容的 WAF 功能,增强了安全防护能力。TEG 将 Envoy 的高级网络流量处理能力带入 Kubernetes 环境,提供了一种简化的方法来部署和管理负载平衡、API 网关功能、安全控制等,同时支持现代的、开放的应用程序暴露 API,如 Kubernetes Gateway API。这些特性使 TEG 成为一个功能丰富、易于管理的企业级网关解决方案。
Tetrate Enterprise Gateway for Envoy (TEG) 构建于 Envoy Gateway 项目之上,提供了一种易于使用和操作的入口,具有先进的按请求流量控制功能、与现有环境的轻松集成,以及一流的可观测性,以理解应用流量和入口健康状况。
TEG 从头到尾注重易用性:从首次安装到启用应用团队,从故障排查到执行升级。TEG 的初始安装只需几分钟,你就可以开始使用高级功能,如速率限制、单点登录和金丝雀流量路由。TEG 还简化了运维流程,与你现有的指标、跟踪和日志记录管道相适应,我们还提供了一个完整的、预配置的可观测性堆栈,以评估 EG 产生的数据,并帮助你计划如何将 TEG 集成到你的现有指标堆栈中。
TEG 由在生产环境中运行大型、关键系统的经验丰富团队构建。TEG 简化了漏洞检查和持续升级过程,与你现有的指标和跟踪提供商轻松集成,并为你现有的 Grafana 部署提供了一套强大的入口可观测性仪表板。
TEG 不仅适用于绿地部署的启动,还可以直接与传统环境以及现代云原生环境集成。它可以帮助你在现有的应用生态系统和你正在构建的云原生目标之间架起桥梁。
你的组织可能已经有一个可观测性系统,你的应用和运营团队已经训练有素地使用它。TEG 可以轻松地嵌入到现有的基础设施中,并在你的组织中运行。TEG 将使 Envoy 的丰富指标集导出,让你的应用团队对其应用流量的行为有最佳的洞察,并看到他们所做配置更改的效果。TEG 还为运行它的平台团队提供了仪表板和警报功能,使你能够自信地操作并快速解决发现的问题。
Envoy 非常强大,但要使其启动并运行简单用例可能很难——像 Istio 这样的系统提供 Envoy 入口管理作为更广泛功能套件的一部分,也附带了许多与简单、流畅的操作体验相冲突的额外功能。这就是 Envoy Gateway 存在的原因:使 Envoy 的强大功能易于用于入口用例。
组织中绝大多数 API 网关的使用归结为三件事:认证发起请求的用户;限制用户对服务的访问;在此 API 端点的服务实例之间进行负载平衡。TEG 简化了在传统和云原生环境中完成这三项任务的过程。
下图展示的是 TEG 的架构图。
从架构图中可以看出,Tetrate Enterprise Gateway for Envoy (TEG) 的架构设计包括以下主要组件和流程:
Kubernetes Cluster
Envoy Proxy
Coraza WAF
Redis Rate Limit Store
Your OIDC Server
流量入口
Envoy Proxy 处理
安全和认证
速率限制
性能监控
这种架构设计利用了 Kubernetes 的灵活性和扩展性,并通过 Envoy 提供了强大的流量管理和安全功能。
执行下面的命令部署 TEG V0.0.0:
export REGISTRY="oci://docker.io/tetrate"
export CHART_VERSION="v0.0.0-latest"
helm install teg ${REGISTRY}/teg-envoy-gateway-helm \
--version ${CHART_VERSION} \
-n envoy-gateway-system --create-namespace
检查部署:
kubectl get pod -n envoy-gateway-system
你将看到下面的结果:
NAMESPACE NAME READY STATUS RESTARTS AGE
envoy-gateway-system envoy-gateway-596dfbcb88-tx7xb 1/1 Running 0 3m55s
envoy-gateway-system envoy-ratelimit-674b8c955c-jhlfn 2/2 Running 2 (3m48s ago) 3m54s
envoy-gateway-system teg-envoy-gateway-64fd8c8fbb-59b4l 1/1 Running 0 3m55s
envoy-gateway-system teg-redis-86bb7d9b9d-27n44 1/1 Running 0 3m55s
部署示例应用:
kubectl create namespace httpbin
kubectl apply -n httpbin -f https://raw.githubusercontent.com/istio/istio/master/samples/httpbin/httpbin.yaml
部署 Envoy Proxy:
cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: dedicated-gateway
namespace: httpbin
spec:
gatewayClassName: teg
listeners:
- name: http
protocol: HTTP
port: 80
EOF
然后你会在 envoy-gateway-system
命名空间下看到一个新的 Envoy 代理。
部署 HTTPRoute,给网关配置路由:
cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin
namespace: httpbin
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: dedicated-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /httpbin/
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- group: ""
kind: Service
name: httpbin
port: 8000
EOF
这个路由配置中有一个 URLRewrite filter,重写 URL 前缀,去掉了 /httpbin/
部分。
发送流量测试:
export DEDICATED_GATEWAY_IP=$(kubectl get gateway/dedicated-gateway -n httpbin -o jsonpath='{.status.addresses[0].value}')
curl -i http://${DEDICATED_GATEWAY_IP}/httpbin/get
/httpbin/get
?
在通过 Tetrate Enterprise Gateway for Envoy (TEG) 暴露 httpbin
应用时,选择 /httpbin/get
作为访问路径的原因主要是为了在同一个 Envoy 网关下能够同时支持多个应用或服务,并能根据不同的路径将流量正确地路由到指定的服务。
这种路径前缀的设置方法允许系统管理员或开发人员为每个服务配置独立的路径前缀,从而通过单一的入口点(即 Envoy 网关)来管理对多个后端服务的访问。这样的配置增加了路由的灵活性,使得在不更改现有服务配置的情况下,轻松地扩展或修改服务的暴露方式。
Istio 提供了成熟且灵活的入口网关支持,基于与 Tetrate Enterprise Gateway(TEG)相同的 Envoy 代理。Istio 主要专注于处理集群内服务之间的通信。相较之下,TEG 设计用于向外界暴露应用,处理人类用户的请求,并支持如 OIDC 单点登录等高级功能。通过结合 Istio 网格和 TEG 的高级网关功能,两者可以共同使用,以提升整体应用的可访问性和安全性。
以下图示展示了 Istio 网格中入口网关的流量路径。
下图展示了在引入 TEG 之后,流量如何从 Istio 网格边缘进入到内部。
将 TEG 集成到 Istio 网格中,通过在 TEG 上配置 sidecar 来颁发证书,同时避免 sidecar 拦截 TEG 中的流量。然后通过 Envoy Gateway 控制入口网关的流量路径。
为了使 TEG 作为 Istio 的入口网关,应注意以下关键点:
Service
而非 Endpoint
,确保 Envoy 代理能正确找到路由。为 TEG 的命名空间添加标签,以确保数据平面获得 Istio sidecar 的注入。
kubectl label namespace envoy-gateway-system --overwrite=true istio-injection=enabled
我们还需要配置 TEG 的 sidecar,使其不处理进入网关的 Envoy 流量。注入 sidecar 的目的是使 Envoy Gateway 的组件及其创建的代理能够被纳入 Istio 网格,并挂载正确的证书进行安全通信。
spec:
ports:
- port: 18000
appProtocol: tls
kubectl patch service -n envoy-gateway-system envoy-gateway \
--type strategic --patch-file control-plane-tls.yaml
配置 Envoy Gateway 中的 sidecar 不拦截流量:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: data-plane-sidecars
namespace: envoy-gateway-system
spec:
provider:
type: Kubernetes
kubernetes:
envoyDeployment:
pod:
annotations:
traffic.sidecar.istio.io/includeInboundPorts: ""
routingType: Service
kubectl apply -f teg-sidecars-no-inbound.yaml
修改 GatewayClass 的配置,将上述 sidecar 配置应用到 Envoy Gateway 数据平面的所有 EnvoyProxy
上:
spec:
parametersRef:
group: gateway.envoyproxy.io
kind: EnvoyProxy
namespace: envoy-gateway-system
name: data-plane-sidecars
kubectl patch gatewayclass teg --patch-file gtwcls-use-envoyproxy.yaml --type merge
使用 minimal profile 部署 Istio,从而不部署 Ingress Gateway:
istioctl install --set profile=minimal -y
现在 Istio 的 sidecar 注入已准备就绪,我们将重启所有 TEG 控制平面 Pod,它们将带有 sidecar 重新启动。
for d in envoy-gateway envoy-ratelimit teg-envoy-gateway teg-redis; \
do kubectl rollout restart deployment -n envoy-gateway-system $d; \
done
此步应在安装 Istio 之后进行,以确保它们也获得 sidecar 的注入。
kubectl create namespace httpbin
kubectl label namespace httpbin --overwrite=true istio-injection=enabled
kubectl apply -n httpbin -f https://raw.githubusercontent.com/istio/istio/master/samples/httpbin/httpbin.yaml
现在我们配置 TEG 处理边缘流量。
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: apps
namespace: httpbin
spec:
gatewayClassName: teg
listeners:
- name: http
protocol: HTTP
port: 80
kubectl apply -f apps-gateway.yaml
部署应用网关,包含以下容器:
istio-init
:由 Istio 注入,负责修改 pod 中的 iptablesenvoy
:由 TEG 控制,作为入口网关istio-proxy
:由 Istio 注入,负责与集群内部 pod 联系shutdown-manager
:由 TEG 控制,负责 Pod 启停创建 HTTP 路由:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin
namespace: httpbin
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: apps
hostnames:
- "www.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /httpbin/
filters:
- type: URLRewrite
urlRewrite:
hostname: httpbin.httpbin.svc.cluster.local
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- kind: Service
name: httpbin
port: 8000
kubectl apply -f httpbin-route.yaml
获取网关的负载均衡器 IP 地址,并发送测试请求:
export GATEWAY_URL=$(kubectl get svc -n envoy-gateway-system -l gateway.envoyproxy.io/owning-gateway-name=apps -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')
curl -v -H Host:www.example.com http://$GATEWAY_URL/httpbin/get
你将看到来自 httpbin
服务的正确响应,如下所示:
* Trying 34.41.0.90:80...
* Connected to 34.41.0.90 (34.41.0.90) port 80
> GET /httpbin/get HTTP/1.1
> Host:www.example.com
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< server: envoy
< date: Wed, 31 Jul 2024 08:21:58 GMT
< content-type: application/json
< content-length: 282
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-envoy-upstream-service-time: 11
<
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "www.example.com",
"User-Agent": "curl/8.7.1",
"X-Envoy-Attempt-Count": "1",
"X-Envoy-External-Address": "123.120.227.173"
},
"origin": "123.120.227.173",
"url": "http://www.example.com/get"
}
* Connection #0 to host 34.41.0.90 left intact
运行下面的命令启用严格的 mTLS:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: "default"
namespace: "istio-system"
spec:
mtls:
mode: STRICT
kubectl apply -f strict-mtls.yaml
创建用于服务签名的根证书和私钥:
mkdir example_certs
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example_certs/example.com.key -out example_certs/example.com.crt
为 www.example.com
创建证书和私钥:
openssl req -out example_certs/www.example.com.csr -newkey rsa:2048 -nodes -keyout example_certs/www.example.com.key -subj "/CN=www.example.com/O=www organization"
openssl x509 -req -sha256 -days 365 -CA example_certs/example.com.crt -CAkey example_certs/example.com.key -set_serial 0 -in example_certs/www.example.com.csr -out example_certs/www.example.com.crt
为入口网关创建 secret:
kubectl create -n httpbin secret tls httpbin-credential \
--key=example_certs/www.example.com.key \
--cert=example_certs/www.example.com.crt
配置入口网关:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: apps
namespace: httpbin
spec:
gatewayClassName: teg
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: httpbin-credential
kubectl apply -f tls-apps-gateway.yaml
发送测试请求:
curl -v -H Host:www.example.com --resolve "www.example.com:443:$GATEWAY_URL" \
--cacert example_certs/example.com.crt "https://www.example.com:443/httpbin/get"
你将可以通过 HTTPS 访问网格内的 httpbin
服务。
Tetrate Enterprise Gateway 为企业提供了一种强大的网关解决方案,能够在云原生环境中高效地暴露和管理应用服务。通过其基于 Envoy 的架构和对 Kubernetes Gateway API 的支持,TEG 不仅确保了高性能的流量管理,还大幅简化了网关的部署和维护。无论是面对复杂的安全需求还是高流量的业务场景,TEG 都能提供可靠的支持,帮助企业实现其业务连续性和技术创新。
2024-07-20 07:30:55
今天 Envoy Proxy 1.31.0 发布,这是今年继 1.29、1.30 以来发布的第三个大版本。Envoy Proxy 1.31.0 的发布标志着此开源网络代理项目在性能优化和功能增强方面又迈出了重要一步。此版本包括了一系列引人注目的新特性、行为变化和新配置选项,下面我们将逐一解析这些更新,帮助你充分利用 Envoy 的最新能力。
Happy Eyeballs(快乐的眼睛)是一种网络算法,主要用于当一个设备同时支持 IPv4 和 IPv6 时,快速决定应该使用哪种 IP 协议来建立连接。该算法通过几乎同时启动两个连接尝试——一个使用 IPv4,另一个使用 IPv6——并使用哪个首先成功建立的连接,从而减少了连接延迟。
在 HTTP/3 中应用 Happy Eyeballs 特性,尤其是 Envoy 1.31 版本中的实现,可以改进服务在支持多种网络协议的环境中的表现。例如,如果一个服务的 IPv4 连接速度比 IPv6 快,Envoy 会偏好 IPv4,反之亦然。这样做的好处是减少了尝试连接的总时间,提高了用户体验和服务效率。
SlotImpl
类的行为更新,其析构函数现可在任何线程上被调用,提高了线程局部存储的灵活性。此版本中,多个旧有的配置和运行时标志被正式弃用和移除,以清理代码库并提升维护效率。这包括一些老旧的 TLS 和 HTTP 配置选项,用户应检查并更新他们的配置以免受到影响。
Envoy 1.31.0 的发布提供了许多值得关注的新特性和改进,不仅增强了其作为现代微服务架构核心组件的地位,也进一步证明了其作为业界领先代理解决方案的能力。无论是在性能提升还是功能拓展方面,Envoy 1.31.0 都为用户带来了实质性的好处。
确保查看完整更新文档,了解所有详细的配置指南和更新说明,以充分利用 Envoy 1.31.0 的潜力。
Envoy 的每次更新都是基于社区的反馈和贡献,我们期待看到你如何利用这些新特性来优化你的应用和服务。如果你有任何问题或需要帮助,欢迎在 Slack 或 GitHub 上与社区交流。
2024-07-17 13:36:15
Envoy Gateway 是由 Envoy Proxy 社区推动的一个开源 API 网关项目,结合了 Contour、Emissary 等项目力量。这个指南将帮助你理解如何贡献代码和参与社区。
了解项目的目标和愿景是非常重要的。Envoy Gateway 旨在作为一个独立或基于 Kubernetes 的应用程序网关,使用 Gateway API 资源来管理 Envoy 代理。
在开发前,建议通过GitHub或Slack与社区交流。始终创建一个 GitHub Issue 来讨论你的想法。
遵守贡献准则,它包括代码规范和社区行为准则。
make build
make build BINS="envoy-gateway"
egctl
:make build BINS="egctl"
make test
来进行 Go 语言的测试。make testdata
来生成 YAML 格式的测试数据。make lint
确保代码风格和标准一致性(注意修正现有的拼写错误)。IMAGE=docker.io/<dockerhub-id>/gateway-dev make image
IMAGE=docker.io/<dockerhub-id>/gateway-dev make push-multiarch
make create-cluster
在 Kind 上创建测试/开发用的集群。IMAGE=docker.io/<dockerhub-id>/gateway-dev TAG=<image-tag> make kube-deploy
将 Envoy Gateway 部署至 Kubernetes。make kube-demo
部署 demo 后端服务及相关网络资源。make kube-demo-undeploy
删除示例应用。执行 make kube-undeploy
删除 Envoy Gateway。当你完成 Envoy Gateway 和示例应用部署后,运行 kubectl get pod -A
命令,你将看到如下所示的 Pod 列表。
NAMESPACE NAME READY STATUS RESTARTS AGE
default backend-96f75bbf-tcdf7 1/1 Running 1 (97s ago) 13h
envoy-gateway-system envoy-default-eg-e41e7b31-668f754989-wb7xr 2/2 Running 2 (97s ago) 13h
envoy-gateway-system envoy-gateway-b457dc69b-l77cr 1/1 Running 2 (97s ago) 13h
kube-system coredns-5dd5756b68-b494d 1/1 Running 1 (97s ago) 14h
kube-system coredns-5dd5756b68-j46bx 1/1 Running 1 (97s ago) 14h
kube-system etcd-envoy-gateway-control-plane 1/1 Running 1 (97s ago) 14h
kube-system kindnet-sq4b4 1/1 Running 1 (97s ago) 14h
kube-system kube-apiserver-envoy-gateway-control-plane 1/1 Running 1 (97s ago) 14h
kube-system kube-controller-manager-envoy-gateway-control-plane 1/1 Running 2 (97s ago) 14h
kube-system kube-proxy-4x72s 1/1 Running 1 (97s ago) 14h
kube-system kube-scheduler-envoy-gateway-control-plane 1/1 Running 2 (97s ago) 14h
local-path-storage local-path-provisioner-6f8956fb48-shjcz 1/1 Running 2 (59s ago) 14h
metallb-system controller-5c6b6c8447-kjl4n 1/1 Running 2 (59s ago) 14h
metallb-system speaker-6zlrb 1/1 Running 1 (97s ago) 14h
export ENVOY_DEPLOYMENT=$(kubectl get deploy -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
kubectl port-forward deploy/${ENVOY_DEPLOYMENT} -n envoy-gateway-system 19000:19000
http://localhost:19000
访问 Envoy 管理界面进行配置调试。若你在中国大陆的网络环境下构建和推送镜像,需要为 Docker 设置代理,否则你将无法下载一些依赖镜像。你可以将它们下载到本地后再用 kind load
命令加载到 kind 里。需要下载和加载到 kind 里的镜像见下面的代码。
#!/bin/bash
echo "Pull the images and load them into the kind cluster..."
docker pull envoy-gateway-control-plane quay.io/metallb/controller:v0.13.10
docker pull envoy-gateway-control-plane quay.io/metallb/speaker:v0.13.10
docker pull envoy-gateway-control-plane docker.io/jimmysong/gateway-dev:435a4dc1
docker pull envoy-gateway-control-plane envoyproxy/envoy:distroless-dev
docker pull envoy-gateway-control-plane gcr.io/k8s-staging-gateway-api/echo-basic:v20231214-v1.0.0-140-gf544a46e
kind load docker-image -n envoy-gateway --nodes envoy-gateway-control-plane quay.io/metallb/controller:v0.13.10
kind load docker-image -n envoy-gateway --nodes envoy-gateway-control-plane quay.io/metallb/speaker:v0.13.10
kind load docker-image -n envoy-gateway --nodes envoy-gateway-control-plane docker.io/jimmysong/gateway-dev:435a4dc1
kind load docker-image -n envoy-gateway --nodes envoy-gateway-control-plane envoyproxy/envoy:distroless-dev
kind load docker-image -n envoy-gateway --nodes envoy-gateway-control-plane gcr.io/k8s-staging-gateway-api/echo-basic:v20231214-v1.0.0-140-gf544a46e
想深入了解如何进行高级测试和贡献,详见 Envoy Gateway 开发文档。
加入我们,与全球开发者共同推进 Envoy Gateway 的成长,同时提升你的开发技能和对开源社区的理解。
为了便于中文和中国时区的用户交流,Envoy Gateway 社区成立的微信群,详见通知,该群成立于 2023 年 4 月,目前已有 400 多名成员。你可以联系联系我、刘训灼、赵化冰等入群。
2024-07-12 11:51:52
最近我观看了一部名为 Fantastic Planet 的电影,这部电影给了我极大的震撼,令人意想不到的是,这居然是一部上世纪七十年代的作品。
在这里我想跟你分享一下这部电影,及其引申作品,还有我对这部电影的一些看法。
《Fantastic Planet》(法语原名“La Planète sauvage”,中文译名“原始星球”)以其独特的世界观和强烈的象征意义吸引了无数观众。这部电影描绘了一个名为 Ygam 的星球,上面居住着智慧而庞大的蓝色生物 Draags 和人类大小的 Oms。Draags 对 Oms 既是宠物又是实验对象,这种关系象征着权力和压迫。电影通过这种超现实的设定,探讨了奴役与反抗、文化冲突与共生的深刻主题。
请看下面的片段。
电影中处处都有一种诡异的氛围,其中的配乐也极具特色。
《Fantastic Planet》的故事主要围绕一个年轻的 Om(人类),名为 Terr 展开。Terr 是在 Draags 的世界中被当作宠物养大的,但他利用一次偶发的机会逃脱了。当他的“主人”Tiwa 在一次学习过程中分心时,Terr 抓住机会逃离,并最终找到了一群野生的 Oms。电影中,Draags 是智慧而高大的蓝色生物,对 Oms 实施着类似宠物和奴隶的管理。在 Terr 的带领下,他和他的同伴们开始探索 Ygam 星球,学习 Draags 的技术和知识,并最终找到了反抗 Draags 统治的方法。
这部电影的剧情充满转折,不仅展现了 Terr 成长的旅程,还揭示了两种文明之间的冲突与和解,最终迫使 Draags 重新考虑对 Oms 的态度,导致了两个种族之间的和解。
电影的情节主要围绕 Terr 的成长和他最终领导 Om 反抗 Draags 的统治展开。故事的主要阶段包括:
成长与学习:在 Tiwa 的家中,Terr 接触到了 Draags 的学习装置,这些装置通过直接向大脑传递信息的方式教授知识。虽然这些装置主要是为 Draags 设计的,但 Terr 利用它们秘密学习了 Draags 的语言和科技知识。
逃离与自由:随着对 Draags 文化的理解加深,Terr 意识到自己的奴役地位,决定逃离 Tiwa 的家。他带走了一个重要的学习装置,这成为他和其他 Om 反抗 Draags 的关键工具。
野生 Om 社区:逃离后,Terr 加入了一个野生 Om 社区,他们居住在 Ygam 星球的荒野中。在那里,Terr 分享了他从 Draags 那里学到的知识,帮助他们提高技术水平,从而更好地抵抗 Draags 的迫害。
反抗与冲突:随着技术和组织的发展,Terr 和其他 Om 开始更加积极地反抗 Draags。他们策划并执行了多次行动,干扰 Draags 的冥想,最终引发了双方的直接冲突。
和解与共存:电影的结尾,经过一系列的斗争和破坏,双方达到了一种脆弱的和解。Draags 开始重新考虑对 Oms 的态度,而 Oms 也获得了更多的自由和生存空间。故事以一种暗示未来可能的和平共存的方式结束。
Draags 的主要弱点之一是他们对精神冥想和学习的依赖,这是他们文化的一个核心部分。Draags 通过冥想和精神投射来维持他们的社会结构和知识传承。这种精神活动虽然展示了他们的高度智慧,但也使他们在某种程度上依赖于固定的环境和仪式,一旦这种平衡被打破,他们的社会秩序和个体能力就会受到影响。
在电影中,Oms 最初是处于被动和受压迫的状态,他们被视为宠物或实验对象。然而,随着故事的发展,Oms 开始积累知识和技能,特别是在 Terr 的领导下,他偷学了 Draags 的知识并分享给其他 Oms。Oms 使用这些知识制造了自己的武器和通讯设备,组织起来进行抵抗。
Oms 的转变点是他们学会了干扰 Draags 的冥想仪式。他们发现,通过破坏 Draags 进行精神投射的特定设施,可以直接影响 Draags 的精神和身体健康。最终,Oms 通过一系列策略和战斗,迫使 Draags 重视他们的需求和权利,从而达到了一种新的平衡和相互理解。
《Fantastic Planet》在七十年代的社会政治背景下具有丰富的象征意义。这一时期,世界各地都充斥着社会动荡,包括越南战争、民权运动、以及对传统权威和社会结构的广泛质疑。
在《Fantastic Planet》的结尾,两个种族之间的和解并不是基于完全的和谐或理想化的情感联系,而是基于力量均衡。
电影中的和解通过展示两种文明之间达成的一种平衡来描绘,其中 Oms 通过获得知识和技术,能够在某种程度上与 Draags 站在同一个水平线上。Oms 学会了干扰 Draags 的冥想仪式,显示了他们能够影响 Draags 的生活和幸福。这种能力的证明迫使 Draags 重新评估他们对 Oms 的看法,并接受 Oms 作为平等的存在。因此,双方的和解更多地基于力量平衡和相互依赖,而不仅仅是单方面的宽恕或让步。
这种通过显示破坏力来达成和解的方式,在某种程度上类似于冷战时期的“共同毁灭”概念。在核大战策略中,共同毁灭(Mutually Assured Destruction, MAD)是一种阻止核战争的理论,它基于的假设是两个拥有大量核武器的对手如果发动核战争,将导致双方的彻底毁灭。因此,恐惧和自我保护的本能阻止了核战争的发生。
在《Fantastic Planet》中,虽然没有直接的核武器,但 Oms 通过获得足够的知识和技术,以及能够干预 Draags 的生活方式的能力,建立了一种形式的战略平衡。这使得 Draags 必须承认 Oms 的权利和地位,从而防止了进一步的冲突和破坏,确保了两个种族的共存。
这样的和解和平衡展现了一种基于相互尊重和理解的共存方式,同时也提醒了现实世界中力量平衡的脆弱性和维持和平的复杂性。
这部电影的译名及其中的角色名称也富有深意。
《Fantastic Planet》的不同译名映射出不同文化对这部电影的解读。法语原名“La Planète sauvage”带有“野性”的暗示,强调了电影中野生与文明的对比;而英文名“Fantastic Planet”则更强调奇幻元素。中文译名有“原始星球”、“神奇星球”、“奇幻星球”等,结合了这两种元素,既体现了电影的奇异美学,也暗示了其深刻的哲理。这些译名反映了上世纪七十年代的文化背景,当时社会动荡和对权威的质疑正酝酿之中。
Fantastic Planet 中的角色和名称富有象征意义,每个名字背后都携带着一定的文化或哲学含义,有助于增强电影的主题和故事。
Draags - 这个名字可能派生自“drag”或“dragoon”,象征着他们的统治地位和力量。Draags 这个名字暗示了他们对 Oms 的支配和冷漠态度。
Oms - 这个名字可能来源于法语单词“homme”,意味“人”。这个名称强调了他们的人性和在 Draags 眼中被视为次等的地位。
Terr - 主角 Terr 的名字来源于“terre”,法语中的“地球”或“土地”。这个名字强调了他作为 Om(类人种族)与自然和地球的紧密联系,同时也体现了他的地位和他的成长旅程。
Tiwa - Terr 的“主人”,一位年轻的 Draag 女性。她的名字可能来源于“twee”,荷兰语中的“二”或表示幼小、可爱的意思,这反映了她相对年轻和她对 Terr 的看待方式,即作为一个宠物或小孩。
《Fantastic Planet》(奇幻星球)的配乐是由法国作曲家 Alain Goraguer 创作的,这部音乐成为了电影的一个显著特色,与其独特的视觉风格和深刻的主题完美结合。Goraguer 的音乐风格融合了爵士、电子乐和管弦乐,为电影带来了一种梦幻般的、超现实的氛围。
电子音乐元素:Goraguer 在音乐中广泛使用了电子合成器,为电影提供了一种前卫的科技感。这种使用在 1970 年代初期是相对新颖的,与电影中的科幻主题和未来主义美学形成了和谐的统一。
爵士风格的影响:配乐中还融入了爵士音乐的元素,特别是在一些轻松或不安的场景中。这些爵士风格的曲目增加了音乐的动态范围,使观众在情感上更加投入电影的世界。
管弦乐的运用:电影音乐还包括了传统的管弦乐部分,尤其是在描绘 Draags 的文化和仪式时。这种传统元素与电子和爵士的现代感形成对比,强调了 Draags 社会的复杂性和高度发展。
节奏和氛围:整个配乐在节奏和氛围上都非常独特,既有悬疑和紧张的片段,也有平静和沉思的片段。这种多样性使得音乐本身几乎成为电影叙事的一个角色。
Alain Goraguer 的配乐为《Fantastic Planet》增添了一层额外的意义和情感深度,使其成为观众和批评家赞誉的对象。这种音乐与电影的结合,为观众提供了一次全面的感官体验,是电影受欢迎的重要因素之一。
René Laloux 的导演生涯以其独树一帜的视觉风格和深刻的寓意著称。《Fantastic Planet》的视觉设计和故事叙述对许多后来的电影制作人产生了影响,其中包括印度导演 Tarsem Singh。Singh 的作品如《The Cell》(2000 年)和《The Fall》(2006 年)中,同样可以看到对 Laloux 奇幻和超现实风格的致敬。
The Cell 是一部科幻惊悚片,中文译作“入侵脑细胞”,讲述了一个男子突然接到一个被绑架女子的电话,随后展开了一场横跨整个城市的紧张营救行动。
The Fall 是一部视觉艺术电影,中文译作“坠入”,通过一个受伤的特技演员在医院里向一个小女孩讲述的五个奇幻英雄的故事,探索了故事讲述的力量和现实与想象的界限。
通过 Terr 的经历,电影《Fantastic Planet》深入探讨了知识、自由与自我实现的重要性,并且通过 Terr 这一角色展示了不同文明间的冲突、理解与和解。Terr 不仅仅是反叛的象征,更是连接不同世界、开启和平共存可能性的桥梁。
Oms 如何利用技术和知识战胜 Draags 的过程突显了教育和智慧在社会变革中的核心作用,同时也展现了如何通过团结和策略战胜强大对手的智慧。电影中的和解是一种脆弱的平衡,随时可能因新的冲突而被打破。
观看《Fantastic Planet》是一次视觉与思维的双重震撼,电影中的超现实场景和丰富的社会隐喻促使我深思现实世界中的类似问题。这部作品对权力、压迫及解放的深刻描绘,不仅仅是视觉上的享受,更是对人类社会的深刻反思,提供了宝贵的启示和思考。
2024-07-11 19:45:20
随着企业信息系统越来越多地采用微服务架构,如何在多集群环境中实现服务的高效、安全地跨集群访问成为了一个重要的挑战。Istio 作为一种流行的服务网格解决方案,提供了丰富的功能来支持跨集群服务的无缝连接。
在部署和使用多集群服务网格时有以下难点:
本文将深入探讨如何在多集群多网格的 Istio 部署中,通过实施 SPIRE 联邦和东西向网关暴露服务的方式,实现跨集群的无缝访问。通过一系列配置和部署示例,本文旨在为读者提供一个清晰的指南,帮助理解和解决多集群服务网格部署中遇到的常见问题和挑战。
Istio 文档中根据集群、网络、控制平面、网格、信任域及租户等维度划分了多种部署模型,我将其总结并附上适用场景说明如下表所示。
维度 | 单一配置 | 多元配置 | 适用场景说明 |
---|---|---|---|
集群 | 一个集群托管所有服务与控制平面。 | 跨多个集群分布服务,可以共享或分离控制平面。 | 单集群适用于资源需求较小、管理相对简单的环境;多集群适合于需要高可用性、地理冗余或遵守数据驻留政策的大型组织。 |
网络 | 所有服务在单一网络内通信,无需跨网络通信。 | 服务跨越多个网络,需通过 Istio 网关进行通信。 | 单网络适用于网络简单、无复杂跨网络通信需求的场景;多网络适合在多云、混合云环境中部署,或需要跨行政边界部署的场景。 |
控制平面 | 一个控制平面管理所有服务。 | 每个控制平面管理一个或多个集群,增强隔离与可用性。 | 单控制平面适用于小型至中型部署,易于管理;多控制平面适用于大规模部署,需要高度的容错能力和安全隔离。 |
网格 | 所有服务在一个连续的服务网格中。 | 服务网格之间通过联盟进行通信,适用于不同组织或区域。 | 单网格适用于组织内部密切协作的服务;多网格适合于需要隔离不同业务线或合作伙伴间的服务,或实施强隔离的大型组织。 |
信任域 | 所有服务使用同一套密钥和证书体系。 | 不同信任域使用不同的密钥和证书,需进行信任链交换。 | 单信任域适用于信任级别统一的环境;多信任域适用于需要严格隔离、满足不同安全级别需求的复杂组织或多方合作场景。 |
租户 | 整个网格为单一租户或用户服务。 | 通过命名空间隔离,支持多个租户在同一网格中运行服务。 | 单租户适用于所有资源和服务由单一组织管理的场景;多租户适用于云服务提供商或需要在同一物理基础设施上运营多个客户的场景。 |
选择合适的部署模型需要考虑到实际的业务需求、安全要求、管理复杂度以及成本等因素。在生产环境中,往往是对多种部署模型的组合使用。
下表展示了在实际应用中如何结合不同的部署模型来满足更复杂的业务和技术需求:
混合部署模型 | 描述 | 适用场景 |
---|---|---|
多集群 + 多网格 + 多控制平面 | 不同的集群可以配置成不同的网格,每个网格都有自己的控制平面。通过网格联邦共享服务和策略。 | 适合大型组织,其中不同的业务单位需要独立运行并管理自己的服务,同时需要一定级别的服务共享和协作。 |
多信任域联邦 + 命名空间隔离的多租户 | 不同的网格可以拥有不同的信任域,通过信任域联邦共享密钥和证书。同时在一个网格内部通过命名空间实现租户隔离。 | 适用于需要强隔离但又要求跨组织或跨业务线协作的环境,如跨国公司或合作伙伴网络。 |
多集群 + 单网格 + 多控制平面 | 多个集群共享一个服务网格,但每个集群拥有自己的控制平面来管理本地服务的配置。 | 适用于需要高可用性和灾难恢复能力的应用,各地区的集群可以独立运行,减少单点故障风险。 |
多集群 + 多网格 + 单控制平面 | 多个集群分布在不同的网格中,但所有网格共享一个中心控制平面。 | 适用于中心化管理的大规模部署,可以减少管理的复杂性,但对控制平面的可用性要求极高。 |
多信任域 + 多网格 + 命名空间隔离的多租户 | 各网格拥有独立的信任域,增强安全性和隔离性。在单个网格内使用命名空间来隔离不同的租户。 | 适用于提供云服务的组织,需要隔离不同客户的数据和服务,同时在不同的法律和合规环境下操作。 |
这些混合模型提供了高度的灵活性和可扩展性,能够满足各种复杂的部署要求。在选择混合模型时,组织需要考虑到管理复杂性、成本、安全要求以及业务需求,以确定最合适的部署策略。通过适当的规划和设计,Istio 的灵活部署模型可以帮助组织构建出既安全又高效的服务网格架构。在大多数场景下,单信任域的多集群 + 单网格 + 多控制平面已足够满足需要。
本文将聚焦多集群 + 多网格 + 多控制平面 + 多信任域的混合部署模型,这是一种相当复杂的场景,如果你可以完成这种场景的部署,那么其他场景也就不在话下了。
网格间的服务要想互相访问,必须了解各自的 FQDN。FQDN 通常由服务名、命名空间和顶级域(如 svc.cluster.local
)组成。在 Istio 的多集群或多网格设置中,可以通过不同的机制(如ServiceEntry
、VirtualService
、Gateway
配置)来控制和管理服务的路由和访问,而不是通过修改 FQDN 来实现。
多集群服务网格中的 FQDN 与单集群并没有什么不同,通常遵循以下格式:
<service-name>.<namespace>.svc.cluster.local
也许你会想到通过 meshID
来区分网格?meshID
主要用于区分和管理在同一环境中或跨环境的多个 Istio 网格,meshID
并不用于直接构造服务的 FQDN。
meshID
的主要作用
在 Istio 多网格环境中,东西向网关(East-West Gateway)起着关键作用,它不仅处理网格间的入口和出口流量,还支持服务的发现和连接。当一个集群需要访问另一个集群中的服务时,它通过这个网关路由到目标服务。
下图展示了跨集群的服务注册发现与路由的过程。
在跨集群的 Istio 网格配置中,服务注册、发现和路由的流程是至关重要的,它们确保了不同集群中的服务可以相互发现并通信。以下是跨集群 Istio 网格中服务注册、发现与路由的基本流程:
在每个 Kubernetes 集群中,当一个服务被部署时,它的信息会被注册到 Kubernetes 的 API Server。这包括服务的名称、标签、选择器、端口等信息。
Istiod,作为控制平面,负责监控 Kubernetes API Server 的状态变化。每当有新的服务被注册或现有服务被更新时,Istiod 会自动检测到这些变化。Istiod 接着提取必要的服务信息并构建内部的服务和端点的配置。
为了使一个集群中的服务能够发现并通信到另一个集群的服务,Istiod 需要将服务端点信息同步到所有相关集群。这通常通过以下两种方式之一实现:
当服务 A 需要与服务 B 通信时,它的 Envoy 代理首先解析服务 B 的名称获取 IP 地址,即服务 B 所在集群的东西向网关的负载均衡器地址。接着该东西向网关将请求路由到目标服务。Envoy 代理可以根据配置的负载均衡策略(如轮询、最少连接数等),选择最佳的服务实例来发送请求。
Istio 提供了丰富的流量管理功能,例如请求路由、故障注入、流量复制等。这些规则在 Istio 的控制平面中定义,并推送到各个 Envoy 代理执行。这样可以在跨集群环境中灵活地控制和优化服务间的通信。
当不同集群中运行的服务需要相互通信时,正确的身份认证和授权是确保服务安全的关键。使用 SPIFFE 可以帮助标识和验证服务的身份,但在多集群环境中需要确保这些身份是唯一且可验证的。
为此,我们将设置 SPIRE 联邦来为多集群的服务分配身份并实现跨集群的身份认证:
spiffe://<trust-domain>/<namespace>/<service>
的唯一标识符。在多集群环境中,可以通过包括集群名称在内的“trust domain”来确保身份的唯一性。例如,可以设置spiffe://foo.com/ns/default/svc/service1
和spiffe://bar.com/ns/default/svc/service1
,以区分不同集群中相同名称的服务。以下是实现 SPIRE 联邦的步骤说明。
每个集群都配置为一个单独的 trust domain。这样,每个集群内的服务都将具有基于其所在 trust domain 的唯一 SPIFFE ID。例如,集群 1 的服务可能拥有 ID spiffe://cluster1/ns/default/svc/service1
,而集群 2 的相同服务则为 spiffe://cluster2/ns/default/svc/service1
。
在 SPIRE 中配置 trust relationships 以允许不同 trust domain 的节点和工作负载相互验证。这涉及到 trust domain 之间交换和接受彼此的 CA 证书或 JWT keys,确保跨集群通信的安全性。
在每个集群中部署 SPIRE Server 和 SPIRE Agent。SPIRE Server 负责管理证书颁发和续签,而 SPIRE Agent 负责将证书和密钥安全地分发给集群内的服务。
服务可以通过 SPIRE 的 Workload API 请求和更新其身份证书。这样,服务即使在不同集群中运行,也能持续验证其身份,并安全地与其他服务通信。我们将配置 Istio 网格中的代理共享 SPIRE Agent 中的 Unix Domain Socket,从而访问 Workload API 来管理证书。
我们将使用 cert-manager 作为 SPIRE 的 UpstreamAuthority,配置 SPIRE 自动轮换服务证书和密钥,增强系统的安全性。通过自动化轮换,即使证书被泄露,攻击者也只能在很短的时间内利用这些证书。
通过这些步骤,你可以建立一个跨集群的、安全的服务身份验证框架,使得各个集群的服务能够安全地识别和通信,从而有效地降低安全风险并简化证书管理。这样的配置不仅增强了安全性,还通过分散的信任域提高了系统的可扩展性和灵活性。
下图展示了 Istio 多集群及 SPIRE 联邦的部署模型。
下面我将演示如何在多集群 Istio 网格中实现无缝地跨集群无缝访问。
cluster-1
和 cluster-2
sidecarInjectorWebhook
挂载 SPIFFE UDS 的 workload-socket
,并启用 DNS 代理我们部署的各组件版本如下:
我将所有命令及步骤说明保存在 Github 上:rootsongjc/istio-multi-cluster,你可以按照该项目中的说明操作。下面是对各主要步骤的说明。
打开 Google Cloud Shell 或本地终端,并确保你已经安装了 gcloud
CLI。使用以下命令创建两个集群:
gcloud container clusters create cluster-1 --zone us-central1-a --num-nodes 3
gcloud container clusters create cluster-2 --zone us-central1-b --num-nodes 3
使用 cert-manager 作为根 CA 为 istiod 和 SPIRE 颁发证书。
./cert-manager/install-cert-manager.sh
SPIRE 联邦的基本信息如下:
Cluster Alias | Trust Domain |
---|---|
cluster-1 | foo.com |
cluster-2 | bar.com |
注意:信任域不需要与 DNS 名称一致,但需要与 Istio Operator 配置中的信任域相同。
执行下面的命令部署 SPIRE 联邦:
./spire/install-spire.sh
想了解 Istio 中使用 SPIRE 进行身份管理的详情,请参考使用 cert-manager 和 SPIRE 管理 Istio 中的证书。
我们将使用 IstioOperator 来安装 Istio,其中为每个集群配置了:
执行下面的命令安装 Istio:
istio/install-istio.sh
为了验证多集群安装的正确性,我们将在两个集群中分别部署不同版本的 helloworld
应用,然后在 cluster-1
中访问 helloworld
服务,以测试以下跨集群访问场景:
执行下面的命令在两个集群中部署 helloworld
应用:
./example/deploy-helloword.sh
部署完成 helloworld
应用后,从 cluster-1
的 sleep
pod 访问 hellowrold
服务:
kubectl exec --context=cluster-1 -n sleep deployment/sleep -c sleep \
-- sh -c "while :; do curl -sS helloworld.helloworld:5000/hello; sleep 1; done"
下图展示的是该场景下的部署架构及流量路由路径。
从请求结果既有 helloworld-v1
又有 helloworld-v2
的响应来看,说明跨集群的服务冗余生效了。
验证 DNS
此时,因为 helloworld
服务既存在于本地又在远程集群中,若你在 cluster-1
中查询 helloworld
服务的 DNS 名称:
kubectl exec -it deploy/sleep --context=cluster-1 -n sleep -- nslookup helloworld.helloworld.svc.cluster.local
你将得到 cluster-1
集群中的 helloworld
服务的 ClusterIP。
验证流量路由
接下来我们将通过查看 Envoy 代理配置来验证跨集群的流量路由路径。
在 cluster-1
中查看 helloworld
服务的端点:
istioctl proxy-config endpoints deployment/sleep.sleep --context=cluster-1 --cluster "outbound|5000||helloworld.helloworld.svc.cluster.local"
你将得到类似下面的输出:
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.76.3.22:5000 HEALTHY OK outbound|5000||helloworld.helloworld.svc.cluster.local
34.136.67.85:15443 HEALTHY OK outbound|5000||helloworld.helloworld.svc.cluster.local
这两个端点,一个是 cluster-1
中的 helloworld
服务的端点,另一个是 cluster-2
的 istio-eastwestgateway
服务的负载均衡器地址。Istio 将为跨集群的 TLS 连接设置 SNI,在 cluster-2
中将通过 SNI 区分目标服务。
执行下面的命令,在 cluster-2
中查询前面 SNI 的端点:
istioctl proxy-config endpoints deploy/istio-eastwestgateway.istio-system --context=cluster-2 --cluster "outbound_.5000_._.helloworld.helloworld.svc.cluster.local"
你将得到类似下面的结果:
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.88.2.4:5000 HEALTHY OK outbound_.5000_._.helloworld.helloworld.svc.cluster.local
这个端点就是 helloworld
服务在 cluster-2
集群中的端点。
通过以上步骤,你应该了解了跨集群冗余服务的流量路径。接下来我们将删除 cluster-1
中的 helloworld
服务,不需要对 Istio 做任何配置,就可以自动实现故障转移。
执行下面的命令将 cluster-1
中的 helloworld
副本数量缩容为 0:
kubectl -n helloworld scale deploy helloworld-v1 --context=cluster-1 --replicas 0
再次从 cluster-1
中访问 helloworld
服务:
kubectl exec --context=cluster-1 -n sleep deployment/sleep -c sleep \
-- sh -c "while :; do curl -sS helloworld.helloworld:5000/hello; sleep 1; done"
依然可以获得来自 helloworld-v2
的响应。
现在,直接删除 cluster-1
中的 helloworld
服务:
kubectl delete service helloworld -n helloworld --context=cluster-1
依然可以获得来自 helloworld-v2
的响应,这说明跨集群的故障转移生效了。
下图展示了该场景下的流量路径。
验证 DNS
此时,因为 helloworld
服务既存在于本地又在远程集群中,若你在 cluster-1
中查询 helloworld
服务的 DNS 名称:
kubectl exec -it deploy/sleep --context=cluster-1 -n sleep -- nslookup helloworld.helloworld.svc.cluster.local
你将得到 cluster-2
集群中东西向网关的地址和 15443 端口。
通过入口网关访问远程集群中的服务,是最传统的跨集群访问方式,下图展示了该场景下的流量路径。
执行下面的命令在 cluster-2
中创建 Gateway 和 VirtualService:
kubectl apply --context=cluster-2 \
-f ./examples/helloworld-gateway.yaml -n helloworld
获取 cluster-2
中的入口网关地址:
GATEWAY_URL=$(kubectl -n istio-ingress --context=cluster-2 get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
执行下面的验证可以通过远程入口网关访问服务:
kubectl exec --context="${CTX_CLUSTER1}" -n sleep deployment/sleep -c sleep \
-- sh -c "while :; do curl -s http://$GATEWAY_URL/hello; sleep 1; done"
你将得到来自 helloworld-v2
的响应。
执行下面的命令获取 cluster-1
集群中 sleep
pod 中的证书:
istioctl proxy-config secret deployment/sleep -o json --context=cluster-1| jq -r '.dynamicActiveSecrets[0].secret.tlsCertificate.certificateChain.inlineBytes' | base64 --decode > chain.pem
split -p "-----BEGIN CERTIFICATE-----" chain.pem cert-
openssl x509 -noout -text -in cert-ab
openssl x509 -noout -text -in cert-aa
如果在输出的消息中看到下面的字段,说明身份分配正确:
Subject: C=US, O=SPIFFE
URI:spiffe://foo.com/ns/sample/sa/sleep
查看 SPIRE 中的身份信息:
kubectl --context=cluster-1 exec -i -t -n spire spire-server-0 -c spire-server \
-- ./bin/spire-server entry show -socketPath /run/spire/sockets/server.sock --spiffeID spiffe://foo.com/ns/sleep/sa/sleep
你将看到类似下面的输出:
Found 1 entry
Entry ID : 9b09080d-3b67-44c2-a5b8-63c42ee03a3a
SPIFFE ID : spiffe://foo.com/ns/sleep/sa/sleep
Parent ID : spiffe://foo.com/k8s-workload-registrar/cluster-1/node/gke-cluster-1-default-pool-18d66649-z1lm
Revision : 1
X509-SVID TTL : default
JWT-SVID TTL : default
Selector : k8s:node-name:gke-cluster-1-default-pool-18d66649-z1lm
Selector : k8s:ns:sleep
Selector : k8s:pod-uid:6800aca8-7627-4a30-ba30-5f9bdb5acdb2
FederatesWith : bar.com
DNS name : sleep-86bfc4d596-rgdkf
DNS name : sleep.sleep.svc
对于生产环境,建议使用统一网关,通过 Tier-2 架构,在 Tier-1 边缘网关配置全局的流量路由,该边缘网关将把转写的 Istio 配置下发给 Tier-2 集群中的各个入口网关。
下图展示了使用 TSB 部署的 Tier2 架构的 Istio 服务网格,其中使用 SPIRE 联邦。
我们将这四个 Kubernetes 集群分为 Tier1 集群(tier1
)和 Tier2 集群(cp-cluster-1
、cp-cluster-2
和 cp-cluster-3
)。在 T1 中安装 Edge Gateway,而在 T2 中安装 bookinfo 和 httpbin 应用程序。每个集群将拥有独立的信任域,所有这些集群将构成 SPIRE 联邦。
下图展示了用户通过入口网关访问 bookinfo 和 httpbin 服务的流量路由。
你需要在 Istio 之上创建一个适用于多集群的逻辑抽象层,关于 TSB 中的统一网关的详细信息,请参考 TSB 文档.
本文详细介绍了在 Istio 多集群网格环境中实现服务身份验证、DNS 解析和跨集群流量管理的关键技术和方法。通过精确配置 Istio 和 SPIRE 联邦,我们不仅增强了系统的安全性,还提高了服务间通信的效率和可靠性。遵循这些步骤,你将能够构建一个强大的、可扩展的多集群服务网格,满足现代应用的复杂需求。
2024-07-02 19:40:40
随着 Istio 1.22 版本的发布,Istio API 已正式升级至 v1 版本,同期,Kubernetes Gateway API 也更新至 v1.1 版本。本篇文章旨在深入探索 Ingress API、Istio API 与 Kubernetes Gateway API 之间的联系与区别,并详述它们在现实应用中的选择及迁移策略。
之前,我曾撰写一篇文章,讨论了 为何 Gateway API 是 Kubernetes 与服务网格入口中的未来方向。文章中指出,作为 Kubernetes 的初始入口网关,Ingress 的资源模型由于过于简单,难以满足当下的可编程网络需求。作为其接班人,Gateway API 近年来发展迅速,获得了广泛支持,包括众多新兴的开源网关项目如 Envoy Gateway 也选择基于 Gateway API 开发。此外,一些传统网关项目也开始适配 Gateway API,或通过 ingress2gateway 这样的工具进行迁移。
Gateway API,作为 Kubernetes 入口网关的最新成果,通过角色划分来分离关注点,并支持跨 namespace,更适合多云环境。它整合了入口网关(南北向)与服务网格(东西向,集群内路由)的重叠功能,为云原生时代的统一流量管理提供了新的参考模型。
Ingress API、Gateway API 与 Istio API 都能实现网关功能,它们之间具体有何联系与区别?本文将为你揭晓这一迷题,并提供 Kubernetes 环境中网关的选择和迁移策略。
随着微服务架构的广泛应用和日益增长的复杂性,Kubernetes 的流量管理工具也在不断演进以适应各种技术需求。Ingress API、Istio API 与 Kubernetes Gateway API 分别标志着这一演变的不同阶段。
Ingress API 提供了 Kubernetes 的基本流量管理功能,允许用户通过定义简单的路由规则(例如 HTTP 和 HTTPS)来管理外部访问集群内服务的流量。其设计虽简洁,但功能有限,主要适用于规模较小、结构较简单的应用场景。
相比之下,Istio API 作为服务网格的一部分,提供了一系列高级流量管理功能,如流量镜像、金丝雀发布和断路器,适合于需要复杂流量管理的大规模微服务架构。
为了克服 Ingress API 的局限性并集成类似 Istio 的高级功能,Kubernetes Gateway API 因应而生。它不仅在设计上提供了更高的灵活性和扩展性,还通过社区的广泛支持,成为连接传统 Ingress 实现和现代服务网格技术如 Istio 的桥梁,目前主流的开源网关都是基于 Gateway API 或已进行适配。
以下表格概述了这三者的核心特点和推荐使用场景:
API 名称 | 对象类型 | 状态 | 推荐使用场景 |
---|---|---|---|
Ingress API | Ingress |
稳定 (Kubernetes v1.19) | 适用于小规模和简单的应用场景,主要用于基本的路由配置 |
Istio API | VirtualService 、Gateway |
稳定 (Istio 1.22) | 适用于高度复杂的微服务架构,需细粒度控制和高级流量管理特性的场景 |
Gateway API | HTTPRoute 、Gateway |
稳定 (Gateway API v1.1) | 适用于新部署或现有部署,需提高灵活性和可扩展性的场景,特别是结合 Istio 使用 |
Gateway API v1.1 的推出,特别是其在提升与现有 Ingress 配置兼容性方面的改进,为用户提供了一个平稳的迁移途径,使从传统的 Ingress 解决方案向更现代的、功能更全面的 Gateway API 的过渡变得更为顺畅。
若想从 Ingress 迁移到 Gateway API,请按以下步骤操作:
Gateway
、HTTPRoute
和 TLSRoute
。这些资源提供了更多的配置选项和灵活性,请参阅 Gateway API 文档以了解其配置。Gateway
资源配置,明确定义如何接收外部流量,包括配置协议、端口和 TLS 终端。为了简化迁移过程,你可以使用工具如 ingress2gateway,该工具能自动将 Ingress 配置转换为 Gateway API 格式。
以下是一个简单的 HTTP 网关配置示例,展示了如何将 Ingress 迁移到 Gateway API。
假设现有一个 Ingress 配置如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: example-service
port:
number: 80
要将其迁移到 Gateway API,首先需要创建一个 Gateway 对象:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: example-gateway
spec:
gatewayClassName: example-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
kinds
- kind: HTTPRoute
请确保 gatewayClassName
指向你集群中配置的有效 GatewayClass。GatewayClass 通常由集群管理员设置,是一个为 Gateway 提供配置的资源。
接下来,创建 HTTPRoute 资源来定义路由规则,将流量路由到后端服务:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: example-httproute
spec:
parentRefs:
- name: example-gateway
hostnames:
- "example.com"
rules:
- matches:
- path:
type: PathPrefix
value: "/"
backendRefs:
- name: example-service
port: 80
在此示例中,我们看到:
Ingress
对象中的规则被直接映射到 HTTPRoute
对象中。虽然可以将 Ingress 迁移到 Gateway API,并可能同时运行它们,但需要考虑以下挑战和迁移的必要性:
对于现有的 Ingress 和 Istio API 用户,是否需要迁移到 Gateway API 取决于具体情况。以下是一些迁移建议:
对于不同网关对 Gateway API 的支持情况,可以参考 Gateway API 实现项目的一致性报告了解详细信息。
Ingress API、Istio API 和 Kubernetes Gateway API 各具特色,适应不同的应用场景和需求。选择合适的 API,进行合理的规划和管理,可以显著提高系统的灵活性和稳定性。随着 Gateway API 的持续发展和成熟,它将越来越成为未来流量管理的主流选择。
选择合适的网关技术,结合你的具体需求和现有架构,可以更好地管理和优化流量,确保应用的高效和稳定运行。随着技术的进步和社区的发展,Gateway API 提供了一个强大且灵活的框架,使得从传统的 Ingress 迁移到更现代的解决方案变得更为简单和高效。
2024-06-26 16:55:45
微信是我们在日常生活和工作中不可或缺的通讯工具,许多用户都有在同一台设备上登录多个微信账号的需求。尽管官方客户端不直接支持这一功能,但通过一些简单的技巧,你可以在 Mac 电脑上实现微信的多开功能。
你可能看到过一些介绍如何在 Mac 上实现微信多开的文章或视频,那些技巧大多已经失效,有的可用的也只能在一台电脑上同时登录两个微信,本文将详细介绍如何在 Mac 上同时运行任意多个微信实例。
下面是演示视频。
下面是详细步骤。
首先,你需要在应用程序文件夹中找到微信应用程序(WeChat.app)并创建启动命令副本:
CMD + Shift + G
/Applications/WeChat.app/Contents/MacOS
WeChat
,鼠标右键选择 创建别名(Make Alias)
即创建了一个启动微信的副本。你也可以通过安装 OPT + CMD
按钮拖动 WeChat
文件到当前或另个目录比如桌面上来创建一个别名(快捷方式)。如果你想同时登录 N 个微信,则依次双击刚创建的微信副本 N + 1 次。比如你想同时登录 3 个微信,那就打开这个副本 4 次。
保持这些窗口在运行状态,你可以将它们最小化,但是不要关闭它们。在这个过程中,你可能会注意到,系统只会打开两个微信登录界面。
当两个微信登录界面打开后,手动退出其中一个已经开启的微信。
关闭一个微信后,系统会再次打开 N-1 个新的微信窗口。现在你就可以通过这些微信的登录界面登录到不同的微信账户了。
以上方法只需要使用最新的官方版本的微信即可,可以做到任意多开。希望这篇指南能帮助你更高效地使用微信,满足你的多账户管理需求。如有任何问题或需要进一步的帮助,欢迎留言讨论。
2024-06-16 06:11:53
2024 年 3 月,一个特别的机会将我带到了法国巴黎——参加 KubeCon EU 2024。这是一场汇集了来自全球的云计算和开源技术爱好者的盛会。利用这次会议的机会,我不仅深入了解了最新的技术趋势,还抓住机会体验了这座城市的历史、文化和日常生活。我的巴黎之行从 3 月 16 日开始,持续到 3 月 24 日,这期间我尽可能多地探索了这座充满魅力的城市。
对于我们中国人来说,无论何时何地,出国的第一步总是签证的申请。尤其是法国申根签证,需要准备众多材料,包括公司证明信、行程单等,但幸好我所在的公司性质让这一切变得相对容易。令人感到略有安慰的是,与申请日本签证相比,法国签证不需要冻结巨额资金或提供庞大的银行存款证明。这次我获得了六个月的签证有效期,这对于我未来的欧洲行计划提供了更多的灵活性和可能性。
从北京直飞巴黎的旅程总是充满期待。我乘坐的法国航空公司航班,从北京时间凌晨起飞,经过长达 13 小时的旅程后,于巴黎时间早晨 6 点多抵达。归途则选择了在伊斯坦布尔转机,让旅行的回忆更添一分异国情调。
戴高乐机场处处可见的中文标牌,字句优雅,显示了法国人对细节的用心。尽管通关时排队等候了近一个小时,但多样化的人流让巴黎的国际化氛围愈发显著。从机场乘坐穿梭地铁时,我体验了三次才成功挤上车,可见人流之多。使用 Bolt 打车服务时,因为语言不通,还得到了一位好心法国人的帮助,他用法语帮我与司机沟通,这让我深感法国人的友好与热心。
在巴黎戴高乐机场随处可见中文标识,很多地方只有英文、法文和中文三种文字的标识。
在巴黎的每一处,都能看到那些独具特色的垃圾桶,它们不仅方便实用,还在安全上做了考虑。例如,一些垃圾桶是为了防爆而设计的,能安全投放玻璃瓶和易拉罐,而另一些仅用透明塑料袋覆盖,也是出于同样的安全考量。这些细节体现了城市管理的精细与周到。
巴黎的垃圾分类采用彩色编码垃圾桶系统,旨在促进适当的废物处理。垃圾箱有不同的颜色:黄色用于纸张和塑料等可回收物,棕色用于可堆肥食物残渣,白色用于酒瓶等玻璃物品,绿色/灰色用于其他废物。该系统可帮助居民有效地分类垃圾,促进回收利用和适当的废物管理实践。
尽管西餐中的牛排和糕点让人难以抗拒,我还是更偏爱家乡的味道。在巴黎,我找到了一家名为杨小厨的川菜馆,其牛肉面虽与国内有所不同,但味道可口,价格亲民。此外,巴黎街头的水果与我在网上购买的相比,不仅价格合理,而且味道也极佳,特别是我喜爱的啤梨。
另外在很多地铁口还有街头巷尾也有社区小摊及烘焙店。
巴黎,法国的首都,不仅以其浪漫和历史著称,同时其行政区划也具有独特的结构。巴黎市通常被分为“大巴黎”和“小巴黎”。小巴黎指的是巴黎市内环,即第一到二十区,涵盖了大部分著名的历史地标和文化地区,总面积约为 105 平方公里。而大巴黎则包括小巴黎及其周边的郊区,形成一个更为广泛的都市区。
下图中环形道路是 Boulevard Périphérique,即巴黎环形高速公路。这条道路环绕着巴黎的 20 个区,这些区域共同构成了所谓的“小巴黎”。
巴黎的 20 个区(arrondissements)按照螺旋状的顺序从市中心向外延伸,包括了市内最核心的商业、居住以及文化区域。这些区域的总面积大约为 105 平方公里(约 40.5 平方英里),从 1 区的市中心向外逐渐扩展至 20 区。
这些区域是巴黎市的行政区划,而“小巴黎”这个名词通常是指的这些内环的区域,即由环形公路所环绕的巴黎市内部区域。因此,图中显示的 20 个区确实组成了“小巴黎”。
相比之下,北京的二环面积约为 62 平方公里,三环面积约为 159 平方公里,小巴黎的面积在二者之间,下图展示了在同等比例尺下的小巴黎和北京三环的地图。
我此行住宿的地点位于巴黎的 15 区,这里是巴黎最大的一个区,位于塞纳河左岸(按塞纳河流向)。15 区不仅居住环境宜人,交通便利,而且距离诸如埃菲尔铁塔等著名景点也非常近,步行大约 20 分钟即可到达。我下榻的住所是一栋三层高的联排公寓,底层设有车库和会客厅,而居住区则分布在二楼和三楼,共有五个房间,旁边还有某国的大使馆官邸,增添了一份特别的国际氛围。
巴黎的道路规划别具一格,道路交错纵横,并非严格的南北走向,加之红绿灯设置在街角,使得初来乍到的人有些不适应。这里的自行车道十分发达,我租了一辆助力自行车,穿行在巴黎的街头巷尾,感受到前所未有的自由与惬意。巴黎的地铁系统复杂多样,但支付方式极为方便,大部分支付都可以通过信用卡完成。
对于游客来说,在小巴黎短距离出行首选方式是自行车。巴黎街头随处可见可供租赁的自行车,你可以下载 App 注册扫码支付后即可使用,注意需要绑定信用卡。有些自行车道是在路的中间,路面上有明确标识自行车道。这些自行车都是助力车,大多维护的比较好,但是也有一些存在故障,需要仔细辨别。另外巴黎的街道较窄,行人也很少遵守红绿灯,可能是因为红绿灯太多了吧。
巴黎的地铁票种类繁多,从单次票、日票到周票、月票一应俱全,适应不同游客的需求。然而,许多外地游客在购票环节都会遇到困惑,需要一些时间来熟悉系统。
巴黎地铁(Métro de Paris)始建于 1900 年,是世界上最早的地铁系统之一。这个广泛的地铁网络包括 16 条线路,覆盖总长度达 225 公里。巴黎地铁不仅连接城市中心和外围区域,还扩展到了一些近郊区域,每年服务数亿乘客,是巴黎公共交通系统的核心部分。因为建造时间比较久远,很多设施都比较老旧,比如车厢陈旧,车厢门要手动打开,运行噪音大,没有电梯等。
在巴黎的第二天,我因饮食不当而开始腹泻,持续了两天后才好转。在这期间,我去了当地的药店买药。药店早上 8 点准时开门,门口总是有人排队等候,这种准时和秩序让我印象深刻。
法国的医疗体系被认为是世界上最好的之一,无论是急诊还是药品购买,都非常便捷。药品的质量和种类也相当丰富,能够满足不同病症的需求。
在 KubeCon EU 期间,我利用空闲时间游览了几处巴黎的著名景点。埃菲尔铁塔是必须打卡的地方,我登上了二层平台,俯瞰整个巴黎,景色壮观。卢浮宫则是艺术爱好者的天堂,蒙娜丽莎的微笑吸引了无数游客驻足。虽然巴黎圣母院还在维修中,但夜晚的圣母院依旧散发着无尽的魅力。
卢浮宫
卢浮宫(Louvre Museum)是世界上最大和最著名的博物馆之一。它最初建于 12 世纪作为皇宫,直到 1793 年开放为公众博物馆。卢浮宫收藏了超过 38 万件展品,跨越从古代文明到 19 世纪的艺术与历史文物。其中最著名的作品包括《蒙娜丽莎》、《维纳斯的诞生》和《胜利女神像》等。
卢浮宫里人流量最大的地方就是《蒙娜丽莎》,很多人在那里排起了长龙,只为一睹她那神秘的微笑。
万神殿
巴黎万神殿,最初建造为教堂,现作为一个纪念馆,位于法国巴黎的拉丁区。这座建筑最初是为了纪念圣日内瓦瑞,后转变为纪念法国伟大人物的安息之地。建筑风格融合了古典与新古典元素,其宏伟的圆顶和庄严的柱廊使它成为巴黎的一个显著地标。万神殿内部装饰豪华,包括傅科摆锤和许多重要法国历史人物的墓穴。
万神殿内的傅科摆,由法国物理学家利昂·福科于 1851 年设计,以证明地球自转的直接效应。这个简单但引人注目的实验包括一根悬挂的铁球,通过其自由摆动,观察者可以看到摆动平面相对于地面缓慢旋转的现象,这一旋转是地球自转的直接证据。福科摆锤不仅是物理学的一个重要实验,也成为了科学与艺术的结合象征。
塞纳河
清晨的塞纳河如诗如画,漫步在河畔,感受到巴黎的静谧与美好。
塞纳河是法国的一条主要河流,流经巴黎市中心。河流全长约 777 公里,起源于勃艮第地区的普拉特高原,最终流入英吉利海峡。塞纳河穿过巴黎时,河两岸布满了历史悠久的桥梁和著名的景点,如巴黎圣母院和埃菲尔铁塔。河流不仅是巴黎的重要交通水道,也是旅游和休闲的热门地点,常有游船在此穿梭,提供观光和餐饮服务。
马德莱娜教堂
马德莱娜教堂(Église de la Madeleine)是一座罗马天主教的教堂,以其古典希腊神庙风格著称。这座教堂建于 19 世纪初,外部有 52 根科林斯式柱子环绕。虽然外观极其庄严、类似神庙,但内部装饰华丽,拥有精美的雕刻和壁画。马德莱娜教堂不仅是宗教活动的场所,也常用于举行音乐会,特别是古典音乐演出。
圣心堂
圣心堂(Basilique du Sacré-Cœur)位于法国巴黎蒙马特高地,是一座罗马天主教教堂,以其白色圆顶著称。这座教堂建于 1875 年至 1914 年间,是为了纪念普法战争中的法国阵亡将士而兴建的。圣心堂采用了罗曼 - 拜占庭风格的建筑设计,内部装饰华丽,拥有壮观的马赛克和雕塑。它不仅是巴黎的一个重要宗教地点,也因其位于城市之巅,提供了俯瞰巴黎全景的绝佳视角。
除此之外,我还在骑行过程中游览了巴黎圣母院、香榭丽舍大道、爱丽舍宫、小皇宫、凯旋门、协和广场、杜乐丽花园、卢森堡公园等,限于篇幅不在此展开。
现代奥运会是法国人在巴黎提倡的,可能是法国人对奥运会已经司空见惯,也有可能是为了尽可能不打扰本地人的生活,此次巴黎之行,感受不到任何奥运会将在巴黎召开的气氛。只有一些标志性建筑旁在搭建一些展台可能是为了供奥运会使用,以及一些商店在售卖奥运会纪念品。
最近在中文互联网上,经常看到一些视频介绍巴黎的治安、环境是如何的不堪,比如街道上很多小偷、随地大小便、找不到厕所等。幸运的是我并没有遇到小偷,也没听到同伴有这样的遭遇。但是确实在一些街道尤其是景区周边闻到一些尿骚味,也遭遇了几个流浪汉问我要烟。还有就是卢浮宫里找不到厕所,唯一找到的一个男厕所还在维修中。
巴黎这座城市以其独特的魅力和丰富的文化底蕴给我留下了深刻的印象。这里的人们热情友好,景色美丽动人。虽然在一些游客密集的地方可能会稍显杂乱,但这也是任何旅游城市难以避免的现象。巴黎之行充满了美好的回忆,让人流连忘返,期待未来再次踏上这片浪漫的土地。也希望这篇游记能对初次踏上这篇土地人有所帮助。
2024-06-14 19:14:40
Istio 依赖 Kubernetes 来进行服务发现,这通常意味着必须在 Kubernetes 集群中部署微服务并使用 Kubernetes 服务发现。然而,很多现有的微服务项目还在使用如 Consul、Eureka 这样的第三方服务注册表,本文将探讨如何将这些现有的微服务的注册表与 Istio 集成。
Istio 最初只支持 Kubernetes 服务,但随着时间的推移,为了适应更广泛的应用场景,它开始支持像 Consul 这样的第三方服务注册表。通过引入 Mesh Configuration Protocol(MCP),Istio 能够与各种服务发现后端通信,如 Consul,从而管理非 Kubernetes 环境中的服务。在 Istio 1.1 版本中,引入了 ServiceEntry 资源对象,这使得用户可以手动将外部服务添加到 Istio 的服务注册表中,并在 Istio 1.8 中取消了对 Consul 的直接支持,转而通过 ServiceEntry 提供了一种更灵活的方式来集成和管理所有服务,无论它们是否托管在 Kubernetes 上。
下图展示了 Istio 代理配置的高层架构,揭示了配置如何从各种源被摄取、转换,并最终服务于 Envoy 代理。
要想详细了解 Istiod 的架构,可以参考 Istio 架构详解。
配置从 ConfigStore 和 ServiceDiscovery 聚合后,由 Config Translator 翻译成适合代理的格式,然后通过 XDS Server 服务于 Envoy 代理。这是将动态配置应用于代理的最终步骤。
为了集成第三方服务注册表,我们可以实现一个 Operator,该 Operator 监视第三方服务注册表并将服务以 ServiceEntry 和 WorkloadEntry 资源形式推送至 Kubernetes API 服务器。以下流程图展示了该同步过程。
Tetrate 开发的 Istio Registry Sync 是一个扩展 Operator,可以作为 TIS 的 add-on 运行。它支持非 Kubernetes 服务注册表(如 AWS Cloud Map 和 Consul)与 Istio 的集成。此工具提供了以下几个使用场景:
通过上述方法,你可以有效地将 Istio 与第三方服务注册表集成,无论是通过开发自定义的 Operator 还是使用现成的 Istio Registry Sync 工具。这样不仅能够保持服务的现代化,还能确保在不同环境之间的高效协同工作。
2024-06-11 16:23:50
最近 Istio 1.22 发布包含大量的重大更新,本文将为你分享这个发布带来的新特性及应用建议。
虽然 Ambient 模式现已进入 Beta 阶段,但这并不意味着我们可以完全告别 Sidecar。尽管 Istio 官方宣称 Ambient 模式可以简化操作并显著减少内存和 CPU 使用,但它仍然存在局限性和潜在的复杂性问题。例如,虽然取消了 Sidecar,但需引入新的 ztunnel 和 waypoint 组件,这可能带来新的挑战。关于 Ambient 模式进入 Beta 模式的详细信息请参阅 Istio 官方博客。
Ambient 模式带来的新的挑战
关于 Sidecar 模式和 Ambient 模式的对比,详见 Istio Ambient 模式的局限性解析。
Istio Istio 1.22 版本中,关键 API 如流量管理、安全、Telemetry 相关的 API 都已正式升级到 v1
版本。你只需要将原有配置的 API 版本修改为 v1
即可,除此之外不需要任何更改。这些 API 早已成熟,你可以放心的使用 v1
版本,对于对稳定性要求较高的环境,Istio 添加了验证准入策略确保只有 v1
API 和字段可以在 Istio API 中使用。
例如下面的 AuthorizationPolicy 示例。
|
|
其他扩展类的 API 如 EnvoyFilter
、WasmPlugin
、ProxyConfig
还未成熟,因此还停留在 alpha 或 beta 阶段。关于 API 升级的更多信息,请参考 v1 API 博客。
v1
API,扩展类 API 尚未稳定为了保证系统稳定性,可以开启验证准入策略。
Gateway API 已更新至版本 1.1.0,现已普遍可用。这一更新扩展了 Istio 的流量管理能力,但需要注意 Istio 原生 API 与 Gateway API 的兼容性问题。在迁移到新 API 时应谨慎,以避免依赖尚未完全成熟的特性。更多详情,请查看 Gateway API v1.1 博客。
Istio 1.22 版本默认启用了增量 xDS,这是一个优化配置分发的机制。与传统的 State of the World(SotW)模式相比,增量 xDS 仅将变更的配置发送给 Envoy 代理,从而显著减少了网络传输的数据量和控制平面的资源消耗。这一变更尤其适用于配置频繁更新的大规模部署环境,能够提高配置更新的效率和性能。此外,增量 xDS 还有助于在网络环境复杂或配置动态变化的情况下,更高效地管理服务网格的配置更新。
更多关于 xDS 的介绍请参考Envoy xDS 及 Istio 中的配置分发流程介绍。
在 Istio 1.22 中,AuthorizationPolicy
新增了对路径模板的支持,极大增强了路径匹配的灵活性和精确性。而在此之前,AuthorizationPolicy
的路径配置并不支持通配符。此功能允许使用基于 Envoy 的 URI 模板匹配来定义 HTTP 请求中的路径。路径可以包括简单的通配符(*
和 **
)或具名变量,从而精确匹配单个或多个路径组件。例如,路径模板 /foo/{*}
能匹配 /foo/bar
但不匹配 /foo/bar/baz
,而 /foo/{**}/
则可以匹配任何以 /foo/
开头的路径。这种灵活的路径模板设计,特别适用于动态和复杂的路由规则,进一步加强了 Istio 的安全策略工具箱。
下图展示了 AuthorizationPolicy 的路径匹配的通配符规则。
了解更多关于路径模板的具体应用和规则,你可以参考 Envoy 的官方文档。
AuthorizationPolicy
中的路径匹配终于支持模板了,你不需要再在配置中一个一个地手动加入路径了。
Istio 1.22 版本引入了多项重要更新和改进,尽管某些特性被广泛宣传,但在实际使用中需要进行详细评估和适当的测试。希望本篇博客能帮助你更深入地理解和应用这些新特性,以在实际操作中获得最佳效果。
2024-06-10 10:38:16
三年前,我与 Addo 环游了新疆北疆,那次旅行让我久久难忘,尤其是伊犁河谷地带,始终萦绕在心头。这次端午佳节,我决定再赴伊犁,开启一场自驾之旅。
经过精心策划,我从北京出发,途经乌鲁木齐转机,来到美丽的伊宁。在这里,我们租了一辆车,开始了为期一周、总行程 1344 公里的自驾之旅。
在这段视频中,你将看到我在旅途中拍摄的壮丽航拍画面。从广阔的草原到清澈的湖泊,从巍峨的雪山到蜿蜒的公路,这些美景都在视频中得到了完美的呈现。
我们的第一站是伊宁市的喀赞其民俗村,这是一个充满民族风情的小镇。这里的街道两旁是独具特色的传统民居,五彩斑斓的墙壁和蓝色的大门,仿佛童话世界。喀赞其的生活气息浓厚,街上随处可见当地居民的日常生活场景。
从喀赞其出发,我们前往了伊犁河。伊犁河的河水清澈见底,两岸绿树成荫,广阔的湿地景色宜人。我们在伊犁湿地公园观看了一场壮美的日落,沉醉于大自然的美景中。
第三站是喀拉峻草原。广阔的草原上,牛羊成群,远处的雪山与蓝天白云相映成趣,构成了一幅绝美的自然画卷。这里平均海拔 2000 多米,空气格外清新,每一口呼吸都让人感到无比的舒畅。我在这里露营了一晚,经过了一夜的风雨,第二天雨过天晴日出时,阳光洒在身上暖洋洋的,眺望远处的日照金山。
接下来,我们来到了琼库什台。这个哈萨克族的原始村庄虽然多了一些商业气息,但依然保留着原始的魅力。草原和河谷里新开的民宿和饭店让更多游客慕名而来。我们骑马前往后山,体验了最纯粹的自然风光。尤其是夕阳西下时,在山顶看着连绵起伏的草原和远处的雪山交相辉映,相映成趣。
夏塔古道是此次行程中的重要景点。古道曾是丝绸之路上的一部分,沿途高山峡谷景色壮丽。尽管景区尚未开放,我们还是通过无人机航拍领略了这里的冰川河谷。
伊昭公路被誉为新疆最美的公路之一。沿途风景从高山到草原,从森林到湖泊,变幻多姿。行驶在悬崖峭壁上,不禁感叹开路人的艰辛。
最后一站是赛里木湖,位于博尔塔拉蒙古自治州。这个高山湖泊的湖水清澈见底,碧蓝如普鲁士蓝,四周环绕着雪山和草原,景色如诗如画。我们在湖边漫步,夜宿赛里木湖西岸,感受这座号称“大西洋的最后一滴眼泪”的静谧与壮丽。
这次新疆伊犁自驾之旅不仅让我领略了壮丽的自然风光,还体验了当地独特的民族文化。通过航拍镜头,我记录下了这一路的美景,制作成了一个视频与大家分享。
伊犁不仅风景如画,美食也令人垂涎。红柳烤肉的鲜香、辣子肉的香辣(当地人将它作为早餐,配合花卷一起吃)、椒麻鸡的麻辣、赛里木湖的高山鲑鱼籽炒饭的鲜香,都是我旅途中难忘的味道。
另外新疆的干果、奶酪和牛肉干也是不错的伴手礼。
这次旅程将成为我人生中一段难忘的回忆。新疆伊犁的美景与魅力,让我深深地爱上了这片土地。如果有机会,我一定会再来这里,探索更多未尽的风景。
希望这篇游记能带给你一些关于新疆伊犁的美好回忆。如果你也有机会去新疆旅行,一定不要错过这些美丽的景点。
2024-06-04 16:18:06
在 Istio 项目的早期采用全局状态(State of the World,简称 SotW)的方式推送配置给 Envoy 代理。一旦有一个服务变更,就要将全局配置推送给所有 Sidecar,造成巨大的网络负担及控制平面的性能损耗。Istio 社区从几年前就开始开发增量 xDS 以解决此问题,并在最近几个 Istio 版本中支持了增量 xDS。在最近的 Istio 1.22 发布中,增量 xDS 成为默认开启的功能。本文将为你介绍 xDS、增量 xDS 及 Istio 的配置分发方式。
xDS(Extensible Discovery Service)是一种通信协议,用于在微服务架构中管理服务发现和动态配置。这种机制被广泛用于 Envoy 代理和 Istio 服务网格中,以管理各种类型的资源配置,如路由、服务发现、负载均衡设置等。
xDS 包括以下主要的发现服务,每种服务都负责不同类型的网络资源配置:
这些服务共同支持动态配置的分发和更新,使得基于 Envoy 的应用架构能够实时适应变化,提高可扩展性和灵活性。每种服务的实现可以独立进行,也可以通过聚合方式(如 ADS)进行统一管理。CNCF 也成立了 xDS API 工作组来推动 xDS API 为 L4/L7 数据平面配置提供事实上的标准,类似于 SDN 中 OpenFlow 在 L2/L3/L4 中所扮演的角色。
xDS 协议主要包括以下变体:
下表概述了 xDS 协议的四种变体,包括对每个变体的解释、使用场景以及优缺点的对比。这些变体为不同的网络环境和服务需求提供了多种选择,可以根据具体情况选择最合适的协议变体以优化服务的性能和资源使用。
变体类型 | 解释 | 使用场景 | 优点 | 缺点 |
---|---|---|---|---|
SotW | 每次都发送所有配置数据,不论是否有变化。 | 适用于配置较少变化的稳定环境。 | 简单易实现,易于理解和维护。 | 数据传输量大,不适合频繁更新配置的环境。 |
Delta xDS | 只传输变更的配置数据,而不是全部数据。 | 适用于配置频繁变化,需要快速响应变更的环境。 | 减少了不必要的数据传输,提高了效率。 | 实现复杂,需要客户端和服务端管理配置状态。 |
ADS | 通过单一的 gRPC 流来管理所有配置数据,无需为每种资源类型建立独立的连接。 | 适用于需要同时管理多种类型资源的复杂服务架构。 | 减少了网络连接数,简化了资源管理。 | 对于网络或服务质量差的情况,单点故障可能导致所有配置更新失败。 |
Delta ADS | 结合了 ADS 和增量 xDS 的优点,通过一个 gRPC 流聚合并且只传输变化部分的资源。 | 适用于既需要管理多种资源类型,又需要频繁更新配置的极其动态的环境。 | 提供了最大的灵活性和效率,适合大规模和高动态的服务架构。 | 实现最为复杂,对于配置管理的逻辑要求高,需要精确控制资源的变更和传输。 |
使用 xDS 协议的服务网格可以更灵活地管理微服务之间的通信和配置,减少了配置变更的延迟,提高了系统的响应速度和可靠性。
在 Istio 中,DiscoveryServer 作为 Envoy 的 xDS API 的实现,负责监听 gRPC 接口并根据 Envoy 的需求动态推送配置。它能够处理各种资源类型的请求,并根据服务的变更实时更新 Envoy 配置。此外,它还支持安全特性,如验证客户端证书,确保只有合法的服务实例可以接收配置数据。
使用 xDS 协议的变体通常涉及在 Envoy 代理或与之类似的服务网格配置中指定 xDS 服务器的详细信息。虽然不同的服务网格和代理服务器的配置细节可能有所不同,下面是一些通用的 YAML 配置示例,说明如何指定 xDS 服务器以及如何使用这些协议变体。
在 Envoy 的配置中,你可以通过静态资源或通过 API 动态获取资源的方式来使用 SotW。这里是一个简单的 Envoy 配置示例,显示了如何静态定义集群和监听器:
|
|
增量 xDS 的配置需要在 xDS 服务端支持增量协议,并在客户端配置中指定使用增量 xDS。Envoy 启动配置中需要添加 API 版本来启用增量 xDS:
|
|
使用 ADS 时,所有资源类型的配置通过一个单一的 API 端点聚合。这在 Envoy 配置中指定:
|
|
增量 ADS 通过在 ADS 配置中指定增量 API 类型,可以实现更为细粒度的更新:
|
|
这些配置示例需要根据你的具体环境和需求进行调整。更多细节和高级配置,你可以参考 Envoy 文档。
得益于 xDS 协议,如 Istio、Envoy Gateway 等可以通过 API 远程动态分发配置到 Envoy 代理。下图展示了 Istio 的配置分发流程(Sidecar 模式)。
Istio 中配置分发的主要流程说明:
kubectl apply
命令或其他 CI/CD 工具。Kubernetes 接收到配置文件并将其存储在 etcd 数据库中。这个配置分发流程确保了 Istio 能够动态管理和配置服务网格中的所有服务实例,提供一致的流量管理和策略执行。
起初,xDS 采用了“全局状态”(State of the World,简称 SotW)的设计,这意味着任何一个配置的更改都需要向 Envoy 发送所有配置的完整状态。这种方法在网络和控制平面上造成了巨大的负担,尤其是在大规模服务部署时。
在 2021 年的 EnvoyCon 上,Aditya Prerepa 和 John Howard 分享了 Istio 如何实现 Delta xDS,这是一种增量式的 xDS 实现。与传统的 SotW xDS 相比,Delta xDS 只发送变更的配置,显著减少了需要通过网络发送的配置数据量,从而提高了效率和性能。这种方法特别适用于那些配置频繁变更的环境,因为它只更新变化的部分而不是整个配置。
在实现 Delta xDS 的过程中,Istio 团队面临了多个挑战,包括如何确保配置更新的正确性以及避免潜在的资源泄漏。他们通过采用干运行(Dry-run)模式来并行运行 SotW 和 Delta 生成器,逐步发现并修复了实现中的缺陷。此外,他们还引入了新的 Envoy 类型,如虚拟主机发现服务(Virtual Host Discovery Service),以支持更细粒度的配置分发。
下图展示了 Delta xDS 增量配置的流程。
Delta xDS 配置流程如下:
该流程确保只有必要的变更被传输和应用,提高了效率并减少了网络和代理资源的负载。
虽然 Delta xDS 解决了在大规模网络下的配置分发的性能问题,但是 SotW 模式依然有它存在的意义,比如在初次下发配置的情况下。下表对比了 Istio 中的两种配置分发方式:SotW (State of the World) 和 Delta xDS。
对比项 | SotW | Delta XDS |
---|---|---|
数据传输量 | 每次传输完整的配置数据,不管配置是否有变更。 | 仅传输发生变化的配置数据,减少了数据传输量。 |
效率 | 在小型或变更少的环境中效率可接受。 | 在大型环境或频繁变更的环境中更高效。 |
复杂性 | 实现简单,易于理解和维护。 | 实现较为复杂,需要精细的变更跟踪和管理。 |
资源消耗 | 可能因为重复发送大量未变更的数据而增加服务器和网络负载。 | 更低的资源消耗,因为只处理变更的部分。 |
实时性 | 配置更新后立即发送全量配置,实时性高。 | 只发送变更部分,响应更快,减少处理时间。 |
适用场景 | 适合配置变动不频繁的小型至中型部署。 | 适合配置频繁变更或大规模部署的场景。 |
这个表格从数据传输量、效率、复杂性、资源消耗、实时性以及适用场景等多个角度对 SotW 和 Delta XDS 进行了对比,有助于在不同的使用环境中做出合适的选择。
在这篇文章中我分享了 xDS 的组成及 Istio 中配置分发的流程,还有 xDS 的两种模式 SotW 和 Delta xDS。随着 Delta xDS 在 Istio 1.22 版本中成为默认配置,这将有助于用户在大规模网络环境下轻松使用 Istio。
2024-05-31 10:21:36
最近我用 Fuse 和 Hugo 导出的全站结构化数据(压缩后仅 2MB)做的即时搜索,还有快捷搜索地址 https://jimmysong.io/search/?q=关键词,定制了下结果展示页面,这就是开源的强大之处,任何地方都可以私人订制。
下面我将分享下如何为你的 Hugo 网站添加即时搜索功能。大体步骤如下:
读者可以参考 hugo-blox-builder 这个项目中的搜索实现,下面是参考的代码:
首先,你需要为你的 Hugo 网站创建一个 JSON 文件,它将包含所有页面的必要元数据,如标题、描述、链接等。你可以通过 Hugo 的自定义输出格式来实现这一点。
在你的 Hugo 配置文件(通常是 config.toml
或 config.yaml
)中,添加一个自定义输出格式:
[outputs]
home = ["HTML", "RSS", "JSON"]
[outputFormats.JSON]
mediaType = "application/json"
baseName = "index"
isPlainText = false
然后,在你的内容模板中(如 layouts/_default/list.json.json
),定义输出的 JSON 结构:
{
"data": [
{{ range .Pages }}
{
"title": "{{ .Title }}",
"url": "{{ .Permalink }}",
"summary": "{{ .Summary }}"
}
{{ if not (eq .Next nil) }},{{ end }}
{{ end }}
]
}
这将为你的整个站点生成一个 index.json
文件,其中包含所有页面的基本信息。当然你可能不想导出网站的所有页面,可以通过 Hugo 的语法,可定制化导出的 Section 或者不同类型页面。
接下来,使用 Fuse.js 库来实现前端的即时搜索功能。首先,你需要在你的网站中包含 Fuse.js 的库文件。你可以从 jsDelivr 等 CDN 加载它:
<script src="https://cdn.jsdelivr.net/npm/fuse.js/dist/fuse.min.js"></script>
然后,在你的 JavaScript 文件中,加载并解析 index.json
文件,并使用 Fuse.js 进行搜索:
fetch('/index.json')
.then(response => response.json())
.then(data => {
const fuse = new Fuse(data.data, {
keys: ['title', 'summary'],
includeScore: true
});
document.getElementById('search-input').addEventListener('input', function (e) {
const results = fuse.search(e.target.value);
displayResults(results);
});
});
function displayResults(results) {
const searchResults = document.getElementById('search-results');
searchResults.innerHTML = '';
results.forEach(result => {
const elem = document.createElement('div');
elem.innerHTML = `<a href="${result.item.url}">${result.item.title}</a>`;
searchResults.appendChild(elem);
});
}
具体实现可以参考 wowchemy-search.js。
在你的网站中添加一个搜索框和结果显示区域:
<input type="text" id="search-input" placeholder="输入搜索词">
<div id="search-results"></div>
另外你还可以添加搜索快捷键,一般是组合键 ⌘/CTRL + K
来快速打开搜索页面。
具体实现可以参考 这个前端模板。
为了保证搜索结果的实时性,可以通过 GitHub Actions 或其他 CI/CD 工具来自动化 Hugo 网站的构建和部署流程,确保 index.json
文件始终是最新的。
创建一个 .github/workflows/hugo_build.yml
文件,定义自动化流程:
name: Build and Deploy
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: 'latest'
- name: Build
run: hugo --minify
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
另外如果你的网站支持多语言,可以为每种语言分别生成 index.json
文件,并在不同的语言页面加载对应的索引文件。
index.json
设置合理的缓存策略,以减少服务器负载和提高响应速度。如果你是会用的是 Github Pages 作为静态网站,那么可以忽略这一步。index.json
文件,你可以选择导出网站的部分数据,比如某些 Section 的数据,对 Content 进行截取,或者压缩文件成 gz 格式,在 JavaScript 加载后再在前端解压,这样可以减少网络数据传输。通过这些步骤,你可以有效地为你的 Hugo 网站添加一个高效且可定制的即时搜索功能。
本文介绍了如何为 Hugo 网站添加即时搜索功能,并提供了进一步优化搜索功能的建议,包括缓存优化、搜索结果高亮显示和高级搜索选项。这不仅展示了开源技术的强大自定义能力,也使网站用户能更快更准确地找到所需信息。
2024-05-24 10:20:20
在微服务中常见的认证方式详解这篇博客中我们介绍到了 OAuth 2.0 认证,该身份认证协议有多种实现方式,其中最流行的就是 OpenID Connect(OIDC)认证。OIDC 能够为用户提供身份验证和授权。本文将介绍如何使用 Envoy Gateway 在 API 网关级别实现 OIDC 认证。
Envoy Gateway 是一个使用 Envoy 实现的高性能的 API 网关,支持多种认证方式来保护 API 和微服务:
本文重点介绍如何在 Envoy Gateway 中配置和使用 OIDC 认证从而在网关侧实现单点登录。
OpenID Connect(OIDC)是一个基于 OAuth 2.0 的身份验证协议。它允许客户端通过认证服务器验证用户身份,并获取有关用户的信息。
OIDC 认证流程如下图所示:
OIDC 为 OAuth 2.0 增加了身份验证层,通过引入 ID Token 和标准化的 UserInfo Endpoint,使 OAuth 2.0 不仅能够用于授权,还可以用于安全地验证用户身份,从而实现单点登录(SSO)和用户身份信息的获取。
单点登录(Single Sign-On, SSO)是一种身份验证方式,它允许用户使用一个账户登录多个独立的应用系统,通过一次身份验证即可无缝访问所有相关应用,减少重复输入用户名和密码的麻烦,从而提升用户体验。SSO 集中管理用户身份和认证,增强了系统安全性,并简化了 IT 管理流程。
对于微服务架构,SSO 尤其重要,因为它在各个微服务之间实现统一的认证和授权,避免了每个服务单独实现身份验证逻辑的需求,减少了用户重复登录的麻烦,并提高了用户体验。集中管理的方式还可以统一应用安全策略,更有效地监控和响应安全事件,提升系统的整体安全性。同时,通过使用标准化的令牌(如 JWT),SSO 简化了微服务之间的身份验证过程,提高了开发效率,让开发人员能够专注于业务逻辑的实现。
接下来我们将使用 Auth0 作为身份供应商,演示如何使用 Envoy Gateway 在 API 网关端实现单点登录。
你可以在 Bilibili 上查看该示例演示。
首先我们先说明下示例中 Envoy Gateway 基于 Auth0 实现单点登录的详细流程,如下图所示。
步骤说明:
https://www.example.com
。https://www.example.com
。通过上述流程,Envoy Gateway 实现了单点登录功能。用户的 HTTP 请求在没有得到授权的情况下都会被转发单点登录页面。除了 Auth0 以外,Envoy Gateway 还支持多个身份提供商,如 Azure AD、Keycloak、Okta、OneLogin、Salesforce、UAA 等。
下面我们将按照时序图中的流程配置 Auth0 和 Envoy Gateway。
请参考以下步骤在 Auth0 上设置一个 Regular Web Application:
{DOMAIN}
{CLIENT_ID}
{CLIENT_SECRET}
https://www.example.com/oauth2/myapp/callback
https://www.example.com/myapp/logout
记住上面的 Auth0 字段,我们将用它们来配置 Envoy Gateway 的安全策略。
下面展示的是 Auth0 的配置页面截图,在设置好用户后并创建普通 Web 应用后,你只需要配置这两个地方。
以上就是 Auth0 的全部配置,接下来我们将安装和配置 Envoy Gateway。
参考 Envoy Gateway 快速开始在 minikube 上安装 Envoy Gateway:
minikube start --driver=docker --cpus=2 --memory=2g
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.0.1 -n envoy-gateway-system --create-namespace
kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/v1.0.1/quickstart.yaml -n default
参考安全网关,为 Envoy Gateway 配置 TLS:
# 创建根证书和私钥来签署证书
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt
# 为 www.example.com 创建证书和私钥
openssl req -out www.example.com.csr -newkey rsa:2048 -nodes -keyout www.example.com.key -subj "/CN=www.example.com/O=example organization"
openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in www.example.com.csr -out www.example.com.crt
# 将证书/密钥存储在 Secret 中
kubectl create secret tls example-cert --key=www.example.com.key --cert=www.example.com.crt
更新快速开始中创建的网关,使其包含 443
端口并引用 example-cert
Secret 的 HTTPS Listener:
echo '[
{
"op": "add",
"path": "/spec/listeners/-",
"value": {
"name": "https",
"protocol": "HTTPS",
"port": 443,
"tls": {
"mode": "Terminate",
"certificateRefs": [
{
"kind": "Secret",
"group": "",
"name": "example-cert"
}
]
}
}
}
]' | kubectl patch gateway eg --type=json --patch-file /dev/stdin
创建 HTTPRoute,为 /myapp
端点增加一条到backend
服务的路由:
cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: myapp
spec:
parentRefs:
- name: eg
hostnames: ["www.example.com"]
rules:
- matches:
- path:
type: PathPrefix
value: /myapp
backendRefs:
- name: backend
port: 3000
EOF
创建一个 Kubernetes Secret,用于存储 OAuth Client 的 Client Secret:
kubectl create secret generic auth0-client-secret --from-literal=client-secret=${CLIENT_SECRET}
${CLIENT_SECRET}
替换成你的 Auth0 Client Secret。
创建一个安全策略(SecurityPolicy):
cat <<EOF | kubectl apply -f -
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: oidc-example
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
oidc:
provider:
issuer: "https://${DOMAIN}"
clientID: "${CLIENT_ID}"
clientSecret:
name: "auth0-client-secret"
redirectURL: "https://www.example.com/myapp/oauth2/callback"
logoutPath: "/myapp/logout"
EOF
注意事项
issuer
应该填写成 Auth0 Domain。redirectURL
的值需要出现在 Auth0 配置的 Allowed Callback URLs 中。logoutPath
是必须的,即使其 URL 端点并为实现 logout 逻辑。在这个示例中我们为 Envoy Gateway 网关设置了 OIDC,修改 targetRef
到 HTTPRoute,也可以为单个路由设置 OIDC。关于 ODIC 的具体配置,请参考 Envoy Gateway API 文档。
将 www.example.com
添加到本地的 /etc/hosts
文件中:
echo "127.0.0.1 www.example.com" | sudo tee -a /etc/hosts
配置应用程序的端口转发,以便你可以在本地通过域名访问示例应用:
export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
sudo kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 443:443
现在在浏览器中访问 https://www.example.com,跳过证书风险提示,页面将跳转到 Auth0 的登录界面,如下图所示,选择使用 Google 账户登录。
在登录完成后,浏览器将跳转会 https://www.example.com 页面,并展示 HTTP 请求结果,如下面的 JSON 代码所示。
{
"path": "/",
"host": "www.example.com",
"method": "GET",
"proto": "HTTP/1.1",
"headers": {
/*Omit*/
"Authorization": [
"Bearer eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwiaXNzIjoiaHR0cHM6Ly9kZXYtYXdoam15MzhnZzVxeng3dS51cy5hdXRoMC5jb20vIn0..IiH9LnxmnrGAVy-q.eQV_0Ssetw9mmrEaJNLlBowGJNX51awhh67WSejPrksuGU9e9-DcPJQqmR67ONFzTXWR6CFy4Rfgs4btsmEtvCtiNTCgrBHP90ddbOTg_pK31WnsQ7NThyRfGwoogSaAtK6hFrC2pxFaLj0XL7XvSPk-OaTzK1Zh1da1IM1cmWAWiBRc3nQiVWRDrExPo8-i5SawFe0jIcwytVSaRiX5Polyd3cZ7A7nlei-vDLCfj0HVzOO605nF7ED2dBSnZyev1sg14q598f3X2Vfhi2oJlnbiulGZIlpXgGbcPhzAJJxyEe6qpRpNg7Hbk8Ya-i8gUTwwNysrgm3.Zu5kD_6DzSfZPvwemttXYQ"
],
"Cookie": [
"OauthHMAC-167a6c5=RPdscXEBap0NeSIppJXoxkHt0qvMz4fNHXo2uvgDgIY=; OauthExpires-167a6c5=1716540771; BearerToken-167a6c5=eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwiaXNzIjoiaHR0cHM6Ly9kZXYtYXdoam15MzhnZzVxeng3dS51cy5hdXRoMC5jb20vIn0..IiH9LnxmnrGAVy-q.eQV_0Ssetw9mmrEaJNLlBowGJNX51awhh67WSejPrksuGU9e9-DcPJQqmR67ONFzTXWR6CFy4Rfgs4btsmEtvCtiNTCgrBHP90ddbOTg_pK31WnsQ7NThyRfGwoogSaAtK6hFrC2pxFaLj0XL7XvSPk-OaTzK1Zh1da1IM1cmWAWiBRc3nQiVWRDrExPo8-i5SawFe0jIcwytVSaRiX5Polyd3cZ7A7nlei-vDLCfj0HVzOO605nF7ED2dBSnZyev1sg14q598f3X2Vfhi2oJlnbiulGZIlpXgGbcPhzAJJxyEe6qpRpNg7Hbk8Ya-i8gUTwwNysrgm3.Zu5kD_6DzSfZPvwemttXYQ; IdToken-167a6c5=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImFKWkxWbnNrai0tYmhsNlJzVm51OCJ9.eyJpc3MiOiJodHRwczovL2Rldi1hd2hqbXkzOGdnNXF6eDd1LnVzLmF1dGgwLmNvbS8iLCJhdWQiOiJUZzhlNWVoa0xKM2hka3cxTzREMTBQd21QeTcxZHZtdiIsImlhdCI6MTcxNjQ1NDM3MSwiZXhwIjoxNzE2NDkwMzcxLCJzdWIiOiJnb29nbGUtb2F1dGgyfDExMjc0NDc3OTAyMjMzMTA0ODY0MCIsInNpZCI6IjRlSjhDZnZuZjd5Mm1kaE94QXBTY0JiUEhjOS1rZUVLIn0.r9dwIy_HeiO5_I3UlohLkeRES5FGoxqQnwmcA00cA_kdc5mUxgeVopXIhBUjJnTKv7bOUVJvFw21ew4gqVRJfllDyG-s_XfhSW1-lEXmCc2bGYDtOzva6k2S_VRgyMKfG04_DWFuTgO_pLtix28aYq8cGzKJ_VglT_KgRhoktzJu4Js5iCv9JPnydRJmpvRJwX3tDv_Q3mmUSazaLkhOTdiBJFrGlS07qEzJ_iWANZgR8uDNhpXdmlcqpb3MZkkMulr5-jXIgEhBQKpw28tUiSlzh6EpAVuBH9T1w8bUmFRzCc6JPPamJRfflYW5onNgYHDfcU0RpvpsCHRHRAZbdA"
],
/*Omit*/
"User-Agent": [
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
],
"X-Envoy-Internal": [
"true"
],
"X-Forwarded-For": [
"10.244.0.51"
],
"X-Forwarded-Proto": [
"https"
],
"X-Request-Id": [
"c1e64057-c5c8-4fb2-a304-25c291eeed32"
]
},
"namespace": "default",
"ingress": "",
"service": "",
"pod": "backend-55d64d8794-4qvgd"
}
此时通过 Chrome 浏览器的 Inspector - Application - Cookies 查看到 ID Token 如下图所示:
编写代码 Python 代码,validate_id_token.py
,解析 ID Token 并验证其有效性:
import jwt
import requests
from jwt.algorithms import RSAAlgorithm
import argparse
import json
import base64
def base64url_decode(input):
rem = len(input) % 4
if rem > 0:
input += '=' * (4 - rem)
return base64.urlsafe_b64decode(input)
def get_signing_key(jwk_url, kid):
jwks = requests.get(jwk_url).json()
for jwk in jwks['keys']:
if jwk['kid'] == kid:
return RSAAlgorithm.from_jwk(jwk)
raise Exception('Public key not found.')
def validate_token(token, audience, issuer, jwk_url):
headers = jwt.get_unverified_header(token)
kid = headers['kid']
signing_key = get_signing_key(jwk_url, kid)
decoded_token = jwt.decode(
token,
signing_key,
algorithms=["RS256"],
audience=audience,
issuer=issuer
)
return decoded_token
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Validate a JWT token.')
parser.add_argument('token', type=str, help='The JWT token to validate')
args = parser.parse_args()
token = args.token
# 解析 token 的 payload 部分,提取 audience 和 issuer
header, payload, signature = token.split('.')
decoded_payload = base64url_decode(payload)
payload_json = json.loads(decoded_payload)
audience = payload_json['aud']
issuer = payload_json['iss']
jwk_url = f"{issuer}.well-known/jwks.json"
try:
decoded = validate_token(token, audience, issuer, jwk_url)
print("Token is valid. Decoded payload:")
for key, value in decoded.items():
print(f"{key}: {value}")
except Exception as e:
print(f"Token validation failed: {e}")
安装依赖的包:
pip install pyjwt requests
运行代码:
python validate_id_token.py ${ID_TOKEN}
你将看到类似下面的输出:
Token is valid. Decoded payload:
iss: https://dev-awhjmy38gg5qzx7u.us.auth0.com/
aud: Tg8e5ehkLJ3hdkw1O4D10PwmPy71dvmv
iat: 1716470905
exp: 1716506905
sub: google-oauth2|112744779022331048640
sid: 4W_hQNJJ8ftDL8S3Cozp8GEu2Au4_e9N
通过该 ID Token 的值可以得出:
iss
字段)。aud
字段),对于 Auth0,这个值是 Client ID。iat
字段),并将在 2024 年 5 月 23 日 14:08:25 UTC 过期(exp
字段)。google-oauth2|112744779022331048640
(sub
字段)。在这里,这个标识符表明使用 Google OAuth2 登录的用户4W_hQNJJ8ftDL8S3Cozp8GEu2Au4_e9N
(sid
字段),用于会话管理。由于我们的示例应用中没有实现 Auth0 的 Logout 逻辑,所以我们需要通过 HTTP 请求明确告知 Auth0 要 logout,在浏览器中访问该 URL:
https://${DOMAIN}/v2/logout?client_id=${CLIENT_ID}
请将 ${DOMAIN}
和 ${CLIENT_ID
修改为你的 Auth0 应用程序的配置项。关于 Auth0 如何登出 OIDC 端点的详细说明请查看 Auth0 文档。
登出后,页面将再次跳转到登录页面,在登录后,页面将重定向到 https://www.example.com。
通过以上步骤,你可以在 Envoy Gateway 中实现 OIDC 认证,确保 API 的安全性。这种方法不仅能提供灵活的身份验证机制,还能简化应用程序的身份管理。通过集成 Auth0 等身份提供商,Envoy Gateway 可以轻松实现单点登录,提升用户体验和系统安全性。未来,你可以根据需求进一步配置和优化 Envoy Gateway,充分利用其强大的认证和授权功能,以满足更复杂的安全要求和业务需求。
2024-05-22 13:54:49
在现代微服务架构中,安全性是一个至关重要的方面。随着微服务数量的增加,如何确保服务间的安全通信成为了一个挑战。本文将介绍几种常见的微服务认证方式,帮助你在设计和实现微服务系统时选择合适的认证方案。
下表列出了几种微服务中常用的认证方式,并从优点、缺点、适用场景和现实示例等维度进行比较。
认证方式 | 优点 | 缺点 | 运行位置 | 适用场景 | 典型用途 | 现实使用场景 |
---|---|---|---|---|---|---|
JWT | 自包含令牌,减少服务器负担 | 令牌较大,可能会增加带宽开销 | API 网关、服务间 | 微服务之间无状态通信 | 用户认证和授权 | 在微服务架构中,用户认证(如 Auth0、Firebase) |
OAuth 2.0 | 广泛支持,灵活性高 | 实现复杂,需要额外的交互 | API 网关 | 第三方应用授权 | 第三方应用访问用户数据 | Github OAuth,用于第三方应用访问 Github 数据和 API |
mTLS | 高安全性,防止中间人攻击 | 证书管理复杂,性能开销较大 | 服务间 | 高安全性要求的通信 | 安全敏感的服务通信 | 银行系统中的服务通信 |
Basic 认证 | 简单易实现 | 不安全,容易被拦截 | API 网关、服务间 | 简单的 API 保护 | 简单的内部服务 | Kubernetes API Server 的基本认证 |
API Key 认证 | 简单易用 | 安全性低,容易被滥用 | API 网关、服务间 | 低安全性要求的场景 | 简单的服务访问控制 | 各种公共 API,如 OpenAI API |
下面我们将详细介绍这几种常见的认证方式。
JWT(JSON Web Token)最早由 IETF JSON Web Token (JWT) 工作组提出,并在 2015 年作为 RFC 7519 标准正式发布。JWT 的设计目标是提供一种紧凑且自包含的方式,用于在各方之间安全地传递信息。由于其易于使用和无状态的特性,JWT 迅速被广泛采用,成为身份验证和信息交换的标准之一,特别是在微服务和现代 Web 应用中。
下图展示的是 JWT 认证流程。
JWT 认证流程说明:
JWT(JSON Web Token)由三个部分组成:头部(Header)、载荷(Payload)和签名(Signature),分别通过 Base64 编码后用点(.)连接在一起组成。
头部(Header):头部包含令牌类型和签名算法。
{
"alg": "HS256",
"typ": "JWT"
}
载荷(Payload):载荷包含声明(claims),即关于用户或其他数据的断言。
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
签名(Signature):签名由编码后的头部、编码后的载荷以及一个密钥通过头部中指定的算法生成。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
下面是一个 JWT 令牌示例:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
OAuth(Open Authorization)协议最早由 Blaine Cook 和 Chris Messina 在 2006 年提出。最初的目标是为 Twitter 提供一个开放的授权标准。OAuth 1.0 于 2007 年发布,提供了一个允许用户授权第三方应用访问其资源的标准化方式,但由于其复杂的签名机制和其他安全问题,受到了一些限制。
为了克服这些缺点,IETF(Internet Engineering Task Force)成立了 OAuth 工作组,旨在开发一个更简化、更灵活的授权协议。2012 年,OAuth 2.0 正式发布(RFC 6749 和 RFC 6750)。OAuth 2.0 简化了授权流程,增加了多种授权模式,如授权码模式、简化模式、资源所有者密码凭证模式和客户端凭证模式。
OAuth 2.0 迅速成为行业标准,广泛应用于各种网络服务和应用程序,如 Google、Facebook、GitHub 等。在此基础上,出现了多个扩展和补充协议(如 OpenID Connect),进一步增强了 OAuth 2.0 的功能和安全性。
OAuth 2.0 的发展和扩展使其成为现代互联网身份验证和授权的重要基石,提供了灵活和安全的解决方案,满足了不断变化的网络应用需求。
下图展示的是 OAuth 2.0 认证流程。
OAuth 2.0 认证流程说明:
在 OAuth 2.0 授权码模式中,授权码是客户端在用户授权后从授权服务器获取的短期凭证,用于交换访问令牌。授权码是一个临时的字符串,可以在授权服务器和客户端之间传递以获得更安全的访问令牌。
OAuth 2.0 在发展过程中,为了适应不同的场景,发展出了众多的扩展,下表罗列出一些常用的扩展名称、主要功能及适用场景。
扩展名称 | 主要功能 | 适用场景 |
---|---|---|
授权码 PKCE 扩展 | 提高授权码模式的安全性,防止授权码拦截攻击 | 公共客户端(如移动应用、单页应用) |
动态客户端注册协议 | 允许客户端动态注册和更新客户端信息 | 自动化和灵活性要求高的系统 |
Token Introspection | 允许资源服务器验证和获取访问令牌的详细信息 | 需要验证令牌有效性和获取令牌详细信息的场景 |
Token Revocation | 提供令牌撤销的标准接口 | 提高系统安全性和控制能力 |
Device Authorization Grant | 允许输入受限的设备通过其他设备完成身份验证 | 智能电视、游戏机等输入能力有限的设备 |
Mutual TLS Client Authentication | 基于双向 TLS 的客户端认证 | 高安全性要求的应用场景 |
Resource Indicators | 允许客户端在授权请求中指定访问的资源服务器 | 多资源服务器的支持 |
Step-up Authentication Challenge Protocol | 允许资源服务器按需请求更强的身份验证(如多因素认证) | 高风险操作的高级认证 |
GitHub 使用 OAuth 2.0 来授权第三方应用访问用户的 GitHub 数据。OAuth 2.0 令牌在 GitHub 上被称为 “access tokens”,用于验证和授权访问 GitHub API。它提供了一种安全、标准化的方法,允许第三方应用在用户授权的情况下访问 GitHub 资源。通过使用访问令牌,应用程序可以代表用户执行各种操作,如读取用户信息、访问仓库、创建 gists 等。这个过程确保了用户的安全和隐私,同时简化了应用程序的认证和授权流程。
以下是使用 GitHub OAuth 2.0 令牌的详细流程和示例:
用户授权:用户在第三方应用程序的界面上点击“Login with GitHub”按钮。应用程序将用户重定向到 GitHub 的授权页面。
获取授权码:用户在 GitHub 授权页面上登录并同意授权,GitHub 会将用户重定向回应用程序,并在 URL 参数中附带一个授权码(authorization code)。
示例:
https://yourapp.com/callback?code=AUTHORIZATION_CODE
交换访问令牌:应用程序服务器使用授权码向 GitHub 的授权服务器请求访问令牌。
请求示例:
POST https://github.com/login/oauth/access_token
Content-Type: application/json
Accept: application/json
{
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"code": "AUTHORIZATION_CODE",
"redirect_uri": "https://yourapp.com/callback"
}
GitHub 返回访问令牌:GitHub 验证请求并返回访问令牌。
响应示例:
{
"access_token": "YOUR_ACCESS_TOKEN",
"token_type": "bearer",
"scope": "repo,gist"
}
使用访问令牌访问资源:应用程序使用获取的访问令牌访问 GitHub API。
请求示例:
curl -H "Authorization: token YOUR_ACCESS_TOKEN" https://api.github.com/user
响应示例:
{
"login": "github-user",
"id": 1,
"node_id": "MDQ6VXNlcjE=",
"avatar_url": "https://github.com/images/avatar.jpg",
"name": "Github User",
"company": "GitHub",
"blog": "https://example.com",
"location": "Earth",
"email": "[email protected]"
}
权限范围(Scopes):访问令牌的权限范围由用户在授权时指定,可以包括读取用户资料、访问用户仓库、管理 gists 等。例如,在上述示例中,scope
包含 repo
和 gist
。
有效期和刷新:访问令牌的有效期可以是长期的也可以设置时间范围,直到用户主动撤销。
安全传输:访问令牌应通过 HTTPS 传输,以确保其不被截获。
mTLS(Mutual TLS)是一种在客户端和服务器之间进行双向身份验证的技术,最早起源于 TLS(传输层安全协议),TLS 的前身 SSL(安全套接层)协议于 1995 年由 Netscape 开发。随着互联网安全需求的增加,TLS 逐步发展为一个高度安全的通信标准,而 mTLS 则在此基础上进一步提升了安全性,通过要求双方互相验证身份,广泛应用于金融、医疗等对安全性要求极高的领域。
下图展示的是 mTLS 认证流程。
mTLS 认证流程说明:
更多关于 TLS 和 mTLS 的内容请参考博客 如何理解 Istio 中的 mTLS 流量加密。
Basic 认证是一种最早由 HTTP/1.0 规范(RFC 1945)定义的简单认证机制,它通过将用户名和密码进行 Base64 编码后附加到 HTTP 请求头中进行身份验证。由于实现简单且易于使用,Basic 认证在早期的 Web 应用中被广泛采用。然而,由于其固有的安全性问题(如明文传输容易被截获),它在现代应用中通常与 HTTPS 一起使用,或被更安全的认证方式所替代。
下图展示的是 Basic 认证流程。
Basic 认证流程说明:
Basic 认证使用 Base64 编码的用户名和密码进行认证。下面是使用 curl
命令进行 Basic 认证请求的示例:
curl -u <username>:<password> https://api.example.com/data
如果用户名为 admin
,密码为 password123
,请求示例如下:
curl -u admin:password123 https://api.example.com/data
API Key 认证是一种通过在请求中包含预先分配的唯一密钥来进行身份验证的方法,最早在 2000 年代初随着 Web API 的兴起而流行。API Key 认证由于其简单易用和便于管理的特性,被广泛应用于各种公共和私有 API 中。尽管它的安全性较低,容易被滥用,但在许多场景中仍然是控制访问的一种有效手段,特别是对于不需要高度安全保护的应用。
下图展示的是 API Key 认证流程。
API Key 认证流程说明:
API Key 是在请求中传递的一个唯一标识符,用于验证客户端身份。API Key 通常通过 HTTP 请求头或 URL 参数传递。
HTTP 请求头中的 API Key 示例:
curl -H "Authorization: ApiKey YOUR_API_KEY" https://api.example.com/data
URL 参数中的 API Key 示例:
curl https://api.example.com/data?api_key=YOUR_API_KEY
API Key 格式通常是一个字符串,包含字母和数字,例如:
1234567890abcdef1234567890abcdef
在微服务架构中选择合适的认证方式至关重要。不同的认证方式在安全性、复杂性和适用场景上各有优劣。本文介绍了 JWT、OAuth 2.0、mTLS、Basic 认证和 API Key 认证五种常见的认证方式,并提供了它们的优缺点和适用场景。此外,其他常见的认证方式如 SAML、LDAP、Kerberos 和 OpenID Connect 也广泛应用于不同的互联网应用场景,特别是在单点登录和跨域认证方面。希望这些信息能帮助你在设计和实现微服务系统时选择最合适的认证方案。
2024-05-16 11:28:34
Istio 1.22 版本的发布标志着 Ambient 模式正式进入 beta 阶段,随之发布了一篇标题为 告别 Sidecar:Istio 的 Ambient 模式在 v1.22 中达到 Beta 的博客,声称 Layer 4 和 Layer 7 的功能现已可用于生产环境。其实社区早在一个月前的 KubeCon EU 上就宣布了这一里程碑。这种激动人心的宣传似乎在暗示我们可以彻底抛弃 Sidecar 模式,但事实真是如此吗?
虽然我对新技术持开放态度,但完全告别 Sidecar 模式可能为时尚早。每种模式都有其特定的应用场景和优缺点。下面,我将详细分享 Ambient 模式相较于 Sidecar 模式的一些限制,帮助大家更好地理解两者之间的差异。
Ambient 模式的 L7 流量管理支持尚未成熟,尚未达到生产环境的可用水平。相较之下,Sidecar 模式在这方面更为稳定和可靠。
在 Ambient 模式下,mTLS 被强制在 namespace 级别开启,而 Sidecar 模式则赋予用户更大的灵活性,可以选择是否启用 mTLS。这种灵活性对于某些应用场景尤为重要。
对于 L7 层的遥测数据,Ambient 模式能否像 Sidecar 模式一样对每个 pod 进行精确的监控和追踪仍是一个疑问。Sidecar 模式在可观测性方面已被广泛验证,其能力更为成熟。
部署方面,Ambient 模式推荐使用 Helm,仅支持 Kubernetes 平台,而 Sidecar 模式还支持虚拟机和混合云环境。此外,Ambient 模式尚未得到主要云厂商的官方支持。在升级过程中,Ambient 模式的爆炸半径更大,暂不支持金丝雀发布,推荐使用蓝绿部署。对于从 Sidecar 模式向 Ambient 模式的迁移或二者共存,仍缺乏最佳实践。
目前对于 Wasm 插件的支持,Ambient 模式仍不明确,而 Sidecar 模式在这方面已经有了较为完善的支持。
Dual Stack 模式在 Sidecar 模式下虽然仍处于实验阶段,但至少已有一定的实现,而 Ambient 模式是否支持这一特性仍不明朗。
虽然 Istio 1.22 带来了令人兴奋的 Ambient 模式,但在完全告别 Sidecar 模式之前,我们需要慎重考虑这些限制和差异。每种模式都有其独特的优势和适用场景,用户应根据自身需求做出明智的选择。我将继续对 Ambient 模式进行测试和追踪,更多深入解读敬请关注本博客。
2024-05-08 11:20:49
在 Kubernetes 环境下选择正确的网络通信工具至关重要。根据Tetrate 的讨论,选择取决于网络通信的类型:南北向流量还是东西向流量。对于主要处理外部请求的服务,Envoy Gateway 是理想选择,它不仅高效管理流量,还能在你向微服务架构过渡时提供无缝集成。
本文将探讨 Envoy Gateway 在 Kubernetes 上部署的优势,及其它与服务网格的关系,展示为何它是暴露服务到公网的理想选择。
Envoy Gateway 是一个围绕 Envoy Proxy 构建的 Kubernetes 原生 API 网关,它旨在降低用户采用 Envoy 作为 API 网关的难度,并为供应商建立 API 网关(例如 Tetrate Enterprise Gateway for Envoy)增值产品奠定基础。
Envoy Gateway 不仅是管理南北流量的理想选择,也可作为连接和保护服务网格中服务的关键组件。它还通过提供安全的数据传输、流量路由、负均衡及故障恢复等功能,增强了微服务之间的通信效率和安全性。Envoy Gateway 利用其内置的 Envoy Proxy 技术,可以处理大量的并发连接和复杂的流量管理策略,同时保持较低的延迟和高吞吐量。
此外,Envoy Gateway 与 Kubernetes Gateway API 的紧密集成使得它能够以声明式的方式进行配置和管理,极大简化了服务网格中网关的部署和更新过程。这种集成不仅提升了操作效率,还使得 Envoy Gateway 能够在不增加额外复杂性的前提下,与服务网格如 Istio 这样的解决方案无缝协作。
下图展示了 Envoy Gateway 与服务网格的关系。
在 Kubernetes 集群中,Envoy Gateway 负责管理南北向流量,即进出集群的流量,并通过 Kubernetes Gateway API 进行配置,后者定义了服务的路由规格。集群内服务直接连接到 Pods。服务网格部分,由控制平面(如 Istio 或 Linkerd)配置数据平面中的 Envoy Sidecars,这些 Sidecars 负责处理集群内部的东西向流量。在这个系统中,Envoy Gateway 可以与服务网格相互协作,但它们各自独立地管理不同方向的流量。
设想一下,Envoy Gateway 像是一个城市的主要入口(比如海关),所有的数据流,就像各种车辆,都得通过这个大门进出。它就像一个严格的守门员,负责审查、指导,确保每个数据包,就像每个乘客,都能被准确地送到目的地。在 Kubernetes 这座城市中,Envoy Gateway 管理着所有进城的流量,它确保数据流可以安全、高效地进入城市,并被准确地送达给城市内部的服务。
进入城市之后,服务网格就接管了,这就像城市内部的一系列交通网络。服务网格中的 Envoy sidecars 就好比是这座城市内部的出租车或者公交车,负责把数据包从海带到它们在城市内部的具体目的地。Envoy Gateway 负责将外部请求顺利引入,之后服务网格负责在集群内部继续高效地处理这些请求。
Envoy Gateway 对 Kubernetes Gateway API 的支持,可以看作是对我们城市交通信号系统的一个重大升级。这不仅为进入城市的数据流提供了更加清晰和个性化的指引,而且让整个城市的交通运行更加智能化。
Envoy Gateway 提供了几个核心功能,使其成为 API 网关的突出选择:
在 Kubernetes 环境中引入的 Gateway API 为集成和配置 Ingress 网关提供了一种新的强大方法,它与传统的 Ingress 相比具有更高的灵活性和功能性。正如我在 Gateway API:Kubernetes 和服务网格入口中网关的未来 中所讨论的,Gateway API 通过区分角色和提供跨命名空间支持,更适应多云环境,且已被多数 API 网关采用。这种 API 设计支持了 ingress 网关(南北向流量)与服务网格(东西向流量,跨集群路由)的融合,使得 Envoy Gateway 成为 Kubernetes 和服务网格中统一未来的网关解决方案。通过引入 Gateway API,Envoy Gateway 强化了其作为云原生环境中前沿代理的角色,使得用户能够更灵活地管理其流量和策略。
Kubernetes Gateway API 是 Envoy Gateway 的基石,它提供了一种更具表达性、灵活性和以角色为导向的方式来配置 Kubernetes 生态系统中的网关和路由。该 API 提供了如 GatewayClass、Gateway、HTTPRoute 等自定义资源定义(CRD),Envoy Gateway 利用这些资源创建用户友好且一致的配置模型,与 Kubernetes 的原生原则保持一致。
API Gateway 是对 API 的全面管理和托管服务。它作为应用程序与后端服务之间的中间层,不仅处理创建、维护、发布、运行和下线等生命周期事件,还承担着更多关键职能。一个完善的 API Gateway 应该提供以下功能来丰富和扩展其基本定义:
综上所述,API Gateway 的角色远远超越了简单的 API 生命周期管理。它是实现微服务架构、确保服务安全性、提高运维效率和优化用户体验的关键组件。通过这些广泛的功能,API Gateway 成为现代云原生应用不可或缺的一部分。
Envoy Gateway 的架构设计旨在轻量级和简洁。它包括一个动态配置运行作为数据平面的 Envoy 代理的控制平面。这种关注点的分离确保了网关可以随着流量的增长而扩展,而不影响控制平面的效率。
Envoy Gateway 的架构图如下所示。
在这个架构图的核心是 Envoy Gateway,它是 Envoy 代理的执行实例,负责处理从 Kubernetes 集群进出的所有流量。初始启动时,Envoy Gateway 通过配置文件提供静态配置,建立其操作的基本参数。
Envoy Gateway 配置的动态方面由提供者处理,该提供者定义了网关与 Kubernetes 或其他动态配置输入源的交互。资源监视器负责监视 Kubernetes 资源的更改,特别关注与自定义资源定义(CRD)相关的 CRUD 操作。
随着更改的发生,资源转换器介入将这些外部资源转换为 Envoy Gateway 可以理解的形式。这一转换过程进一步由特定于提供者的基础设施管理器促进,后者负责管理与特定云或基础设施提供商相关的资源,塑造中间表示形式的基础设施,这对于网关的功能至关重要。
然后,该中间表示形式转变为 xDS 中间表示形式,作为 Envoy 理解和执行的最终 xDS 配置的先导。xDS 翻译器承担将这种中间表示形式转换为具体的 xDS 配置的角色。
这些配置由 xDS 服务器交付并执行,该服务器作为服务,根据其收到的 xDS 配置,认真管理 Envoy 实例。Envoy 作为实际运行的代理,最终从 xDS 服务器接收这些配置,解释并实现它们以有效管理流量请求。
最终,所有请求经过 Envoy 的处理后被重定向到了 Envoy Gateway 路由的流量的最终目的地,也就是后端服务。
与 Istio 的入口网关或 NGINX Ingress 等其他流行解决方案相比,Envoy Gateway 凭借其与 Kubernetes 的原生集成以及利用 Envoy 全部潜力的专注,而脱颖而出。下图从多方面对比了目前流行的一些开源的 API 网关。
API 网关 | 支持的认证和授权策略 | 支持的服务发现组件 | 支持的协议 | 控制平面配置分发方法 | 支持的插件扩展机制 | 组织隶属 |
---|---|---|---|---|---|---|
Envoy Gateway | OAuth2, JWT, mTLS, OIDC | Kubernetes, EDS | HTTP, HTTPS, gRPC | xDS | 基于 Envoy Filter | CNCF |
Kuma | mTLS, JWT | Kubernetes, Consul | HTTP, HTTPS, gRPC, TCP | REST, gRPC | 基于 Lua, Go | CNCF |
NGINX Ingress | RBAC | Kubernetes | HTTP, HTTPS, TCP, UDP | Kubernetes CRD | 基于 Nginx 模块 | N/A |
APISIX | OAuth2, JWT, Key Auth, Basic Auth, mTLS, OIDC, LDAP, OpenID 等 | Kubernetes, DNS, Consul, Nacos, Eureka | HTTP, HTTPS, TCP, UDP, WebSocket | REST, CLI, Web UI | 基于 Lua, Wasm | Apache Software Foundation |
Kong | OAuth2, JWT, Basic Auth, Key Auth | Kubernetes, DNS, Consul | HTTP, HTTPS, gRPC, WebSocket | REST, gRPC, Web UI | 基于 Lua | N/A |
Emissary | Basic Auth | Kubernetes | HTTP, HTTPS, gRPC | Kubernetes CRD | 基于 Lua, Go | CNCF |
要快速上手 Envoy Gateway,你可以通过以下简化步骤快速搭建一个本地实验环境。首先,启动一个本地 Kubernetes 集群:
minikube start --driver=docker --cpus=2 --memory=2g
接下来,部署 Gateway API CRD 和 Envoy Gateway 本身:
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.0.1 -n envoy-gateway-system --create-namespace
然后,安装网关配置并部署一个示例应用:
kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/v1.0.1/quickstart.yaml -n default
为了暴露 LoadBalancer 服务,这里我们使用端口转发作为示例。你也可以选择使用 minikube tunnel
或安装 MetalLB 作为负载均衡器:
export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8888:80 &
通过以下命令测试你的 Envoy Gateway 是否正常工作:
curl --verbose --header "Host: www.example.com" http://localhost:8888/get
想了解更多详细的安装和配置步骤,请访问 Envoy Gateway 网站。通过这些步骤,你可以快速开始探索 Envoy Gateway 的功能。
Envoy Gateway 不仅优化了云原生时代的七层网关配置,而且为从边缘网关向服务网格过渡提供了一个平滑的道路。由于服务网格的推广面临一些挑战,如对应用的侵入性和运维团队推动问题,边缘网关则更易于被开发团队接受。Envoy Gateway 采用简化的 Kubernetes Gateway API,提高了流量管理和可观测性的能力。此外,Envoy Gateway 到 Istio 的过渡对于已熟悉 Envoy 功能的团队来说,将是一个自信的技术进步,同时还支持从标准的 Kubernetes Gateway API 到 Istio Ingress Gateway 的无缝切换,或者作为一个定制解决方案继续与 Istio 协作。这些特点使得 Envoy Gateway 成为一个在云原生时代值得投资的网关选择。
请继续关注本系列博客的后续部分,我们将深入探讨如何配置和优化 Envoy Gateway,提供实用指南并展示更广泛的实际应用案例。
2024-05-07 21:11:49
近日 CNCF 发布了 KubeCon EU 2024 的透明度报告,KubeCon + CloudNativeCon Europe 2024 在巴黎举办,这是有史以来最大规模的一次会议,我也有幸能亲临现场参加,巴黎的美景和会议的氛围让我久久难以忘怀。
我们见证了开源和云原生社区的力量,以及它如何推动技术的下一个重大转变 —— 人工智能。在这次会议上,CNCF 宣布成立 AI 工作组,并推出了第一版云原生 AI 白皮书,随后有创建了云原生 AI Landscape。
本次活动迎来了超过 12,000 名参与者,大部分来自欧洲(78%),其中 52% 为首次参会者。来自不同地区的参与者都表现出了对云原生技术的热情。我们还看到了业务运营、开发者和架构师等多样化的职能背景,这突显了云原生技术跨领域的广泛应用。
下表来自不同国家的参会人数 Top 10:
国家 | 参会人数 |
---|---|
法国 | 1,956 |
德国 | 1,879 |
美国 | 1,733 |
英国 | 816 |
荷兰 | 797 |
瑞士 | 368 |
西班牙 | 355 |
以色列 | 312 |
波兰 | 303 |
丹麦 | 293 |
活动期间,有 331 场会议和 19 场主题演讲,覆盖了人工智能、应用开发、平台工程等多个热门领域。本届 KubeCon 首次举办了面向研究者的海报会话和项目馆导览,帮助参会者更好地了解各个项目。
KubeCon 致力于支持多样性、公平性和包容性。活动提供的多样性午餐和 Peer Group Mentoring 等活动,为参与者提供了建立联系和互帮互助的平台。(PS. 会场提供的餐饮实在是让我喜欢不了,尤其是茶的味道,还有硬邦邦的面包)
在环保和可持续性方面,主办方选择了具有环保意识的会场,并实施了减少食物浪费和回收废物的措施。这体现了 CNCF 对环境保护的承诺。
展望未来,我们期待将 KubeCon 的魔力带到全球更多地区。无论是即将到来的 KubeCon + CloudNativeCon China 2024 还是其他地区的活动,我都非常期待与你相见。我也向 KubeCon China 提交了一个 Panel session,如果能够入选,今年 8 月我们将在香港相见。
KubeCon + CloudNativeCon Europe 2024 不仅是技术的盛会,更是社区力量的展示。如你想了解更多细节,请查看我之前关于 KubeCon + CloudNativeCon Europe 的回顾。
我们希望这篇透明性报告能帮助你更好地理解活动的影响力,并激励你参与未来的 KubeCon 活动。
2024-04-29 09:27:49
亲爱的云原生社区的朋友们,我很高兴向大家推荐 Isovalent 最新推出的电子书《Kubernetes 网络和 Cilium 网络工程师指南(英文原版)》。
作为一名资深的云原生倡导者,我深知 Kubernetes 网络对于网络工程师来说是一个巨大的挑战。但是,随着 Kubernetes 在企业中的广泛应用,学习 Kubernetes 网络知识已经变得非常重要和紧迫。这本电子书正是为了帮助网络工程师们克服这些挑战而诞生的。
这本 56 页的电子书由 Isovalent 的 Senior Staff Technical Marketing Engineer Nico Vibert 撰写,内容涵盖了 Kubernetes 网络的方方面面,包括 Cilium 这个事实上的 Kubernetes 网络层。即使你不是网络工程师,相信你也能轻松理解和学习这本书的内容。
这本电子书就像一本使用说明手册,为网络工程师们提供了一个循序渐进的学习路径。从 Kubernetes 网络的基础知识,到 Cilium 的高级功能,再到实际的部署和运维,应有尽有。相信这本书一定会成为网络工程师学习 Kubernetes 网络的必备资料。
根据这本由 Isovalent 推出的电子书《Kubernetes Networking and Cilium: An Instruction Manual for the Network Engineer》的内容,我为大家总结了以下几点。
这本电子书主要面向 Kubernetes 网络工程师,帮助他们全面掌握 Kubernetes 网络的方方面面知识。即使不是网络工程师,对云原生技术感兴趣的读者也能从中受益,学习 Kubernetes 网络的基础知识。
如果你想阅读该书的中文版,请访问这里获取。中文版由 Isovalent 的黄力一翻译。
2024-04-17 18:54:49
本文将深入探讨 Istio CNI 插件的设计理念、实现方式以及如何通过 Ambient Mode 来解决传统模式中存在的安全和权限问题。本文内容包括:
Istio 服务网格通过 Sidecar 模式实现应用流量的拦截和管理。该模式通过在应用程序 Pod 中注入 Sidecar Proxy 和 init 容器,并使用 iptables 规则来管理网络流量。详细的部署和操作过程请参见 Istio 中的 Sidecar 注入、透明流量劫持及流量路由过程详解。虽然此方法在多数 Kubernetes 平台上有效,但对高权限的依赖在多租户环境中引发了安全方面的担忧。
Istio 在其网络配置初期采用了 istio-init
容器来初始化流量拦截规则,这需要容器具有高级权限来修改网络配置,如 IPTables 规则。虽然这种方法实现了对流量的有效管理,但它也显著提高了权限需求并增加了安全风险。根据 Istio 官方文档,istio-init
容器默认被注入到 Istio 网格中的 Pod 里,以便将网络流量劫持到 Istio 的 Sidecar 代理。这一过程需要对部署 Pod 的 Service Account 赋予 NET_ADMIN
容器权限,可能与某些组织的安全政策相悖。
为响应这一挑战,Istio 社区推出了 Istio CNI 插件,该插件避免了对 init 容器的需求,允许直接在 Kubernetes 的网络层面操作,从而降低权限需求并简化部署流程,但是存在 CNI 兼容性问题。
Istio 的 Ambient Mode 是一种创新的无 sidecar 方案,它通过 使用 Geneve 隧道 或 Istio CNI 提高网络的灵活性和安全性。
直到最近 Istio 社区才推出适配任意 CNI 的通用的解决方案。此模式解决了与任意 CNI 的兼容性问题,使 Istio 能够在不影响现有网络策略的前提下,更有效地管理服务间的流量。
在 Kubernetes 和 Docker 等容器化环境中,NET_ADMIN
权限允许容器内的进程执行广泛的网络相关操作。这包括修改 iptables 规则、更改网络接口配置、管理 IP 路由表,以及控制网络相关的内核参数。然而,这种权限的使用引发了安全上的考虑,特别是在权限过度和潜在的攻击面方面。
最佳实践包括:
NET_ADMIN
权限,并通过 Kubernetes 网络策略加以限制。NET_ADMIN
权限的容器进行严格的日志记录和监控。Istio CNI 插件是一个二进制文件,作为代理安装在每个节点的文件系统中。以下流程图说明了 Istio CNI 节点代理的工作原理:
CAP_SYS_ADMIN
、 CAP_NET_ADMIN
和 CAP_NET_RAW
才能在任一模式下运行。Istio 的 Ambient Mode 是为了适配所有 CNI 而设计的一种模式,它通过 ztunnel 来透明地处理 Pod 内的流量转发,而不影响现有的 CNI 配置。这种模式下,Ambient Mode 通过 ztunnel 管理流量,使其流经 Istio 服务网格,而标准的 CNI 则侧重于为 Pod 提供标准化的网络接入。
CNI 的主要职责是解决 Kubernetes Pod 之间的网络连通性,例如分配 IP 地址和转发数据包。相比之下,Ambient Mode 需要将流量导入 ztunnel,这与 CNI 的网络配置可能存在不兼容,主要问题包括:
为解决这些问题,可以通过将 ztunnel 运行在与 Pod 相同的用户空间中,避免与 CNI 修改过的内核空间的冲突。这样,Pod 可以直接连接到 ztunnel,绕过 CNI 的影响。
下面的时序图描述了 Ambient mode 下的流程:
为缓解这些冲突,Istio 的 Ambient Mode 避免了对 CNI 修改过的内核空间的依赖:
这些措施帮助 Istio 的 Ambient Mode 在不干扰现有 CNI 插件的情况下,有效管理服务间流量。
Ambient Mode 在 Istio 中通过 node-local Ztunnel 实现了改进的流量转发机制,允许在 Pod 的网络命名空间中设置侦听套接字,实现从服务网格内部的加密(mTLS)和明文流量的有效重定向。这种方法不仅提高了流量管理的灵活性,还避免了与现有的 CNI 插件之间的潜在冲突。下面是该模式的具体实现流程:
具体步骤如下:
istio.io/dataplane-mode=ambient
的 Pod。通过这种方法,Istio Ambient Mode 为 Kubernetes 环境中的服务间流量管理提供了一种更为高效和安全的解决方案。
本文全面解析了 Istio CNI 插件的设计理念、实现方式和优势,特别是 Istio CNI 如何解决了传统 istio-init
方法中存在的权限和安全问题。通过这些创新,Istio 在网络安全和操作简便性上取得了重大进步,为 Kubernetes 环境中实施 Istio 提供了更灵活和高效的方法。
2024-04-16 12:54:49
2024 年 3 月,在 KubeCon EU 期间,云原生计算基金会(CNCF)发布了首份关于云原生人工智能(CNAI)的详细白皮书。这份报告详尽地探讨了将云原生技术与人工智能融合的当前状态、面临的挑战、以及未来的发展方向。本文将对这份白皮书的核心内容进行深入解读。
云原生 AI 指的是利用云原生技术原则来构建和部署人工智能应用和工作负载的方法。这包括利用微服务、容器化、声明式 API 和持续集成/持续部署(CI/CD)等云原生技术来增强 AI 应用的可扩展性、可复用性和可操作性。
下图展示了云原生 AI 的架构,图片根据该白皮书重新绘制。
云原生技术提供了一个灵活、可扩展的平台,使得开发和运行 AI 应用变得更加高效。通过容器化和微服务架构,开发人员可以快速迭代和部署 AI 模型,同时保证系统的高可用性和可扩展性。Kubernetes 和其他云原生工具提供了必要的支持,例如资源调度、自动扩缩容和服务发现等。
白皮书中给出了两个例子说明云原生 AI 与云原生技术的关系,即在云原生基础架构上运行 AI:
尽管云原生技术为 AI 应用提供了坚实的基础,但在将 AI 工作负载与云原生平台整合时,仍然存在一些挑战。这些挑战包括数据准备的复杂性、模型训练的资源需求、以及在多租户环境中保持模型的安全性和隔离性。此外,云原生环境中的资源管理和调度对于大规模 AI 应用尤其关键,需要进一步优化以支持高效的模型训练和推理。
白皮书中提出了几条云原生 AI 的发展路径,包括改进资源调度算法以更好地支持 AI 负载、开发新的服务网格技术以提高 AI 应用的性能和安全性,以及通过开源项目和社区合作来推动云原生 AI 技术的创新和标准化。
云原生 AI 涉及到多种技术,从容器和微服务到服务网格和无服务器计算。Kubernetes 是部署和管理 AI 应用的关键平台,而 Istio、Envoy 等服务网格技术则提供了强大的流量管理和安全功能。此外,Prometheus 和 Grafana 等监控工具对于维护 AI 应用的性能和可靠性至关重要。
下面是白皮书中给出的云原生 AI 景观图。
最后,笔者梳理了以下关键观点:
开源社区的推动作用:白皮书明确指出开源社区对云原生 AI 进步的推动作用,其中包括通过开源项目和广泛的合作来加速创新和降低成本。
云原生技术的重要性:云原生 AI 是按照云原生原则构建和部署的,突出了可重复性和可扩展性的重要性。云原生技术为 AI 应用提供了高效的开发和运行环境,特别是在资源调度和服务可伸缩性方面。
存在的挑战:尽管云原生 AI 带来了诸多优势,但在数据准备、模型训练资源需求以及模型安全性和隔离性方面,仍面临不少挑战。
未来发展方向:白皮书提出的发展路径包括优化资源调度算法以支持 AI 负载,开发新的服务网格技术以提升性能和安全性,以及利用开源项目和社区合作进一步促进技术创新和标准化。
关键技术组件:云原生 AI 涉及的关键技术包括容器、微服务、服务网格和无服务器计算等,其中 Kubernetes 扮演着 AI 应用部署和管理的中心角色,Istio 和 Envoy 等服务网格技术提供了必要的流量管理和安全保障。
有关详情,请下载 云原生 AI 白皮书。
2024-04-15 13:54:49
在容器化环境中,有效管理网络是至关重要的。容器网络接口(CNI)是一个标准,定义了容器应如何配置网络。本文将深入探讨 CNI 的基础知识,并带你了解 CNI 与 CRI 的关系。
CNI(容器网络接口)规范为容器运行时和网络插件之间提供了一个通用的接口,旨在实现容器网络配置的标准化。
CNI 规范包含以下几个核心组成部分:
CNI 规范通过定义这些核心组成部分,确保了不同的容器运行时和网络插件能够以一致的方式进行交互,实现网络配置的自动化和标准化。
CNI 插件根据操作类型,接收相应的网络配置参数,执行网络配置或清理任务,并返回执行结果。这一流程确保了容器网络的动态配置与容器生命周期的同步。
下图展示了 CNI 包含了众多的网络插件。
根据 CNI 规范,一个 CNI 插件负责以某种方式配置容器的网络接口。插件可分为两大类:
CNI 和 CRI(容器运行时接口)是 Kubernetes 中两个关键的接口,它们分别处理容器的网络配置和运行时管理。在 Kubernetes 集群中,CRI 调用 CNI 插件来配置或清理容器的网络,这确保了网络配置的过程与容器的创建和销毁过程紧密协调。
下图直观地展示了 CNI 如何与 CRI 协同运行的:
下图展示了在 Kubernetes 中为 Pod 设置网络所涉及的详细步骤:
容器网络接口(CNI)规范定义了容器如何配置网络,其中包括 ADD
、CHECK
、DELETE
、GC
和 VERSION
五种操作。容器运行时通过调用各种 CNI 插件来执行这些操作,从而实现容器网络的动态管理和更新。
为了详细说明序列图中描述的每个步骤,涉及 Kubelet、Pod、CNI 插件(包括接口和链式 CNI 插件)、网络设置和 IP 地址管理(IPAM)之间的交互,让我们深入了解这个过程:
以下是针对 CNI 官方示例中的 ADD
操作、CHECK
操作和 DELETE
操作的示例序列图以及详细说明。通过这些操作,容器运行时与 CNI 插件之间进行交互,实现容器网络配置的动态管理和更新。
以下是 ADD 操作的示例序列图以及详细说明:
这些操作确保了在容器启动时,其所需的网络配置能够按照预期进行设置,包括端口映射、网络调优和 IP 地址分配等。
以下是 CHECK 操作的示例序列图以及详细说明:
这些操作确保了在容器运行期间,其网络配置和网络调优参数能够按照预期进行检查和验证,以确保网络配置的一致性和正确性。
以下是 DELETE 操作的示例序列图以及详细说明:
这些操作确保了在容器停止运行时,其所需的网络配置能够被正确清理和移除,以确保网络资源的有效释放和管理。
通过对 ADD、CHECK 和 DELETE 操作的示例序列图及详细说明,可以清晰地了解容器运行时与 CNI 插件之间的交互过程,以及如何实现容器网络配置的动态管理和更新。
CNI 为容器化环境中的网络管理提供了一种标准化的接口,通过与 CRI 的配合,确保了 Kubernetes 集群中容器的网络配置高效且一致。通过深入理解 CNI,开发者和系统管理员可以更好地管理和优化其容器网络。
2024-03-29 12:54:49
本文将介绍 Tetrate 新推出的工具——Tetrate Vulnerability Scanner (TVS),一款针对 Istio 和 Envoy 定制的 CVE 扫描器。在深入了解 TVS 的具体功能前,我们先简要回顾 CVE 的概念及其在软件安全性中的核心作用。
CVE,即通用漏洞和暴露,是一个公开的漏洞数据库,由 MITRE 公司负责维护。它旨在为软件中的漏洞提供一个标准化的命名体系,包含了漏洞的标识号、详细描述及参考链接。虽然 CVE 本身不提供漏洞的严重性评分,但它为网络安全专家、开发人员和企业提供了一个获取关键安全信息的重要平台。每个 CVE 记录的唯一标识号便于追踪漏洞相关信息,诸如受影响的软件系统、修复措施等。例如,2021 年著名的 Log4j 漏洞(CVE-2021-44228)由于影响广泛,严重程度评级为 10。
一个典型的 CVE 使用案例是将 CVE 扫描功能集成到 CI/CD 管道中,以自动化安全测试,从而阻止带有已知漏洞的代码合并到代码库并接收警报。这一过程有助于确保应用程序不会使用带有漏洞的包或库,从而提高了软件的安全性。
例如 Github 将 CVE 检测和处理作为供应链安全的关键一环,如果你在 Github 上托管了开源项目,并开启了 Dependabot,每当你的 PR 或 commit 存在漏洞时,你就可能收到类似下面的 CVE 通知:jQuery Cross Site Scripting vulnerability。收到通知后你可以选择容忍该漏洞或者应用 patch。下图展示了 CVE 的处理流程。
Istio 经常在其官网发布 CVE 通知,例如 ISTIO-SECURITY-2024-001。以前,你必须手动跟踪这些通知,但现在你可以使用 TVS 自动执行 CVE 扫描任务,从而显着减少安全团队的工作量。
目前 TVS 仅提供命令行工具,未来将作为服务集成到 TIS 中。下图展示了 TVS 运行结果。
下图说明了 TVS 的工作流程。
所有人都可以免费下载和使用 TVS,不过在执行 CVE 扫描之前你需要先注册,详见 TIS 文档。
有报告指出,现在即使最流行的容器最新版本也有数百个 CVE,下面是为了保证的一些建议:
TVS 通过其命令行工具提供简便的 CVE 扫描操作,未来还计划在 Kubernetes 和 Tetrate Istio Subscription (TIS) 中集成,以进一步简化 Istio 和 Envoy 的 CVE 管理过程。TIS 提供自 Istio 发布起 14 个月内的 CVE 补丁和向后兼容支持,帮助用户及时获得安全更新,同时保持系统的稳定运行。
TVS 为所有用户免费开放下载使用,使用前需进行简单的注册。更多信息请参阅 TIS 文档。
通过采纳 TVS 这一自动化的 CVE 扫描工具,企业能够更有效地识别和处理 Istio 及 Envoy 中的安全漏洞,提升基础设施的安全性,同时减轻安全团队的负担,推动安全管理流程的高效运作。
2024-03-27 16:54:49
上周我在巴黎参加了 KubeCon EU 2024,这也是我第一次参加中国以外的 KubeCon。本次大会可谓盛况空前,据说有 1.2 万人参加了会议。本文将为你分享我对本次 KubeCon 的一些观察,主要着重在我关注的服务网格与云原生基础架构领域。
Istio 和 Service Mesh 成为了热门讨论的话题,集中展示了在云原生生态系统中这两项技术的最新进展和应用。本次大会涵盖了从基础设施优化、数据本地化、分布式追踪到多集群部署等多个领域,反映了 Service Mesh 技术在实际应用中的广泛关注和持续创新。
Pigment 的 Arthur Busser 和 Baudouin Herlicq 分享了如何利用 Kubernetes 和 Istio 实现数据本地化的需求。他们介绍了利用 Istio 基于自定义头部进行请求路由的方法,这对于满足如 GDPR 和 CCPA 等法规的数据驻留要求至关重要。
ThousandEyes (part of Cisco) 的 Chris Detsicas 探讨了如何配置 Istio 以使用 OpenTelemetry 实现有效的分布式跟踪,这为微服务生态系统提供了宝贵的可见性,有助于问题诊断和性能优化。
China Mobile 的 Haiwen Zhang 和 Yongxi Zhang 介绍了一个简化 Istio 多集群部署的新方法,该方法使用一个全局唯一的 Istio 控制平面,通过主集群的 Apiserver 实现全局服务发现,自动连接多个集群的容器网络,为 Pod 提供直接网络连接。特别强调了 Kosmos 项目,它提供了一种新的解决方案,以简化多集群环境下的服务网格部署和管理。
Google 的 Ameer Abbas 和 John Howard 探讨了如何在基础设施可靠性为 99.9% 的情况下构建出 99.99% 可靠性的服务,并提出了一系列应用架构原型(Archetypes),这些原型可以帮助设计和实现高可靠性的多集群应用程序。
多个议题,如 Microsoft 的 Niranjan Shankar 所介绍的,聚焦于在生产环境中加固 Istio 的重要性和方法。他讨论了利用 Istio 与网络策略、第三方 Kubernetes 工具和云提供的安全服务相结合,构建零信任和深层防御架构的步骤和策略。
Benjamin Leggett 和 Yuval Kohavi 引入了一种创新的方法,使 Istio 的 Amibent mode 能够支持任意 Kubernetes CNI,详见 Istio 博客。这一进步解决了 Ambient mesh 中 CNI 支持有限的问题,无需重启应用程序 Pod 即可将其纳入 Ambient mode,这对于简化操作和降低基础设施成本具有重要意义。
Istio 社区宣布在即将到来的 Istio 1.22 版本,Ambient 模式将成为 beta,详见 CNCF 博客。多个演讲和讨论聚焦于 Istio Ambient Mesh 的未来,特别是其简化工作负载操作和降低基础设施成本的潜力。Istio Ambient Mesh 的介绍预示了服务网格技术的一个新方向,即无 sidecar 的数据平面架构,提供了更高的性能和更低的资源消耗。
在 KubeCon EU 2024 上,关于 Sidecar 的讨论主要集中在评估和比较使用 Sidecar 与无 Sidecar(如 Istio 的 Ambient Mesh)服务网格模式的优缺点。特别是 Christian Posta 对 Cilium 和 Istio 在无 sidecar 服务网格实现方面的设计决策和权衡进行了深入分析,突出了这种模式在提高性能、降低资源消耗和简化运维操作方面的潜力。通过分析纽约时报从 Istio 过渡到 Cilium 的案例,进一步证明了无 sidecar 模式在处理复杂、多区域服务网格时的有效性,同时指出了在这一转变过程中的挑战和实施考虑。这些讨论预示着服务网格技术未来可能朝向更加灵活和高效的方向发展,其中无 Sidecar 架构可能成为优化云原生应用性能和资源使用的关键策略。
Cilium 在 KubeCon EU 2024 上被广泛讨论,作为一种基于 eBPF 的技术,Cilium 不仅被看作是一个高效的容器网络接口(CNI),而且还展示了其在服务网格领域的强大潜力。通过 Isovalent 和其他组织的演讲,Cilium 被展示为一种能够提供连接、观测和保障服务网格安全的先进解决方案。特别是 Cilium 的无 Sidecar 服务网格实现方式被认为是未来方向,其利用 eBPF 技术在不增加传统 Sidecar 代理负担的情况下实现了微服务的安全通信和精细流量管理。此外,Cilium 在服务网格之外的扩展能力,例如在多云网络和负载平衡方面的应用,凸显了其作为云原生生态系统基础设施核心组件的地位。Cilium 的这些讨论和案例研究证明了其在推动服务网格和云原生技术创新方面的重要作用。
当前云原生领域的几个主要趋势:
可持续性和环保意识的增强:例如,Deutsche Bahn 将开发者引入其基础设施绿化过程,强调了在设计和运营云原生解决方案时,越来越多的公司开始考虑环境因素。这反映了一个趋势,即企业在追求技术进步的同时,也在努力减少对环境的影响,通过绿色计算和能效优化来实现可持续的技术生态。
人工智能与云原生技术的融合:人工智能(AI)正在成为 Kubernetes 和云原生生态系统面临的下一个主要挑战。Nvidia 关于 AI 策略的讨论、CNCF 对 AI 在云原生未来中标准化工作的推动,以及各种关于 AI 和机器学习(ML)集成的工具和平台的更新,都突显了这一点。这一趋势表明,将 AI 和 ML 无缝集成到云原生架构中,不仅可以加速应用开发和部署,还能够提供更加智能和自动化的操作能力。同时 CNCF 还宣布成立 AI WG,并发布了人工智能白皮书。
WebAssembly(Wasm)的兴起:Cosmonic 对最新 Wasm 标准的支持,以及 Fermyon 将其开源 Wasm 平台 SpinKube 捐赠给 CNCF,显示了 WebAssembly 在云原生应用开发中日益增长的重要性。Wasm 提供了一种高效、安全的方式来运行在浏览器外的客户端和服务器端代码,这对于构建跨平台、高性能的云原生应用尤为重要。
云原生观测性的强化:例如,New Relic 在其可观测性平台中添加了原生 Kubernetes 支持,凸显了对云原生应用的监控、日志记录和性能分析需求的增加。随着云原生架构的复杂性增加,企业需要更加强大的工具来保持系统的透明度和健康,从而优化性能和可靠性。
云原生社区的协作和开源精神的强化:CNCF 成立最终用户技术咨询委员会、Red Hat 与 Docker 合作开发 Testcontainers Cloud 框架等举措,反映了云原生社区致力于促进协作和分享的文化。这种开放的协作精神不仅加速了新技术的发展和采纳,也为云原生生态系统的健康成长提供了坚实的基础。
这些趋势共同描绘了一个多元化、持续创新且日益成熟的云原生技术景观,其中可持续性、AI/ML 集成、WebAssembly、加强的可观测性和社区协作是推动这一领域前进的关键因素。
KubeCon EU 2024 的见闻为我们揭示了云原生技术领域的多个重要进展和未来方向。从服务网格的持续创新到云原生生态系统对环境可持续性的关注,再到人工智能与机器学习技术的深度整合,以及 WebAssembly 在应用开发中的日益重要性,这些趋势共同构成了当前云原生技术的前沿。
特别值得注意的是,Istio 和 Cilium 在服务网格领域的最新动态,展现了无 Sidecar 架构的潜力以及 eBPF 技术在提升性能、安全性和可观测性方面的作用。这些进展不仅为开发者提供了更为高效和灵活的工具,也为云原生应用的设计和运营提出了新的思路。
同时,云原生社区的持续发展和对开源精神的坚持,为技术创新和知识共享提供了坚实的基础。通过强化观测性、推动环境可持续性和促进技术标准化,云原生生态正展现出其深厚的发展潜力和广阔的应用前景。
作为一名观察者和参与者,我深感云原生技术的快速发展给我们带来了前所未有的机遇和挑战。未来,随着技术的不断演进和社区的共同努力,我们有理由相信,云原生技术将在推动数字化转型和创造更加智能、可持续的技术世界方面发挥更大的作用。让我们拭目以待,并积极参与这一令人兴奋的技术旅程。
2024-03-07 11:27:49
即将发生的政策变更:请注意,ICA 认证期限政策将于 2024 年 4 月 1 日 00:00UTC 发生变更。在此日期或之后获得的认证将于满足计划认证要求(包括通过考试)之日起 24 个月后到期。我们鼓励任何有兴趣并准备好的人在政策变更之前安排并参加考试。请在此处查看更多详细信息。
当前的认证有效期是 3 年,4 月 1 日之后通过的认证有效期是 2 年。
Tetrate 运营的 Tetrate Academy 已经有好几年时间,期间推出了 Istio 基础教程、Envoy 基础教程和 CIAT 认证考试,一共有 13000 多人学习了 Tetrate Academy 的课程。去年 9 月 Tetrate 将 CIAT 贡献给了 CNCF,改名为 ICA 考试,至 11 月该认证考试正式上线。
2024-01-29 11:27:49
本博文解析了在 Istio 服务网格中服务端获取客户端源 IP 的挑战,并提供了解决方案。将探讨以下问题:
保留客户端源 IP 的主要理由包括:
保留源 IP 指的是在请求从客户端发出、经过负载均衡器或反向代理后,避免真实的客户端源 IP 被替换的情况。
以下是源 IP 地址丢失的流程示例:
上面图只是最常见的一种情况。本文考虑到以下几种情况:
在 Istio 服务网格中,Envoy 代理通常会将客户端 IP 添加到 HTTP 请求的 “X-Forwarded-For” 头部中。以下是确认客户端 IP 的步骤:
详情请见 Envoy 文档中对 x-forwarded-for
标头的说明。对于 TCP/IP 连接,可以通过协议字段解析客户端 IP。
GKE
Istio
CNI
我们使用了 Cilium CNI,但是没有开启无 kube-proxy 模式。
Node
节点名称 | 内部 IP | 备注 |
---|---|---|
gke-cluster1-default-pool-5e4152ba-t5h3 | 10.128.0.53 | |
gke-cluster1-default-pool-5e4152ba-ubc9 | 10.128.0.52 | |
gke-cluster1-default-pool-5e4152ba-yzbg | 10.128.0.54 | Ingress Gateway Pod 所在节点 |
执行测试的本地客户端电脑的公网 IP:123.120.247.15
下图展示了测试方式:
首先参考 Istio 文档部署 Istio,然后为 default 命名空间开启 sidecar 自动注入:
kubectl label namespace default istio-injection=enabled
在 Istio 中部署 echo-server 应用测试。echo-server 是一个基于 Nginx 的服务器,用于回显客户端发送的请求信息,例如请求头、客户端地址、请求方法等。
kubectl create deployment echo-server --image=registry.k8s.io/echoserver:1.4
kubectl expose deployment echo-server --name=clusterip --port=80 --target-port=8080
创建 Ingress Gateway:
cat>config.yaml<<EOF
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: clusterip-gateway
spec:
selector:
istio: ingressgateway # 根据你的环境选择适当的 selector
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "clusterip.jimmysong.io" # 替换成你想要使用的主机名
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: clusterip-virtualservice
spec:
hosts:
- "clusterip.jimmysong.io" # 替换成与 Gateway 中相同的主机名
gateways:
- clusterip-gateway # 这里使用 Gateway 的名称
http:
- route:
- destination:
host: clusterip.default.svc.cluster.local # 替换成你的 Service 的实际主机名
port:
number: 80 # Service 的端口
EOF
kubectl apply -f config.yaml
查看 Ingress Gateway 中的 Envoy 日志:
kubectl logs -f deployment/istio-ingressgateway -n istio-system
查看 Sleep Pod 中的 Envoy 日志:
kubectl logs -f deployment/sleep -n default -c istio-proxy
查看 Source IP App 中的 Envoy 日志:
kubectl logs -f deployment/echo-server -n default -c istio-proxy
获取网关公网 IP:
export GATEWAY_IP=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
在本地使用 curl 测试:
curl -H "Host: clusterip.jimmysong.io" $GATEWAY_IP
当部署好测试应用后,你需要获取与以下资源的 IP 地址。在接下来的实验环节中将会用到。
Pod
下面是初始状况下的 Pod IP,随着对 Deployment 的补丁,Pod 会重建,名称和 IP 地址都会变。
Pod 名称 | Pod IP |
---|---|
echo-server-6d9f5d97d7-fznrq | 10.32.1.205 |
sleep-9454cc476-2dskx | 10.32.3.202 |
istio-ingressgateway-6c96bdcd74-zh46d | 10.32.1.221 |
Service
Service 名称 | Cluster IP | External IP |
---|---|---|
clusterip | 10.36.8.86 | - |
sleep | 10.36.14.12 | - |
istio-ingressgateway | 10.36.4.127 | 35.188.212.88 |
我们首先考虑客户端位于 Kubernetes 集群外,通过负载均衡器来访问集群内部服务的情况。
这是通过以上步骤部署完测试应用后的默认情况,也是大家遇到的所谓的源 IP 地址丢失的情况。
curl 测试:
curl -H "Host: clusterip.jimmysong.io" $GATEWAY_IP
|
|
你只需要关注 client_address
和 x-forwarded-for
这两个结果即可。下文的 curl 测试结果中将省略其他信息。
该结果中字段的含义:
client_address
:通过解析 TCP/IP 协议而获取的客户端 IP 地址,在 Envoy 中称为 remote address。x-forwarded-for
:x-forwarded-for
(XFF) 是一个标准的代理头部,用于指示请求在从客户端到服务器的过程中经过的 IP 地址。一个合规的代理会在代理请求之前将最近客户端的 IP 地址添加到 XFF 列表中。详见 Envoy 文档。从测试结果中我们可以看出,源 IP 地址变成了 Ingress Gateway Pod 所在节点的 IP 地址(10.128.0.54
)。
下图展示是两个 Pod 中的数据包流量路径。
对于这种情况,要想保留源 IP 其实很简单,而且也是 Kubernetes 提供的标准选项。
下图展示客户端的源 IP 是如何在请求过程中丢失的。
因为负载均衡器将数据包发送到 Kubernetes 集群中的任意节点,在此过程中会进行 SNAT,导致最终发送到 Server Pod 中的客户端源 IP 丢失。
你可以通过设置 service 中的 externalTrafficPolicy
字段为 Local
控制负载均衡器保留源 IP。
externalTrafficPolicy
externalTrafficPolicy
是一个标准 Service 选项,用于定义传入 Kubernetes 节点的流量是否进行负载均衡以及如何进行负载均衡。Cluster
是默认策略,但 Local
通常用于保留传入集群节点的流量的来源 IP。Local
会在集群节点上有效停用负载均衡,以使本地 Pod 接收的流量看到原始来源 IP 地址。
也就是说将 externalTrafficPolicy
设置为 Local
就可以让数据包绕过节点上的 kube-proxy,而直达目标 Pod。但是大多数人在 Kubernetes 中创建 Service 时都没有设置 externalTrafficPolicy
,所以使用了默认的 Cluster
策略。
既然 Service 采用 Local 外部流量策略可以保留客户端的源 IP 地址,那为什么 Kubernetes 不默认采用呢?
Kubernetes 默认将 Service 的 externalTrafficPolicy
设置为 Cluster
而非 Local
,主要是基于以下考虑:
Cluster
模式降低了网络配置的复杂性。将 Ingress Gateway Service 设置为 Local 外部流量策略:
kubectl patch svc istio-ingressgateway -p '{"spec":{"externalTrafficPolicy":"Local"}}' -n istio-system
Curl 测试:
curl -H "Host: clusterip.jimmysong.io" $GATEWAY_IP
|
|
通过 Envoy 日志可以得出现在的数据包路径:
客户端源 IP 被正确识别为 123.120.247.15
。
在 Istio 默认配置的情况下,对于东西向流量,服务端也无法获取正确的客户端源 IP。
将 Source IP App 中的流量拦截方式从 iptables 修改为 tproxy:
kubectl patch deployment -n default echo-server -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/interceptionMode":"TPROXY"}}}}}'
注意:此时 Source IP App 的 Pod 将会重建,新的 Pod 名称是 echo-server-686d564647-r7nlq
,IP 地址是 10.32.1.140。
Curl 测试:
kubectl exec -it deployment/sleep -it -- curl clusterip
|
|
下图展示了数据包路径:
客户端 IP 被正确识别为 10.32.3.202
。
将 Source IP App 中的流量拦截方式恢复为 redirect:
kubectl patch deployment -n default echo-server -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/interceptionMode":"REDIRECT"}}}}}'
注意:此时 Source IP App 的 Pod 将会重建,新的 Pod 名称是 echo-server-6d9f5d97d7-bgpk6
,IP 地址是 10.32.1.123。
Curl 测试:
kubectl exec -it deployment/sleep -it -- curl clusterip
|
|
下图展示了数据包路径:
客户端源 IP 被识别为 127.0.0.6
。
在单层代理的情况下,只需要将 Ingress Gateway 的 Service 的 externalTrafficPolicy
设置为 Local
即可保留客户端源 IP。将目标服务的流量拦截模式修改为 TPROXY
即可以保留东西向请求中的源 IP。
如果流量在进入 Istio Mesh 前已经经过的多层代理转发,每次流量经过代理时,代理解析 HTTP 流量并将其自身的 IP 地址追加到 x-forwarded-for
标头中。那么可以使用 numTrustedProxies
配置您信任的代理跳数,请参考 Envoy 文档 了解如何确定 X-Forwarded-For
标头和受信任的客户端地址。
实际上我们很难确定流量在到达 Istio Mesh 时究竟经过了几层代理,但你可以根据 x-forwarded-for
标头了解流量的转发路径。
下图展示了 Envoy 如何根据 x-forwarded-for
标头和 xff_num_trusted_hops
(对应 Istio 中的 numTrustedProxies
配置)来确认源 IP 的流程。详见 Envoy 文档。
执行下面的命令为入口网关开启受信代理数量配置:
kubectl patch deployment istio-ingressgateway -n istio-system -p '{"spec":{"template":{"metadata":{"annotations":{"proxy.istio.io/config":"{\"gatewayTopology\":{\"numTrustedProxies\": 2,\"forwardClientCertDetails\":\"SANITIZE_SET\"}}"}}}}}'
当 Istio Gateway 收到这个请求时,它将 X-Envoy-External-Address
头设置为您 curl 命令中 X-Forwarded-For
头中的倒数第二个地址(numTrustedProxies: 2
)。根据 Istio 的文档,Gateway 在将其转发到服务端负载之前,会将自己的 IP 附加到 X-Forwarded-For
头中。但实际情况是标头中只有客户端源 IP 和 External Gateway Pod IP。
你可以执行下面的命令取消这个补丁:
kubectl patch deployment istio-ingressgateway -n istio-system -p '{"spec":{"template":{"metadata":{"annotations":{"proxy.istio.io/config":"{}"}}}}}'
上文所说的使用标头获取客户端源 IP 的方式只适用于 L7 网络,对于 L4 网络的 TCP 流量可以使用 Proxy 协议。
Proxy 协议是一种网络协议,它在 TCP 连接的起始处添加了一个协议头部,用于传递连接过程中的一些元数据,如客户端的真实 IP 地址和端口号。这对于在负载均衡器(LB)后部署的应用程序非常有用,因为负载均衡器通常会更改客户端的原始 IP 地址成 LB 的地址,导致服务端无法知晓客户端的真实 IP。很多代理软件都支持 Proxy Protocol,比如 Envoy 和 HAProxy、NGINX 等。
你可以使用下面的命令为 Ingress Gateway 打上补丁,以支持 Proxy 协议:
kubectl patch deployment istio-ingressgateway -n istio-system -p '{"spec":{"template":{"metadata":{"annotations":{"proxy.istio.io/config":"{\\"gatewayTopology\\":{\\"proxyProtocol\\":{}}}"}}}}}'
注意:不是所有的公有云中的 Kubernetes 中 LoadBalancer
类型的 Service 创建的的负载均衡器都支持该配置。比如 GKE 中就不支持。在 AWS NLB 中开启 Proxy 协议请参考该博客。
Envoy 并不建议使用 Proxy 协议,因为它:
关于 Envoy 对 Proxy 协议的支持请参考该文档。
下面是常见的两个源 IP 地址的应用场景。
在 Istio 的入口网关配置基于源 IP 的访问控制策略。这通过设置入口网关的授权策略,根据源 IP 地址实现访问限制。
下图展示了基于源 IP 地址的访问控制流程图。
假设请求经过三个代理,其 IP 地址分别为 1.1.1.1
、2.2.2.2
和 3.3.3.3
。在 Ingress Gateway 中,numTrustedProxies
被设置为 2,因此 Istio 信任的源 IP 为 2.2.2.2
(即 x-envoy-external-address
)。
curl -H "Host: clusterip.jimmysong.io" -H 'X-Forwarded-For: 1.1.1.1,2.2.2.2,3.3.3.3' $GATEWAY_IP
若需屏蔽来自 2.2.2.2
的请求,可以使用以下授权策略:
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: ingress-policy
namespace: istio-system
spec:
selector:
matchLabels:
app: istio-ingressgateway
action: DENY
rules:
- from:
- source:
remoteIpBlocks:
- "2.2.2.2/24"
如果希望识别与 Istio Mesh 直连的客户端 IP(即 x-forwarded-for
中的最后一个 IP,例如 123.120.234.15
),则需要用 ipBlocks
配置:
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: ingress-policy
namespace: istio-system
spec:
selector:
matchLabels:
app: istio-ingressgateway
action: DENY
rules:
- from:
- source:
ipBlocks:
- "123.120.234.15/24"
这种方法通过配置 Istio 的入口网关授权策略,可以有效地实现基于源 IP 的访问控制。它允许管理员根据不同的需求(如屏蔽特定 IP 或信任最终客户端 IP)灵活设定规则,从而增强了服务的安全性和灵活性。
要在 Istio 中根据源 IP 地址配置负载均衡策略,你需要使用 DestinationRule
资源,并指定 LOAD_BALANCER_POLICY_CONSISTENT_HASH
策略。这种策略允许您根据一致性哈希算法为流量分配目标,可以基于源 IP 地址来实现会话亲和性(session affinity),确保来自同一源 IP 的请求被路由到相同的目标。
下面是一个示例配置,展示了如何使用 DestinationRule
来根据源 IP 地址实现负载均衡:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: example-destination-rule
spec:
host: example-service
trafficPolicy:
loadBalancer:
consistentHash:
httpHeaderName: x-forwarded-for # 这通常包含源 IP 地址,适用于经过代理或负载均衡器转发的流量。
注意,如果直接连接到 Istio Ingress Gateway 而不经过其他代理,你可能需要根据实际情况调整 httpHeaderName
或使用其他哈希键,例如 useSourceIp
,如下所示:
spec:
trafficPolicy:
loadBalancer:
consistentHash:
useSourceIp: true
x-forwarded-for
头或其他相应机制能准确反映原始的客户端 IP。X-Forwarded-For
头部来处理 HTTP 请求中的客户端源 IP。externalTrafficPolicy
和选择合适的流量劫持方式(REDIRECT
或 TPROXY
),可以在南北向和东西向流量中正确获取客户端源 IP。numTrustedProxies
配置是关键。2024-01-03 11:27:49
在这篇博客中我将指导你如何安装 TIS 并启用监控插件。
Tetrate Istio Subscription(TIS)是由 Tetrate 提供的企业级、全面支持的产品,提供了经过全面测试且适用于所有主要云平台的 Istio 版本。TIS 基于开源的 Tetrate Istio Distro 项目,增加了对这些构建版本的全面高级支持,并可选提供 FIPS 验证的加密模块。此外,TIS 包含一系列经过测试和支持的 Add-Ons 和 Integrations,使得 Istio 的功能扩展和与常用基础设施工具的集成变得简单安全。
TIS 不是 Istio 的一个分支,而是提供针对特定环境进行测试的上游发行版。我们对 Istio 所做的任何增强都会应用于上游。TIS 与普通的 Istio 相比有以下关键优势:
想要了解 TIS 的更多信息请访问:https://docs.tetrate.io/istio-subscription/
在安装 TIS 及其插件前,你需要准备:
首先使用下面的命令查看 TIS 支持的 Istio 版本:
helm search repo tetratelabs/base --versions
NAME CHART VERSION APP VERSION DESCRIPTION
tetratelabs/base 1.20.1+tetrate0 1.20.1-tetrate0 Helm chart for deploying Istio cluster resource...
tetratelabs/base 1.20.0+tetrate0 1.20.0-tetrate0 Helm chart for deploying Istio cluster resource...
tetratelabs/base 1.19.5+tetrate0 1.19.5-tetrate0 Helm chart for deploying Istio cluster resource...
tetratelabs/base 1.19.4+tetrate0 1.19.4-tetrate0 Helm chart for deploying Istio cluster resource...
tetratelabs/base 1.19.3+tetrate0 1.19.3-tetrate0 Helm chart for deploying Istio cluster resource...
tetratelabs/base 1.18.6+tetrate0 1.18.6-tetrate0 Helm chart for deploying Istio cluster resource...
tetratelabs/base 1.18.5+tetrate0 1.18.5-tetrate0 Helm chart for deploying Istio cluster resource...
tetratelabs/base 1.18.3+tetrate0 1.18.3-tetrate0 Helm chart for deploying Istio cluster resource...
tetratelabs/base 1.17.8+tetrate0 1.17.8-tetrate0 Helm chart for deploying Istio cluster resource...
tetratelabs/base 1.17.6+tetrate0 1.17.6-tetrate0 Helm chart for deploying Istio cluster resource...
tetratelabs/base 1.16.7+tetrate0 1.16.7-tetrate0 Helm chart for deploying Istio cluster resource...
tetratelabs/base 1.16.6+tetrate0 1.16.6-tetrate0 Helm chart for deploying Istio cluster resource...
我们将安装当前最新的 Istio 1.20.1 版本。
export TIS_USER=<tis_username>
export TIS_PASS=<tis-password>
# Helm chart version
export VERSION=1.20.1+tetrate0
# Image tag
export TAG=1.20.1-tetrate0
kubectl create namespace istio-system
kubectl create secret docker-registry tetrate-tis-creds \
--docker-server="addon-containers.istio.tetratelabs.com" \
--docker-username=${TIS_USER} \
--docker-password=${TIS_PASS} \
-n istio-system
# Install Istio
helm install istio-base tetratelabs/base -n istio-system \
--set global.tag=${TAG} \
--set global.hub="addon-containers.istio.tetratelabs.com" \
--set "global.imagePullSecrets[0]=tetrate-tis-creds" \
--version ${VERSION}
helm install istiod tetratelabs/istiod -n istio-system \
--set global.tag=${TAG} \
--set global.hub="addon-containers.istio.tetratelabs.com" \
--set "global.imagePullSecrets[0]=tetrate-tis-creds" \
--version ${VERSION} \
--wait
# install ingress Gateway
kubectl create namespace istio-ingress
kubectl create secret docker-registry tetrate-tis-creds \
--docker-server="addon-containers.istio.tetratelabs.com" \
--docker-username=${TIS_USER} \
--docker-password=${TIS_PASS} \
-n istio-ingress
helm install istio-ingress tetratelabs/istio-ingress -n istio-ingress \
--set global.tag=${TAG} \
--set global.hub="addon-containers.istio.tetratelabs.com" \
--set "global.imagePullSecrets[0]=tetrate-tis-creds" \
--version ${VERSION} \
--wait
# Install TIS addon
helm install istio-monitoring-demo tis-addons/istio-monitoring-demo --namespace tis --create-namespace
端口转发 Grafana 服务,然后在本地浏览器中打开 Grafana:http://localhost:3000
kubectl port-forward --namespace tis svc/grafana 3000:3000
注意:请保持该命令持续运行,因为我们在向 Grafana 导入 dashboard 时还需要访问该端口。
使用默认的用户名密码 admin/admin
登录后,在左侧导航栏中选择 Administration - Service accounts,参考 Grafana 文档上的说明创建一个 admin 权限的 Service account。
记下这个 Token,我们将在下面的操作中用到。
使用 Terraform 向 Grafana 中导入 dashboard:
cat>~/.terraformrc<<EOF
credentials "terraform.cloudsmith.io" {
token = "tetrate/tis-containers/kuhb8CPZhaOiR3v6"
}
EOF
# Create a terraform module file
cat>istio-monitoring-grafana.tf<<EOF
module "istio_monitoring_grafana" {
source = "terraform.cloudsmith.io/tis-containers/istio-monitoring-grafana/tetrate"
version = "v0.2.0"
gf_url = "<http://localhost:3000>"
gf_auth = "<grafana_token>"
}
EOF
# Run the commands
terraform init
terraform plan
terraform apply -auto-approve
恭喜你现在已经成功的向 Grafana 中导入了以下四个 dashboard:
但是现在有些 dashboard 还没有数据,我们需要在网格中制造一些流量。
部署 Bookinfo 应用和入口网关:
kubectl create secret docker-registry tetrate-tis-creds \
--docker-server="addon-containers.istio.tetratelabs.com" \
--docker-username=${TIS_USER} \
--docker-password=${TIS_PASS} \
-n default
kubectl label namespace default istio-injection=enabled
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n default
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -n default
获取入口网关的 IP 并发送一些流量:
export GATEWAY_IP=$(kubectl -n istio-ingress get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
for i in $(seq 1 100);do curl http://$GATEWAY_IP/productpage ; sleep 3;done
现在访问 Grafana dashboard,你可以看到监控数据了。
除此之外,在导入了这些 dashboard 的同时,我们还导入了以下警报规则:
你也可以在 Grafana 中定义警报规则,比如整合 Telegram 或 Slack 来发送通知。
运行下面的命令清理 Bookinfo 应用和 TIS:
kubectl delete -f samples/bookinfo/platform/kube/bookinfo.yaml -n default
kubectl delete -f samples/bookinfo/networking/bookinfo-gateway.yaml -n default
helm uninstall istio-ingress -n istio-ingress
helm uninstall istio-monitoring-demo -n tis
helm uninstall istiod -n istio-system
helm uninstall istio-base -n istio-system
kubectl delete namespace tis
kubectl delete namespace istio-ingress
kubectl delete namespace istio-system
通过执行这些步骤,您已经使用 TIS 成功地在 Istio 中设置和测试了监视。在 Istio 环境中享受增强监控的见解和优势!
2023-12-27 11:27:49
我经常在 Istio 的 GitHub Discussions 上回答网友的问题,最近我遇到了一个关于 Istio 主 - 远程部署的讨论,问题是关于远程集群中网关如何最初验证到外部 Istiod 实例的。这个问题触及到服务网格在多集群配置中的核心安全机制,我认为这值得在社区中进行更深入的分享。
在 Istio 官方的不同网络上安装 Primary-Remote文档中,有一个步骤是将 cluster2 作为 cluster1 的远程集群进行附加。这个过程中会创建一个包含 kubeconfig 配置的 Secret,这个配置文件中含有访问远程集群(cluster2)所需的证书和令牌。
# 这个文件是自动生成的,请不要编辑。
apiVersion: v1
kind: Secret
metadata:
annotations:
networking.istio.io/cluster: cluster2
creationTimestamp: null
labels:
istio/multiCluster: "true"
name: istio-remote-secret-cluster2
namespace: istio-system
stringData:
cluster2: |
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: {CERTIFICATE}
server: {CLUSTER2-APISERVER-ADDRESS}
name: cluster2
contexts:
- context:
cluster: cluster2
user: cluster2
name: cluster2
current-context: cluster2
kind: Config
preferences: {}
users:
- name: cluster2
user:
token: {TOKEN}
这个 Secret 的关键作用是让主集群(cluster1)中的 Istio 能够访问远程集群的 API 服务器,从而获得服务信息。此外,远程集群(cluster2)中的 Istiod 服务,通过端点指向主集群中 Istiod 服务的 LoadBalancer IP(端口 15012 和 15017),使得 cluster2 能够通过 Istiod 与主集群进行通信。
因为这两个集群共用一个 CA(由主集群提供),并且远程集群能够访问自己的 API 服务器,所以主集群中的 Istiod 可以验证来自远程集群(cluster2)的请求。下面的序列图清晰地展示了这一过程:
这一过程是 Istio 多集群配置中的关键一环,确保了服务网格中跨集群通信的安全性。正如我们在这次讨论中看到的,无论是远程网关还是服务都依赖于主集群的 CA 来进行初始的 mTLS 认证,这为整个服务网格的安全通信提供了坚实的基础。
在本篇博客中,我们探讨了在 Istio 主 - 远程部署中,远程集群的网关如何进行初始验证以连接到外部的 Istiod。我们解释了如何通过创建一个含有 kubeconfig 的 Secret 来允许主集群的 Istio 访问远程集群的 API,以及如何通过共享的 CA 和服务账户令牌来确保 mTLS 认证的安全性。这一过程确保了服务网格中的跨集群通信的安全,为理解和实施 Istio 的多集群配置提供了重要的见解。
2023-12-06 10:43:27
在上一篇博客中,我向大家介绍了我开发的Istio Advisor Plus GPT。但是,要使用这个工具,需要满足一个前提条件,即您必须已经订阅了 ChatGPT Plus。对于很多中国用户来说,注册 ChatGPT 账户可能已经费了不少力气,但是在订阅 ChatGPT Plus 时可能会遇到一些困难。在这篇文章中,我将指导您如何通过正规渠道、无需使用国外信用卡,也无需虚拟信用卡来成功订阅和续费 ChatGPT Plus。
答案其实很简单,首先您需要拥有一个美国地区的 Apple ID。然后,您可以前往 https://shop.pockyt.io/ 这个网站购买App Store & iTunes礼品卡,您可以选择礼品卡的金额,范围从 2 美元到 500 美元不等。接下来,您可以使用支付宝进行支付。您也可以直接在您自己的支付宝中将地区设置为美国,然后搜索礼品卡,即可找到购买链接。我为了方便起见,选择在网站上直接购买。购买完成后,您将收到礼品卡代码,登录您的美国地区的 Apple Store 账户后,即可兑换礼品卡。
通过这种方式,您可以轻松订阅 ChatGPT Plus,无需繁琐的操作,同时也避免了使用国外信用卡或虚拟信用卡的麻烦。这是一个简单而有效的方法,让更多人能够享受 ChatGPT Plus 的服务。
2023-11-25 08:43:27
大家好,今天我要向你们隆重介绍一位特别的“老中医” —— Istio Advisor Plus GPT(以下简称“Istio 老中医”)。不要误会,他不是给人看病的,而是专治您在 Istio 这个“网络世界”中遇到的各种疑难杂症!
“老中医”来自于 OpenAI 最近推出的一项革命性技术 —— GPT。这个技术简直是黑科技,能让你不用写一行代码就能创建自定义的 GPT 模型。想象一下,只需几次点击,就能得到专门解答 Istio 问题的智能助手!而且,不久后 GPT Store 就要上线,届时你将能看到更多像“老中医”这样的高手。
我准备了一个视频,展示“老中医”在实战中的表现。例如拿一个 Istio 的 GitHub Issue 问他,看看他会给你开什么样的处方?
你可以在 Github 获取导出 GitHub Issue 的代码。
解释 Istio 概念和特性:从流量管理到安全性,再到可观测性,无所不知,无所不能。
指导配置:无论您需要怎样的配置建议,“老中医”总有办法。
诊断和解决问题:遇到棘手的问题?不用怕,“老中医”在此。
性能优化建议:让您的 Istio 运行得更加流畅,更加高效。
安全最佳实践:零信任安全原则在此不再是难题。
可视化表示:用图表展示复杂的网络,让一切变得易懂。
协助升级:升级 Istio 就像喝水一样简单。
Bug 报告指导:遇到 bug?“老中医”帮您梳理、上报。
参考相关文档:针对复杂问题,提供深度资料。
生态系统工具建议:让您在 Istio 生态中如鱼得水。
Istio 基础:基础知识一应俱全。
Envoy 代理:深入探索 Envoy 的奥秘。
服务网格概念:掌握服务网格的本质。
Tetrate 文档:了解 Tetrate 的一切。
零信任安全:安全问题,轻松解决。
SkyWalking 集成:深入了解 APM 系统。
Envoy 网关:流量管理和安全性的高手。
用例和案例研究:实际应用,一目了然。
TLDR:简洁明了,一目了然。
查询的解释:提供广泛的上下文。
详细答案:深入浅出,条理清晰。
实际示例:实操演示,直观易懂。
建议的下一步操作:明确指引,方便操作。
参考资料:海量资源,随手可得。
虽然“老中医”很厉害,但也有局限。比如,要使用它,您需要有 ChatGPT Plus 订阅。而且,当回答太长时,可能需要分多次提问。还有,目前可能存在一些隐私问题,所以建议暂时只用公开数据。
综上所述,Istio 老中医是您在 Istio 世界旅行的必备良伴。无论是丰富的知识库、定制的回应,还是实际的指导,它都能帮您轻松驾驭 Istio 的复杂世界。所以,一起来尝试一下吧,和 Istio 老中医一起探索无限可能!
2023-11-10 14:27:49
随着 Kubernetes 不断演进,Istio 功能逐渐在 Kubernetes 中找到对应实现,如 Sidecar 容器、Gateway API 以及本文的主题 ExternalName。ExternalName 和 ServiceEntry 都能起到引入 Kubernetes 集群外部服务的作用,但是它们的功能和使用场景也有所区别,本文将为你详细解析。
下表从多个方面对比了 ExternalName
和 ServiceEntry
:
特性/用例 | ExternalName | ServiceEntry |
---|---|---|
流量控制 | 有限,仅支持 TCP 和 UDP | 更灵活,支持 TCP、UDP、HTTP 等多种协议,可以指定端口、TLS 等选项 |
服务发现 | 适用于外部服务的简单别名 | 适用于描述网格内外服务,包括外部和内部服务的详细配置 |
配置复杂性 | 简单,适用于基本的服务发现需求 | 较复杂,适用于需要高级流量控制和详细配置的场景 |
TLS 支持 | 有限,较简单 | 更丰富的 TLS 支持,可以指定证书等详细选项 |
安全性 | 较基本,适用于简单的用例 | 更强大的安全性支持,可以定义 subjectAltNames 等选项 |
用途 | 适用于简单的外部服务别名 | 适用于复杂的流量管理和服务发现需求,尤其是在多协议和复杂网络拓扑中 |
ExternalName 的使用情况:
ExternalName
。ExternalName
。ServiceEntry 的使用情况:
ServiceEntry
。ServiceEntry
更适合。subjectAltNames
等,需使用 ServiceEntry
。在 Istio 1.20 以前,网格内存在 ExternalName 类型的 Service 时,若该 Service 的端口与其他外部服务的端口重叠,流量可能错误路由到该 ExternalName Service。该问题已在 Istio 1.20 版本中解决,详见 Better support ExternalName #37331。
在服务网格的选择中,ExternalName 和 ServiceEntry 分别提供了简单的服务别名和更复杂的流量管理与服务发现选项。ExternalName 适用于简单的外部服务别名,而 ServiceEntry 在处理复杂流量控制和网格内外服务时更具优势。在实际应用中,根据具体需求和配置的复杂性权衡,灵活选择合适的机制。随着 Istio 和 Kubernetes 的不断演进,这些功能的使用方式可能会受到影响,因此保持关注相关社区的更新和最佳实践是保持系统健康和高效运行的关键。选择合适的服务网格组件将有助于构建可靠、安全且高度可扩展的微服务架构。
2023-11-10 06:27:49
Istio 1.20 代表了 Istio 服务网格能力的显著进步,为运维人员和开发人员提供了更好的体验。这个新版本引入了一些关键的功能和更新,将影响到服务网格架构的设计和实施。
Istio 1.20 全面支持 Kubernetes Gateway API,并已正式发布(GA)。这标志着服务网格生态系统的重大进步,为用户提供了一组稳定且丰富的网络 API,与 Kubernetes 的核心服务相一致。Istio 对 Gateway API 的支持是实现更无缝和灵活的流量管理的重要一步,使用户能够利用一致的声明方式定义在 Kubernetes 集群内如何路由流量。如果你想了解更多关于 Gateway API 的信息,可以阅读我的博客 Istio 1.19 有哪些更新:Gateway API 还有更多。
在服务发现领域,Istio 1.20 对于ExternalName
服务的处理进行了重要更新(见 Better support ExternalName #37331),使得 Istio 的行为更加符合 Kubernetes 的行为。这个变化简化了配置,并使得 Istio 能够更好地处理 DNS,对于依赖于外部终点的服务至关重要。关于 ExternalName 服务的更多信息,你可以参考 Kubernetes 官方文档。
ExternalName
和 Istio 中的 ServiceEntry
都可以用于处理服务发现,特别是引入 Kubernetes 集群之外的服务,但有一些关键区别:
ExternalName
是 Kubernetes 的原生 Service 类型,相当于给集群外部服务这设置了一个别名,使得外部服务在 Kubernetes 内部的表现与原生 Service 保持一致,从而可以统一管理和使用内部和外部服务。你可以先定义 ExternalName
类型的服务,如果后来你决定将服务移到集群中,则可以启动其 Pod,添加适当的选择算符或端点并更改服务的类型。使用时需要注意不要在多个命名空间中使用相同的 ExternalName
,可能会引起命名冲突或混淆。ServiceEntry
是 Istio 特有的配置对象,它提供了更灵活的控制,可以描述网格内或网格外的服务,以及指定特定的协议、端口等属性。例如,可以使用ServiceEntry
将网格内服务访问网格外的服务,或者定义自定义的服务入口点。一致的 Envoy 过滤器排序: 在新版本中,Envoy 过滤器的排序在所有流量方向和协议上变得一致了。这确保了过滤器的统一应用,对于服务网格的可预测行为和安全性至关重要。
网络 Wasm 插件扩展: Istio 继续通过引入新的NETWORK
类型扩展网络 Wasm 插件的支持,推动了可扩展性的边界。这个扩展巩固了 Istio 作为服务网格创新领域的领导地位,为用户提供了更多的控制和定制选项。
TCP 元数据交换增强: Istio 1.20 中的两个更新旨在改进 TCP 元数据交换:回退元数据发现过程和控制 ALPN 令牌的能力。这些改进显示了 Istio 对强大高效的网络的承诺。
流量镜像到多个目的地: 新版本扩展了 Istio 的流量镜像功能以支持多个目的地。这个功能对于调试和监控非常宝贵,可以提供关于跨不同服务版本或配置的流量行为的见解。
可插拔的根证书轮换: 加强了安全性,Istio 现在支持可插拔的根证书轮换,增强了服务网格在使用更新的加密凭证时保持服务间信任的能力。
Sidecar 容器中的 StartupProbe: 为了改善启动时间,Istio 在 Sidecar 容器中引入了startupProbe
,它可以在初始阶段进行积极的轮询,而不会在整个 Pod 的生命周期中持续存在。
OpenShift 安装增强: 通过去除某些特权要求,Istio 简化了在 OpenShift 上的安装过程,从而降低了 OpenShift 用户的使用门槛。
在 Istio 1.20 中的这些功能和增强将简化运维操作,加强安全性,并提供更具动态和可定制的服务网格体验。随着服务网格领域的不断发展,Istio 的最新版本证明了社区对改进和创新的不懈追求。
2023-11-09 17:10:49
上周 Kubernetes Gateway API 的正式发布公告标志着 Kubernetes 生态系统内 Gateway 能力的重要里程碑。与此同时,Kubernetes 社区一致认同Backstage是内部开发平台和门户的领先解决方案。Kubernetes Gateway API 和 Backstage 都从一开始就鼓励社区的可扩展性。可以说 API Gateway 的出现为增强 Kubernetes 网络提供了巨大的机会。
不过也有人对 Gateway API 与 Istio 服务网格的关系存在疑问。对于 Gateway API 和 Istio 服务网格,两者都是为了解决 Kubernetes 网络中的问题。然而,Gateway API 着重于提供一种标准化和简化的方式来配置和部署 Ingress 和 Egress,是一个更加通用的 API。另一方面,Istio 服务网格更关注于服务到服务的通信,提供丰富的流量管理,安全,策略和遥测功能。
Kubernetes Gateway API 代表了 API Gateway 的关键基础,引入了一种标准,基于角色的,高度适应性的方法来配置和部署 Gateway。Kubernetes Gateway API 相比现有的 Kubernetes Ingress 的显著改进之一是其基于角色的 API 结构。这使得基础设施,平台和应用程序领域的各种角色能够拥有直接与他们的用例相关的 API 的各个方面。Gateway API 的另一个关键特性是其针对可扩展性的设计 - API 专注于核心 Gateway 和路由用例,具有扩展附加能力的可能性,例如安全性,速率限制和转换。
Backstage 是一个开源的开发者平台,它集成了所有开发者需要的服务,提供了一个统一的视图。这包括版本控制系统、持续集成/持续部署(CI/CD)系统、监控、日志、警报和文档。它旨在让开发者更高效地进行日常任务,而无需在多个工具之间切换,它也可以帮助开发者更好地理解和管理他们的软件。
Backstage 可以应用在多种使用场景中:
Backstage 通过其软件目录用于发现 API,软件模板用于提供带有防护栏的自动 API 上线流程,以及Tech Docs用于提供 API 文档的中心用例,用于围绕 API Gateway 的协作。
Backstage 的目标是简化开发者工作流程,提供一站式的解决方案,它使开发者能够在一个平台上查找他们需要的所有信息,而不是在多个工具间切换。此外,Backstage 可以让开发团队专注于编码,而不是管理工具。它还支持多种插件,可以根据团队的需求进行定制。
Backstage 和 Kubernetes Gateway API 已经牢固地将自己建立为云原生 API Gateway 的基础支柱,两个项目都在各自的路线图中充满创新。其中最有趣的领域是 Kubernetes Gateway API 超越其传统的南北入口能力,包括东西服务至服务通信,通过引入GAMMA API。在真实的流量在每个方向上流动的情况下,为南北和东西流量提供单一基础将有助于提高任何容器化应用的安全性,弹性和可观测性。
2023-11-09 16:27:49
我很高兴呈现 Istio 的最新版本— Istio 1.19。这篇博客将概述此版本中的更新内容。
我们的前一篇博客强调了 Gateway API 将 Kubernetes 和服务网格中的入口网关统一的潜力,为跨命名空间的流量支持打开了大门。有了 Istio 的官方支持,Gateway API 成为了焦点。它不仅用于北 - 南流量(网格的入口和出口),现在还扩展到东 - 西流量的领域,也就是网格内部的流量。
在 Kubernetes 中,服务承担多项职责,从服务发现和 DNS 到工作负载选择、路由和负载均衡。然而,对这些功能的控制一直有限,工作负载选择是显著的例外。Gateway API 改变了这一局面,让你可以控制服务路由。这与 Istio 的 VirtualService 有一些重叠,因为两者都对流量路由有影响。以下是三种情况的简介:
Gateway API 与 Istio 的这种动态结合不仅精细化了服务网络,也巩固了 Istio 在 Kubernetes 生态系统中的地位。
在当前的实验阶段(v0.8.0 版本),服务网格的 Gateway API 引入了一种新的方法来配置 Kubernetes 中的服务网格支持。它直接将单个路由资源(如 HTTPRoute)与服务资源关联起来,简化了配置过程。
以下是一些关键点:
实验阶段:在 v0.8.0 版本中,服务网格的 Gateway API 仍处于实验阶段。建议不要在生产环境中使用。
服务与路由关联:在配置服务网格时,与使用 Gateway 和 GatewayClass 资源不同,单个路由资源直接与服务资源关联。
服务的前端和后端:服务的前端包括其名称和集群 IP,后端由其端点 IP 的集合组成。这种区分使得在网格内进行路由无需引入冗余资源。
路由附加到服务:将路由附加到服务上以将配置应用到指向该服务的任何流量。如果没有附加路由,流量会遵循网格的默认行为。
命名空间关系:
组合路由:在单个命名空间中的同一服务的多个路由,无论是生产者路由还是消费者路由,都将根据 Gateway API 路由合并规则进行合并。这意味着在同一命名空间中为多个消费者定义不同的消费者路由是不可能的。
请求流程:
请记住,在实验阶段,服务网格的 Gateway API 可能会有更多的变化,不建议在生产环境中使用。
但等等,还有更多!我们的旅程并没有结束 - 使用 API 的入口流量支持正快速向通用可用性 (GA) 进发,预计还会有更多动态的发展!
让我们进一步探讨这个版本中的其他增强功能。
Istio 团队一直在不断优化 ambient mesh,这是一种创新的部署模型,提供了一个替代传统 sidecar 方法的选择。如果你还没有探索 ambient,现在是深入了解介绍博客的好时机。
在这次更新中,我们强化了对ServiceEntry
、WorkloadEntry
、PeerAuthentication
以及 DNS 代理的支持。并且,修复了一些 bug,增强了可靠性,以确保无缝的体验。
请记住,ambient mesh 在这个版本中处于 alpha 阶段。Istio 社区热切期待你的反馈,以推动它向 Beta 阶段前进。
简单易用是关键,特别是在处理虚拟机和多集群设置的时候。在这个版本中,我们在WorkloadEntry
资源中使地址字段变为可选。这个看似小小的调整将大大简化你的工作流程。
你现在可以为你的 Istio 入口网关的 TLS 设置配置OPTIONAL_MUTUAL
,提供可选的客户端证书验证的灵活性。此外,你可以通过MeshConfig
微调你偏好的非 Istio mTLS 流量使用的密码套件。
有了这些更新,Istio 1.19 赋予你在管理你的服务网格时更大的控制、灵活性和安全性。
欢迎你探索这些增强功能,并与 Istio 社区分享你的体验。更多详细信息,请参考官方发布说明。
祝你网格愉快!
本博客最初在tetrate.io上发布。
2023-11-08 11:27:49
云计算专业人士,自 Istio Certified Associate (ICA) 认证 旅程开始已经一个月了。这是云原生计算基金会(CNCF)、Linux 基金会培训与认证以及 Tetrate 合作的成果,为微服务管理设立了新的标杆。
Tetrate 是 Istio 项目的关键贡献者,最初创建了 Tetrate 认证的 Istio 管理员(CIAT),为 ICA 认证奠定了基础。自从推出以来,ICA 已成为 Kubernetes 生态系统的重要组成部分,帮助数千人掌握服务网格技术。
认证课程涵盖了诸如安装、流量管理和安全等基本领域,反映出该领域所需的全面专业知识。在短短时间内,ICA 获得了显著动力,得益于 Tetrate 对云原生领域的愿景和投入。
在 ICA 成立一个月之际,Tetrate 继续通过其 Tetrate Academy 承诺开源教育,提供有关服务网格和 Kubernetes 安全的免费、高质量课程。对于那些打算在生产中部署 Istio 的人来说,Tetrate 提供了Tetrate Istio Distribution (TID),一种安全且得到支持的 Istio 发行版。
如果您还没有加入,现在是时候加入这个不断增长的 Istio 专家社区了。提升您的职业生涯,为云原生技术的演进做出贡献。
ICA 是专为工程师,CI/CD 从业者或任何对 Istio 有特殊兴趣的人设计的专业前认证。
获得认证的 ICA 学员可确认他们对 Istio 原则、术语和最佳实践的基础知识,并展示他们建立 Istio 的能力。
ICA 认证考试展示了考生对 Istio 原则、术语和建立 Istio 的最佳实践的深入理解。
ICA 认证考试包括这些一般领域及其在考试中的权重:
详细内容如下:
安装、升级和配置:7%
流量管理:40%
弹性和故障注入:20%
固定工作负载:20%
高级场景:13%
这只是一个开始。让我们期待在服务网格熟练度上达到更多里程碑,由 Tetrate 和 CNCF 引领潮流。
注:ICA 认证提供中文认证考试,证书有效期 3 年。
2023-10-21 10:18:40
云原生应用的发展导致开发左移,应用迭代频率更高,这就催生了 GitOps 的需求。本文将介绍如何使用 Argo 项目,包括 ArgoCD 和 Argo Rollouts,通过 Istio 实现 GitOps 和金丝雀部署。文中还有一个演示,展示了如何基于 Tetrate Service Express(也适用于 Tetrate Service Bridge)提供的 Istio 环境实现 GitOps。
本文 demo 的部署架构图如图 1 所示。如果您已经熟悉本文介绍的部署策略和 Argo 项目,可以直接跳到 demo 部分。
首先,我想简单介绍一下 Argo Rollouts 支持的两种部署策略,可以实现零停机部署。
蓝绿部署和金丝雀部署的步骤如图 2 所示。
蓝绿部署和金丝雀部署的主要区别在于部署方式和变更规模。蓝绿部署是将整个应用部署在新的环境中,然后进行切换,适合大规模的变更,比如整个应用的重大升级。金丝雀部署逐渐引入新版本或功能,适合小规模更改,例如添加或修改单个功能。
从应用场景来看,蓝绿部署适合对高可用、零宕机部署要求较高的系统。在部署大规模变更时,蓝绿部署可以保证稳定性和可靠性,并且可以快速回滚以应对突发情况。金丝雀部署适合需要快速验证新功能或版本的系统。通过逐步引入变更,可以及早发现问题并进行调整,尽量减少对用户的影响。
在 Kubernetes 中,Deployment 资源对象是管理应用程序部署和更新的主要工具之一。部署提供了一种声明式方式来定义应用程序的预期状态,并通过控制器的功能实现发布策略。Deployment 的架构如图 3 所示,其中彩色方块代表不同版本的 Pod。
发布策略可以在 Deployment 的 spec 字段中配置。以下是一些常见的发布策略选项:
spec.replicas
字段来指定所需的副本数量。在发布过程中,Kubernetes 控制器保证新版本 ReplicaSet 的副本数量在创建时逐渐增加,旧版本 ReplicaSet 的副本数量在删除时逐渐减少,实现平滑切换。spec.strategy.type
字段来选择。常见政策包括:
RollingUpdate
:默认策略以一定的时间间隔逐渐更新副本。不同时可用的副本数量以及额外可用的副本数量可以通过设置 spec.strategy.rollingUpdate.maxUnavailable
和 spec.strategy.rollingUpdate.maxSurge
字段来控制。ReCreate
:该策略在更新过程中首先删除旧版本的所有副本,然后创建新版本的副本。此策略将导致应用程序在更新期间暂时不可用。spec.template.metadata.labels
字段为每个版本的 ReplicaSet 设置标签,以便控制器准确跟踪和管理。这样 ReplicaSet 的多个版本可以共存,并且可以精确控制每个版本的副本数量。通过使用这些配置选项,Deployment 可以实现不同的发布策略。更新 Deployment 对象的 spec 字段可以触发新版本的发布。Kubernetes 控制器会根据指定的策略自动处理副本的创建、更新和删除,以实现平滑的应用更新和部署策略。
可以使用 Deployment 来手动管理发布策略,但要实现自动化,我们还需要使用 ArgoCD 等 GitOps 工具。
ArgoCD 是一个基于 GitOps 的持续交付工具,用于自动化和管理 Kubernetes 应用程序的部署。它为提高应用程序部署的效率和可靠性提供了一些关键的帮助。
以下是 ArgoCD 为 Kubernetes 应用程序部署提供的一些帮助:
与 Deployment 资源对象相比,ArgoCD 提供了更高级的功能和工作流程,补充了原生 Kubernetes 资源对象的功能:
基于 GitOps 的配置管理:ArgoCD 将应用程序配置存储在 Git 存储库中,从而实现基于 GitOps 的配置管理。这种方法确保配置更改是可跟踪、可审计的,并且可以与现有的 CI/CD 管道集成。
自动化部署和持续交付:ArgoCD 可以自动检测 Git 存储库中的配置更改并将应用程序部署到 Kubernetes 环境,从而实现自动化部署和持续交付。
状态管理和自动恢复:ArgoCD 持续监控应用程序的状态并将其与预期状态进行比较。如果检测到不一致,它会自动恢复并确保应用程序状态与预期状态保持一致。
虽然 ArgoCD 可以实现 GitOps,但它本质上是在 Kubernetes 部署上运行并通过副本数量控制流量路由。为了实现细粒度的流量路由,使用了 Istio 等服务网格。
Istio 通过以下方法实现更细粒度的流量路由和应用发布:
VirtualService:Istio 使用 VirtualService 来定义流量路由规则。通过配置 VirtualService,可以根据请求头、路径、权重等请求属性对流量进行路由和分发,将请求定向到不同的服务实例或版本。
DestinationRule:Istio 的 DestinationRule 用于定义服务版本策略和负载均衡设置。通过指定不同版本服务实例之间不同的流量权重,可以实现金丝雀发布、蓝绿部署等高级应用发布策略。
流量控制和策略:Istio 提供了丰富的流量控制和策略能力,如流量限制、故障注入、超时设置、重试机制等,这些功能帮助应用程序实现更高级别的负载均衡、容错和可靠性要求。
与 ArgoCD 和 Kubernetes Deployment 对象相比,Istio 在应用部署方面提供了以下优势:
细粒度的流量路由控制:Istio 提供了更丰富的流量路由能力,可以根据多种请求属性进行灵活的路由和分发,从而实现更细粒度的流量控制和管理。
高级发布策略支持:Istio 的 DestinationRule 可以指定不同版本服务实例之间的流量权重,支持金丝雀发布、蓝绿部署等高级应用发布策略。这使得应用程序的版本管理和发布更加灵活可控。
强大的流量控制和策略能力:Istio 提供了丰富的流量控制和策略能力,如流量限制、故障注入、超时设置、重试机制等,这些功能帮助应用程序实现更高级别的负载均衡、容错和可靠性要求。
将 Istio 与 Argo Rollouts 相结合,可以充分发挥 Istio 细粒度流量路由的优势。现在让我们一起进行演示。在我们的演示中,我们将使用 TSE 提供的 Kubernetes 和 Istio 环境,使用 ArgoCD 实现 GitOps,并使用 Argo Rollouts 实现金丝雀发布。
我们的演示中使用的软件版本是:
我们将使用 Istio 的 VirtualService 和 DestinationRule 来实现基于 Subset 的流量分组路由,并使用 ArgoCD Rollouts 进行渐进式发布。
我提前创建了一个 Kubernetes 集群并将其添加到 TSE 中,TSE 会自动为集群安装 Istio 控制平面。我们还需要安装 ArgoCD 和 Argo Rollouts:
# Install ArgoCD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Install ArgoCD CLI on macOS
brew install argocd
# Change the service type of argocd-server to LoadBalancer
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
# Get the ArgoCD UI address
ARGOCD_ADDR=$(kubectl get svc argocd-server -n argocd -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
# Login using ArgoCD CLI, see https://argo-cd.readthedocs.io/en/stable/getting_started/#4-login-using-the-cli to get password
argocd login $ARGOCD_ADDR --skip-test-tls --grpc-web --insecure
# Install Argo Rollouts
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/download/latest/install.yaml
# Install rollouts plugin on macOS
curl -LO https://github.com/argoproj/argo-rollouts/releases/download/v1.5.0/kubectl-argo-rollouts-darwin-amd64
chmod +x ./kubectl-argo-rollouts-darwin-amd64
sudo mv ./kubectl-argo-rollouts-darwin-amd64 /usr/local/bin/kubectl-argo-rollouts
该功能不适用于 TSE Bridge Mode,因此我们将使用 TSE Direct Mode 来实现渐进式发布。
接下来,部署 Rollouts Dashboard:
git clone https://github.com/argoproj/argo-rollouts.git
kustomize build manifests/dashboard-install|kubectl apply -n argo-rollouts -f -
kubectl port-forward svc/argo-rollouts-dashboard -n argo-rollouts 3100:3100
您现在可以通过 https://localhost:3100/rollouts/ 访问 Rollouts 仪表板。
我们已经为 Bookinfo 应用程序准备了配置文件(保存在 tse-gitops-demo 存储库中),您也可以将其 fork 到您自己的帐户并将其替换为您自己的存储库。运行以下命令来部署 Bookinfo 应用程序:
argocd app create bookinfo-app --repo https://github.com/tetrateio/tse-gitops-demo.git --path application --dest-server https://kubernetes.default.svc --dest-namespace bookinfo --sync-policy automated
注意:我们在 reviews
部署中将 replicas
设置为 0
,因为我们将创建 Argo Rollouts 来操纵 reviews
的实例数量服务。如果这里设置为非零正整数,我们将无法实现金丝雀部署。
现在您可以在浏览器中打开 ArgoCD UI,如图 4 所示。
如果您发现应用程序状态不同步,可以运行以下命令或单击 UI 中的 SYNC 按钮。
argocd app sync bookinfo-app
首先,我们使用 Argo CD 创建 Istio 相关的资源对象:
argocd app create bookinfo-tse-conf --repo https://github.com/tetrateio/tse-gitops-demo.git --path argo/tse --dest-server https://kubernetes.default.svc --dest-namespace bookinfo --sync-policy automated --self-heal
# Check the creation status
argocd app get bookinfo-tse-conf
假设我们要发布新版本的 reviews
服务。为了实现零停机更新,我们将使用金丝雀部署,具体步骤如下:
reviews
Deployment 的 replicas
减少为 0;reviews
Deployment 的 Rollout;reviews
服务以实现自动金丝雀部署进度。您可以在 GitHub 上查看本演示中使用的 Rollout 和 AnalysisTemplate 配置。运行以下命令来部署 reivews-rollout
:
argocd app create reviews-rollout --repo https://github.com/tetrateio/tse-gitops-demo.git --path argo/rollout --dest-server https://kubernetes.default.svc --dest-namespace bookinfo --sync-policy automated
注意:我们可以使用 argocd
命令来部署或使用 kubectl apply
。推荐使用 argocd
,因为您可以同时在 ArgoCD UI 和 Argo Rollouts Dashboard 中查看部署状态,并使用 argocd
命令管理部署。
在 Argo Rollouts Dashboard 中查看 reviews
部署的状态,并使用以下命令将流量发送到 reviews
服务一段时间:
export GATEWAY_HOSTNAME=$(kubectl -n bookinfo get service tsb-gateway-bookinfo -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
while 1;do curl -H "Host: bookinfo.tetrate.com" http://$GATEWAY_HOSTNAME/api/v1/products/1/reviews;sleep 3;done
您将在输出中看到来自具有不同 rollouts-pod-template-hash 标签的 pod 的响应,这证明金丝雀部署是有效的。大约 10 分钟后,您看到的 Argo Rollouts 仪表板将如图 5 所示。
从图 5 中我们可以看到金丝雀部署进展顺利,已经到了第三步。这是因为 reviews
服务的 apdex
(应用性能指数)指标正常。您可以使用 Postman 向 SkyWalking 提交 GraphQL 查询来验证这一点,如图 6 所示。
我们构建的 GraphQL 查询语句如下:
query ReadMetricsValues {
readMetricsValues(condition: {
name: "service_apdex", entity: {scope: Service, serviceName: "canary|reviews|bookinfo|cluster-1|-", normal: true}
}, duration: {
start: "2023-07-13 0812",
end: "2023-07-13 0813",
step: MINUTE
}) {
label
values {
values {
id
value
}
}
}
}
该语句从 UTC 2023-07-13 8:12
到 2023 8:13
查询 canary|reviews|bookinfo|cluster-1|-
服务的 apdex
指标,持续两分钟,得到以下结果:
{
"data": {
"readMetricsValues": {
"label": null,
"values": {
"values": [
{
"id": "service_apdex_202307130812_Y2FuYXJ5fHJldmlld3N8Ym9va2luZm98Y2x1c3Rlci0xfC0=.1",
"value": 10000
},
{
"id": "service_apdex_202307130813_Y2FuYXJ5fHJldmlld3N8Ym9va2luZm98Y2x1c3Rlci0xfC0=.1",
"value": 10000
}
]
}
}
}
}
apdex
指标的值大于 9900(AnalysisTemplate 的 successCondition
中配置的阈值),因此 Rollouts 会顺利进行。您还可以在 Argo Rollouts Dashboard 上单击“手动升级”来升级它,或运行以下命令:
kubectl argo rollouts promote reviews-rollout -n bookinf
删除已部署的 ArgoCD 应用程序和 Rollout:
argocd app delete -y reviews-rollout
argocd app delete -y bookinfo-tse-conf
argocd app delete -y bookinfo-app
与 Istio 集成时,Argo Rollouts 支持基于 VirtualService 和 Subset 的流量拆分,如图 7 所示。
下表提供了这两种流量分段方法的详细比较。
类型 | 适用场景 | 资源对象 | 原则 |
---|---|---|---|
主机级流量分割 | 适用于根据主机名访问不同版本的服务; | 2 个服务、1 个虚拟服务、1 个部署; | Rollout 将 rollouts-pod-template-hash 标签注入到 ReplicaSet 中,并通过更新 Service 中的选择器来选择带有这些标签的 pod; |
子集级流量分割 | 适用于根据标签访问不同的服务; | 1 个服务、1 个虚拟服务、1 个目标规则和 1 个转出; | Rollout 将 rollouts-pod-template-hash 标签注入到 ReplicaSet 中,并通过更新 DestinationRule 中的选择器来选择具有这些标签的 pod; |
本演示中使用基于子集的流量分割,Argo 不断推出:
spec.http[].route[].weight
以匹配当前所需的金丝雀权重spec.subsets[].labels
以包含 canary 和稳定 ReplicaSet 的 rollouts-pod-template-hash
标签请访问 Argo Rollouts 文档,了解有关使用 Istio 进行流量管理的详细信息。
本文介绍如何使用 Argo 项目和 Istio 实现 GitOps 和金丝雀部署。首先我们使用 ArgoCD 实现 GitOps,然后使用 Argo Rollout 和 SkyWalking 实现自动化金丝雀发布。从 demo 中我们可以看到 TSE 部署的 Istio 与开源版本完全兼容。TSE 有许多功能值得探索,请访问 Tetrate 网站了解更多信息。
2023-09-07 20:16:49
在之前的博客为什么在使用了 Kubernetes 后你可能还需要 Istio 中提到 Istio 是在 Kubernetes 的基础之上构建起来的,Kubernetes 中的组件 kube-proxy 本身已有负载均衡功能,但是只支持四层流量的负载均衡,而且无法实现服务超时、熔断等高级功能。具体来说,服务网格比起 Kubernetes 新增了以下负载均衡及韧性(Resiliency)特性:
Layer 7 负载均衡:服务网格在应用层(Layer 7)操作和管理流量,可以更细粒度地识别和控制流量。这使得它可以实现更高级的负载均衡策略,如基于 HTTP 请求头、URL 路径、Cookie 等的路由和流量分发。
动态负载均衡:服务网格通常具备自动负载均衡的能力,可以根据后端服务的实时健康状态和性能指标来动态分发流量。这允许它实现智能负载均衡策略,将流量路由到性能最佳的服务实例。
故障检测和自动故障转移:服务网格具备高级的故障检测和自动故障转移功能。它可以检测到后端服务实例的故障,并自动将流量从故障实例转移到健康实例,以确保应用程序的可用性。
A/B 测试和金丝雀发布:服务网格允许实施高级部署策略,如 A/B 测试和金丝雀发布。这些策略允许在不同的服务版本之间动态分配流量,并根据结果进行决策。
熔断和重试:服务网格通常包含熔断和重试机制,以提高应用程序的可用性和稳定性。它可以根据后端服务的性能和可用性情况来自动执行熔断操作,并在必要时重试请求。
全局流量控制:服务网格提供了集中式的流量控制和策略定义,允许对整个服务网格中的流量进行全局管理。这使得实现统一的安全性、监控和策略成为可能。
深度集成的监控和追踪:服务网格通常集成了强大的监控和追踪工具,可以提供有关流量性能和可见性的详细信息,帮助进行故障排除和性能优化。
虽然 Kubernetes 提供了基本的负载均衡能力,但服务网格在其之上构建了更高级的负载均衡和流量管理功能,以满足微服务架构中复杂的需求。
客户端负载均衡和服务端负载均衡是两种不同的负载均衡方法,它们在不同的场景和应用中有各自的优势。以下是对它们的解释,适用的场景,实现案例以及相关的开源项目:
客户端负载均衡(Client-Side Load Balancing)
客户端负载均衡的示意图如图 1 所示。
定义:在客户端负载均衡中,负载均衡决策是由服务的消费者(客户端)来做出的。客户端负载均衡器通常会维护一个服务实例列表,并根据配置和策略选择要发送请求的实例。
适用场景:客户端负载均衡适用于以下情况:
实现案例:常见的实现客户端负载均衡的开源项目包括:
服务端负载均衡(Server-Side Load Balancing)
服务端负载均衡如图 2 所示。
定义:在服务端负载均衡中,负载均衡决策是由服务端的负载均衡器或代理来做出的。客户端只需将请求发送到服务端,然后服务端决定将请求路由到哪个后端服务实例。
适用场景:服务端负载均衡适用于以下情况:
实现案例:常见的实现服务端负载均衡的开源项目包括:
在实际应用中,有时也会将客户端负载均衡和服务端负载均衡结合使用,以满足特定的需求。选择哪种负载均衡方法通常取决于您的架构、部署需求以及性能要求。服务网格(如 Istio)通常使用客户端负载均衡来实现细粒度的流量控制和策略定义,而在云服务提供商中,服务端负载均衡通常用于自动扩展和流量管理。
在服务网格(如 Istio)中,客户端负载均衡通常是通过 Envoy 代理实现的。Envoy 是一个高性能的代理服务器,它可以用于构建服务网格的数据平面,用于处理服务之间的通信。客户端负载均衡是一种在服务消费者(客户端)一侧实现的负载均衡策略,它决定了请求应该如何路由到后端服务实例。
单集群单网络 Istio 服务网格的负载均衡如图 3 所示。
以下是服务网格中如何实现客户端负载均衡的一般流程:
Sidecar 代理: 在服务网格中,每个部署的服务实例通常都与一个 Sidecar 代理(通常是 Envoy)关联。这个 Sidecar 代理位于服务实例旁边,负责处理该服务实例的入站和出站流量。
服务注册与发现: 在服务网格中,服务实例的注册和发现通常由服务注册表(Kubernetes 的服务发现机制)处理。这些注册表维护了服务实例的信息,包括它们的网络地址和健康状态。
客户端负载均衡配置: 在客户端(服务消费者)发送请求时,Sidecar 代理会执行负载均衡策略。这些负载均衡策略通常在服务注册表中获取的服务实例列表上操作。策略可以基于多种因素进行选择,例如权重、健康状态、延迟等。
请求路由: 根据负载均衡策略,Sidecar 代理将请求路由到选择的后端服务实例。这可以包括使用轮询、加权轮询、最少连接等算法来选择目标实例。
通信处理: 一旦选择了目标实例,Sidecar 代理将请求转发给该实例,然后将响应传回给客户端。它还可以处理连接管理、故障检测和自动故障转移等任务。
总之,客户端负载均衡是在服务消费者一侧(通常是 Envoy 代理)实现的负载均衡策略,它使服务网格能够有效地分发流量并处理后端服务实例的故障。这种方式使得负载均衡决策在服务消费者的控制下,并允许更精细的流量控制和策略定义。Envoy 代理是实现客户端负载均衡的关键组件之一,它具有丰富的配置选项,可用于满足不同的负载均衡需求。
在 Istio 的DestinationRule资源中,loadBalancer
部分用于配置负载均衡策略,控制请求如何分发到不同的服务实例或版本,如下图所示。
从图中我们可以看出,Istio 支持三种类型的负载均衡,分别是:
simple
:基于常用负载均衡算法的简单负载均衡consistentHashLB
:基于一致性哈希算法的负载均衡localityLbSetting
:基于地域的本地性负载均衡以下是与负载均衡配置相关的字段的含义:
这些字段允许你根据你的需求选择适当的负载均衡策略,并配置额外的选项,以确保请求按照所需的方式分发到后端服务实例。不同的策略和配置选项可以满足各种负载均衡需求,如性能、可靠性和流量控制。关于这些字段的详细介绍请见 Istio 文档。
正如我在如何理解 Istio 中的 VirtualService 和 DestinationRule这篇文章中所说的,VirtualService
主要用于设置路由规则,而服务弹性(负载均衡、超时、重试、熔断等)需要靠它和 DestinationRule 来共同维持。只有同时部署了以上两种资源,负载均衡才能真正生效。
以下是设置负载均衡的一般步骤:
创建 DestinationRule 资源:首先,你需要创建一个 DestinationRule 资源,该资源定义了服务的流量策略和目标规则。在 DestinationRule 中,你可以指定要设置负载均衡的服务的名称(host)以及负载均衡策略。
以下是一个 DestinationRule 的示例,其中将流量分发到具有标签 “version: v1” 和 “version: v2” 的两个子集中,并使用 ROUND_ROBIN
负载均衡策略:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: my-destination-rule
spec:
host: my-service.example.com
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
应用 DestinationRule:创建 DestinationRule 后,将其应用于要进行负载均衡的服务。这通常可以通过 Istio 的 VirtualService 资源来完成,通过在 VirtualService 中引用 DestinationRule。
以下是一个 VirtualService 示例,将流量引导到名为 “my-destination-rule” 的 DestinationRule:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-virtual-service
spec:
hosts:
- my-service.example.com
http:
- route:
- destination:
host: my-service.example.com
subset: v1
weight: 80
- route:
- destination:
host: my-service.example.com
subset: v2
weight: 20
在上面的示例中,根据权重配置,80% 的流量将路由到子集 v1,而 20% 的流量将路由到子集 v2。
应用配置:最后,将 VirtualService 和 DestinationRule 资源应用到你的 Istio 环境中,以确保负载均衡规则生效。
使用 kubectl 命令将 VirtualService 和 DestinationRule 应用到 Istio 中:
kubectl apply -f your-service.yaml
通过这些步骤,你可以为你的服务设置负载均衡策略,根据需要将流量分发到不同的服务版本或实例,并控制流量的权重。这有助于实现诸如金丝雀发布、A/B 测试和灰度发布等部署策略。请根据你的具体需求和环境调整负载均衡配置。
在 Istio 中,负载均衡和路由是两个不同的概念,它们通常用于控制服务之间的流量和行为,因此通常分别配置在两个不同的资源对象中:DestinationRule
用于负载均衡,VirtualService
用于路由。这种分离的设计有一些优点:
模块化和清晰性: 将负载均衡和路由配置分离成两个资源对象可以使配置更加模块化和清晰。这样,您可以更容易地理解和维护这两个方面的配置,而不会使配置对象过于复杂。
可维护性: 将负载均衡和路由配置分开可以使它们更容易维护和修改,因为它们位于不同的资源对象中。这样,您可以针对不同的需求更改负载均衡策略而不会影响路由规则,反之亦然。
可重用性: 模块化的配置允许您更容易地重用配置片段。您可以在不同的 DestinationRule
或 VirtualService
中使用相同的负载均衡策略或路由规则,以提高配置的可重用性。
精细控制: 分离的配置允许您对每个方面进行更精细的控制。您可以根据需要为每个服务定制不同的路由规则和负载均衡策略,以满足特定的用例和要求。
虽然负载均衡和路由通常是分开配置的,但它们之间仍然存在紧密的关联,因为路由规则决定了请求将如何被路由到后端服务,而负载均衡策略决定了在所选目标服务之间如何分发流量。因此,在 Istio 中,这两个配置对象通常需要协同工作,以实现您的流量管理需求。通过将它们分开配置,使得配置更加清晰和可维护,并允许更灵活地满足不同的需求。
在微服务领域,Istio 已被证明是管理服务通信的无价之宝。虽然它在单集群场景下表现出色,但多集群设置引入了独特的挑战,特别是在负载均衡方面。接下来我们将揭秘 Istio 中的多集群负载均衡,为您提供解决这一复杂任务的清晰路线图。
在涉及来自不同供应商的集群的多集群设置中,第一步是为每个集群建立一个网关。然而,需要特别注意的关键一点是需要一个唯一的用户访问入口点。尽管可以在同一集群中部署此网关,但通常建议将其放置在一个单独的集群中。
两层入口网格的部署架构如图 4 所示。
基于 Istio 创建的多集群网格,通常是多网格多网络模式,为了让网格互通,我们需要添加一个一级(Tier-1)集群,并在每个集群中创建如下组件:
在这个演示中,我将涵盖三个 GKE 上的 Kubernetes 集群,分布在不同的区域,如图 5 所示。当然你也可以使用不同的供应商或者跨供应商。在每个集群中部署了 Istio,为多集群通信奠定了基础。
建立了两层集群:一个专门托管 productpage
服务,另一个包含完整 bookinfo 的服务套件。
为了实现诸如负载均衡和故障转移等高级功能,解决多集群路由问题至关重要。由于一级集群也部署了 Istio,可以将先前讨论的负载均衡技巧应用于此网关。
关键步骤:
在每个集群中创建入口网关,并获取网关使用的负载均衡器的 IP 地址。
在每个集群中创建 VirtualServices、DestinationRules 和 ServiceEntries。确保 ServiceEntries 包含每个集群入口网关的入口点。
为进一步的测试,检索 Tier 1 网关的 IP 地址。
export GATEWAY_IP=$(kubectl -n tier1 get service tier1-gateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
注意:这一步需要在一级集群中操作。
一级集群的网关作为统一网关入口,你可以通过在这个集群中配置 Gateway、VirtualService、DestinationRule 和 ServiceEntry 资源对象,实现多集群的路由,如图 6 所示。
在这个演示中我们将实现基于 HTTP header 和 prefix 的多集群的路由,最终的路由路径如图 7 所示。
关于操作的细节可以参考 TSB 文档中的统一网关。
演示继续进行实际测试,使用 curl
命令:
无需 HTTP 标头的请求 URL。
curl -Ss "http://bookinfo.tetrate.io/productpage" --resolve "bookinfo.tetrate.io:80:$GATEWAY_IP" -v > index1.html
使用指示首选集群的 HTTP 标头请求 URL。
curl -Ss "http://bookinfo.tetrate.io/productpage" --resolve "bookinfo.tetrate.io:80:$GATEWAY_IP" -v -H "X-CLUSTER-SELECTOR: gke-jimmy-us-west1-1" > index2.html
curl -Ss "http://bookinfo.tetrate.io/productpage" --resolve "bookinfo.tetrate.io:80:$GATEWAY_IP" -v -H "X-CLUSTER-SELECTOR: gke-jimmy-us-west1-2" > index3.html
通过导出的 HTML 文件验证结果。在浏览器中分别打开 index1.html
、index2.html
和 index3.html
这三个文件,你将看到页面 1 和页面 2 中都显示 reviews 和 details 服务不可用,只有页面 3 中的所有服务都可访问。
演示成功展示了如何利用 HTTP 标头和路径路由。路由是负载均衡的基础。实现了多集群路由之后,你就可以将来自二级(Tier-2)集群的端点添加到一个 subset 中,从而在 DestinationRule 中实现负载均衡配置。
可以通过将二级集群中的入口网关配置为东西向网关,从而解决 Cluster 1 中的故障转移问题。请参考 Istio 文档。
尽管 Istio 提供了基于 Envoy 的各种负载均衡类型,但手动在多个集群中创建资源对象容易出错且效率低下。自动化,最好是在 Istio 之上添加一个解释层,是下一个发展阶段。
Tetrate 使用 TSB 解决了这个需求,TSB 与上游的 Istio 兼容,为多集群部署提供了无缝的解决方案。有关更多信息,请访问 Tetrate 网站。
精通 Istio 中的多集群负载均衡对于在复杂环境中发挥微服务的全部潜力至关重要。通过谨慎的配置和合适的工具,您可以在集群之间实现强大且可靠的通信,确保您的应用程序无论部署在何处都能顺利运行。对于更精细的负载均衡调整,请考虑探索 EnvoyFilter。感谢您加入我们一起揭秘 Istio 中的多集群负载均衡之旅!
2023-07-20 16:27:49
在本文中,我将解释如何使用 GraphQL 与Postman 一起从 SkyWalking 查询数据。它包括获取不记名令牌、构建查询以检索特定服务的负载指标以及使用 GraphQL 自省来查看 SkyWalking GraphQL API 架构的步骤。本文还提供了更多信息的参考。
GraphQL 是 Facebook 开发的一种 API 查询语言和运行时。它允许客户端准确指定他们需要的数据并仅接收该数据作为响应,从而为传统 REST API 提供了更高效、更强大、更灵活的替代方案。使用 GraphQL,客户端可以在单个请求中查询多个资源,从而减少与服务器的往返次数并提高性能。
GraphQL 允许客户端仅请求他们需要的数据,而 REST API 要求客户端检索资源中的所有内容,无论他们是否需要。此外,GraphQL 允许客户端在单个请求中查询多个资源,这使其比 REST API 更高效、更简洁。
SkyWalking 定义了查询阶段的通信协议。SkyWalking 原生 UI 和 CLI 使用此协议从后端持续获取数据,无需担心后端更新。
从 SkyWalking 查询指标有两种方法:
本文提供了有关如何使用 GraphQL 从 SkyWalking 查询指标的指南。如果你对 PromQL API 感兴趣,可以参阅文章为 Apache SkyWalking 构建 Grafana Dashboard - 原生 PromQL 支持 。继续执行以下步骤需要安装 TSB。如果你没有,但仍想体验使用 GraphQL 在 SkyWalking 中查询数据,你可以使用 SkyWalking 提供的免费演示环境(用户名 / 密码:skywalking/skywalking)。登录演示网站并获取查询令牌。GraphQL 查询的端点地址是 http://demo.skywalking.apache.org/graphql 。构造查询的步骤与下面描述的相同。
在我们使用 Postman 构建自己的 GraphQL 查询之前,我们首先观察 TSB 如何从 SkyWalking 获取数据。
观察网络请求列表并右键单击其中一个 graphql 请求,如下图所示:
你看到的 curl 命令将如下所示。在终端中执行该命令,你将从 SkyWalking 中获取 TSB 管理的服务列表。
curl '<https://saturn.tetrate.work/ui/graphql>' \\
-H 'Accept-Language: en,zh-CN;q=0.9,zh;q=0.8,en-US;q=0.7,zh-TW;q=0.6' \\
-H 'Cache-Control: no-cache' \\
-H 'Client-Timestamp: 1686104776136' \\
-H 'Connection: keep-alive' \\
-H 'Content-Type: application/json' \\
-H 'Cookie: ...' \\
-H 'Origin: <https://saturn.tetrate.work>' \\
-H 'Pragma: no-cache' \\
-H 'Referer: <https://saturn.tetrate.work/mp/services>' \\
-H 'Request-Id: ...' \\
-H 'Sec-Fetch-Dest: empty' \\
-H 'Sec-Fetch-Mode: cors' \\
-H 'Sec-Fetch-Site: same-origin' \\
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' \\
-H 'X-Bridge-Csrf-Token: IOmJszLAqY3TRIUNhTuGu7vQgnfQY1FtgYFm+l/+Mu4EmVQU5T8EaQ7bngkCv4hQ12ZGids+I21pHMdepE9/qQ==' \\
-H 'X-Csrf-Token: xTbxZerD3t8N3PaS7nbjKCfxk1Q9dtvvrx4D+IJohHicb0VfB4iAZaP0zh1eXDWctQyCYZWaKLhAYT3M6Drk3A==' \\
-H 'accept: application/json' \\
-H 'sec-ch-ua: "Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"' \\
-H 'sec-ch-ua-mobile: ?0' \\
-H 'sec-ch-ua-platform: "macOS"' \\
--data-raw $'{"query":"query ServiceRegistryListMetrics(...)}' \\
--compressed
注意: 上例中的某些字段太长,用点 (…) 替换。
接下来,我将指导你构建一个查询来检索特定服务的负载指标。
首先,你需要获取网站的 Bearer Token。登录到 TSB UI,点击右上角的用户按钮,然后点击“Show token information”。在弹出窗口中,你将看到 Bearer Token,如下图所示。
注意:Bearer token 的有效期比较短。当它过期时,你需要重新登录 TSB 以获取新的 token。
我们已经预先部署了bookinfo 应用程序并发送了一些测试流量。要在 Postman 客户端中使用 GraphQL 查询reviews
的负载指标,请执行以下步骤:
$TSB_ADDRESS/graphql
Bearer $TOKEN
的Authorization
头readMetricsValues
项。你将在右侧看到变量。填写condition
和duration
项目,如下图所示。变量如下:
query ReadMetricsValues {
readMetricsValues(condition: {
name: "service_cpm", entity: {scope: Service, serviceName: "reviews", normal: true}
}, duration: {
start: "2023-06-05 0625",
end: "2023-06-05 0627",
step: MINUTE
}) {
label
values {
values {
id
value
}
}
}
}
单击 Query 按钮以获取结果。它应该类似于以下内容:
{
"data": {
"readMetricsValues": {
"label": null,
"values": {
"values": [
{
"id": "service_cpm_202306050625_cmV2aWV3cw==.1",
"value": 0
},
{
"id": "service_cpm_202306050626_cmV2aWV3cw==.1",
"value": 0
},
{
"id": "service_cpm_202306050627_cmV2aWV3cw==.1",
"value": 0
}
]
}
}
}
}
以上是使用 SkyWalking Demo 环境测试 GraphQL 查询。TSE 也支持 GraphQL 查询,并且端点地址为$TSB_SERVER/graphql
。
注意:此处的查询端点与 DevTool 中看到的不同。TSB UI 特定的 GraphQL 查询端点是$TSB_SERVER/ui/graphql
。
有关 SkyWalking GraphQL 查询协议的详细信息,请参见GitHub。
在本文中,我介绍了如何在 Postman 中使用 GraphQL 查询协议查询 SkyWalking 中的数据。你可以根据 SkyWalking 的 GraphQL 模式构建自己的查询条件。TSB / TSE 中也提供了此功能。
2023-05-16 13:19:28
Envoy Gateway 是一款基于 Envoy 代理和 Kubernetes Gateway API 开发的开源 API 网关,最近发布了 0.4.0 版本。此次发布的版本着重于自定义功能,旨在为最终用户提供更多的用例。在本文中,我们将讨论此版本中可用的新自定义选项及其对用户的重要性。
此次版本中最主要的自定义功能之一是配置 EnvoyProxy(Envoy Gateway 定义的 CRD)部署的确切类型。你可以定义 EnvoyProxy 部署的副本数、镜像和资源限制。还可以向 EnvoyProxy 部署和服务添加注解(Annotation)。这使得不同的用例成为可能,例如:
此外,Envoy Gateway 除了默认的 Kubernetes 单租户模式以外还新增其他部署模式支持,例如多租户,如下图所示。
分别在每个租户的 namespace 部署一个 Envoy Gateway Controller,它们监视 Kubernetes 中的 HTTPRoute 和 Service 资源,并在各自的 namespace 中创建和管理 EnvoyProxy 部署。
此版本中的另一个重要自定义功能是自定义 Envoy xDS 引导程序。使用此功能,用户可以提供引导配置,在启动 EnvoyProxy 时配置一些静态资源。例如配置访问日志记录、跟踪和指标以发送到 SkyWalking(可以作为 APM)非常有用。此外,此版本添加了大量 CLI 工具,以帮助验证用户配置。用户可以将 CLI 用作干运行以更改引导程序中的特定字段,如果配置在语法上不正确,则将失败。
Envoy Gateway 现在允许供应商和扩展开发人员在 Envoy Gateway 管道的不同阶段添加 gRPC 钩子,以进一步扩展其功能,允许用户做一些事情,比如增强发送给 EnvoyProxy 的 xDS 配置,这在以前是不可能的。
最后,Envoy Gateway 0.4.0 扩展了自定义 API,并为最终用户提供了更多用例。新的自定义功能包括自定义 Envoy 部署、Envoy xDS 引导程序以及扩展控制平面。这些新功能消除了用户创建自己的证书的需要,配置访问日志记录、跟踪和指标,并使供应商能够扩展 XDS 翻译用例。通过此版本的发布,Envoy Gateway 正变得更加用户友好,成为 Istio 的绝佳替代品。
2023-04-26 13:09:28
ChatGPT 是一个强大的工具,可以根据提示生成文本响应。然而,使用浏览器版本可能会很繁琐和耗时。幸运的是,有几个浏览器扩展可以帮助您更有效地使用 ChatGPT。在本文中,我们将讨论几个我个人测试并推荐的最有用的 ChatGPT 浏览器扩展。这些插件都是完全免费的,不存在订阅或者后期收费选项,大家可以放心使用。
下图展示了安装了插件的 Chrome 浏览器中的 ChatGPT 页面。
GitHub:https://github.com/benf2004/ChatGPT-Prompt-Genius
这个项目是一个多功能的 ChatGPT 浏览器扩展,它可以帮助你发现、分享、导入和使用最好的 ChatGPT 提示。你也可以把你的聊天记录保存在本地,方便以后查看和参考。你可以使用扩展的提示模板功能,轻松地找到并添加提示到你的收藏。你可以在 ChatGPT 页面上搜索、分类和选择提示,找到有创意和有用的方式使用 ChatGPT。还可以添加一些主题,比如短信、温馨的壁炉和黑客。
在搜索引擎结果中同时显示 ChatGPT 的回答,功能点如下:
你可以在 Chrome 网上应用商店 下载。
GitHub:https://github.com/xcanwin/KeepChatGPT
让我们在使用 ChatGPT 过程中更高效、更顺畅,完美解决 ChatGPT 网络错误,不再频繁地刷新网页,足足省去 10 个多余的步骤。还可以取消后台监管审计。
解决了这几类报错:
这个 Chrome 扩展的主要内容是让你可以用语音和 ChatGPT 交流,而不需要打字。它的功能有:
这个扩展可以让你更方便地使用 ChatGPT,也可以帮助你学习外语或提高口语能力。它是一个免费和开源的项目,你可以在 Chrome 网上应用商店 下载。
需要注意的是,你无法关闭用语音朗读,除非你卸载掉该扩展。
这个免费的扩展程序将相关的网络结果添加到您对 ChatGPT 的提示中,以获得更准确和最新的对话。
当你不想使用时,也可以在 ChatGPT 页面上随时关闭它。你可以在 Chrome 网上应用商店 下载该扩展。
这几个 ChatGPT 浏览器扩展可以帮助您更有效地使用 ChatGPT。无论您需要更便捷的界面、带有有用功能的侧边栏,都有一款扩展可以帮助。我建议尝试每个扩展,以确定哪个最适合您的需求。有了这些工具,您可以改善您的 ChatGPT 体验,快速轻松地生成高质量的文本响应。以后再发现其他更好的插件,笔者会在本文中更新,也欢迎读者朋友们有推荐的插件可以在评论中留言。
2023-04-25 19:09:28
Docker 多平台构建是一种用于构建 Docker 镜像以在多种 CPU 架构和操作系统上运行的技术。它可以让用户在一个 Dockerfile 中定义一个通用的构建过程,然后使用 Docker CLI 命令将其构建为多个不同平台的镜像。这些镜像可以在不同的计算机、云平台和容器编排系统上运行,从而为用户提供更广泛的部署选项。
在多平台构建中,用户需要使用 Docker Buildx 插件来构建镜像。Docker Buildx 可以构建并输出多个不同平台的镜像,包括 x86、ARM、IBM Power 等。用户可以使用该插件创建多种平台的构建环境,并使用这些环境构建镜像。
需要注意的是,多平台构建需要在支持多平台的 Docker 主机上进行。在这种主机上,Docker 可以使用 QEMU 等模拟器来模拟其他平台的环境,从而实现构建多种平台的镜像。
Docker Buildx 是 Docker 的一个插件,它提供了一种简单、高效的方式来构建和打包 Docker 镜像。它能够在多个平台上构建和输出 Docker 镜像,包括 Linux、Windows、macOS 等,支持 CPU 架构和操作系统等多种参数的设置。
Docker Buildx 在构建镜像时使用了 BuildKit,这是 Docker 官方推出的一个基于 Go 语言实现的高性能构建引擎。BuildKit 提供了更快的构建速度、更小的镜像体积、更好的缓存管理等优势,也可以在 Docker Buildx 之外使用。
使用 Docker Buildx,可以将不同平台上的 Docker 镜像构建合并到一个 manifest 中,使得用户只需要下载一个 manifest,就可以获取多个平台的镜像。这为跨平台开发和分发应用程序提供了很大的便利。
Docker buildx 实现多平台镜像构建的原理是基于 Docker 的多架构支持。Docker 可以在一个主机上运行多个容器,每个容器运行在自己的隔离环境中,相互独立。而 Docker 镜像则是用于创建容器的基础文件系统。
在 Docker 中,不同的 CPU 架构和操作系统可以使用不同的 base image(基础镜像)进行构建。而 Docker buildx 可以自动识别当前主机的架构和操作系统,并选择合适的 base image 进行构建。在构建过程中,Docker buildx 会使用 BuildKit 引擎进行构建,支持多平台的交叉编译和镜像打包。
在构建完成后,Docker buildx 会将不同平台上的镜像打包成一个 manifest 文件,其中包含了所有平台的镜像信息。用户可以通过 Docker CLI 命令或者 Docker registry 接口来操作 manifest 文件,获取不同平台上的镜像。对于不支持多架构的 Docker 版本,可以通过安装 Docker CLI 的 experimental 版本来使用 Docker buildx。
Docker buildx 利用了 Docker 的多架构支持和 BuildKit 引擎,实现了跨平台的 Docker 镜像构建和分发。
BuildKit 是 Docker 官方推出的一个高性能的构建引擎,它可以用于构建 Docker 镜像、构建应用程序以及执行其他构建任务。BuildKit 引擎采用了分布式的架构,可以并行地执行多个构建任务,提高构建效率。
BuildKit 引擎的主要特点包括:
Docker buildx 支持的平台主要包括以下几种:
除了以上平台外,Docker buildx 还支持构建和输出多种其他平台的 Docker 镜像,包括 FreeBSD、Solaris 等。用户可以通过指定对应的 platform
参数来构建和输出不同平台的 Docker 镜像,例如:
docker buildx build --platform linux/amd64,linux/arm64 .
这个命令将会构建一个同时支持 x86_64 和 ARM64 架构的 Docker 镜像。用户也可以通过指定不同的 buildx 构建配置来支持更多的平台,例如使用 qemu-user-static 等模拟器来支持其他的 CPU 架构。总之,Docker buildx 的多平台支持非常强大,为跨平台开发和分发应用程序提供了便利。
Docker buildx 引擎的架构是一个分布式的构建系统,通过多阶段、多组件的设计,实现了高性能、多平台支持、安全性等优点,为 Docker 镜像构建和应用程序构建提供了强大的支持。它由以下几个主要组成部分组成:
使用 docker buildx 命令可以方便地进行 Docker 镜像的构建和输出。下面是一些常用的 docker buildx 命令及其用法:
查看当前的 buildx 构建器列表
docker buildx ls
创建新的 buildx 构建器
docker buildx create --name mybuilder
切换到指定名称的 buildx 构建器
docker buildx use mybuilder
设置 buildx 构建器的平台支持
docker buildx inspect --bootstrap
docker buildx inspect --platform
docker buildx build --platform linux/amd64,linux/arm64 .
构建 Docker 镜像:
docker buildx build --tag myimage .
输出 Docker 镜像到本地文件系统
docker buildx build --output=type=local,dest=./output .
输出 Docker 镜像到 Docker Hub 或其他远程仓库
docker buildx build --tag myrepo/myimage --push .
删除指定名称的 buildx 构建器
docker buildx rm mybuilder
除了以上命令外,docker buildx 还支持许多其他的参数和选项,例如设置构建缓存、并行处理、构建标签等。用户可以通过查看官方文档或者使用 –help 选项来了解更多详情。
在 Docker 中,构建器(Builder)是指一个 Docker 容器,它包含了构建所需要的环境和工具,可以执行构建任务。Docker buildx 构建器是指使用 BuildKit 引擎的多平台构建器,可以通过 Docker CLI 命令进行管理和操作。在使用 Docker buildx 构建器时,用户可以配置多个构建器,以支持多个平台和多个构建环境。
用户可以通过创建、切换、查看和删除构建器,来管理和维护 Docker buildx 的构建环境。构建器的主要作用是提供一个干净、独立的构建环境,避免构建过程中的依赖冲突和环境污染。此外,构建器还可以方便地进行版本管理和共享,以便多个用户或者团队协同构建 Docker 镜像。
Docker buildx 构建器还支持多平台构建,用户可以在同一个构建器中设置多个平台,以便生成跨平台的 Docker 镜像。通过 Docker buildx 构建器,用户可以轻松实现 Docker 镜像的多平台构建,提高构建效率和应用程序的兼容性。
这通常是因为你当前使用的 Docker context 不支持编译出来的镜像架构。例如 Orbstack,虽然它支持编译跨平台的镜像,但是执行 docker buildx
构建出来的镜像不会直接保存在本地的 Docker 镜像仓库中,而是保存在构建器(Builder)的缓存中。这是因为 Docker buildx 采用了分层构建的方式,构建出的每一层镜像都可以被重用,以减少构建时间和磁盘空间的占用。
你应该使用 docker context
命令切换会 Docker 默认的上下文环境再执行构建,这样构建出来的跨平台镜像就可以在本地看见了。
要将 Docker buildx 构建的多平台镜像保存到本地,可以使用 --output
选项指定输出类型为 type=local
,并指定输出目录,例如:
docker buildx build --platform linux/amd64,linux/arm64 --output type=local,dest=./output .
上述命令将构建包含 linux/amd64
和 linux/arm64
两种平台的镜像,并将输出类型设置为本地(type=local
),输出目录为 ./output
。
构建完成后,输出目录中会生成多个子目录,每个子目录分别对应一个平台,其中包含该平台下的镜像文件。
如果只想保存其中一个平台的镜像,可以在 --output
选项中指定要保存的平台,例如:
docker buildx build --platform linux/amd64,linux/arm64 --output type=local,dest=./output/linux/amd64 .
上述命令将只保存 linux/amd64
平台的镜像,输出到 ./output/linux/amd64
目录中。
需要注意的是,--output
选项只支持部分输出类型,如果要将镜像保存到其他类型的输出(例如 tar 包、OCI 存储、Docker registry 等),需要使用其他的输出插件和选项。具体细节可以参考 Docker 官方文档。
WebAssembly 是一种中间代码格式,需要使用编译器将源代码编译为 WebAssembly 格式的二进制文件,再将其打包成镜像。以下是构建 WebAssembly 镜像的一般步骤:
编写 WebAssembly 源代码,并使用编译器将其编译为 WebAssembly 格式的二进制文件。例如使用 Rust 编写代码,并使用 Cargo 编译出 .wasm
文件。
编写 Dockerfile 将 Wasm 二进制文件添加到空镜像中。例如:
# syntax=docker/dockerfile:1
FROM scratch
COPY ./target/wasm32-wasi/debug/hello-wasm.wasm /hello.wasm
ENTRYPOINT [ "hello.wasm" ]
使用 docker buildx
命令构建镜像,例如 docker buildx build --platform wasi/wasm32 -t jimmysong/hello-wasm .
将在本地构建。若你想将该镜像同时同时推送到 Docker Hub,可以在命令中加上 --push
标志。基于 WebAssembly 平台的镜像并上传到 Docker Hub。
除了构建多平台镜像、导出和加载镜像外,还有一些 Docker buildx 命令的常用操作及注意事项,包括:
-progress
选项:可以使用 -progress
选项指定构建过程的输出格式,包括 auto
、plain
、tty
三种格式。-no-cache
选项:可以使用 -no-cache
选项禁用构建过程中的缓存机制,强制重新构建镜像。-push
选项:可以使用 -push
选项将构建的镜像推送到 Docker registry 中。-tag
选项:可以使用 -tag
选项为构建的镜像指定标签。-file
选项:可以使用 -file
选项指定 Dockerfile 文件的路径。-build-arg
选项:可以使用 -build-arg
选项传递构建参数给 Dockerfile 中的指令。.dockerignore
文件排除不需要传输的文件。需要注意的是,Docker buildx 是一个比较新的命令,不同版本的 Docker Engine 可能会存在差异,因此在使用时需要注意查阅官方文档,并根据实际情况进行操作。
2023-04-07 18:45:40
在 Docker 发展史:四个重大举措,影响深远! 这篇文章中我提到了 Docker 从一开始引领容器运行时,再到在容器编排这一维度上落后于 Kubernetes。为了在保住容器运行时的统治地位,Docker 公司提出了 OCI 并通过 containerd-wasm-shim 支持更多的 WebAssembly 运行时。
为了解决 Docker 在安全、稳定性、性能及可移植性方面的局限性,Kubernetes 社区开发了具有不同实现和功能的其他容器运行时,并为其制定了容器运行时接口(CRI)规范。目前实现该规范的容器运行时有 containerd、cri-o。还有 katacontainers、gvisor 等未实现 CRI 但是可以通过添加虚拟化层在 Kubernetes 上运行的其他容器运行时。
开放容器倡议 (OCI) 旨在定义容器镜像格式和运行时的行业标准,Docker 捐赠了其运行时 runc 作为该标准的第一个实现。最近,WASM 社区对 OCI 工具链表现出了兴趣,Docker 现在支持 WebAssembly 模块作为其工件之一。现在 Docker Hub 已经支持除了镜像以外的,Helm、Volume 和 WebAssembly 等常用工件。
使用 Docker 构建包含 WebAssembly 模块的镜像,并保存在 Docker Hub 中。通过 containerd-wasm-shim,可以让它们在 Kubernetes 中运行,如下图所示。
Containerd 是一种符合 CRI(Container Runtime Interface)规范的容器运行时,是由 Docker 公司开源并贡献给 CNCF 的。只要支持 CRI 规范的运行时都可以在 Kubernetes 中运行。
关于以上提到的名词 containerd、CRI、OCI 等的关系介绍,可以参考 Docker,containerd,CRI,CRI-O,OCI,runc 分不清?看这一篇就够了
使用 Docker 运行 WebAssembly 应用相对运行 Linux 镜像有以下优势。
更高的性能
WebAssembly 应用的启动时间更短,因为它不需要启动整个操作系统,而 Linux 容器需要。WebAssembly 模块的冷启动时间比 Docker 容器快 100 倍。WebAssembly 模块的内存占用更小,因为它是一个二进制格式,可以高效地压缩代码和依赖,而 Docker 容器需要打包整个镜像。WebAssembly 模块的大小一般在 1MB 以内,而 Docker 镜像的大小可以达到 100 或 200 MB。
更高的可移植性
WebAssembly 应用是一个架构中立的格式,只要有相应的运行时,就可以在任何底层架构上运行,而不需要考虑不同架构之间的兼容性问题。Docker 容器需要针对不同的架构构建不同的镜像,可能会存在一些潜在的安全风险或漏洞。
更好的安全性和隔离性
WebAssembly 应用可以提供代码级别的安全性,防止恶意代码访问系统资源,具体来说:
因为有以上优势,WebAssembly 在一些场景下比 Docker 容器更有优势,例如边缘计算、云原生应用和微服务。当然,WebAssembly 应用也有一些局限性,比如不支持多线程、垃圾回收和二进制打包等。因此,并不是所有的场景都适合使用 WebAssembly 应用。你可以根据你的具体需求和偏好来选择合适的技术方案。
在 Docker 中运行 WebAssembly 应用的方式与普通的 Linux 镜像没有太大的不同,只是在运行时需要指定下平台和运行时。下面的例子来自 Docker 官方文档,以在 Docker Desktop 中为例运行 WebAssembly 应用:
docker run -dp 8080:8080 --name=wasm-example --runtime=io.containerd.wasmedge.v1 --platform=wasi/wasm32 michaelirwin244/wasm-example
其中:
--runtime=io.containerd.wasmedge.v1
指定使用 WasmEdge 运行时,替代默认的 Linux 容器运行时。--platform=wasi/wasm32
指定镜像的架构。通过利用 Wasm 架构,无需为不同的机器架构构建单独的镜像。Wasm 运行时负责将 Wasm 二进制文件转换为机器指令的最后一步。目前 Docker 支持四种 WebAssembly 运行时,分别为:
运行时名称 | API 名称 | 开发者 | 基金会托管 |
---|---|---|---|
spin | io.containerd.spin.v1 |
Fermyon | 无 |
SpiderLightning | io.containerd.slight.v1 |
DeisLabs | 无 |
WasmEdge | io.containerd.wasmedge.v1 |
SecondState | CNCF 沙箱项目 |
Wasmtime | io.containerd.wasmtime.v1 |
Mozilla、Fastly、Intel、Red Hat 等公司 | 字节码联盟项目 |
在命令行终端中输入以下命令可以查看 WebAssembly 应用的运行情况:
curl http://localhost:8080/
你将看到如下输出:
Hello world from Rust running with Wasm! Send POST data to /echo to have it echoed back to you
你还可以向/echo
端点发送 POST 测试请求:
curl localhost:8080/echo -d '{"message":"Hello"}' -H "Content-type: application/json"
你将看到如下输出:
{"message":"hello"}
本文介绍了 Docker 为什么要增加对 WebAssembly 的支持,以及在 Docker 中运行 WebAssembly 应用的优势和方法。WebAssembly 应用相对于 Linux 镜像有更高的性能、可移植性和安全性,适用于边缘计算、云原生应用和微服务等场景。Docker 支持四种 WebAssembly 运行时,分别为 spin、spiderlightning、WasmEdge 和 wasmtime。在接下来的文章中我将介绍如何开发一个 WebAssembly 应用,敬请期待。
2023-04-06 21:25:40
在 2017 年的容器编排大战中,Docker 公司失败后沉寂了几年,但近年来又开始频繁行动,例如腾退开源组织账号,支持 WebAssembly 等。本文将回顾 Docker 公司发展过程中的四个重大举措,这些措施深深地影响了 Docker 公司的发展,也对 Docker 甚至 Kubernetes 社区产生了深远的影响。
首先我们需要先确定 Docker 这个词的含义。当人们在谈论 Docker 时可能指的是:
为什么同一个词会有这么多不同的意思呢?这都是有历史原因的。Docker 软件于 2013 年发布,起初定位为开发者工具。作为最早发布的容器工具,它迅速走红,并成为容器技术的代名词。但它最初只是在单机上运行,有太多耦合的接口设计。后来容器集群出现,才需要用到容器编排调度工具。因为 Kubernetes 具有丰富的功能和扩展性,Docker 公司推出的 Swarm 在这场容器编排大战中败下阵来。归根结底,Docker 面向开发者,而容器运行时则面向机器,只需要对应的接口即可,不需要那么丰富的管理工具。如今,Docker 仍然是最受开发者喜爱的容器工具之一,其 Docker Hub 是全球最大的镜像仓库。
2017 年 4 月,Docker 公司将 Docker 项目重命名为 Moby,详见 Introducing Moby Project: a new open-source project to advance the software containerization movement:
Moby Project 是一个新的开源项目,旨在推动软件容器化运动的发展,帮助生态系统让容器技术走向主流。它提供了一个组件库,一个用于将组件组装成定制的基于容器的系统的框架,以及一个让所有容器爱好者可以实验和交流想法的地方。
Moby Project 和 Docker 的区别和联系是:
Docker 公司在 2017 年 12 月发布的 Docker 17.12 版本中开始支持 Kubernetes。在此之前,Docker 公司一直在发展自己的容器编排和调度工具 Docker Swarm。然而,Kubernetes 在容器编排和调度方面具有更广泛的支持和社区贡献,已经成为了业界标准。因此,Docker 公司决定将 Kubernetes 集成到 Docker 平台中,以提供更广泛的选择和更好的用户体验。Docker 公司在 Docker Desktop 和 Docker Enterprise 中提供了 Kubernetes 的集成支持,使得 Kubernetes 和 Docker 容器可以更加方便地部署和管理。同时,Docker 公司也开发了一些工具,如 Kompose 和 Docker Compose,使得用户可以将 Docker Compose 配置文件转换为 Kubernetes YAML 文件,以便更加方便地将应用程序从 Docker Swarm 迁移到 Kubernetes。
Kubernetes 从 v1.20 起不再支持 Docker 运行时并在 2022 年 4 月发布的 v1.24 中被完全移除,如下图所示。这意味着在 Kubernetes 中只能使用 containerd 或 CRI-O 容器运行时,不过你依然可以使用 Docker 镜像,只是无需使用 docker 命令或 Docker 守护程序。
Kubernetes v1.24 正式移除 Docker 运行时
2023 年 3 月,据 Alex Ellis 的博客 介绍,Docker 公司决定删除一些开源组织的账户和镜像,除非他们升级到付费的团队计划,这对开源社区造成了很大的困扰和不安。很多 Docker 忠实拥护者和贡献者对 Docker 的这一举动表示了不满和失望。
这一事件是这样的:
2022 年 10 月,Docker 公司发布了 Docker+Wasm 技术预览,这是一个特殊的构建,可以让开发者更容易地使用 Docker 运行 Wasm 工作负载。作为这次发布的一部分,Docker 还宣布将加入 Bytecode Alliance 作为一个投票成员。
Wasm 是一种新技术,可让你在沙箱环境中运行 40 多种语言的应用程序代码,包括 Rust,C,C++,JavaScript 和 Golang。最初,Wasm 的用例是在浏览器中运行本地代码,如 Figma,AutoCAD 和 Photoshop 等。现在,一些公司如 Vercel,Fastly,Shopify 和 Cloudflare 等支持使用 Wasm 在边缘和云端运行代码。
Docker+Wasm 技术预览包括:
2023 年 3 月 Docker 公司又发布了 Docker+Wasm 技术预览 2,包括了三个新的 Wasm 运行时引擎:Fermyon 的 spin,Deislabs 的 slight,和 Bytecode Alliance 的 wasmtime。
该版本的主要更新是:
本文介绍了 Docker 发展过程中的四个重大举措:Moby Project、支持 Kubernetes、删除开源组织账号和增加对 WebAssembly 运行时的支持。其中,Moby Project 旨在推动容器技术走向主流,支持 Kubernetes 的举措提供了更广泛的选择和更好的用户体验,删除开源组织账号的举措引起了开源社区的不满和失望,增加对 WebAssembly 运行时的支持的举措则扩展了 Docker 的应用场景。