├── .github └── ISSUE_TEMPLATE │ └── istio-weekly-episode-suggestion.md ├── .gitignore ├── LICENSE ├── README.md ├── istio-big-talk ├── 001 │ ├── README.md │ └── istio-big-talk-slide-001.pdf ├── 002 │ ├── README.md │ └── istio-big-talk-slide-002.pdf ├── 003 │ ├── README.md │ └── istio-big-talk-slide-003.pdf ├── 004 │ ├── README.md │ └── istio-big-talk-slide-004.pdf ├── 005 │ ├── README.md │ └── istio-big-talk-slide-005.pdf ├── 006 │ └── README.md ├── 007 │ ├── README.md │ └── istio-big-talk-slide-007.pdf ├── 008 │ ├── README.md │ └── istio-big-talk-slide-008.pdf └── playlist.md └── istio-weekly ├── 000 └── README.md ├── 001 └── README.md ├── 002 └── README.md ├── 003 ├── 003.png ├── README.md ├── demo.md └── yaml │ ├── gateway.yaml │ ├── hello-world.yaml │ └── vs.yaml ├── 004 ├── 004.png ├── README.md └── demo.md ├── 005 ├── 005.png ├── README.md ├── arch.png └── demo.md ├── 006 ├── 006.png ├── README.md ├── config.yaml └── demo.md ├── 007 ├── 007.png ├── README.md └── demo.md ├── 008 ├── 008.png └── README.md ├── 009 ├── 009.png ├── README.md └── demo.md ├── 010 ├── 010.png └── README.md ├── 011 ├── 011.png └── README.md ├── 012 ├── 012.png └── README.md ├── 013 ├── 013.png └── README.md ├── 014 ├── 014.png └── README.md ├── 015 ├── 015.png └── README.md ├── 016 ├── 016.png └── README.md └── playlist.md /.github/ISSUE_TEMPLATE/istio-weekly-episode-suggestion.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Istio Weekly Episode Suggestion 3 | about: Suggest an episode for Istio Weekly 4 | title: '' 5 | labels: episode suggestion 6 | assignees: '' 7 | 8 | --- 9 | 10 | Describe what you'd like us to discuss and cover in future Istio Weekly episodes. 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | 8 | # Crash log files 9 | crash.log 10 | 11 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 12 | # .tfvars files are managed as part of configuration and so should be included in 13 | # version control. 14 | # 15 | # example.tfvars 16 | 17 | # Ignore override files as they are usually used to override resources locally and so 18 | # are not checked in 19 | override.tf 20 | override.tf.json 21 | *_override.tf 22 | *_override.tf.json 23 | 24 | # Include override files you do wish to add to version control using negated pattern 25 | # 26 | # !example_override.tf 27 | 28 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 29 | # example: *tfplan* 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Istio weekly 2 | 3 | Istio weekly is Tetrate's bi-weekly live video stream, broadcasted live at 11am pacific time. 4 | 5 | Check out the [list of all Istio Weekly episodes](./istio-weekly/playlist.md). 6 | 7 | The offical [Istio weekly YouTube playlist can be found here](https://www.youtube.com/playlist?list=PLm51GPKRAmTnMzTf9N95w_yXo7izg80Jc). 8 | 9 | Join the [Tetrate Slack Community](https://tetr8.io/tetrate-community) for Istio weekly and other mesh discussions. 10 | 11 | ## Istio Big Talk 12 | 13 | 《Istio 大咖说》(Istio Big Talk)是由企业级服务网格提供商 Tetrate 冠名播出的系列直播节目,每期节目将邀请 Istio 和服务网格相关领域的大咖前来分享知识和生产实践。 14 | 15 | - [往期节目列表](istio-big-talk/playlist.md) 16 | - [直播间](https://live.bilibili.com/23095515) 17 | - [直播回放](https://space.bilibili.com/1698576814) 18 | - [提问互动文档](https://docs.qq.com/doc/DRUZSbHVkck9Wc0V4) 19 | 20 | ## Suggest an episode 21 | 22 | If you have an idea for an episode, please [open an issue](https://github.com/tetratelabs/istio-weekly/issues/new). 23 | -------------------------------------------------------------------------------- /istio-big-talk/001/README.md: -------------------------------------------------------------------------------- 1 | # 第 1 期 2 | 3 | 想了解 Istio 的来历吗?想知道 Istio 自我救赎般的架构重构吗?想窥探 Istio 开发背后的趣事吗?想一起解读最新版本的新特性吗?北京时间 5 月 25 日晚上 8 点,相约 B 站,让我们一起回顾 Istio 发布四周年的点点滴滴,[B 站直播间](https://live.bilibili.com/23095515)不见不散! 4 | 5 | ## 节目信息 6 | 7 | - 时间:2021 年 5 月 25 日晚 8 点 8 | - 主持人:宋净超(Tetrate) 9 | - 嘉宾:马若飞(FreeWheel) 10 | - 嘉宾介绍:《Istio 实战指南》作者、极客时间《Service Mesh 实战》专栏作者、AWS Container Hero 11 | - 主题:Istio 开源四周年回顾与展望 12 | - 视频回放:[《Istio 大咖说》第 1 期:Istio 开源四周年回顾与展望](https://www.bilibili.com/video/BV1jK4y1R7Tk) 13 | -------------------------------------------------------------------------------- /istio-big-talk/001/istio-big-talk-slide-001.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-big-talk/001/istio-big-talk-slide-001.pdf -------------------------------------------------------------------------------- /istio-big-talk/002/README.md: -------------------------------------------------------------------------------- 1 | # 第 2 期 2 | 3 | 云原生赛场已经进入了下半场的比拼,Istio 作为服务网格赛道上的明星选手,社区活跃度和用户知名度都位列前茅。但是国内环境下 Istio 的落地实践却并不多。是什么阻碍了 Istio 的落地,到底 Istio 好不好用?到底什么情况下使用 Istio 利大于弊?本次我们将站在企业用户角度上,邀请了潘天颖分享 Istio 在小电科技的完整落地经验,讲述为什么要从传统微服务架构迁移至服务网格架构,其中遇到的困难与解决方法,以及针对 Istio 的改进方案。 4 | 5 | ## 节目信息 6 | 7 | - 时间:2021 年 6 月 2 日晚 8 点 8 | - 主持人:宋净超(Tetrate) 9 | - 嘉宾:潘天颖(小电科技) 10 | - 嘉宾介绍:小电科技工程师,云原生爱好者,Kubernetes contributor,Apache committer。 11 | - 直播间:https://live.bilibili.com/23095515 12 | - 视频回放:https://www.bilibili.com/video/BV1QQ4y1X7hP/ 13 | 14 | ## Q&A 整理 15 | 16 | 请问刚参加工作的应届生,工作涉及istio中的envoy,请问应届生应该如何提前学习Envoy? 17 | 18 | 答:需要多了解下网络知识,还有云原生社区的Envoy中文文档可以学习,也可以参加社区的翻译活动。 19 | 20 | --- 21 | 22 | 在 service 特别多的时候,比如几万个 service,sidecar 是否会占用过多内存?如果是的话,可以有什么解决思路? 23 | 24 | 答:可以通过将应用按业务组进行分组,将相互依赖的应用分开部署到不同的namespace中,然后配置sidecar配置进行配置收拢,使应用只关心特定namespace中的服务配置,个别服务通过网关调用。毕竟很难有应用会依赖几万个svc的。 25 | 26 | --- 27 | 28 | 我们想上Istio,请教下有什么坑?Istio1.10版本。建议上吗?架构为 SpringCloud。 29 | 30 | 答:本次分享应该回答了问题,这里很难回答。 31 | 32 | --- 33 | 34 | 请问针对使用dubbo框架开发的应用来说,上Istio有什么建议?老师对aeraki这个项目怎么看?Istio对于支持dubbo以及其它协议这块有什么好的支持方式? 35 | 36 | 答:可以考虑升级下dubbo 3.0.0,istio目前已经支持dubbo协议,但是由于dubbo数据包attachment在整个数据体的最后,反序列化成本较高,需要关注下性能。还有一点是一般dubbo服务sdk比较难去掉,和 Istio功能重合太大了。不太了解aeraki这个项目。社区可以邀请项目的人来分享。 37 | 38 | --- 39 | 40 | IRA开源吗? 41 | 42 | 答:这个服务通过istio的configController机制完成,代码量不大,目前还没开源。 43 | 44 | --- 45 | 46 | Mesh外的服务怎么访问Mesh内的服务?走Mesh的Ingess gateway 吗? 47 | 48 | 答:分享中已经提到,我们通过register-helper sidecar容器,保留了迁移过程中mesh外服务通过注册中心访问网格内服务的能力。完成迁移后可以将该sidecar去掉。当然网格外的服务通过ingress也是能够访问网格内的服务的。 49 | 50 | --- 51 | 52 | 请问接入Istio需要开发介入什么操作变更,当前架构为Spring Cloud,注册中心为nacos/eureka,95%应用在Kubernetes上,现在需要用到流量控制,ingress gateway,熔断,限流等功能。 53 | 54 | 答:如果迁移设计的比较完美,其实可以做到开发零介入。比如我们的实践,大多数java服务只需要引入一个java架包就可以。这个包中你可以将原来java服务底层的register sdk屏蔽,并且去除loadbalace逻辑,保留上层的接口。减少开发的接入成本,也方便Istio的推广。 55 | 56 | --- 57 | 58 | 上网格后springcloud consumer是否需要手动修改每个provider地址为Kubernetes service name? 59 | 60 | 答:这个建议是要替换的。但是有很多比较优雅的方式,详细见分享。 61 | 62 | --- 63 | 64 | 能分享下目前用wasm主要做了哪些事么?稳定性和性能方面怎么样? 65 | 66 | 答:对流量打标处理,方便后续进行route分发。由于是使用在sidecar而不是ingress上,性能上面并没有问题。稳定性需要使用者来保证了,wasm插件切不可出错,否则会影响所有流量。 67 | 68 | --- 69 | 70 | 目前Istio控制面管理不友好,如果不通过自研方案的话有什么推荐么?yaml方面,目前看没有很好的gui配置。 71 | 72 | 答:社区比较主流的有kiali,如果企业支持,可以参考下一些企业支持版的Istio版本,比如GetIstio。 73 | 74 | --- 75 | 76 | 什么样的业务或者场景适合上Istio,运维工程师该注意那些点,是否有很好的方案供参考,运维如何和开发配合完善推进上Istio,我们的业务是支付打款相关的,目前是.Net。 77 | 78 | 答:Istio适不适合其实和业务关系不大,和历史技术架构关系比较大。运维工程师和开发接受Istio架构需要比较大的学习成本。如果对这个有信心,那么并没有大问题。至于.Net还是其他语言关系并不大,毕竟Istio是语言无关的。 79 | -------------------------------------------------------------------------------- /istio-big-talk/002/istio-big-talk-slide-002.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-big-talk/002/istio-big-talk-slide-002.pdf -------------------------------------------------------------------------------- /istio-big-talk/003/README.md: -------------------------------------------------------------------------------- 1 | # 第 3 期 2 | 3 | - 时间:6 月 9 日(星期三)晚 8 点 - 9 点 4 | - 直播间:https://live.bilibili.com/23095515 5 | - 主持人:宋净超(Tetrate) 6 | - 嘉宾:杨笛航(网易数帆) 7 | - 话题:如何让 Istio 变得更为高效和智能 8 | - 直播回放:https://www.bilibili.com/video/BV18o4y1y75e/ 9 | 10 | ## 嘉宾简介 11 | 12 | 杨笛航,Istio 社区成员,网易数帆架构师,负责网易轻舟 Service Mesh 配置管理,并主导 Slime 组件设计与研发,参与网易严选和网易传媒的 Service Mesh 建设。具有三年 Istio 控制面功能拓展和性能优化经验。 13 | 14 | ## 话题介绍 15 | 16 | Istio 作为当前最火的 Service Mesh 框架,既有大厂背书,也有优秀的设计,及活跃的社区。但是随着 Mixer 组件的移除,我们无法通过扩展 mixer adapter 的方式实现高阶的流量管理功能,Istio 的接口扩展性成为亟待解决的问题。本次直播将分享本次分享将介绍网易自研的智能网格管理器 Slime,借助它,我们实现了配置懒加载,自适应限流,HTTP 插件管理等扩展功能,从而更为高效的使用 Istio。 17 | 18 | ## 听众收益 19 | 20 | - 了解在实际业务中驾驭 Istio 框架的挑战 21 | - 了解 Slime 的设计特点、技术路线及开源进展 22 | - 了解网易解决 Service Mesh 架构成熟的经验 -------------------------------------------------------------------------------- /istio-big-talk/003/istio-big-talk-slide-003.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-big-talk/003/istio-big-talk-slide-003.pdf -------------------------------------------------------------------------------- /istio-big-talk/004/README.md: -------------------------------------------------------------------------------- 1 | # 第 4 期 2 | 3 | - 分享时间:2021 年 6 月 23 日(周三)晚 8 点到 9 点 4 | - 议题名称:如何让 Istio 在大规模生产环境落地 5 | - 主持人:宋净超(Tetrate) 6 | - 分享嘉宾:陈鹏(百度) 7 | - 直播间地址: 8 | - 提问地址: 9 | - 回放地址: 10 | 11 | 陈鹏,百度研发工程师,现就职于百度基础架构部云原生团队,主导和参与了服务网格在百度内部多个核心业务的大规模落地,对云原生、Service Mesh、Isito 等方向有深入的研究和实践经验。 12 | 13 | ### 分享大纲 14 | 15 | 1. 百度服务治理现状 & Istio 落地挑战 16 | 2. 深入解读如何让 Isito 在大规模生产环境落地 17 | 3. 实践经验总结 & 思考 18 | 19 | 通过本次分享你将了解当前 Isito 落地的困境和解决思路。 20 | 21 | ### Q&A 22 | 23 | 1. 请问,Istio 组件,包括数据面和控制面发生故障时,有哪些快速 fallback 的方案,之前阅读了大佬的相关文章,这块好像没有细讲,谢谢! 24 | 25 | > 相对来说, 数据面 fallback 更重要一些,因为它直接接流量。最好是能结合流量劫持环节,让 sidecar 故障时,系统能自动感知到,流量自动 fallback 到直连模式,具体思路可以参考分享内容,其次 sidecar 的监控也是必要的,用来辅助感知和处理故障。控制面故障短时间内不会对流量转发造成影响,也可以通过部署多副本来应对故障。 26 | 27 | 1. 有些服务 QoS 想设置 guaranteed,但是 istio 的 sidecar 不是 request 和 litmit 一样的。要 guaranteed 的话必须 sidecar 的 QoS 相关配置也要改。你们是怎么做的?如果改,建议设置为多少?感谢大佬! 28 | 29 | > 我们通常 sidecar 内存 limit 200M,cpu limit 是业务的 10% 到 20%,但我觉得这个没有通用的参考数据,需要结合业务场景压测拿到数据,更为科学。 30 | 31 | 1. 你好。作为业务方的技术负责人,被中间件团队推动上 Istio,目前带来的收益主要是服务治理方向的。从业务迭代效率的角度看,上 Istio 的增量收益抵不上迁移成本的代价;另外还降低了业务方工作的技术含量。请问有没有实践中,业务方在 Mesh 化的过程中获得显著收益的例子? 32 | 33 | > 不能只关注 mesh 自身的能力,还要深入了解业务,最好是能挖掘业务最痛点的问题,比如原有框架治理能力比较弱,或者可视化能力弱,或者变更效率低等,业务最痛点的问题对于 mesh 来说可能是普通的能力,但却会给业务线带来很大的提升。 34 | 35 | 1. 为什么没有采用 mcp over xds 的方案? 而是独立搭建了 API server 和 etcd? 36 | 37 | > api server + etcd 可以比较容易的独立部署,能复用尽量复用。 38 | 39 | 1. pilot 的多业务方案是怎么做的? 如果是多个 pilot 的话,那独立的 Kubernetes API server 和 etcd 也要多个么? 40 | 41 | > 我们目前的实践是 api server + etcd 是一套,pilot 根据业务线多套,当然 api server + etcd 也可以是多套,可以根据系统性能以及数据隔离等需求灵活部署。 42 | 43 | 1. Envoy 的 brpc 改造方案,会考虑开源么? 怎么 follow 后续社区 Envoy 的最新代码呢 44 | 45 | > brpc 本身也是开源的,Envoy 只是做了集成。社区版本更新很快,具体多久更新一次其实很难抉择,需要考虑架构升级成本,以及社区版本的成熟度,这块我也没有太好的建议。 46 | 47 | 1. 内部的 mesh 方案,考虑通过百度云的方式对外输出么? 48 | 49 | > 一些高级策略能力会逐步输出到公有云产品。 50 | 51 | 1. 随着 istio 新版本的不断发布,内部使用的版本是否跟进了开源新版本,跟进社区版本升级有什么经验分享? 52 | 53 | > 同上,社区版本更新很快,具体多久更新一次其实很难抉择,需要考虑架构升级成本,以及社区版本的成熟度,这块需要结合团队现实情况考虑升级时机。 54 | 55 | 1. Envoy filter 管理麻烦的话,nshead、dubbo 等多协议支持是怎么实现的?在 pilot 中是如何管理的? 56 | 57 | > 我们内部是直接在 pilot 内部实现支持,类似于 http 的功能。 58 | 59 | 1. 引入两个 sidecar 后问题定位的成本和难度会大福增加,这块有什么经验可以分享 60 | 61 | > 一方面 Envoy 自身提供了丰富的接口,可以暴露内部很多的状态,另一方面也需要和自有监控基础设施对接。 62 | 63 | 1. Sidecar 带来的额外成本问题谁来买单?业务认可吗 64 | 65 | > 这个其实需要和业务团队明确,额外的资源成本是需要业务买单的,但对于内部业务,具体的成本可以比较低,业务普遍是能接受的。 66 | 67 | 1. Sidecar 可以使用的的资源配额是怎么分配管理的,动态的还是静态的,有什么经验 68 | 69 | > 不同的业务场景可能不太一样,内存大概在几百 M,CPU 一般是是业务的 10% 到 20%,但最好是要根据业务场景进行压测,得到数据。 70 | 71 | 1. Sidecar 的监控是怎么做的? 权限,成本方面可能都有一些疑问 72 | 73 | > Envoy 本身会暴露自身指标,对接相关的监控即可。 74 | 75 | 1. Naming 这个 agent 和框架非常不错,请问 Naming 可以支持负载均衡么, 也就是 PodX 访问 PodY 的时候,naming 不要返回 PodY 真实 IP,而是返回负载均衡的 VIP 给 PodX; 十分感谢 - Ken 76 | 77 | > 目前没有这么做,直接返回了 Envoy 的 loopback ip 来做流量劫持。 78 | 79 | 1. 这种架构的话,PodX 主动出公网的逻辑是怎样的呢,也是通过 ip-masq 做 NAT 吗? 80 | 81 | > 目前主要做内网服务的 mesh,这块没有太多经验,十分抱歉~ 82 | 83 | 1. Naming agent 是部署在哪个容器? 84 | 85 | > 是一个主机部署一个的单机 agent,工作在主机网络上的。 86 | 87 | 1. Pliot 在落地过程中部署模型,大规模 Envoy 注册后,是否存在一些性能瓶颈,有什么优化的经验? 88 | 89 | > 可以增加 pilot 的副本数,来应对大规模 Envoy 的链接,另外控制面处理逻辑也有很多可以优化的地方,来优化从 API server 拿到数据之后的计算过程,这部分需要对 pilot 代码有一定开发经验和熟悉程度。 90 | 91 | 1. 虽然老师不一定有关注这一块,但也提个问题看看吧。 Envoy 流量劫持是在 userSpace 还要经 TCP 协议栈其实损耗非常大的,后续 Envoy 有考虑 byPass Kernel,直接传包给网卡驱动提速么(例如 DPDK、SPDK) 92 | 93 | > 这个一方面要考虑成本问题,比如内核和硬件是否满足,另一方面也要评估收益,比如流量劫持这一部分虽然优化了,但是缩减的耗时对于整个请求链路的占比是否足够明显。 94 | 95 | 1. 流量都经过 sidecar 后,sidecar 在 trace 这方面是怎么考虑和设计的? 96 | 97 | > Envoy 本身支持 trace 相关的功能,这块其实是需要业务 sdk 中来进行支持,必须要透传 trace 相关的信息。 98 | 99 | 1. 对于 inbound 流量的限流是如何设计的呢? 100 | 101 | > 可以使用 EnvoyFilter CRD,给被调用方 inbound listener 插入 LocalRateLimiter 对应的 filter 来实现。 102 | 103 | 1. 私有协议如果要变更的时候,是不是要级联更新? 104 | 105 | > 抱歉,这个问题没太看明白~ 106 | 107 | 1. 支持服务治理的配置灰度下发吗?可以简单说下实现方案吗 108 | 109 | > 内部其实是实现了,方案比较复杂,简单来说就是控制面自己控制 xds 下发,会先挑选部分实例生效,然后再给全部实例下发。 110 | 111 | 1. 你们 内部对于 istio deployment 里的 version 字段在落地时有大规模使用吗?我们最近在基于 istio 做灰度发布,但是每次灰度都要给他一个版本号,导致完成之后 deployment 名称就从 v1 变成 v2 以此累加,这样还会导致 deployment 本身的回滚功能失效。 112 | 113 | > 我理解是不是只需要 v1 和 v2 就够了,先灰度给 v1,没问题的话 v2 也生效,这时候 v1 和 v2 策略就打平了。下次恢复依然还是这个流程,好像不需要一直叠加版本好吧,不确定我理解的对不对~ 114 | 115 | 1. Envoy 对于我司来说技术储备其实不是很够, 请问贵司刚上线的时候, Envoy 有没有遇到哪些问题。 特别是稳定性和故障方面。 如果能建议一下 Envoy 应该如何监控,那就 perfect. 116 | 117 | > Envoy 本身比较复杂,上线初期一定会遇到问题,最好是能结合流量劫持方案,做到 Envoy 故障自动 fallback,思路可以参考分享内容。监控的话,Envoy 自身会暴露 stats 接口,比较容易接入监控系统。 118 | 119 | 1. 对于 dubbo 的泛化调用,探针会实时检测调用关系的变化么?如果 sidecar 还没有被生成,这个时候流量请求阻塞怎么处理呢?一直等待还是直接拒绝?如果服务是新的请求呢? 120 | 121 | > 泛化调用这种比较灵活的方式,我们目前也没有很好的支持,一个思路是可以提前手动配置好调用关系。 122 | 123 | 1. link 模型解决 xDS 问题,可以再详细介绍一下整个逻辑链路么?例如 consumer 和 provider 的 link 数据是怎么获得的 124 | 125 | > 目前内部大规模落地的方案中,是需要用户在产品上显示定义的。 126 | 127 | 1. 2ms 的 Envoy 额外消耗,请问是怎么查看的呢?curl endpoint 跟 curl Envoy 做一次对比么 128 | 129 | > 官方的测试方法没有详细研究过,自己测试的话,可以用经过 Envoy 和 没经过 Envoy 的耗时 diff,也可以在程序里打点来看。 130 | 131 | 1. Envoy 注入后业务 pod 会存在 2 个 container, 那么 Envoy 的配额是怎么限制的呢? 比如限制 4 核心可能就是 2 个容器(1 个 pod)里面的配额了; 132 | 133 | > 可以参见上面的回答 134 | 135 | 1. 就是我们在落地的时候,会遇到部分服务有 sidecar,部分没有 (服务 A 会被其他 10 个服务调用),一般如何去判断配置设置在哪里,是在 outbound(其他 10 个服务部署 sidecar)处还是 inbound 处(服务 A 部署 sidecar)。这个有没有什么比较好的实践 136 | 137 | > 这个需要结合流量劫持方案,做到有 sidecar 就过 sidecar,没有就走直连,具体思路可以参考分享内容。 138 | 139 | 1. Envoy 如何实现长连接的动态开关的? 140 | 141 | > 这个问题比较好,我们是通过让 Envoy 重新生成一个 lisener,更改了 listen 的地址,让调用 Enovy 的 SDK 感知到,并重新链接。 -------------------------------------------------------------------------------- /istio-big-talk/004/istio-big-talk-slide-004.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-big-talk/004/istio-big-talk-slide-004.pdf -------------------------------------------------------------------------------- /istio-big-talk/005/README.md: -------------------------------------------------------------------------------- 1 | # 第 5 期 2 | 3 | - 分享时间:2021 年 6 月 30 日(周三)晚 8 点到 9 点 4 | - 议题名称:腾讯云服务网格生产落地最佳实践 5 | - 主持人:宋净超(Tetrate) 6 | - 分享嘉宾:钟华(腾讯云) 7 | - 直播间地址: 8 | - 回放地址: 9 | - 提问地址: 10 | 11 | 钟华,腾讯云高级工程师,Istio contributor,Dapr contributor, Tencent Cloud Mesh 技术负责人。专注于容器和服务网格,在容器化、服务网格生产落地和性能调优方面具有丰富经验。 12 | 13 | 通过本次分享了解大规模场景下,Istio 性能调优和最佳实践,包括 xDS 懒加载,控制面负载平衡,控制面灰度升级,Ingress gateway 优化等。 14 | 15 | ### 分享大纲 16 | 17 | 1. Istio 生产落地挑战 18 | 2. 腾讯云服务网格全托管架构介绍 19 | 3. 大规模服务网格性能优化 20 | 4. Istio 生产落地最佳实践 21 | 22 | ### Q&A 23 | 24 | 1. Istio 的 gateway 对比 ambassador 的差异在哪?是否在 Istio 的基础上增加 api 网关这一层?增加后能填补哪些缺陷? 25 | 26 | 答:Ambassador 本身也是基于 envoy 之上的一个云原生网关产品, 本身包括控制平面;api gateway 范畴包括一些 Istio ingress gateway 不具备的功能,比如 api 生命周期管理,api 计费,限速,监控,认证等。所以 api gateway 本身有存在的必要,不过 API Gateway 需求中很大一部分需要根据不同的应用系统进行定制。 27 | 28 | 我们有客户将 kong, openresty 等 api gateway 和 Istio ingress gateway 结合起来用。 29 | 30 | 2. 对于多集群 Istio 部署了解到架构图如下所示,由单个控制平面管控所有集群,这里如果有 k8s 集群间网络不通,pod 与 pilot 交互链路是? 31 | 32 | 答:数据面 k8s 间不互通,不会影响 控制面和数据面的通信。 33 | 34 | Istio 多集群的前提是:多 k8s 之间要互通,可以是 pod 扁平互通,或者通过 Istio gateway 互通。 35 | 36 | 3. Istio Envoy Sidecar 使用 iptables 劫持流量,一定规模环境下性能损耗较大,排障复杂,很多大厂都是自研 Envoy,比如阿里蚂蚁金服、新浪、腾讯、华为等,自研的 Envoy 是使用什么来劫持流量呢,亦或者说自研的 envoy 解决了原生的 envoy 哪些缺陷呢? 37 | 38 | 答:常见的有三种: 39 | 40 | 1)uds:数据包不过协议栈,性能高,但只适合私有 mesh,因为需要应用面向 uds 编程。不适合公有云。比如美团,字节在使用这种方案。 41 | 42 | 2)localhost+port:使用 port 代表不同的服务,通常需要拦截服务发现流量,再重新规划服务到端口映射,有一定管理成本,比如百度在使用这种方案。 43 | 44 | 3)ebpf:在内核 socket ops 挂载 ebpf 程序,应用流量和 envoy 流量在 这个互通,流量不经过协议栈,性能高,对用户透明,但技术门槛高,对内核有版本要求。目前腾讯云 TCM 在小范围推广。 45 | 46 | 4. 长连接的情景下懒加载又是如何实现的?Workload 流量如何重定向到 egress,通过 passthrough? 47 | 48 | 1)目前 lazy xds 对长连接没有特殊处理,用户需要权衡一下,首跳长连接性能 vs 数据面内存开销,以此决定是否使用长连接,大家如果对长连接 lazy xds 有想法,欢迎联系我。 49 | 50 | 2)没有走 passthrough,请看 lazyxds 架构图上第二步,是会给 workload 2 下发具体的重定向规则,也就是指明哪些服务流量要到 lazy egress。 51 | 52 | 5. 钟老师您好, Istio 属于较新的技术,能否推荐一下监控应该怎么做, 或具体监控哪些指标? 另外,下图步骤 10, Istiod 更新的时候是全量所有 workload 都更新吗, 还是只更新 wordload1 ? 53 | 54 | 1)mesh 监控包括三个方面:metric, tracing,logging, TCM 技术选型偏云原生:metric 使用 prometheus, tracing 使用 jaeger collector, logging 是自研的技术。另外也用到了腾讯云上的监控服务。 55 | 56 | 2)只更新 workload1,注意架构图上的第八,sidecar 里会指定具体的 workload。 57 | 58 | 6. Istio 目前的性能优化有什么实践经验吗 59 | 60 | 答:TCM 团队之前在 kubeconf 上有数据面性能分享,请参考:[深入了解服务网格数据平面性能和调优](https://cloud.tencent.com/developer/article/1685873)。 61 | 62 | 7. 请问 isitod 的稳定性有什么实践经验可以分享吗,failback,failover 容错机制是怎么实现的? 63 | 64 | 1. 本次分享包括 2 个 Istiod 稳定性实践:如何保证 Istiod 负载平衡,如何对 Istiod 做灰度升级 65 | 2. 数据面 failback,failover 本身是 envoy 的能力,Istio 会给 eds 设置 priority, 这个值表示和 当前 pod 的亲和度(地域和区域),(如果开启就近访问)服务访问会优先访问 priority 为 0 的 endpoint, 如果为 0 的 endpoint 都失效了,访问会 failover 到 priority 为 1 的 endpoint,接下来是 priority 为 2 的,逐级失效转移。 66 | 67 | 8. Istio 与已有的基础设施 (注册中心等) 如何整合,是使用 mcp 还是 k8s api server 实现 68 | 69 | 答:之前我们尝试过 mcp,不过比较难调试,目前我们更推荐使用扩展 service entry 方式,参考我们开源的 [dubbo2istio](https://github.com/aeraki-framework/dubbo2istio) 或 [consul2istio](https://github.com/aeraki-framework/consul2istio)。 70 | 71 | 9. TKE 注入 sidecar pod 会从 1 个容器升级为 2 个容器,请问 pod 对集群内其他 pod 访问的链路是怎么走的呢? 20:28 说到控制面板资源 HPA 后依然会紧张,能否建议下 ISTIOD 的资源应该如何设计么, 比如 n 个 pod 对应 1 个 Istiod。 72 | 73 | 1. client 业务容器 ->client pod iptables->client envoy (将 service ip 转成 pod ip) -> node (iptables 不做 service nat 了) -> server pod iptables-> server envoy -> server 业务容器 74 | 2. 需要结合业务做压测,通常建议可以把 request 设小一点,把 limit 设大一点。 75 | 76 | 10. isito 的部署模型是怎么样的?是每个业务部署一个 isitod 集群,还是多个业务共享? 77 | 78 | 答:TCM 托管场景下,每个 mesh 有一个 Istiod。Istiod 按照 namespace 隔离。 79 | 80 | 11. namespace 是如何划分的,是按照业务来划分吗? 81 | 82 | 答:TCM 场景下,是的,通过 namespace 隔离多租户的控制面。 83 | 84 | 12. Istio 使用 envoyFilter 做限流,可以在 inbound 上根据 url 前缀匹配或者接口级别的维度做限流么?目前看只能在 outbound 上引用 virtualService 里面的配置,inbound 只能限制总流量。 85 | 86 | 答:目前社区应该不支持 url 级别的限流,需要自研。这个需求是刚需,我们可以一起调研下解决方案。 87 | 88 | 13. CRD 托管的原理能详细介绍下吗? 89 | 90 | 答:核心使用的是 kubernetes aggregation 技术,把 Istio CRD 作为 kubernetes 的外部扩展。 91 | 92 | 当用户读写 Istio crd 时, api server 会将流量路由到我们指定的外部服务,我们这外部服务实现了 crd 的托管。 93 | 94 | 14. Envoy 如何做热更新?怎么在容器内注入新版本的 Envoy? 95 | 96 | 答:热更新核心是通过 UDS(UNIX Domain Socket),可以参考下 openkruise 解决方案,不过该方案只能解决仅有镜像版本变化的更新,对于 yaml 变化太大的更新,目前不好处理。 97 | 98 | 15. 业务容器已经启动接收流量了,而 envoy 还没完成 eds 的下发,出现流量损失?Istio 是否会出现这种情况? 99 | 100 | 答:会的,所以需要遵循 make before break,核心原因在于:目前 Istio 实现中,没法知道 规则下发是否完全生效。 101 | 102 | 目前的姑息办法是 make before break + 等待一定时间。 103 | 104 | 16. 如何支持 `subdomain-*.domain.com` 这样的 host 规则?Envoy 是不支持的,有没有方法可以扩展 105 | 106 | 答:目前的确不支持,建议去社区提 issue,参与共建。不过 Istio 的 header match 支持正则,可以尝试使用 host header,或者 authority 属性,需要验证一下。 107 | 108 | 17. Istio 可否实现类似于 dubbo 服务的 warmup 机制,动态调整新注册 pod 的流量权重由低到正常值?ZPerling 109 | 110 | 答:Envoy 社区有提案,目前没有完成:[issue #11050](https://github.com/envoyproxy/envoy/issues/11050) 和 [issue 13176](https://github.com/envoyproxy/envoy/pull/13176)。 111 | 112 | 18. Mysql 和 mq 可以做版本流量控制吗?他们的流量识别怎么做呢? 113 | 114 | 答:目前不行,这是 Istio 的软肋,envoy mysql filter 功能比较基础,关注下 Dapr 这个项目。 115 | 116 | 19. 原来的 SpringCloud 项目 服务注册发现 & 配置中心用的 consul,如果切换 Istio 的话,服务发现和配置中心要怎么支持? 117 | 118 | 答:注册发现考虑下 [consul2istio](https://github.com/aeraki-framework/consul2istio),另外 SpringCloud 组件可能需要做一些减法,去掉一些 Istio 支持的流控能力组件。 119 | 120 | 20. SpringCloud 项目 通过 K8s 集群部署,切换到 Istio,原来业务依赖的中间件通信方式需要改变?原本的流量如果直接切换到 Istio 风险较高,有没有一键下掉 Istio 的开关或者这种机制:降低有问题流量降级切换到原来的部署架构? 121 | 122 | 1)可能改变的通信方式:主要是服务发现过程改变。Istio 支持透明接入,通常中间件的通信方式不会受影响。 123 | 124 | 2)这个能力的确会给刚开始 mesh 化的业务带来信心,开源 Istio 没有这个能力,参考之前百度陈鹏的分享。 125 | 126 | 21. 使用 traefik 作为边缘代理,Istio 来管理服务内部的流量。traefik 转发策略是直连 pod,而不是走 k8s 的 service,如何使用 Istio 来管理到达服务的流量? 127 | 128 | 答:抱歉我对 traefik 并不熟悉,不过大概看了这篇[在 Istio 服务网格中使用 Traefik Ingress Controller](https://cloudnative.to/blog/using-traefik-ingress-controller-with-istio-service-mesh/),流量从 traefik 出来是经过了 envoy,在这里应该还可以做服务治理,后面我再研究下。 129 | 130 | 22. 目前 Istio 版本缺失限流功能,这部分要怎么支持? 131 | 132 | 答:目前 Istio 支持 local 和 global 两种方式,不过 local 无法多 pod 共享限频次数,global 性能可能不一定满足用户需求。 133 | 134 | 目前社区应该不支持 url 级别的限流,需要自研。这个需求是刚需,我们可以一起调研下解决方案。 135 | 136 | 23. 现有 K8S 集群业务切换到腾讯云 Istio 部署需要做哪些操作?成本高? 137 | 138 | 答:看当前业务的技术特征,如果是 http、grpc+ k8s 服务发现,迁移成本比较低,如果有私有协议,会有一定难度。 139 | 140 | 24. 是一套 k8s 对应一套 Istio,还是一套 Istio 对应多个 k8s 集群?多集群是怎么做的? 141 | 142 | 1. 主要看业务需求,如果有跨集群业务互访,或者跨集群容灾,就可以考虑使用 Istio 多集群方案。 143 | 2. 多集群实现可以参考我之前的分享:[Istio 庖丁解牛 (五) 多集群网格实现分析](https://zhonghua.io/2019/07/29/istio-analysis-5/) 和 [istio 庖丁解牛 (六) 多集群网格应用场景](https://zhonghua.io/2019/08/01/istio-analysis-6/)。 144 | 145 | 25. Istio 下的服务限流方案? 146 | 147 | 答:目前支持 local 和 global 两种方式,参考 [Enabling Rate Limits using Envoy](https://istio.io/latest/docs/tasks/policy-enforcement/rate-limit/),另外网易 slime 中有动态的限流方案。 148 | 149 | 26. Istio 到现在都不支持 path rewrite 的正则,这块是否有一些社区的方案支持,因为这个策略在实际的业务中还是很常见的 150 | 151 | 答:目前的确不支持,建议去社区提 issue,参与共建。 152 | 153 | 27. 多网络单控制平面的情况下,从集群如果没有某服务的 Pod 的话,该集群其他 Pod 通过域名访问主集群 pod 的话从集群必须有空的 svc 吗,有其他什么方案实现吗 智能 dns 方案成熟了吗?Pilot Agent 不是有 DNS Proxy 么 154 | 155 | 答:Istio 1.8 提供的 智能 DNS 可以解决这个问题,1.8 里有 bug, 1.9 修复了,目前我们有生产客户在用了,目前看起来生产可用,可以尝试。 156 | 157 | 28. 切换到 istio, 原来业务依赖的中间件通信方式需要改变?MySQL Redis Consul Kafka 158 | 159 | 答:Istio 对 db mesh 支持功能不多,通信方式不需要改变。 160 | 161 | 29. 推荐使用哪个版本的 Istio? 162 | 163 | 答:建议使用次新版本,比如现在 1.10 发布了,建议使用 1.9;未来 1.11 发布了,就要着手升级到 1.10。 -------------------------------------------------------------------------------- /istio-big-talk/005/istio-big-talk-slide-005.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-big-talk/005/istio-big-talk-slide-005.pdf -------------------------------------------------------------------------------- /istio-big-talk/006/README.md: -------------------------------------------------------------------------------- 1 | # 第 6 期 2 | 3 | - 分享时间:2021 年 8 月 3 日(周三)中午 12:30 点到 2 点 4 | - 议题名称:腾讯云服务网格生产落地最佳实践 5 | - 主持人:宋净超(Tetrate) 6 | - 分享嘉宾:周礼赞(Tetrate) 7 | - 直播间地址: 8 | - 回放地址: 9 | - 提问地址: 10 | 11 | 我们在过去两个月内已经陆续举办了 5 期《[Istio 大咖说](http://mp.weixin.qq.com/s?__biz=MzI1NTE2NDE2MA==&mid=2649385244&idx=1&sn=c03da04686c82d75a62c214f851da48b&chksm=f224e373c5536a655f5f7270da8ed66f3f92d55f9a3a92d26125d14699fd40e3112db397cedf&scene=21#wechat_redirect)》,直播过程中很多观众反馈想要了解下 Envoy,有很多关于 Envoy 的问题却没有人可以来解答,而 Envoy 作为 Istio 中默认的数据平面,可以说如果你搞懂了 Envoy 就算把 Istio 搞懂 80% 了。这次我们邀请了来自企业级服务网格提供商 Tetrate 公司的周礼赞,他是 Envoy 的核心 maintainer。 12 | -------------------------------------------------------------------------------- /istio-big-talk/007/README.md: -------------------------------------------------------------------------------- 1 | # 第 7 期 2 | 3 | - 分享时间:2021 年 8 月 25 日(周三)晚上 8:00 到 9:00 4 | - 议题名称:基于 Envoy/Istio 的云原生 API 网关 —— 开源项目 Hango 的设计与实现 5 | - 主持人:宋净超(Tetrate) 6 | - 分享嘉宾:韩佳浩(网易轻舟) 7 | - 直播间地址: 8 | - 回放地址: 9 | - 提问地址: 10 | - PPT 下载:见 [Istio 大咖说往期节目列表](https://github.com/tetratelabs/istio-weekly)) 11 | 12 | ## 讲师简介 13 | 14 | 韩佳浩,网易数帆资深研发工程师,主导 Hango 网关开源研发及设计,负责网易数帆轻舟 API 网关集团内部大规模落地及产品化建设。具有三年网关相关研发及大规模实践经验。 15 | 16 | ## 话题介绍 17 | 18 | 云原生架构演进下,更多的业务着重于 API 的统一暴露,API 网关便成为 API 统一接入的必备组件。本次分享主要从云原生概念出发,探讨云原生模式下 API 网关的选型之道;介绍网易研发的高性能、可扩展,功能丰富的云原生 API 网关 Hango 的设计之道以及落地实践。 19 | 20 | ## 问答 21 | 22 | 1. Envoy体系学习图谱,现在是整体文档都看完有用到时再翻文档 23 | 24 | 答:可以关注社区动态,学习思路路线上可以根据自己想对 Envoy了解的程度按照以下线路进行:了解 Envoy 基本架构 -> 使用 Envoy 常用特性 -> 尝试扩展 envoy -> 对 Envoy 做深度定制,另外 Tetrate 即将推出免费的 Envoy 教程,敬请关注。 25 | 26 | 2. Hango项目与网易轻舟项目是什么关系?开源版么? 27 | 28 | 答:网易轻舟项目包含轻舟微服务、轻舟API网关、轻舟容器等产品,轻舟API网关是Hango项目的商业版。 29 | 30 | 3. Ingress Controller与API Management是否有必要合为一个产品? 就是 k8s 资源,意思两个产品位置是否需要合一? 31 | 32 | 答:具体需要看网关的定位,如果作为微服务网关的话,不建议合为一个产品;如果承担ingress功能,可以合一。 33 | 34 | 4. 使用 Envoy 以网关的形式和以 Sidecar 的形式做服务治理有什么区别,使用场景分别是什么呢?以网关的形式做东西南北向流量的服务治理的方案可行吗? 35 | 36 | 答:网关主要做南北流量治理;Sidecar承担集群东西流量治理。在大规模场景下,不建议网关作为东西流量治理;服务调用关系简单,API规模有限可以。 37 | 38 | 5. Hango必须配合Istio一起使用吗? 39 | 40 | 答:推荐使用Istio, 仅单独使用网关数据面丧失网关动态配置能力,自身静态配置复杂度也大大提高。 41 | 42 | 6. 接问题5,如果是可以独立使用,在k8s内额外创建一个网关,这个网关目的是什么,这在集群内服务之间互访的时候等于破坏了Kubernetes本身的svc特性,consumer服务找这个网关所注册的服务?能否举例一个具体的场景。 43 | 44 | 答:不推荐独立使用,网关的功能对外统一暴露集群内API。网关暴露的意义,一部分是代理,另一部分是丰富的治理功能以及多维度的指标监控。 45 | 46 | 7. 加载 Lua后性能有下降吗? 47 | 48 | 答:简单的插件,性能基本在20%损失。 49 | 50 | 8. 边缘网关有哪些场景?看到ppt里有写,但是没有讲。 51 | 52 | 答:类似集群中的统一API暴露,只是不需要额外的用户配置。 53 | 54 | 9. 性能没太看懂,9wqps是几台机器?几c? 55 | 56 | 答:容器:8c8g 物理机:56c256g 57 | 58 | 10. lua 怎么保证脚本安全?隔离性怎么样?写个while true 会不会把整个网关搞崩? 59 | 60 | 答:lua的插件链的异常不会导致主线程crash,异常后跳过逻辑,执行之后的插件链。 61 | 62 | 11. 大规模场景下,踩过哪些坑 63 | 64 | 答:升级的平滑度以及线上规模的预估。 65 | 66 | 12. 可以认为是在Istio gateway + virtualservice的一个升级版么? 是不是用了这个网关我就可以不用Istio gateway了? 67 | 68 | 答:是的 69 | -------------------------------------------------------------------------------- /istio-big-talk/007/istio-big-talk-slide-007.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-big-talk/007/istio-big-talk-slide-007.pdf -------------------------------------------------------------------------------- /istio-big-talk/008/README.md: -------------------------------------------------------------------------------- 1 | # 第 8 期 2 | 3 | - 分享时间:2021 年 11 月 9 日(周二)晚上 8:00 到 9:30 4 | - 议题名称:小红书服务网格大规模落地经验分享 5 | - 主持人:宋净超(Tetrate) 6 | - 分享嘉宾:贾建云(小红书) 7 | - 直播间地址: 8 | - 回放地址: 9 | - 提问地址: 10 | - PPT 下载:见 [Istio 大咖说往期节目列表](https://github.com/tetratelabs/istio-weekly) 11 | 12 | ## 讲师简介 13 | 14 | 贾建云,小红书 Kubernetes 云原生工程师,负责小红书服务网格相关工作。主导设计了小红书服务网格落地方案,对于大规模服务网格落地、调优有丰富的经验。 15 | 16 | ## 话题介绍 17 | 18 | 1. 小红书基于 Istio 的服务网格方案和架构设计 19 | 2. 小红书对于 Pilot、Envoy 做的特性增强 20 | 3. 小红书落地服务网格碰到的性能/Bug 问题 21 | 22 | ## 听众收获 23 | 24 | 了解小红书服务网格关于流量拦截、thrift 协议、懒加载等做的特性增强,同时了解在大规模落地服务网格过程中碰到的控制面性能问题,以及 ServiceEntry 场景下 pilot 存在的 Bug。 25 | 26 | ## 问答 27 | 28 | 1. 我们在落地Istio 中碰到一个坑是 envoy 的 connection idleTime 和各种语言的 keepalive 时间不同,在大量使用长连接(http1.1)的情况下,可能会出现客户端用现有的长连接发起请求,但是服务端连接刚好超时回收了,导致会有部分请求 503(报错是 connection reset),在 Istio 社区也看到了这类的 issue,但是都没发现一个合适的解决方案。Istio 默认内置的重试条件中不包括 connection reset 这种情况,可能是害怕对非幂等请求的重试。不知道小红书内部有没有类似的问题? 29 | 30 | 答:这个问题可以参考Envoy官网关于超时时间设置的[最佳实践](https://www.envoyproxy.io/docs/envoy/v1.17.1/faq/configuration/timeouts)。 31 | 32 | 2. Envoy是否考虑降级,以应对envoy异常时跳过sidecar直接访问服务,不知道是否有类似经验? 33 | 34 | 答:我们目前是通过监听实际端口来做流量拦截的,这样当出现问题之后我们会让sdk把流量切换到中央sidecar。这种流量回滚方式与我们的流量拦截方式强相关,同时也对sdk有一定入侵,可以看一下小红书关于流量拦截方案的介绍。 35 | 36 | 3. xds 和 eds 分开会不会有数据不一致的问题? 37 | 38 | 答:不会有问题 39 | 40 | 4. 有没有使用webassembly开发扩展? 41 | 42 | 答:小红书暂时没有使用wasm,扩展是直接开发envoy filter。 43 | 44 | 5. 配置灰度下发解决思路是什么? 45 | 46 | 答:跟我们sidecar灰度升级的思路比较一致,通过创建cluster/ns/service粒度的升级任务,由pilot决定配置要下发给哪些sidecar 47 | 48 | 6. Envoy引入brpc是替换了Envoy哪些部分? 49 | 50 | 答:不算事替换吧,是想做到自由切换线程模型,引入bthread。 51 | 52 | 7. 虚机服务(通过域名+nginx+tomcat)如何解决服务网格的灰度上线? 53 | 54 | 答:虚拟机跟pod应该是一样的,通过创建dr维护版本信息,然后配置流量配比。 55 | 56 | 8. 手动维护服务依赖的话还算懒加载吗? 57 | 58 | 答:严格意义上面不算了。但是本质上都是为了做服务可见性。 59 | 60 | 9. 懒加载中hosts依赖的serviceEntry信息是不是依然要全局envoy下发? 61 | 62 | 答:特定服务的所有实例/流控配置是全量的,这个跟pilot实现有关,目前社区的新版本已经在开发增量推送了,可以关注一下。 63 | 64 | 10. 不拦截入流量的话要做 inbound 的策略怎么办? 65 | 66 | 答:原生的方案inbound本身也没有什么流量治理的特性,就是流量转发,所以我们不担心不拦截inbound会有流量治理能力的缺失。主要是担心可观察性会有影响,目前期望通过SDK补齐丢失的指标。 67 | 68 | 11. 对 Istio multi-tenancy有支持增强吗? 69 | 70 | 答:小红书内部对多租户没有什么诉求,这个应该是公有云比较关心。 71 | 72 | 12. Thrift Proxy 的路由变化后会导致重建 Listener,线上业务可以接受客户端存量链接在路由规则变化后被断开吗? 73 | 74 | 答:目前业务方可以接受,我们是告知过这个事情的。另外就是社区已经有envoy thrift filter支持rds的pr,合并到主干之后我们会升级,届时就没有问题了。 75 | 76 | 13. 调用的下游过多的情况下,端口的冲突怎么解决? 77 | 78 | 答:端口不会冲突,一个Pod内部依赖的服务不会重复,每个服务都有唯一的端口。但是主机网络会存在端口冲突的情况,目前我们的方案就是让用户改为非主机网络。 79 | 80 | 14. 懒加载中serviceEntry+sidecar中如何支持按照route等方式配置http路由信息,就像virtualserver中支持的httproute功能? 81 | 82 | 答:使用serviceEntry+sidecar不影响vs等的使用。两个东西没有太大关系。 83 | 84 | 15. 老师提到了小红书用到了开源项目 Aeraki 来管理 Thrift 协议,请问这部分后续的开源计划? 85 | 86 | 答:后续会有团队小伙伴小红书分享关于aeraki做的扩展,但是应该不会合并到aeraki,内容偏小红书定制。 87 | 88 | 16. 流量拦截中还是用到了iptables(tproxy)模式,性能上会不会依然受影响? 89 | 90 | 答:会有影响的,但是用了tproxy模式会好一些。 91 | 92 | 17. 有没有Envoy数据面性能的参考数据,总体上和业务容器的平均占比会是怎样的,cpu 和内存呢? 93 | 94 | 答:按照我们内部一个业务的压测,单跳Envoy延迟增加2ms。Envoy大概占用0.5核,300m左右内存。后续我们会压测高QPS业务,届时我再补充数据。整体来看配置了懒加载envoy资源吃的不多。 95 | 96 | 18. 灰度下发的方案,不同sidecar配置的diff是保存在那个地方? 97 | 98 | 答:存储在mysql。 99 | 100 | 19. Istio 通过 virtualservice 做灰度的话,基于流量比例的灰度无法做到 session sticky,这个有最佳实践吗? 101 | 102 | 答:这个没有。目前小红书的灰度是通过注册中心来实现的。 103 | 104 | 20. 性能测试数据如何? 105 | 106 | 答:参考问题17。 107 | 108 | 21. 为什么不用 service 而用 serviceentry 呀?小红书内部没有使用 k8s service 吗? 109 | 110 | 答:小红书内部不用service,而且serviceentry可以支持虚机。 111 | 112 | 22. 老师能否介绍下小红书的Service Mesh发展到现在的程度,大概是多少人的团队,做了多久? 113 | 114 | 答:目前4个人,大概做了半年。 115 | 116 | 23. Envoy延迟的长尾情况呢? 117 | 118 | 答:还是比较明显的,这个跟Envoy线程模型有关吧。但是引入backuprequest会好很多,来自百度的内部实践。 119 | 120 | 24. 大佬微信发下? 121 | 122 | 答:请加入云原生社区 Istio SIG 交流,大佬在群里。 123 | 124 | 25. 原生 Istio 自动注入会跳过主机模式host的pod? 125 | 126 | 答:出于安全考虑 Istio一般也不敢直接在虚机上面拦,比较危险,最好还是不要用主机网络吧。非要用的话只能修改webhook吧。 127 | 128 | 26. 大佬服务注册这边是什么方案注册的 129 | 130 | 答:公司内部自研的注册中心,细节不太清楚,后续可能有同事分享小红书注册中心。 131 | 132 | 27. 请问sidecar热升级前后,通过istioctl ps 查看proxy的版本有变化吗? 133 | 134 | 答:不会有变化。版本号是我们自己在Envoy开发的api,跟istioctl ps哪个版本没关系。 135 | -------------------------------------------------------------------------------- /istio-big-talk/008/istio-big-talk-slide-008.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-big-talk/008/istio-big-talk-slide-008.pdf -------------------------------------------------------------------------------- /istio-big-talk/playlist.md: -------------------------------------------------------------------------------- 1 | # 往期节目列表 2 | 3 | - [001:Istio 开源四周年回顾与展望,马若飞(FreeWheel),2021.05.25](001) 4 | - [002:从微服务架构到 Istio——架构升级实践分享,潘天颖(小电科技),2021.06.02](002) 5 | - [003:如何让 Istio 变得更为高效和智能,杨笛航(网易数帆),2021.06.08](003) 6 | - [004:如何让 Istio 在大规模生产环境落地,陈鹏(百度),2021.06.23](004) 7 | - [005:腾讯云服务网格生产落地最佳实践,钟华(腾讯云),2021.06.30](005) 8 | - [006:Envoy Proxy 在线答疑,周礼赞(Tetrate),2021.08.03](006) 9 | - [007:基于 Envoy/Istio 的云原生 API 网关 —— 开源项目 Hango 的设计与实现,韩佳浩(网易轻舟),2021.08.25](007) 10 | - [008:小红书服务网格大规模落地经验分享,贾建云(小红书),2021.11.09](008) -------------------------------------------------------------------------------- /istio-weekly/000/README.md: -------------------------------------------------------------------------------- 1 | # What is GetIstio - Inaugural Community Meetup 2 | 3 | - Hosted by Orion Letizi 4 | - Presenters: 5 | - Zack Butcher 6 | - Christoph Pakulski 7 | - Recording date: Feb 18, 2021 8 | - Video: https://www.youtube.com/watch?v=EGzvJK0pzx8&list=PLm51GPKRAmTnMzTf9N95w_yXo7izg80Jc 9 | 10 | 11 | ## Show notes 12 | 13 | The inaugural meetup will be a special edition with 90 minutes to introduce the community, unpacking the GetIstio project, an overview of the GetEnvoy project and an update on what’s new in the Istio 1.9 release. We look forward to diving into the topics, demonstrating some new Istio capabilities and answering all of your questions during the Q&A session 14 | 15 | ### Agenda 16 | 17 | - Welcome and Introduction 18 | - GetIstio community 19 | - Community goals and objectives 20 | - Meeting cadence 21 | - Current stakeholders 22 | - Future topics 23 | - Community resources 24 | - Introduction to the GetIstio project with Zack Butcher 25 | - Review of the GetEnvoy project with Christoph Pakulski 26 | - Istio 1.9 Release Update 27 | - Demonstration of new features related to VMs, observability, and more 28 | - Demo pushed to next week due to Sean being out this week 😕 29 | - Q&A 30 | - Closing with community resource links 31 | 32 | ## Links 33 | 34 | Repositories: 35 | 36 | - https://github.com/tetratelabs/getistio 37 | - https://github.com/tetratelabs/getistio.io 38 | - https://github.com/tetratelabs/getenvoy 39 | - https://github.com/tetratelabs/getenvoy.io 40 | 41 | 42 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) -------------------------------------------------------------------------------- /istio-weekly/001/README.md: -------------------------------------------------------------------------------- 1 | # Effortless Envoy and WASM with GetEnvoy 2 | 3 | - Hosted by Sean O'Dell 4 | - Presenters: 5 | - Christoph Pakulski 6 | - Recording date: Mar 4, 2021 7 | - Video: https://www.youtube.com/watch?v=mauuUWrxpdk&list=PLm51GPKRAmTnMzTf9N95w_yXo7izg80Jc 8 | 9 | 10 | ## Show notes 11 | 12 | Episode 01 of the community launches into the broader Istio ecosystem with a look into Envoy and how, like GetIstio, the GetEnvoy project helps ensure success on any cloud or platform. Christoph Pakulski will be showing off the power of WASM and how Istio and Envoy are better together. 13 | 14 | ### Agenda 15 | - Interaction 16 | - YouTube 17 | - Show notes 18 | - Github repo - coming soon 19 | - Ask questions!! 20 | - Effortless Envoy and WASM with GetEnvoy 21 | - Community resources walkthrough 22 | - Future meetings 23 | 24 | ## Links 25 | 26 | Repositories: 27 | 28 | - https://github.com/tetratelabs/getistio 29 | - https://github.com/tetratelabs/getistio.io 30 | - https://github.com/tetratelabs/getenvoy 31 | - https://github.com/tetratelabs/getenvoy.io 32 | 33 | 34 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) -------------------------------------------------------------------------------- /istio-weekly/002/README.md: -------------------------------------------------------------------------------- 1 | # Istio the Easy Way with GetIstio 2 | 3 | - Hosted by Sean O'Dell 4 | - Presenters: 5 | - Zack Butcher 6 | - Recording date: Mar 18, 2021 7 | - Video: https://www.youtube.com/watch?v=Q5MQjwUpay0&list=PLm51GPKRAmTnMzTf9N95w_yXo7izg80Jc 8 | 9 | 10 | ## Show notes 11 | 12 | Episode 01 of the community launches into the broader Istio ecosystem with a look into Envoy and how, like GetIstio, the GetEnvoy project helps ensure success on any cloud or platform. Christoph Pakulski will be showing off the power of WASM and how Istio and Envoy are better together. 13 | 14 | ### Agenda 15 | - Welcome and Introduction 16 | - Community news 17 | - Future topics 18 | - Community resources 19 | - GetIstio 20 | - GetIstio CLI 21 | - GetIstio demo 22 | - GetIstio roadmap 23 | - getistio gen-ca 24 | - Generate intermediate CA from different managed services 25 | - Q&A 26 | - Closing with resource links 27 | 28 | ## Links 29 | 30 | Repositories: 31 | 32 | - https://github.com/tetratelabs/getistio 33 | - https://github.com/tetratelabs/getistio.io 34 | - https://github.com/tetratelabs/getenvoy 35 | - https://github.com/tetratelabs/getenvoy.io 36 | 37 | 38 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) -------------------------------------------------------------------------------- /istio-weekly/003/003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-weekly/003/003.png -------------------------------------------------------------------------------- /istio-weekly/003/README.md: -------------------------------------------------------------------------------- 1 | # SSL certificates in Istio ingress gateway 2 | 3 | - Hosted by [Orion Letizi](https://twitter.com/orionletizi) 4 | - Presenters: 5 | - [Peter Jausovec](https://twitter.com/pjausovec) 6 | - Recording date: May 27, 2021 7 | - Video: https://www.youtube.com/watch?v=nYJJ57WCkxE&list=PLm51GPKRAmTnMzTf9N95w_yXo7izg80Jc 8 | 9 | ![episode image](003.png) 10 | 11 | ## Show notes 12 | 13 | In episode 3, we will talk about how to set up SSL certificates in your Istio ingress gateway. We’ll show you how to use self-signed certificates (and why you should never do this) and how to automate certificate management. 14 | 15 | Demo script for all scenarios is [here](demo.md). 16 | 17 | ### Resources 18 | 19 | - Let’s Encrypt: https://letsencrypt.org/ 20 | - SSL For Free: https://www.sslforfree.com/ 21 | - cert-manager: https://cert-manager.io/docs/ 22 | 23 | ## Links 24 | 25 | - Community page: https://istio.tetratelabs.io/community 26 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) 27 | -------------------------------------------------------------------------------- /istio-weekly/003/demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: DEMO: Setting up SSL certificates on Istio ingress gateway 3 | date: 05/27/2021 4 | --- 5 | 6 | ## Prerequisites 7 | 8 | You'll need a Kubernetes cluster with [Istio installed](https://istio.tetratelabs.io/). You'll also need a domain name if you're doing the second and third scenario in the demo. 9 | 10 | ## Deploying a sample Hello World application 11 | 12 | Create the deployment and service: 13 | 14 | ```yaml 15 | apiVersion: v1 16 | kind: ServiceAccount 17 | metadata: 18 | name: hello-world 19 | --- 20 | apiVersion: apps/v1 21 | kind: Deployment 22 | metadata: 23 | name: hello-world 24 | labels: 25 | app: hello-world 26 | spec: 27 | replicas: 1 28 | selector: 29 | matchLabels: 30 | app: hello-world 31 | template: 32 | metadata: 33 | labels: 34 | app: hello-world 35 | spec: 36 | serviceAccountName: hello-world 37 | containers: 38 | - image: gcr.io/tetratelabs/hello-world:1.0.0 39 | imagePullPolicy: Always 40 | name: svc 41 | ports: 42 | - containerPort: 3000 43 | --- 44 | kind: Service 45 | apiVersion: v1 46 | metadata: 47 | name: hello-world 48 | labels: 49 | app: hello-world 50 | spec: 51 | selector: 52 | app: hello-world 53 | ports: 54 | - port: 80 55 | name: http 56 | targetPort: 3000 57 | ``` 58 | 59 | Save the above to `hello-world.yaml` and deploy it using `kubectl apply -f hello-world.yaml`. 60 | 61 | 62 | We also need to deploy a public gateway and a virtual service to expose the Hello world application through the ingress gateway: 63 | 64 | ```yaml 65 | apiVersion: networking.istio.io/v1alpha3 66 | kind: Gateway 67 | metadata: 68 | name: public-gateway 69 | spec: 70 | selector: 71 | istio: ingressgateway 72 | servers: 73 | - port: 74 | number: 80 75 | name: http 76 | protocol: HTTP 77 | hosts: 78 | - '*' 79 | ``` 80 | 81 | Save the above YAML to `gateway.yaml` and deploy it using `kubectl apply -f gateway.yaml`. 82 | 83 | ```yaml 84 | apiVersion: networking.istio.io/v1alpha3 85 | kind: VirtualService 86 | metadata: 87 | name: helloworld 88 | spec: 89 | hosts: 90 | - '*' 91 | gateways: 92 | - public-gateway 93 | http: 94 | - route: 95 | - destination: 96 | host: hello-world.default.svc.cluster.local 97 | port: 98 | number: 80 99 | ``` 100 | 101 | Save the above YAML to `vs.yaml` and deploy it using `kubectl apply -f vs.yaml`. 102 | 103 | Finally, let's get the external IP address of the ingress gateway: 104 | 105 | ```sh 106 | export INGRESS_IP=$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 107 | ``` 108 | 109 | If you run `curl $INGRESS_IP` you should get back a "Hello World" response. 110 | 111 | ## Using self-signed certificate 112 | 113 | In this scenario we are manually creating a self-signed certificate. First thing - pick a domain you want to use - note that to test this, you don’t have to own an actual domain name because we will use a self-signed certificate. 114 | 115 | I will use `tetratelabs.dev` as my domain name and I'll use a subdomain called `hello`. So we will configure the gateway with a host called `hello.tetratelabs.dev` and present the self-signed certificate. 116 | 117 | Let's store that value in a variable because we will use it throughout this example. 118 | 119 | ```sh 120 | export DOMAIN_NAME=tetratelabs.dev 121 | ``` 122 | 123 | I will also create a separate folder to hold the root certificate and the private key we will create. 124 | 125 | ```sh 126 | mkdir -p tetratelabs-certs 127 | ``` 128 | 129 | ### Creating the cert files 130 | 131 | Next we will create the root certificate called `tetratelabs.dev.crt` and the private key used for signing the certificate (file `tetratelabs.dev.key`): 132 | 133 | ```sh 134 | openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=$DOMAIN_NAME Inc./CN=$DOMAIN_NAME' -keyout $DOMAIN_NAME.key -out $DOMAIN_NAME.crt 135 | ``` 136 | 137 | The next step is to create the certificate signing request and the corresponding key: 138 | 139 | ```sh 140 | openssl req -out hello.$DOMAIN_NAME.csr -newkey rsa:2048 -nodes -keyout hello.$DOMAIN_NAME.key -subj "/CN=hello.$DOMAIN_NAME/O=hello world from $DOMAIN_NAME" 141 | ``` 142 | 143 | Finally using the certificate authority and it's key as well as the certificate signing requests, we can create our own self-signed certificate: 144 | 145 | ```sh 146 | openssl x509 -req -days 365 -CA $DOMAIN_NAME.crt -CAkey $DOMAIN_NAME.key -set_serial 0 -in hello.$DOMAIN_NAME.csr -out hello.$DOMAIN_NAME.crt 147 | ``` 148 | 149 | ### Creating the Kubernetes secret 150 | 151 | Now that we have the certificate and the correspondig key we can create a Kubernetes secret to store them in our cluster. 152 | 153 | We will create the secret in the `istio-system` namespace and reference it from the Gateway resource: 154 | 155 | ```sh 156 | kubectl create -n istio-system secret tls tetratelabs-credential --key=hello.tetratelabs.dev.key --cert=hello.tetratelabs.dev.crt 157 | ``` 158 | 159 | With secret in place, let's update the Gateway resource: 160 | 161 | ```yaml 162 | apiVersion: networking.istio.io/v1alpha3 163 | kind: Gateway 164 | metadata: 165 | name: public-gateway 166 | spec: 167 | selector: 168 | istio: ingressgateway 169 | servers: 170 | - port: 171 | number: 443 172 | name: https 173 | protocol: HTTPS 174 | tls: 175 | mode: SIMPLE 176 | credentialName: tetratelabs-credential 177 | hosts: 178 | - hello.tetratelabs.dev 179 | ``` 180 | 181 | Let's also update the VirtualService to update the host name: 182 | 183 | ```yaml 184 | apiVersion: networking.istio.io/v1alpha3 185 | kind: VirtualService 186 | metadata: 187 | name: helloworld 188 | spec: 189 | hosts: 190 | - hello.tetratelabs.dev 191 | gateways: 192 | - public-gateway 193 | http: 194 | - route: 195 | - destination: 196 | host: hello-world.default.svc.cluster.local 197 | port: 198 | number: 80 199 | ``` 200 | 201 | To try it out we will use cURL and set the host header to `hello.tetratelabs.dev` then tell curl to resolve the `hello.tetratelabs.dev` to the $INGRESS_IP address. Additionaly, we are also presenting the certificate authority cert we created: 202 | 203 | ```sh 204 | curl -H "Host:hello.tetratelabs.dev" --resolve "hello.tetratelabs.dev:443:$INGRESS_IP" --cacert tetratelabs.dev.crt "https://hello.tetratelabs.dev:443" 205 | ``` 206 | 207 | Notice we get back the response - just like we did before. We can re-run the command with `-v` for verbose output and you'll notice that the certificate was used. 208 | 209 | Next, let's see how we can use a service called SSL For Free to create a real certificate for a real domain. 210 | 211 | ## Using "SSL for Free" 212 | 213 | Note that for this you'll need an actual real domain name. For this demo I registered a domain called `istioweekly.com`. 214 | 215 | I have already created the certificate bundle on SSL For Free website. 216 | 217 | You can create your own certificate by clicking "New Certificate" button, provide the domain name and then verify the domain. There are multiple ways to do that, you can get a code sent to an email address from that domain, you can create a `CNAME` entry in the DNS records or you can upload a file to a specific location on your domain. 218 | 219 | Either way you go, once the domain is verified you'll be able to download a zip file with your certificate, certficiate key and the CA bundle. 220 | 221 | Once you extracted the certificate bundle file, we need to create a new Kuberentes secret to hold the private key and the certificate. Then we will have to update the gateway and the virtual service as well. 222 | 223 | Let's start with the secret: 224 | 225 | ```sh 226 | kubectl create -n istio-system secret tls istioweekly-credential --key=private.key --cert=certificate.crt 227 | ``` 228 | 229 | Let's update the Gateway with the secret name and the host: 230 | 231 | ```yaml 232 | apiVersion: networking.istio.io/v1alpha3 233 | kind: Gateway 234 | metadata: 235 | name: public-gateway 236 | spec: 237 | selector: 238 | istio: ingressgateway 239 | servers: 240 | - port: 241 | number: 443 242 | name: https 243 | protocol: HTTPS 244 | tls: 245 | mode: SIMPLE 246 | credentialName: istioweekly-credential 247 | hosts: 248 | - istioweekly.com 249 | ``` 250 | 251 | And also update the VirtualService: 252 | 253 | ```yaml 254 | apiVersion: networking.istio.io/v1alpha3 255 | kind: VirtualService 256 | metadata: 257 | name: helloworld 258 | spec: 259 | hosts: 260 | - istioweekly.com 261 | gateways: 262 | - public-gateway 263 | http: 264 | - route: 265 | - destination: 266 | host: hello-world.default.svc.cluster.local 267 | port: 268 | number: 80 269 | ``` 270 | 271 | You can now navigate to the domain to see the "Hello World" response as well as the padlock that shows the connection is secure. 272 | 273 | 274 | In order to hook-up your domain name with the ingress IP, you have to update the DNS records on the domain. Specifically, create an A record and point it to the external IP address of the ingress. That way, when you type your domain name (e.g. `istioweekly.com`), it resolves to the ingress gateways external IP address. 275 | 276 | This works great, however, it's a bit awkward updating the certificates manually before they expire. In the next demo we will use a tool called [cert-manager](https://cert-manager.io/docs/) to automate this. 277 | 278 | ## Using cert-manager 279 | 280 | Let's start by installing the cert-manager first: 281 | 282 | ```sh 283 | kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.3.1/cert-manager.yaml 284 | ``` 285 | 286 | There are two challenges you can use to verify the ownership of the domain - in this demo we will use the HTTP challenge 287 | 288 | Once the cert-manager is installed (make sure all Pods in the `cert-manager` namespace are running), we can create the Issuer resource. 289 | 290 | Make sure you add your email address in the `email` field: 291 | 292 | 293 | ```yaml 294 | apiVersion: cert-manager.io/v1 295 | kind: Issuer 296 | metadata: 297 | name: letsencrypt-prod 298 | namespace: istio-system 299 | spec: 300 | acme: 301 | # For staging: https://acme-staging-v02.api.letsencrypt.org/directory 302 | server: https://acme-v02.api.letsencrypt.org/directory 303 | email: [youremail@yourdomain.com] 304 | privateKeySecretRef: 305 | name: letsencrypt-prod 306 | solvers: 307 | - selector: {} 308 | http01: 309 | ingress: 310 | class: istio 311 | ``` 312 | In the `server` field have an option of using a staging or a production Let's Encrypt server. If you're testing things out and you don't want to get rate limited, switch to the staging URL. For production you should always use the production server address. 313 | 314 | Then, in the `solvers` section we specify that we want to use HTTP challenge. Additionally, we specify the `class: istio` annotation. This annotation will later get added to the Ingress resource that gets created by the cert-manager. 315 | 316 | Next we can create the certificate and get it issued: 317 | 318 | ```yaml 319 | apiVersion: cert-manager.io/v1 320 | kind: Certificate 321 | metadata: 322 | name: hello-istioweekly-com 323 | namespace: istio-system 324 | spec: 325 | secretName: hello-istioweekly-com-tls 326 | issuerRef: 327 | name: letsencrypt-prod 328 | commonName: hello.istioweekly.com 329 | dnsNames: 330 | - hello.istioweekly.com 331 | ``` 332 | 333 | When we create the `Certificate` a certificate request workflow kicks off - this involves creating a `CertificateRequest` resource, a Pod that runs a web server that's able to answer the challenge and a Kubernetes Ingress resource that points to that workload. 334 | 335 | Once the verification is passed, the certificate will get issued. You can check that the certificate was issued by running `kubectl get certificate -A`. 336 | 337 | Last thing we need to do is to update the Gateway resource and reference the secret name with the certificate: 338 | 339 | ```yaml 340 | apiVersion: networking.istio.io/v1alpha3 341 | kind: Gateway 342 | metadata: 343 | name: public-gateway 344 | spec: 345 | selector: 346 | istio: ingressgateway 347 | servers: 348 | - port: 349 | number: 443 350 | name: https 351 | protocol: HTTPS 352 | tls: 353 | mode: SIMPLE 354 | credentialName: hello-istioweekly-com-tls 355 | hosts: 356 | - 'hello.istioweekly.com' 357 | ``` 358 | 359 | Also update the VirtualService with the different host: 360 | 361 | 362 | ```yaml 363 | apiVersion: networking.istio.io/v1alpha3 364 | kind: VirtualService 365 | metadata: 366 | name: helloworld 367 | spec: 368 | hosts: 369 | - hello.istioweekly.com 370 | gateways: 371 | - public-gateway 372 | http: 373 | - route: 374 | - destination: 375 | host: hello-world.default.svc.cluster.local 376 | port: 377 | number: 80 378 | ``` 379 | 380 | >Note: if you use staging issuer, make sure you add `-k` when running curl. Otherwise you'll get an error. Similarly, you'll get an error (untrusted cert) if you use the browser to navigate to the page presenting the staging certificate. -------------------------------------------------------------------------------- /istio-weekly/003/yaml/gateway.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: Gateway 3 | metadata: 4 | name: public-gateway 5 | spec: 6 | selector: 7 | istio: ingressgateway 8 | servers: 9 | - port: 10 | number: 80 11 | name: http 12 | protocol: HTTP 13 | hosts: 14 | - '*' -------------------------------------------------------------------------------- /istio-weekly/003/yaml/hello-world.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: hello-world 5 | --- 6 | apiVersion: apps/v1 7 | kind: Deployment 8 | metadata: 9 | name: hello-world 10 | labels: 11 | app: hello-world 12 | spec: 13 | replicas: 1 14 | selector: 15 | matchLabels: 16 | app: hello-world 17 | template: 18 | metadata: 19 | labels: 20 | app: hello-world 21 | spec: 22 | serviceAccountName: hello-world 23 | containers: 24 | - image: gcr.io/tetratelabs/hello-world:1.0.0 25 | imagePullPolicy: Always 26 | name: svc 27 | ports: 28 | - containerPort: 3000 29 | --- 30 | kind: Service 31 | apiVersion: v1 32 | metadata: 33 | name: hello-world 34 | labels: 35 | app: hello-world 36 | spec: 37 | selector: 38 | app: hello-world 39 | ports: 40 | - port: 80 41 | name: http 42 | targetPort: 3000 -------------------------------------------------------------------------------- /istio-weekly/003/yaml/vs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: helloworld 5 | spec: 6 | hosts: 7 | - '*' 8 | gateways: 9 | - public-gateway 10 | http: 11 | - route: 12 | - destination: 13 | host: hello-world.default.svc.cluster.local 14 | port: 15 | number: 80 -------------------------------------------------------------------------------- /istio-weekly/004/004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-weekly/004/004.png -------------------------------------------------------------------------------- /istio-weekly/004/README.md: -------------------------------------------------------------------------------- 1 | # Deploying multiple Istio ingress gateways 2 | 3 | - Hosted by [Orion Letizi](https://twitter.com/orionletizi) 4 | - Presenters: 5 | - [Peter Jausovec](https://twitter.com/pjausovec) 6 | - Streaming live: June 10th, 11 am PST, 2021 7 | - Link: https://www.youtube.com/watch?v=QIkryA8HnQ0 8 | 9 | ![episode image](004.png) 10 | 11 | ## Show notes 12 | 13 | How can you customize Istio installation? What is Istio operator and how can you configure it? Can I run multiple Istio ingress gateways? The answer is yes! 14 | 15 | Join us in this episode where introduce the Istio operator and talk about how to deploy multiple Istio ingress gateways. Running more than one Istio ingress gateway allows for more complex scenarios. For example, you can run a separate internal ingress gateway for internal traffic, a dedicated public gateway, or running any combination of internal and/or external ingress gateways. 16 | 17 | [Demo script](demo.md) 18 | 19 | ## Episode notes 20 | 21 | **News** 22 | 23 | - Istio 1.10 Discovery selectors (article): https://www.tetrate.io/blog/discovery-selectors 24 | - Istio 1.10 Discovery selectors (video): https://www.youtube.com/watch?v=M3jK4s8MX7A 25 | - Istio 1.10 Improves scalability and revision control (article): https://thenewstack.io/istio-1-10-improves-scalability-and-revision-control 26 | - Intro to Tetrate Service Bridge (TSB): https://www.tetrate.io/blog/intro-to-tetrate-service-bridge 27 | - Service mesh & the next generation of cloud networking with Varun Talwar (podcast): https://techblogwriter.co.uk/tetrate 28 | - Istio Big Talk, the latest episode: https://www.bilibili.com/video/BV18o4y1y75e 29 | 30 | **Events** 31 | 32 | - Jun 17, 10 a.m.: Zero-trust architecture for multi-cloud service mesh (Keyfacor + Tetrate Webinar): https://www.brighttalk.com/webcast/17778/491379 33 | 34 | **Links** 35 | - Istio operator: https://istio.io/latest/docs/setup/install/operator/ 36 | - Operator configuration: https://istio.io/latest/docs/reference/config/istio.operator.v1alpha1/ 37 | - Istio configuration profiles: https://istio.io/latest/docs/setup/additional-setup/config-profiles/ 38 | 39 | 40 | ## Connect 41 | 42 | - Follow us on [Twitter](https://twitter.com/tetrateio) 43 | - Follow us on [LinkedIn](https://www.linkedin.com/company/tetrate) 44 | - Past episodes: https://istioweekly.com 45 | 46 | - Community page: https://istio.tetratelabs.io/community 47 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) 48 | 49 | ## Participate 50 | 51 | Suggest an episode: http://tetr8.io/istio-weekly-suggestions 52 | -------------------------------------------------------------------------------- /istio-weekly/004/demo.md: -------------------------------------------------------------------------------- 1 | # Multiple gateways 2 | 3 | Prerequisites: 4 | - Kubernetes cluster 5 | - VM running in the same network as the Kubernetes cluster 6 | 7 | To get started we'll initialize the Istio operator first. To do that we can run the istioctl operator init command. 8 | 9 | ```sh 10 | istioctl operator init 11 | ``` 12 | 13 | The init command will create the operator in the istio-operator namespace as well as the namespaces the operator watches -- since we haven't provided any watched namespaces, it defaults to `istio-system`; we can look at the actual operator Pod in that namespace: 14 | 15 | ```sh 16 | kubectl get po -n istio-operator 17 | ``` 18 | Next, we can create the IstioOperator resource to install Istio. We'll use the default profile - that profile includes the `istiod` and a public `istio-ingressgateway`: 19 | 20 | ```yaml 21 | apiVersion: install.istio.io/v1alpha1 22 | kind: IstioOperator 23 | metadata: 24 | namespace: istio-system 25 | name: default-installation 26 | spec: 27 | profile: default 28 | ``` 29 | 30 | Save the above to `default-installation.yaml` and create the resource with `kubectl apply -f default-installation.yaml`. 31 | 32 | We can check the status of the installation by listing the Istio operator resource: 33 | 34 | ``` 35 | kubectl get iop -A 36 | ``` 37 | 38 | With Istio installed, let's create a namespace called `internal` and an operator that will install internal gateway into that namespace: 39 | 40 | ``` 41 | kubectl create ns internal 42 | ``` 43 | 44 | Now we can create another operator that installs an internal gateway to that namespace: 45 | 46 | ```yaml 47 | apiVersion: install.istio.io/v1alpha1 48 | kind: IstioOperator 49 | metadata: 50 | namespace: istio-system 51 | name: internal-gw 52 | spec: 53 | profile: empty 54 | components: 55 | ingressGateways: 56 | - namespace: internal 57 | name: ilb-gateway 58 | enabled: true 59 | label: 60 | istio: internal-ingressgateway 61 | k8s: 62 | serviceAnnotations: 63 | networking.gke.io/load-balancer-type: "Internal" 64 | ``` 65 | 66 | Save the above YAML to `internal-gw.yaml` and deploy it using `kubectl apply -f internal-gw.yaml`. 67 | 68 | Just like before, we can check the status by listing the operator resources in all namespaces: 69 | 70 | ```sh 71 | kubectl get iop -A 72 | ``` 73 | 74 | If we look at the services (`kubectl get svc -n internal`) we'll notice that the external IP address is a private IP address that's only accessible within the same network. 75 | 76 | Let's also create a Gateway resource for this internal ingress gateway: 77 | 78 | ```yaml 79 | apiVersion: networking.istio.io/v1alpha3 80 | kind: Gateway 81 | metadata: 82 | name: internal-gateway 83 | namespace: internal 84 | spec: 85 | selector: 86 | istio: internal-ingressgateway 87 | servers: 88 | - port: 89 | number: 80 90 | name: http 91 | protocol: HTTP 92 | hosts: 93 | - '*' 94 | ``` 95 | 96 | Save the above YAML to `internal-gateway.yaml` and create it using `kubectl apply -f internal-gateway.yaml`. 97 | 98 | We'll use the `httpbin` as an example workload in the internal namespace. Let's label the namespace for injection and then deploy httpbin to that namespace: 99 | 100 | ```sh 101 | kubectl label ns internal istio-injection=enabled 102 | kubectl apply -f https://raw.githubusercontent.com/istio/istio/master/samples/httpbin/httpbin.yaml -n internal 103 | ``` 104 | 105 | Finally, we can create the VirtualService and attach the `internal-gateway` resource to it: 106 | 107 | ```yaml 108 | apiVersion: networking.istio.io/v1alpha3 109 | kind: VirtualService 110 | metadata: 111 | name: httpbin 112 | namespace: internal 113 | spec: 114 | hosts: 115 | - '*' 116 | gateways: 117 | - internal-gateway 118 | http: 119 | - route: 120 | - destination: 121 | host: httpbin.internal.svc.cluster.local 122 | port: 123 | number: 8000 124 | ``` 125 | 126 | Save the above to `httpbin-vs.yaml` and create it using `kubectl apply -f httpbin-vs.yaml`. 127 | 128 | To test the internal gateway, create a VM instance, then SSH into the instance and run `curl [internal-gateway-IP]`. -------------------------------------------------------------------------------- /istio-weekly/005/005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-weekly/005/005.png -------------------------------------------------------------------------------- /istio-weekly/005/README.md: -------------------------------------------------------------------------------- 1 | # Security in Istio 2 | 3 | - Hosted by [Orion Letizi](https://twitter.com/orionletizi) 4 | - Presenters: 5 | - [Peter Jausovec](https://twitter.com/pjausovec) 6 | - Streaming live: June 24th, 11 am PST, 2021 7 | - Link: https://www.youtube.com/watch?v=_ExvSKOX_gY 8 | 9 | ![episode image](005.png) 10 | 11 | ## Show notes 12 | 13 | In episode 5, we will talk about Security in Istio. You'll learn about the difference between authentication and authorization. We'll show you how to enable mutual TLS with peer authentication, use request authentication with Auth0, and how to control access to your workloads with the authorization policies. 14 | 15 | [Demo script](demo.md) 16 | 17 | ## Episode notes 18 | 19 | **News** 20 | 21 | - Executive order mandates ZTA for federal agencies: 22 | - [Zero Trust Architecture (SP 800-207)](https://csrc.nist.gov/publications/detail/sp/800-207/final) 23 | - [Building Secure Microservices-based Applications Using Service-Mesh Architecture (SP 800-204A)](https://csrc.nist.gov/publications/detail/sp/800-204a/final) 24 | - [Attribute-based Access Control for Microservices-based Applications Using a Service Mesh (SP 800-204B)](https://csrc.nist.gov/news/2021/draft-sp-800-204b-abac-for-microservices-apps) 25 | - [Why you should choose NGAC as your access control model](https://tetr8.io/choose-ngac) 26 | - [Offload authn/authz to the mesh](https://tetr8.io/service-mesh-auth) 27 | - [Service mesh as security kernel](https://tetr8.io/mesh-security-kernel) 28 | 29 | **Events** 30 | 31 | - July 6th - ZTA Webinar with USAF Chief Software Officer - [Register here](https://tetr8.io/zero-trust-webinar) 32 | - Istio Weekly #6: Envoy fundamentals: https://www.youtube.com/watch?v=f0QEHEm9ERc 33 | 34 | ## Connect 35 | 36 | - Follow us on [Twitter](https://twitter.com/tetrateio) 37 | - Follow us on [LinkedIn](https://www.linkedin.com/company/tetrate) 38 | - Past episodes: https://istioweekly.com 39 | 40 | - Community page: https://istio.tetratelabs.io/community 41 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) 42 | 43 | ## Participate 44 | 45 | Suggest an episode: http://tetr8.io/istio-weekly-suggestions 46 | -------------------------------------------------------------------------------- /istio-weekly/005/arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-weekly/005/arch.png -------------------------------------------------------------------------------- /istio-weekly/005/demo.md: -------------------------------------------------------------------------------- 1 | # Auth0 and Istio 2 | 3 | In this demo we'll show how to use RequestAuthentication and AuthorizationPolicy resources together with Auth0 for authentication. Github repo with the web frontend app is [here](https://github.com/peterj/simple-login). 4 | 5 | ![arch](arch.png) 6 | 7 | Set environment variables with the values from your Auth0 application/API: 8 | 9 | ```sh 10 | export CLIENT_ID=[from Auth0 app] 11 | export SECRET=[from auth0 app] 12 | export ISSUER_BASE_URL=https://[YOUR_DOMAIN].us.auth0.com 13 | export AUDIENCE=[identifier set in the Auth0 API] 14 | export BASE_URL=[set to your ingress IP/domain name] 15 | ``` 16 | 17 | Next, create the secrets for the web-frontend workload: 18 | 19 | ```sh 20 | kubectl create secret generic webfrontend-auth0 \ 21 | --from-literal=CLIENT_ID=$CLIENT_ID \ 22 | --from-literal=SECRET=$SECRET 23 | 24 | kubectl create configmap webfrontend-auth0 \ 25 | --from-literal=ISSUER_BASE_URL=$ISSUER_BASE_URL \ 26 | --from-literal=AUDIENCE=$AUDIENCE \ 27 | --from-literal=BASE_URL=$BASE_URL 28 | ``` 29 | 30 | Now we can create the deployment: 31 | 32 | ```sh 33 | kubectl apply -f https://raw.githubusercontent.com/peterj/simple-login/main/k8s/deploy.yaml 34 | ``` 35 | 36 | And Gateway and the VirtualService: 37 | 38 | ```yaml 39 | apiVersion: networking.istio.io/v1alpha3 40 | kind: Gateway 41 | metadata: 42 | name: gateway 43 | spec: 44 | selector: 45 | istio: ingressgateway 46 | servers: 47 | - port: 48 | number: 80 49 | name: http 50 | protocol: HTTP 51 | hosts: 52 | - '*' 53 | --- 54 | apiVersion: networking.istio.io/v1alpha3 55 | kind: VirtualService 56 | metadata: 57 | name: web-frontend 58 | spec: 59 | hosts: 60 | - '*' 61 | gateways: 62 | - gateway 63 | http: 64 | - route: 65 | - destination: 66 | host: web-frontend.default.svc.cluster.local 67 | port: 68 | number: 80 69 | ``` 70 | 71 | If you go to the ingress IP, you'll notice that the website shows the data from the customers service. 72 | 73 | Let's set up the RequestAuthentication and resource and apply it to the customers workload. This resource will check that anything calling the customers service has a valid JWT token set: 74 | 75 | ```yaml 76 | apiVersion: security.istio.io/v1beta1 77 | kind: RequestAuthentication 78 | metadata: 79 | name: customers 80 | spec: 81 | selector: 82 | matchLabels: 83 | app: customers 84 | jwtRules: 85 | # Note: Replace with your own issuer/jwksUri 86 | - issuer: "https://istioweekly.us.auth0.com/" 87 | jwksUri: "https://istioweekly.us.auth0.com/.well-known/jwks.json" 88 | ``` 89 | 90 | If we refresh the page again, everything will still work. Remember that authentication without authorization is not really helpful. 91 | 92 | Let's create the AuthorizationPolicy that will require all callers to the customer service to have a request principal set (note that we aren't checking for any specific request principal, we just want to have *a* request principal set): 93 | 94 | ```yaml 95 | apiVersion: security.istio.io/v1beta1 96 | kind: AuthorizationPolicy 97 | metadata: 98 | name: require-jwt 99 | spec: 100 | selector: 101 | matchLabels: 102 | app: customers 103 | action: ALLOW 104 | rules: 105 | - from: 106 | - source: 107 | requestPrincipals: ["*"] 108 | ``` 109 | 110 | Finally, if we refresh the page again, we'll get back the HTTP 403 response. This means that we aren't authorized to call the customers service. If we click the login link and register, then we'll be able to access the service, because the request will have a valid JWT token attached to the request.. 111 | 112 | ## Cleanup 113 | 114 | ```sh 115 | kubectl delete secret webfrontend-auth0 116 | kubectl delete configmap webfrontend-auth0 117 | kubectl delete -f https://raw.githubusercontent.com/peterj/simple-login/main/k8s/deploy.yaml 118 | kubectl delete gateway gateway 119 | kubectl delete virtualservice web-frontend 120 | kubectl delete authorizationpolicy require-jwt 121 | kubectl delete RequestAuthentication customers 122 | ``` -------------------------------------------------------------------------------- /istio-weekly/006/006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-weekly/006/006.png -------------------------------------------------------------------------------- /istio-weekly/006/README.md: -------------------------------------------------------------------------------- 1 | # Envoy Fundamentals 2 | 3 | - Hosted by [Orion Letizi](https://twitter.com/orionletizi) 4 | - Presenters: 5 | - [Peter Jausovec](https://twitter.com/pjausovec) 6 | - Streaming live: July 8th, 11 am PST, 2021 7 | - Link: https://www.youtube.com/watch?v=f0QEHEm9ERc 8 | 9 | ![episode image](006.png) 10 | 11 | ## Show notes 12 | 13 | Envoy is one part of the engine that keeps Istio running. How does Envoy work? What are listeners, clusters, and endpoints? 14 | 15 | Join us on July 8th for another Istio weekly episode where we'll introduce the fundamentals of Envoy proxy. 16 | 17 | Check out the [demo here](demo.md). 18 | 19 | ## Episode notes 20 | 21 | [Envoy Deep Dive (by Lizan Zhou)](https://www.youtube.com/watch?v=spzfupads2o) 22 | 23 | [Lyft's Envoy: Embracing a service mesh (by Matt Klein)](https://www.youtube.com/watch?v=55yi4MMVBi4) 24 | 25 | [Making Envoy Contributions Feasible for Everyone (by Yaroslav Skopets)](https://www.youtube.com/watch?v=mJAYHHKmLhU) 26 | 27 | [Envoy & Service Mesh for Databases: what the Future Holds (by Christoph Pakulski and Prasad Radhakrishnan)](https://www.youtube.com/watch?v=muyVO6C3em8) 28 | 29 | ## Connect 30 | 31 | - Follow us on [Twitter](https://twitter.com/tetrateio) 32 | - Follow us on [LinkedIn](https://www.linkedin.com/company/tetrate) 33 | - Past episodes: https://istioweekly.com 34 | 35 | - Community page: https://istio.tetratelabs.io/community 36 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) 37 | 38 | ## Participate 39 | 40 | Suggest an episode: http://tetr8.io/istio-weekly-suggestions 41 | -------------------------------------------------------------------------------- /istio-weekly/006/config.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - name: listener_0 4 | address: 5 | socket_address: 6 | address: 0.0.0.0 7 | port_value: 10000 8 | filter_chains: 9 | - filters: 10 | - name: envoy.filters.network.http_connection_manager 11 | typed_config: 12 | "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager 13 | stat_prefix: edge 14 | access_log: 15 | - name: envoy.access_loggers.stdout 16 | typed_config: 17 | "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog 18 | http_filters: 19 | - name: envoy.filters.http.router 20 | route_config: 21 | virtual_hosts: 22 | - name: all_domains 23 | domains: ["*"] 24 | routes: 25 | - match: 26 | prefix: "/blue" 27 | route: 28 | cluster: blue 29 | - match: 30 | prefix: "/green" 31 | route: 32 | cluster: green 33 | clusters: 34 | - name: blue 35 | connect_timeout: 5s 36 | load_assignment: 37 | cluster_name: blue 38 | endpoints: 39 | - lb_endpoints: 40 | - endpoint: 41 | address: 42 | socket_address: 43 | address: 0.0.0.0 44 | port_value: 5050 45 | - name: green 46 | connect_timeout: 5s 47 | load_assignment: 48 | cluster_name: green 49 | endpoints: 50 | - lb_endpoints: 51 | - endpoint: 52 | address: 53 | socket_address: 54 | address: 0.0.0.0 55 | port_value: 5000 56 | admin: 57 | address: 58 | socket_address: 59 | address: 0.0.0.0 60 | port_value: 9901 -------------------------------------------------------------------------------- /istio-weekly/006/demo.md: -------------------------------------------------------------------------------- 1 | # Envoy fundamentals demo 2 | 3 | Let's start by running two Docker containers -- one is listening on port 5050 and the other one listening on port 5000. 4 | 5 | ```sh 6 | docker run -dit --env BG_COLOR="blue" -p 5050:3000 gcr.io/tetratelabs/color-app:1.0.0 7 | 8 | docker run -dit --env BG_COLOR="green" -p 5000:3000 gcr.io/tetratelabs/color-app:1.0.0 9 | ``` 10 | 11 | The two containers run simple Express web app that sets the background color -- the first one sets the background color to blue and the second one to green. 12 | 13 | By the end of this demo we'll have an Envoy configuration that routes all traffic sent to `/blue` to the blue container and traffic sent to `/green` to the green container. We'll have a single listener and then based on the URI we'll route traffic to or the other container. 14 | 15 | ## Installing func-e CLI 16 | 17 | Before we start writing the configuration, let's install a CLI called [func-e](https://func-e.io). 18 | 19 | You can use this CLI to manage and run different Envoy versions: 20 | 21 | ```sh 22 | curl -L https://func-e.io/install.sh | bash -s -- -b . 23 | ``` 24 | 25 | Let's start with a minimal configuration that doesn't do much: 26 | 27 | ```yaml 28 | static_resources: 29 | listeners: 30 | - name: listener_0 31 | address: 32 | socket_address: 33 | address: 0.0.0.0 34 | port_value: 10000 35 | filter_chains: [{}] 36 | ``` 37 | 38 | Save the above YAML to `config.yaml`. If we run Envoy with this configuration, the proxy will start and it will listen on port 10000, however, we haven't defined any filter chains, routes or clusters, so it's not going to know what to do with the request: 39 | 40 | ```sh 41 | func-e run -c config.yaml 42 | ``` 43 | 44 | If we send the request, Envoy will just close the connection. 45 | 46 | Let's update this config and add the HTTP filter and the router filter to the HTTP filter chain, but without any configuration: 47 | 48 | ```yaml 49 | filter_chains: 50 | - filters: 51 | - name: envoy.filters.network.http_connection_manager 52 | typed_config: 53 | "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager 54 | stat_prefix: edge 55 | http_filters: 56 | - name: envoy.filters.http.router 57 | route_config: {} 58 | ``` 59 | 60 | We are adding a single filter - the HTTP connection manager and then inside that filter we are adding the router filter - remember, that's the last filter in the chain that does the routing. Note that this config doesn't have any routes defined, so if we run this - it works, but we'll get back a 404. 61 | 62 | Let's create a very simple route config that just returns a direct response, just so we see how the configuration looks like: 63 | 64 | ```yaml 65 | route_config: 66 | virtual_hosts: 67 | - name: direct_response_service 68 | domains: ["*"] 69 | routes: 70 | - match: 71 | prefix: "/" 72 | direct_response: 73 | status: 200 74 | body: 75 | inline_string: "Hello" 76 | ``` 77 | 78 | With this configuration we're defining a single virtual host that matches all domains. Once it matches the domain, it will try to match the prefix. Once the prefix is matched as well it returns a direct response. 79 | 80 | Let's run Envoy with this configuration and send a request to `localhost:10000`: 81 | 82 | ``` 83 | $ func-e run -c config.yaml 84 | ... 85 | 86 | $ curl localhost:10000 87 | ``` 88 | 89 | The response should be an HTTP 200 and `Hello` - you'll also notice the server response header is set to Envoy (`server: envoy`). 90 | 91 | Sending a direct response is not too useful, let's change that and instead of a `direct_response` use a route that will select a cluster. 92 | 93 | ```yaml 94 | route_config: 95 | virtual_hosts: 96 | - name: all_domains 97 | domains: ["*"] 98 | routes: 99 | - match: 100 | prefix: "/blue" 101 | route: 102 | cluster: blue 103 | - match: 104 | prefix: "/green" 105 | route: 106 | cluster: green 107 | ``` 108 | 109 | With this change we are creating a single virtual host that matches all domains and then within the routes we are checking for the prefix match - first match checks for `/blue` and within the `route` we're specifying the cluster name - similarly for the `/green` path and the `green` cluster. 110 | 111 | We also need to define the two clusters: 112 | 113 | ```yaml 114 | clusters: 115 | - name: blue 116 | connect_timeout: 5s 117 | load_assignment: 118 | cluster_name: blue 119 | endpoints: 120 | - lb_endpoints: 121 | - endpoint: 122 | address: 123 | socket_address: 124 | address: 127.0.0.1 125 | port_value: 5050 126 | - name: green 127 | connect_timeout: 5s 128 | load_assignment: 129 | cluster_name: green 130 | endpoints: 131 | - lb_endpoints: 132 | - endpoint: 133 | address: 134 | socket_address: 135 | address: 127.0.0.1 136 | port_value: 5000 137 | ``` 138 | 139 | This is where we specify the endpoints - the actual IP addresses and ports. 140 | 141 | Let's re-run the Envoy (`func-e run -c config.yaml`) - now if you open `localhost:10000/blue` you'll get the Blue container and if you open `localhost:10000/green` you'll get the Green container. 142 | 143 | ## Enabling admin interface, metrics, and access logging 144 | 145 | Let's see how to get the metrics and enable access logging. 146 | 147 | We'll start with the access logger first - we'll define it at the HTTP connection manager filter, and we'll just write the logs to standard out. The other options for logging are to log to a file or provide an Access log service that Envoy can send the logs to through grpc. 148 | 149 | Add the following snipper right under the `stat_prefix` field: 150 | ```yaml 151 | access_log: 152 | - name: envoy.access_loggers.stdout 153 | typed_config: 154 | "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog 155 | ``` 156 | 157 | If we make a couple of requests, you'll notice Envoy is writting the access logs to standard out: 158 | 159 | ```sh 160 | 161 | ``` 162 | 163 | Next, let's see how we could get some statistics and figure out how many successful requests were sent to different clusters. 164 | 165 | Envoy does expose a statistics endpoint, but we need to enable the admin interface in order to access it. 166 | 167 | ```yaml 168 | admin: 169 | address: 170 | socket_address: 171 | address: 0.0.0.0 172 | port_value: 9901 173 | ``` 174 | 175 | If we restart Envoy, we can now send a request to `/green` or `/blue` and then observe how the metrics change: 176 | 177 | ``` 178 | curl localhost:9901/stats 179 | ``` 180 | 181 | Envoy also emits the Prometheus style metrics under /stats/prometheus. 182 | -------------------------------------------------------------------------------- /istio-weekly/007/007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-weekly/007/007.png -------------------------------------------------------------------------------- /istio-weekly/007/README.md: -------------------------------------------------------------------------------- 1 | # Developing Envoy Wasm Extensions 2 | 3 | - Hosted by [Orion Letizi](https://twitter.com/orionletizi) 4 | - Presenters: 5 | - [Peter Jausovec](https://twitter.com/pjausovec) 6 | - Streaming live: July 22nd, 11 am PST, 2021 7 | - Link: https://www.youtube.com/watch?v=JIq8wujlG9s 8 | 9 | ![episode image](007.png) 10 | 11 | ## Show notes 12 | 13 | WebAssembly (Wasm) and the Envoy Proxy Wasm SDK are a way to extend the Envoy proxy functionality. We'll show you how to use the Proxy Wasm Go SDK and func-e CLI (https://func-e.io) to develop and test your Wasm extensions. 14 | 15 | [DEMO](demo.md) 16 | 17 | ## Episode notes 18 | 19 | **Resources** 20 | - [func-e CLI](https://func-e.io) 21 | - [Wasm modules and Envoy extensibility explained](https://tetr8.io/wasm-modules-and-envoy-extensibility) 22 | - [WebAssembly for app security and extensibility](https://tetr8.io/webassembly-security-and-extensibility) 23 | - [Istio security assessment](https://tetr8.io/istio-security-assessment) 24 | - [Free Istio labs](https://tetr8.io/istio-fundamentals) 25 | 26 | **Events** 27 | 28 | - August 4th, 2021: [Tetrate & Mirantis joint webinar: Istio in the enterprise](https://tetr8.io/istio-in-the-enterprise-webinar) 29 | - On demand: [ZTA webinar with USAF chief software officer](https://tetr8.io/zero-trust-at-DoD) 30 | 31 | ## Connect 32 | 33 | - Follow us on [Twitter](https://twitter.com/tetrateio) 34 | - Follow us on [LinkedIn](https://www.linkedin.com/company/tetrate) 35 | - Past episodes: https://istioweekly.com 36 | 37 | - Community page: https://istio.tetratelabs.io/community 38 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) 39 | 40 | ## Participate 41 | 42 | Suggest an episode: http://tetr8.io/istio-weekly-suggestions -------------------------------------------------------------------------------- /istio-weekly/007/demo.md: -------------------------------------------------------------------------------- 1 | # Developing Envoy Wasm Extensions 2 | 3 | We will be using [TinyGo](https://tinygo.org), [proxy-wasm-go-sdk](https://github.com/tetratelabs/proxy-wasm-go-sdk) and [func-e CLI](https://func-e.io) to build and test an Envoy Wasm extension. Then we'll show a way to configure the Wasm module using the EnvoyFilter resource and deploy it to Envoy sidecars in a Kubernetes cluster. 4 | 5 | We'll start with something trivial for our first example and write a simple Wasm module using TinyGo that adds a custom header to response headers. 6 | 7 | ## Installing func-e CLI 8 | 9 | Let's get started by downloading func-e CLI and installing it to `/usr/local/bin`: 10 | 11 | ```sh 12 | curl https://func-e.io/install.sh | bash -s -- -b /usr/local/bin 13 | ``` 14 | 15 | Once downloaded, let's run it to make sure all is good: 16 | 17 | ```sh 18 | $ func-e --version 19 | func-e version 0.5.0 20 | ``` 21 | 22 | ## Installing TinyGo 23 | 24 | TinyGo powers the SDK we'll be using as Wasm doesn't support the official Go compiler. 25 | 26 | Let's download and install the TinyGo: 27 | 28 | ```sh 29 | wget https://github.com/tinygo-org/tinygo/releases/download/v0.18.0/tinygo_0.18.0_amd64.deb 30 | sudo dpkg -i tinygo_0.18.0_amd64.deb 31 | ``` 32 | 33 | You can run `tinygo version` to check the installation is successful: 34 | 35 | ```sh 36 | $ tinygo version 37 | tinygo version 0.18.0 linux/amd64 (using go version go1.16.5 and LLVM version 11.0.0) 38 | ``` 39 | 40 | ## Scaffolding the Wasm module 41 | 42 | We'll start by creating a new folder for our extension, initializing the Go module, and downloading the SDK dependency: 43 | 44 | ```sh 45 | $ mkdir header-filter && cd header-filter 46 | $ go mod init header-filter 47 | $ go mod edit -require=github.com/tetratelabs/proxy-wasm-go-sdk@main 48 | $ go mod download github.com/tetratelabs/proxy-wasm-go-sdk 49 | ``` 50 | 51 | Next, let's create the `main.go` file where the code for our WASM extension will live: 52 | 53 | ```go 54 | package main 55 | 56 | import ( 57 | "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm" 58 | "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types" 59 | ) 60 | 61 | func main() { 62 | proxywasm.SetVMContext(&vmContext{}) 63 | } 64 | 65 | type vmContext struct { 66 | // Embed the default VM context here, 67 | // so that we don't need to reimplement all the methods. 68 | types.DefaultVMContext 69 | } 70 | 71 | // Override types.DefaultVMContext. 72 | func (*vmContext) NewPluginContext(contextID uint32) types.PluginContext { 73 | return &pluginContext{} 74 | } 75 | 76 | type pluginContext struct { 77 | // Embed the default plugin context here, 78 | // so that we don't need to reimplement all the methods. 79 | types.DefaultPluginContext 80 | } 81 | 82 | // Override types.DefaultPluginContext. 83 | func (*pluginContext) NewHttpContext(contextID uint32) types.HttpContext { 84 | return &httpHeaders{contextID: contextID} 85 | } 86 | 87 | type httpHeaders struct { 88 | // Embed the default http context here, 89 | // so that we don't need to reimplement all the methods. 90 | types.DefaultHttpContext 91 | contextID uint32 92 | } 93 | 94 | func (ctx *httpHeaders) OnHttpRequestHeaders(numHeaders int, endOfStream bool) types.Action { 95 | proxywasm.LogInfo("OnHttpRequestHeaders") 96 | return types.ActionContinue 97 | } 98 | 99 | func (ctx *httpHeaders) OnHttpResponseHeaders(numHeaders int, endOfStream bool) types.Action { 100 | proxywasm.LogInfo("OnHttpResponseHeaders") 101 | return types.ActionContinue 102 | } 103 | 104 | func (ctx *httpHeaders) OnHttpStreamDone() { 105 | proxywasm.LogInfof("%d finished", ctx.contextID) 106 | } 107 | ``` 108 | 109 | Save the above contents to a file called `main.go`. 110 | 111 | Let's build the filter to check everything is good: 112 | 113 | ```sh 114 | tinygo build -o main.wasm -scheduler=none -target=wasi main.go 115 | ``` 116 | 117 | The build command should run successfully, and it should generate a file called `main.wasm`. 118 | 119 | We'll use `func-e` to run a local Envoy instance to test the extension we've built. 120 | 121 | First, we need an Envoy config that will configure the extension: 122 | 123 | ```yaml 124 | static_resources: 125 | listeners: 126 | - name: main 127 | address: 128 | socket_address: 129 | address: 0.0.0.0 130 | port_value: 10000 131 | filter_chains: 132 | - filters: 133 | - name: envoy.http_connection_manager 134 | typed_config: 135 | "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager 136 | stat_prefix: ingress_http 137 | route_config: 138 | name: local_route 139 | virtual_hosts: 140 | - name: local_service 141 | domains: ["*"] 142 | routes: 143 | - match: 144 | prefix: "/" 145 | direct_response: 146 | status: 200 147 | body: 148 | inline_string: "Hello world" 149 | http_filters: 150 | - name: envoy.filters.http.wasm 151 | typed_config: 152 | "@type": type.googleapis.com/udpa.type.v1.TypedStruct 153 | type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm 154 | value: 155 | config: 156 | vm_config: 157 | runtime: "envoy.wasm.runtime.v8" 158 | code: 159 | local: 160 | filename: "main.wasm" 161 | - name: envoy.filters.http.router 162 | 163 | admin: 164 | access_log_path: "/dev/null" 165 | address: 166 | socket_address: 167 | address: 0.0.0.0 168 | port_value: 9901 169 | ``` 170 | 171 | Save the above to `envoy.yaml` file. 172 | 173 | The Envoy configuration sets up a single listener on port 10000 that returns a direct response (HTTP 200) with body `hello world`. Inside the `http_filters` section, we're configuring the `envoy.filters.http.wasm` filter and referencing the local WASM file (`main.wasm`) we've built earlier. 174 | 175 | Let's run the Envoy with this configuration in the background: 176 | 177 | ```sh 178 | func-e run -c envoy.yaml & 179 | ``` 180 | 181 | Envoy instance should start without any issues. Once it's started, we can send a request to the port Envoy is listening on (`10000`): 182 | 183 | ```sh 184 | $ curl localhost:10000 185 | [2021-06-22 16:39:31.491][5314][info][wasm] [external/envoy/source/extensions/common/wasm/context.cc:1218] wasm log: OnHttpRequestHeaders 186 | [2021-06-22 16:39:31.491][5314][info][wasm] [external/envoy/source/extensions/common/wasm/context.cc:1218] wasm log: OnHttpResponseHeaders 187 | [2021-06-22 16:39:31.492][5314][info][wasm] [external/envoy/source/extensions/common/wasm/context.cc:1218] wasm log: 2 finished 188 | example body 189 | ``` 190 | 191 | The output shows the two log entries - one from the OnHttpRequestHeaders handler and the second one from the OnHttpResponseHeaders handler. The last line is the example response returned by the direct response configuration in the filter. 192 | 193 | You can stop the proxy by bringing the process to the foreground with `fg` and pressing CTRL+C to stop it. 194 | 195 | ## Setting additional headers on HTTP response 196 | 197 | Let's open the `main.go` file and add a header to the response headers. We'll be updating the OnHttpResponseHeaders function to do that. 198 | 199 | We'll call the `AddHttpResponseHeader` function to add a new header. Update the OnHttpResponseHeaders function to look like this: 200 | 201 | ```go 202 | func (ctx *httpHeaders) OnHttpResponseHeaders(numHeaders int, endOfStream bool) types.Action { 203 | proxywasm.LogInfo("OnHttpResponseHeaders") 204 | err := proxywasm.AddHttpResponseHeader("my-new-header", "some-value-here") 205 | if err != nil { 206 | proxywasm.LogCriticalf("failed to add response header: %v", err) 207 | } 208 | return types.ActionContinue 209 | } 210 | ``` 211 | 212 | Let's rebuild the extension: 213 | 214 | ```sh 215 | tinygo build -o main.wasm -scheduler=none -target=wasi main.go 216 | ``` 217 | 218 | And we can now re-run the Envoy proxy with the updated extension: 219 | 220 | ``` 221 | func-e run -c envoy.yaml & 222 | ``` 223 | 224 | Now, if we send a request again (make sure to add the `-v` flag), we'll see the header that got added to the response: 225 | 226 | ```sh 227 | $ curl -v localhost:10000 228 | ... 229 | < HTTP/1.1 200 OK 230 | < content-length: 13 231 | < content-type: text/plain 232 | < my-new-header: some-value-here 233 | < date: Mon, 22 Jun 2021 17:02:31 GMT 234 | < server: envoy 235 | < 236 | example body 237 | ``` 238 | 239 | ## Reading values from configuration 240 | 241 | Hardcoding values like that in code is never a good idea. Let's see how we can read the additional headers. 242 | 243 | 1. Add the `additionalHeaders` and `contextID` to the `pluginContext` struct: 244 | 245 | ```go 246 | type pluginContext struct { 247 | // Embed the default plugin context here, 248 | // so that we don't need to reimplement all the methods. 249 | types.DefaultPluginContext 250 | additionalHeaders map[string]string 251 | contextID uint32 252 | } 253 | ``` 254 | 255 | 2. Update the `NewPluginContext` function to initialize the values: 256 | 257 | ```go 258 | func (*vmContext) NewPluginContext(contextID uint32) types.PluginContext { 259 | return &pluginContext{contextID: contextID, additionalHeaders: map[string]string{}} 260 | } 261 | ``` 262 | 263 | 3. In the `OnPluginStart` function we can now read in values from the Envoy configuration and store the key/value pairs in the `additionalHeaders` map: 264 | 265 | ```go 266 | func (ctx *pluginContext) OnPluginStart(pluginConfigurationSize int) types.OnPluginStartStatus { 267 | // Get the plugin configuration 268 | config, err := proxywasm.GetPluginConfiguration() 269 | if err != nil && err != types.ErrorStatusNotFound { 270 | proxywasm.LogCriticalf("failed to load config: %v", err) 271 | return types.OnPluginStartStatusFailed 272 | } 273 | 274 | // Read the config 275 | scanner := bufio.NewScanner(bytes.NewReader(config)) 276 | for scanner.Scan() { 277 | line := scanner.Text() 278 | if strings.HasPrefix(line, "#") { 279 | continue 280 | } 281 | // Each line in the config is in the "key=value" format 282 | if tokens := strings.Split(scanner.Text(), "="); len(tokens) == 2 { 283 | ctx.additionalHeaders[tokens[0]] = tokens[1] 284 | } 285 | } 286 | return types.OnPluginStartStatusOK 287 | } 288 | ``` 289 | 290 | To access the configuration values we've set, we need to add the map to the HTTP context when we initialize it. To do that, we need to update the `httpheaders` struct first: 291 | 292 | ```go 293 | type httpHeaders struct { 294 | // Embed the default http context here, 295 | // so that we don't need to reimplement all the methods. 296 | types.DefaultHttpContext 297 | contextID uint32 298 | additionalHeaders map[string]string 299 | } 300 | ``` 301 | 302 | Then, in the `NewHttpContext` function we can instantiate the httpHeaders with the additional headers map coming from the plugin context: 303 | 304 | ```go 305 | func (ctx *pluginContext) NewHttpContext(contextID uint32) types.HttpContext { 306 | return &httpHeaders{contextID: contextID, additionalHeaders: ctx.additionalHeaders} 307 | } 308 | ``` 309 | 310 | Finally, in order to set the headers we modiy the `OnHttpResponseHeaders` function, iterate through the `additionalHeaders` map and call the `AddHttpResponseHeader` for each item: 311 | 312 | ```go 313 | func (ctx *httpHeaders) OnHttpResponseHeaders(numHeaders int, endOfStream bool) types.Action { 314 | proxywasm.LogInfo("OnHttpResponseHeaders") 315 | 316 | for key, value := range ctx.additionalHeaders { 317 | if err := proxywasm.AddHttpResponseHeader(key, value); err != nil { 318 | proxywasm.LogCriticalf("failed to add header: %v", err) 319 | return types.ActionPause 320 | } 321 | proxywasm.LogInfof("header set: %s=%s", key, value) 322 | } 323 | 324 | return types.ActionContinue 325 | } 326 | ``` 327 | 328 | Let's rebuild the extension again: 329 | 330 | ```sh 331 | tinygo build -o main.wasm -scheduler=none -target=wasi main.go 332 | ``` 333 | 334 | Also, let's update the config file to include additional headers in the filter configuration: 335 | 336 | ```yaml 337 | - name: envoy.filters.http.wasm 338 | typed_config: 339 | "@type": type.googleapis.com/udpa.type.v1.TypedStruct 340 | type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm 341 | value: 342 | config: 343 | vm_config: 344 | runtime: "envoy.wasm.runtime.v8" 345 | code: 346 | local: 347 | filename: "main.wasm" 348 | # ADD THESE LINES 349 | configuration: 350 | "@type": type.googleapis.com/google.protobuf.StringValue 351 | value: | 352 | header_1=somevalue 353 | header_2=secondvalue 354 | ``` 355 | 356 | With the filter updated, we can re-run the proxy again. When you send a request, you'll notice the headers we set in the filter configuration are added as response headers: 357 | 358 | ```sh 359 | $ curl -v localhost:10000 360 | ... 361 | < HTTP/1.1 200 OK 362 | < content-length: 13 363 | < content-type: text/plain 364 | < header_1: somevalue 365 | < header_2: secondvalue 366 | < date: Mon, 22 Jun 2021 17:54:53 GMT 367 | < server: envoy 368 | ... 369 | ``` 370 | 371 | ## Add a metric 372 | 373 | Let's add another feature - a counter that increases each time there's a request header called `hello` set. 374 | 375 | First, let's update the `pluginContext` to include the `helloHeaderCounter`: 376 | 377 | ```go 378 | type pluginContext struct { 379 | // Embed the default plugin context here, 380 | // so that we don't need to reimplement all the methods. 381 | types.DefaultPluginContext 382 | additionalHeaders map[string]string 383 | contextID uint32 384 | // ADD THIS LINE 385 | helloHeaderCounter proxywasm.MetricCounter 386 | } 387 | ``` 388 | 389 | With the metric counter in the struct, we can now create it in the `NewPluginContext` function. We'll call the header `hello_header_counter`. 390 | 391 | ```go 392 | func (*vmContext) NewPluginContext(contextID uint32) types.PluginContext { 393 | return &pluginContext{contextID: contextID, additionalHeaders: map[string]string{}, helloHeaderCounter: proxywasm.DefineCounterMetric("hello_header_counter")} 394 | } 395 | ``` 396 | 397 | Since we want need to check the incoming request headers to decide whether to increment the counter, we need to add the `helloHeaderCounter` to the `httpHeaders` struct as well: 398 | 399 | ```go 400 | type httpHeaders struct { 401 | // Embed the default http context here, 402 | // so that we don't need to reimplement all the methods. 403 | types.DefaultHttpContext 404 | contextID uint32 405 | additionalHeaders map[string]string 406 | // ADD THIS LINE 407 | helloHeaderCounter proxywasm.MetricCounter 408 | } 409 | ``` 410 | 411 | Also, we need to get the counter from the `pluginContext` and set it when we're creating the new HTTP context: 412 | 413 | ```go 414 | // Override types.DefaultPluginContext. 415 | func (ctx *pluginContext) NewHttpContext(contextID uint32) types.HttpContext { 416 | return &httpHeaders{contextID: contextID, additionalHeaders: ctx.additionalHeaders, helloHeaderCounter: ctx.helloHeaderCounter} 417 | } 418 | ``` 419 | 420 | Now that we've piped the `helloHeaderCounter` all the way through to the `httpHeaders`, we can use it in the `OnHttpRequestHeaders` function: 421 | 422 | ```go 423 | func (ctx *httpHeaders) OnHttpRequestHeaders(numHeaders int, endOfStream bool) types.Action { 424 | proxywasm.LogInfo("OnHttpRequestHeaders") 425 | 426 | _, err := proxywasm.GetHttpRequestHeader("hello") 427 | if err != nil { 428 | // Ignore if header is not set 429 | return types.ActionContinue 430 | } 431 | 432 | ctx.helloHeaderCounter.Increment(1) 433 | proxywasm.LogInfo("hello_header_counter incremented") 434 | return types.ActionContinue 435 | } 436 | ``` 437 | 438 | Here, we're checking if the "hello" request header is defined (note that we don't care about the header value), and if it's defined, we call the `Increment` function on the counter instance. Otherwise, we'll ignore it and return ActionContinue if we get an error from the `GetHttpRequestHeader` call. 439 | 440 | Let's rebuild the extension again: 441 | 442 | ```sh 443 | tinygo build -o main.wasm -scheduler=none -target=wasi main.go 444 | ``` 445 | 446 | And then re-run the Envoy proxy. Make a couple of requests like this: 447 | 448 | ```sh 449 | curl -H "hello: something" localhost:10000 450 | ``` 451 | 452 | You'll notice the log Envoy log entry like this one: 453 | 454 | ```text 455 | wasm log: hello_header_counter incremented 456 | ``` 457 | 458 | You can also use the admin address on port 8001 to check that the metric is being tracked: 459 | 460 | ```sh 461 | $ curl localhost:9901/stats/prometheus | grep hello 462 | # TYPE envoy_hello_header_counter counter 463 | envoy_hello_header_counter{} 1 464 | ``` 465 | 466 | ## Deploying Wasm module to Istio using EnvoyFilter 467 | 468 | The resource we can use to deploy a Wasm module to Istio is called the EnvoyFilter. EnvoyFilter gives us the ability to customize the Envoy configuration. It allows us to modify values, configure new listeners or clusters, and add filters. 469 | 470 | In the previous example, there was no need to push or publish the `main.wasm` file anywhere, as it was accessible by the Envoy proxy because everything was running locally. However, now that we want to run the Wasm module in Envoy proxies that are part of the Istio service mesh, we need to make the `main.wasm` file available to all those proxies so they can load and run it. 471 | 472 | Since Envoy can be extended using filters, we can use the Envoy HTTP Wasm filter to implement an HTTP filter with a Wasm module. This filter allows us to configure the Wasm module and load the module file. 473 | 474 | Here's a snippet that shows how to load a Wasm module using the Envoy HTTP Wasm filter: 475 | 476 | ```yaml 477 | name: envoy.filters.http.wasm 478 | typed_config: 479 | "@type": type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm 480 | config: 481 | config: 482 | name: "my_plugin" 483 | vm_config: 484 | runtime: "envoy.wasm.runtime.v8" 485 | code: 486 | local: 487 | filename: "/etc/envoy_filter_http_wasm_example.wasm" 488 | allow_precompiled: true 489 | configuration: 490 | '@type': type.googleapis.com/google.protobuf.StringValue 491 | value: | 492 | {} 493 | ``` 494 | 495 | This particular snippet is reading the Wasm file from the local path. Note that "local" in this case refers to the container the Envoy proxy is running in. 496 | 497 | One way we could bring the Wasm module to that container is to use a persistent volume, for example. We'd then copy the Wasm file to the persistent disk and use the following annotations to mount the volume into the Envoy proxy sidecars: 498 | 499 | ```yaml 500 | sidecar.istio.io/userMount: '[{"name": "wasmfilters", "mountPath": "/wasmfilters"}]' 501 | sidecar.istio.io/userVolume: '[{"name": "wasmfilters", "gcePersistentDisk": { "pdName": "my-data-disk", "fsType": "ext4" }}]' 502 | ``` 503 | 504 | Note that the above snippet assumes a persistent disk running in GCP. The disk could be any other persistent volume as well. We'd then have to patch the existing Kubernetes deployments and 'inject' the above annotations. 505 | 506 | Luckily for us, there is another option. Remember the local field from the Envoy HTTP Wasm filter configuration? Well, there's also a remote field we can use to load the Wasm module from a remote location, a URL. The remote field simplifies things a lot! We can upload the .wasm file to remote storage, get the public URL to the module, and then use it. 507 | 508 | In this example, we'll upload the module to a GCP storage account and made the file publicly accessible. 509 | 510 | The updated configuration would now look like this: 511 | 512 | ```yaml 513 | vm_config: 514 | runtime: envoy.wasm.runtime.v8 515 | code: 516 | remote: 517 | http_uri: 518 | uri: [PUBLIC-URL]/extension.wasm 519 | sha256: "[sha]" 520 | ``` 521 | 522 | You can get the SHA by running sha256sum command. If you're using Istio 1.9 or newer, you don't have to provide the sha256 checksum, as Istio will fill that automatically. However, if you're using Istio 1.8 or older, the sha256 checksum is required, and it prevents the Wasm module from being downloaded each time. 523 | 524 | Let's create a new storage bucket first (use your name/alias instead of the `wasm-bucket` value), using the `gsutil` command (the command is available in the GCP cloud shell): 525 | 526 | ```sh 527 | gsutil mb gs://wasm-bucket 528 | Creating gs://wasm-bucket/... 529 | ``` 530 | 531 | >Note that you can use any other storage service to host the Wasm extension. 532 | 533 | Next, we use the commands below to copy the built extension to the Google Cloud Storage and make it publicly accessible: 534 | 535 | ```sh 536 | BUCKET_NAME="wasm-bucket" 537 | 538 | # Copy the extension to the storage bucket 539 | gsutil cp main.wasm gs://$BUCKET_NAME 540 | 541 | # Make the extension readable to all users 542 | gsutil acl ch -u AllUsers:R gs://$BUCKET_NAME/main.wasm 543 | ``` 544 | 545 | The URL where the uploaded file is available is: `http://BUCKET_NAME.storage.googleapis.com/OBJECT_NAME`. For example, `http://wasm-bucket.storage.googleapis.com/main.wasm`. 546 | 547 | We can now create the EnvoyFilter resource that tells Envoy where to download the extension as well as where to inject it (make sure you update the `uri` field with your bucket URI): 548 | 549 | ```yaml 550 | apiVersion: networking.istio.io/v1alpha3 551 | kind: EnvoyFilter 552 | metadata: 553 | name: headers-extension 554 | spec: 555 | configPatches: 556 | - applyTo: EXTENSION_CONFIG 557 | patch: 558 | operation: ADD 559 | value: 560 | name: headers-extension 561 | typed_config: 562 | "@type": type.googleapis.com/udpa.type.v1.TypedStruct 563 | type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm 564 | value: 565 | config: 566 | vm_config: 567 | vm_id: headers-extension-vm 568 | runtime: envoy.wasm.runtime.v8 569 | code: 570 | remote: 571 | http_uri: 572 | uri: http://istio-weekly-ep7.storage.googleapis.com/main.wasm 573 | configuration: 574 | "@type": type.googleapis.com/google.protobuf.StringValue 575 | value: | 576 | header_1=somevalue 577 | header_2=secondvalue 578 | - applyTo: HTTP_FILTER 579 | match: 580 | context: SIDECAR_INBOUND 581 | listener: 582 | filterChain: 583 | filter: 584 | name: envoy.filters.network.http_connection_manager 585 | patch: 586 | operation: INSERT_BEFORE 587 | value: 588 | name: headers-extension 589 | config_discovery: 590 | config_source: 591 | ads: {} 592 | initial_fetch_timeout: 0s # wait indefinitely to prevent bad Wasm fetch 593 | type_urls: [ "type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm"] 594 | ``` 595 | 596 | Note that we're deploying the EnvoyFilters to the default namespace. We could also deploy them to a root namespace (e.g. `istio-system`) if we wanted to apply the filter to all workloads in the mesh. Additionally, we could specify the selectors to pick the workloads to which we want to apply the filter. 597 | 598 | Save the above YAML to `envoyfilter.yaml` file and create it: 599 | 600 | ```sh 601 | $ kubectl apply -f envoyfilter.yaml 602 | envoyfilter.networking.istio.io/headers-extension created 603 | ``` 604 | 605 | To try out the module, you can deploy a sample workload. 606 | 607 | I am using this httpbin example: 608 | 609 | ```yaml 610 | apiVersion: v1 611 | kind: ServiceAccount 612 | metadata: 613 | name: httpbin 614 | --- 615 | apiVersion: v1 616 | kind: Service 617 | metadata: 618 | name: httpbin 619 | labels: 620 | app: httpbin 621 | service: httpbin 622 | spec: 623 | ports: 624 | - name: http 625 | port: 8000 626 | targetPort: 80 627 | selector: 628 | app: httpbin 629 | --- 630 | apiVersion: apps/v1 631 | kind: Deployment 632 | metadata: 633 | name: httpbin 634 | spec: 635 | replicas: 1 636 | selector: 637 | matchLabels: 638 | app: httpbin 639 | version: v1 640 | template: 641 | metadata: 642 | labels: 643 | app: httpbin 644 | version: v1 645 | spec: 646 | serviceAccountName: httpbin 647 | containers: 648 | - image: docker.io/kennethreitz/httpbin 649 | imagePullPolicy: IfNotPresent 650 | name: httpbin 651 | ports: 652 | - containerPort: 80 653 | ``` 654 | 655 | Save the above file to `httpbin.yaml` and deploy it using `kubectl apply -f httpbin.yaml`. 656 | 657 | Before continuing, check that the httpbin Pod is up and running: 658 | 659 | ```sh 660 | $ kubectl get po 661 | NAME READY STATUS RESTARTS AGE 662 | httpbin-66cdbdb6c5-4pv44 2/2 Running 1 11m 663 | ``` 664 | 665 | To see if something went wrong with downloading the Wasm module, you can look at the istiod logs. 666 | 667 | Let's try out the deployed Wasm module! 668 | 669 | We will create a single Pod inside the cluster, and from there, we will send a request to `http://httpbin:8000/get` 670 | 671 | ```sh 672 | $ kubectl run curl --image=curlimages/curl -it --rm -- /bin/sh 673 | Defaulted container "curl" out of: curl, istio-proxy, istio-init (init) 674 | If you don't see a command prompt, try pressing enter. 675 | / $ 676 | ``` 677 | 678 | Once you get the prompt to the curl container, send a request to the `httpbin` service: 679 | 680 | ```sh 681 | / $ curl -v http://httpbin:8000/headers 682 | > GET /headers HTTP/1.1 683 | > User-Agent: curl/7.35.0 684 | > Host: httpbin:8000 685 | > Accept: */* 686 | > 687 | < HTTP/1.1 200 OK 688 | < server: envoy 689 | < date: Mon, 22 Jun 2021 18:52:17 GMT 690 | < content-type: application/json 691 | < content-length: 525 692 | < access-control-allow-origin: * 693 | < access-control-allow-credentials: true 694 | < x-envoy-upstream-service-time: 3 695 | < header_1: somevalue 696 | < header_2: secondvalue 697 | ... 698 | ``` 699 | 700 | Notice the two headers we defined in the Wasm module are being set in the response. 701 | 702 | ## Cleanup 703 | 704 | To delete all created resources from your cluster, run the following: 705 | 706 | ```sh 707 | kubectl delete envoyfilter headers-extension 708 | kubectl delete deployment httpbin 709 | kubectl delete svc httpbin 710 | kubectl delete sa httpbin 711 | ``` 712 | -------------------------------------------------------------------------------- /istio-weekly/008/008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-weekly/008/008.png -------------------------------------------------------------------------------- /istio-weekly/008/README.md: -------------------------------------------------------------------------------- 1 | # External CA with Istio 2 | 3 | - Hosted by [Orion Letizi](https://twitter.com/orionletizi), [Peter Jausovec](https://twitter.com/pjausovec) 4 | - Guests: 5 | - [Josh van Leeuwen](https://twitter.com/joshvanl) 6 | - Streamed live on August 5th, 11 am PST, 2021 7 | - Link: https://www.youtube.com/watch?v=4b3H7isIAnQ 8 | 9 | ![episode image](008.png) 10 | 11 | ## Show notes 12 | 13 | Istio CA generates a self-signed root certificate and key and uses them to sign all workload certificates. In this episode, [Josh van Leeuwen](https://twitter.com/joshvanl) from [Jetstack](https://jetstack.io) will show us how to configure Istio and use [istio-csr](https://github.com/cert-manager/istio-csr)/[cert-manager](https://cert-manager.io/) to configure external CA for Istio to use. 14 | 15 | - [DEMO](https://github.com/JoshVanL/tetrate-istio-weekly-2021-08-05) 16 | - [Slides (PDF)](https://github.com/JoshVanL/tetrate-istio-weekly-2021-08-05/blob/main/assets/istio_External_CA.pdf) 17 | 18 | ## Episode notes 19 | 20 | **Weekly highlights** 21 | - [Istio as an API Gateway](https://tetr8.io/istio-api-gateway) 22 | - [Get started with Envoy in 5 min](https://tetr8.io/5-minute-envoy) 23 | - [How to debug microservices in Kubernetes](https://tetr8.io/debug-microservices) 24 | - [Tetrate Certified Istio Administrator](https://tetr8.io/istio-administrator) 25 | 26 | **Resources** 27 | - [Jetstack](https://www.jetstack.io/) 28 | - [Use Istio service mesh and deploy mTLS everywhere (Ebook)](https://campaigns.jetstack.io/istio_service_mesh/) 29 | - [Secure production identity framework for everyone (SPIFFE)](https://spiffe.io) 30 | - [cert-manager](https://github.com/jetstack/cert-manager) 31 | - [istio-csr](https://github.com/jetstack/istio-csr) 32 | - [Istio Workload Certificate API](https://docs.google.com/document/d/1QACaJW8LpQMvdbPd-EoVtYNcNprTb6vScj72k-qHyT4/edit#heading=h.as1yzu52kj40) 33 | 34 | 35 | ## Connect 36 | 37 | - Follow us on [Twitter](https://twitter.com/tetrateio) 38 | - Follow us on [LinkedIn](https://www.linkedin.com/company/tetrate) 39 | - Past episodes: https://istioweekly.com 40 | 41 | - Community page: https://istio.tetratelabs.io/community 42 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) 43 | 44 | ## Participate 45 | 46 | Suggest an episode: http://tetr8.io/istio-weekly-suggestions 47 | -------------------------------------------------------------------------------- /istio-weekly/009/009.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-weekly/009/009.png -------------------------------------------------------------------------------- /istio-weekly/009/README.md: -------------------------------------------------------------------------------- 1 | # Customizing Istio metrics 2 | 3 | - Hosted by [Orion Letizi](https://twitter.com/orionletizi) 4 | - Presenters: 5 | - [Peter Jausovec](https://twitter.com/pjausovec) 6 | - Streamed live on August 19th, 11 am PST, 2021 7 | - Link: https://www.youtube.com/watch?v=hhoKWEBGM_c 8 | 9 | ![episode image](009.png) 10 | 11 | ## Show notes 12 | 13 | In this episode we talked about customizing and creating new Istio service-level metrics. 14 | 15 | [DEMO](demo.md) 16 | 17 | ## Episode notes 18 | 19 | - [Istio 1.11 release](https://tetr8.io/istio-1-11) 20 | 21 | **Resources** 22 | 23 | - [Envoy attributes](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/advanced/attributes) 24 | - [Attributes in Istio source](https://github.com/istio/proxy/blob/master/src/istio/utils/attribute_names.cc) 25 | - [Standard Istio metrics](https://istio.io/latest/docs/reference/config/metrics/) 26 | - [Stats Wasm extension](https://github.com/istio/proxy/tree/master/extensions/stats) 27 | - [Stats configuration](https://istio.io/latest/docs/reference/config/proxy_extensions/stats/) 28 | - [Attribute gen configuration](https://istio.io/latest/docs/reference/config/proxy_extensions/attributegen/) 29 | 30 | **Events** 31 | 32 | - August 25th, 11am: [Zero Trust with a Service Mesh](https://www.tetrate.io/event/zero-trust-with-a-service-mesh/) 33 | - August 31st, 11am: [Application Security in a Contactless World: A fintech roundtable](https://www.tetrate.io/event/application-security-in-a-contactless-world-a-fintech-roundtable/) 34 | 35 | ## Connect 36 | 37 | - Follow us on [Twitter](https://twitter.com/tetrateio) 38 | - Follow us on [LinkedIn](https://www.linkedin.com/company/tetrate) 39 | - Past episodes: https://istioweekly.com 40 | 41 | - Community page: https://istio.tetratelabs.io/community 42 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) 43 | 44 | ## Participate 45 | 46 | Suggest an episode: http://tetr8.io/istio-weekly-suggestions 47 | -------------------------------------------------------------------------------- /istio-weekly/009/demo.md: -------------------------------------------------------------------------------- 1 | # Customizing Istio metrics 2 | 3 | The metrics can be customize by configuring the [stats extension](https://github.com/istio/proxy/tree/master/extensions/stats). 4 | 5 | ## Adding dimension to an existing metric 6 | 7 | We'll use the Istio operator to update the `istio_requests_total` metric and add two dimensions to it: 8 | 9 | - my_request_id 10 | - gcp_location 11 | 12 | The `my_request_id` will get its value from the `request.id` [Envoy attribute](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/advanced/attributes). The `gcp_location` value is coming from the bootstrap portion of the Envoy proxy configuration. 13 | 14 | Deploy the following IstioOperator: 15 | 16 | ```yaml 17 | apiVersion: install.istio.io/v1alpha1 18 | kind: IstioOperator 19 | metadata: 20 | name: demo-install 21 | namespace: istio-system 22 | spec: 23 | profile: demo 24 | meshConfig: 25 | defaultConfig: 26 | extraStatTags: 27 | - my_request_id 28 | - gcp_location 29 | values: 30 | telemetry: 31 | v2: 32 | prometheus: 33 | configOverride: 34 | inboundSidecar: 35 | metrics: 36 | - name: requests_total 37 | dimensions: 38 | my_request_id: request.id 39 | gcp_location: node.metadata.PLATFORM_METADATA['gcp_location'] 40 | ``` 41 | 42 | If you make a couple of requests to a workload running the mesh, you can check the `istio_requests_total` metric updated with the two dimensions we added. (Use `istioctl dash envoy [workload]` to open the Envoy dashboard) 43 | 44 | ## Creating a new metric 45 | 46 | To create a new metric we'll define it in the `definitions` field. The value of the metric is a string, however, it needs to evaluate to an integer. Note the name of the metric (`my_custom_metric`) will have the stat prefix `istio` (this is hardcoded and can't be changed at the moment). That's why we need to use the full name (`istio_my_custom_metric`) in the `inclusionPrefixes` field. 47 | 48 | ```yaml 49 | apiVersion: install.istio.io/v1alpha1 50 | kind: IstioOperator 51 | metadata: 52 | name: demo-install 53 | namespace: istio-system 54 | spec: 55 | profile: demo 56 | meshConfig: 57 | defaultConfig: 58 | proxyStatsMatcher: 59 | inclusionPrefixes: 60 | - istio_my_custom_metric 61 | values: 62 | telemetry: 63 | v2: 64 | prometheus: 65 | configOverride: 66 | inboundSidecar: 67 | definitions: 68 | - name: my_custom_metric 69 | type: "COUNTER" 70 | value: "(request.method.startsWith('POST') ? 1 : 0)" 71 | ``` 72 | 73 | ### Creating new attributes 74 | 75 | To create a new attribute we use the [AttributeGen extension](https://github.com/istio/proxy/tree/master/extensions/attributegen). 76 | 77 | ```yaml 78 | apiVersion: networking.istio.io/v1alpha3 79 | kind: EnvoyFilter 80 | metadata: 81 | name: new-attribute 82 | namespace: istio-system 83 | spec: 84 | configPatches: 85 | - applyTo: HTTP_FILTER 86 | match: 87 | context: SIDECAR_INBOUND 88 | proxy: 89 | proxyVersion: '1\.10.*' 90 | listener: 91 | filterChain: 92 | filter: 93 | name: "envoy.filters.network.http_connection_manager" 94 | subFilter: 95 | name: "istio.stats" 96 | patch: 97 | operation: INSERT_BEFORE 98 | value: 99 | name: istio.attributegen 100 | typed_config: 101 | "@type": type.googleapis.com/udpa.type.v1.TypedStruct 102 | type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm 103 | value: 104 | config: 105 | configuration: 106 | "@type": type.googleapis.com/google.protobuf.StringValue 107 | value: | 108 | { 109 | "attributes": [ 110 | { 111 | "output_attribute": "istio_my_new_attribute", 112 | "match": [ 113 | { 114 | "value": "GetRequest", 115 | "condition": "request.method == 'GET'" 116 | }, 117 | { 118 | "value": "PostRequest", 119 | "condition": "request.method == 'POST'" 120 | } 121 | ] 122 | } 123 | ] 124 | } 125 | vm_config: 126 | runtime: envoy.wasm.runtime.null 127 | code: 128 | local: { inline_string: "envoy.wasm.attributegen" } 129 | ``` 130 | 131 | We can now add the new attribute as a dimension to the existing metric: 132 | 133 | 134 | ```yaml 135 | apiVersion: install.istio.io/v1alpha1 136 | kind: IstioOperator 137 | metadata: 138 | name: demo-install 139 | namespace: istio-system 140 | spec: 141 | profile: demo 142 | meshConfig: 143 | defaultConfig: 144 | extraStatTags: 145 | - my_method 146 | values: 147 | telemetry: 148 | v2: 149 | prometheus: 150 | configOverride: 151 | inboundSidecar: 152 | metrics: 153 | - name: requests_total 154 | dimensions: 155 | my_method: istio_my_new_attribute 156 | ``` 157 | 158 | 159 | ## Resources 160 | 161 | - Envoy attributes: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/advanced/attributes 162 | - Attributes in source: https://github.com/istio/proxy/blob/master/src/istio/utils/attribute_names.cc 163 | - Standard Istio metrics: https://istio.io/latest/docs/reference/config/metrics/ 164 | - Stats Wasm extension: https://github.com/istio/proxy/tree/master/extensions/stats 165 | - Stats configuration: https://istio.io/latest/docs/reference/config/proxy_extensions/stats/ 166 | - Attribute gen configuration: https://istio.io/latest/docs/reference/config/proxy_extensions/attributegen/ -------------------------------------------------------------------------------- /istio-weekly/010/010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-weekly/010/010.png -------------------------------------------------------------------------------- /istio-weekly/010/README.md: -------------------------------------------------------------------------------- 1 | # How to become a certified Istio expert? 2 | 3 | - Hosted by [Orion Letizi](https://twitter.com/orionletizi), [Peter Jausovec](https://twitter.com/pjausovec) 4 | - Guests: 5 | - [Vijay Nadkarni](https://twitter.com/vnadkarni) 6 | - Streamed live on September 2nd, 11 am PST, 2021 7 | - Link: https://www.youtube.com/watch?v=29JQA5jQ8OI 8 | 9 | ![episode image](010.png) 10 | 11 | ## Show notes 12 | 13 | Join us to learn about the Tetrate Istio Certified Administrator exam. Vijay Nadkarni will share his tips and tricks on how he prepared and passed the TCIA exam. 14 | 15 | ## Episode notes 16 | 17 | - [Istio security patches]( https://tetr8.io/istio-security-2021-008) 18 | 19 | **Resources** 20 | 21 | - [Tetrate Academy: Istio Fundamentals course](https://academy.tetrate.io/courses/istio-fundamentals) 22 | - [Certified Istio Administrator by Tetrate exam](https://academy.tetrate.io/courses/certified-istio-administrator) 23 | - [Istio Documentation](https://istio.io/docs) 24 | 25 | ## Connect 26 | 27 | - Follow us on [Twitter](https://twitter.com/tetrateio) 28 | - Follow us on [LinkedIn](https://www.linkedin.com/company/tetrate) 29 | - Past episodes: https://istioweekly.com 30 | 31 | - Community page: https://istio.tetratelabs.io/community 32 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) 33 | 34 | ## Participate 35 | 36 | Suggest an episode: http://tetr8.io/istio-weekly-suggestions 37 | -------------------------------------------------------------------------------- /istio-weekly/011/011.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-weekly/011/011.png -------------------------------------------------------------------------------- /istio-weekly/011/README.md: -------------------------------------------------------------------------------- 1 | # Enterprise service mesh and why you need it 2 | 3 | - Hosted by [Orion Letizi](https://twitter.com/orionletizi), [Peter Jausovec](https://twitter.com/pjausovec) 4 | - Guests: 5 | - [Adam Zwickey](https://twitter.com/zwickey) 6 | - Streamed live on September 16th, 11 am PST, 2021 7 | - Link: https://www.youtube.com/watch?v=HQ3BBsJDeXU 8 | 9 | ![episode image](011.png) 10 | 11 | ## Show notes 12 | 13 | Join us on September 16th for another Istio weekly episode where we'll talk to Adam Zwickey, director of global solutions engineering at Tetrate. Adam will talk about scenarios that call for an enterprise service mesh, such as TSB. He’ll show us how TSB can help us manage and configure service meshes in enterprise environments. 14 | 15 | ## Episode notes 16 | 17 | - [Tetrate Service Bridge (TSB)](https://www.tetrate.io/tetrate-service-bridge/) 18 | - [Local-aware routing demo](https://www.youtube.com/watch?v=v_PVxsYiZts&t=0s) 19 | 20 | ## Connect 21 | 22 | - Follow us on [Twitter](https://twitter.com/tetrateio) 23 | - Follow us on [LinkedIn](https://www.linkedin.com/company/tetrate) 24 | - Past episodes: https://istioweekly.com 25 | 26 | - Community page: https://istio.tetratelabs.io/community 27 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) 28 | 29 | ## Participate 30 | 31 | Suggest an episode: http://tetr8.io/istio-weekly-suggestions 32 | -------------------------------------------------------------------------------- /istio-weekly/012/012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-weekly/012/012.png -------------------------------------------------------------------------------- /istio-weekly/012/README.md: -------------------------------------------------------------------------------- 1 | # How I started contributing to Istio and Envoy 2 | 3 | - Hosted by [Orion Letizi](https://twitter.com/orionletizi), [Peter Jausovec](https://twitter.com/pjausovec) 4 | - Guests: 5 | - [Aditya Prerepa](https://twitter.com/aprerepa) 6 | - Streamed live on Octover 1st, 4 pm PST, 2021 7 | - Link: https://youtu.be/o3Fi6nwuuiI 8 | 9 | ![episode image](012.png) 10 | 11 | ## Show notes 12 | 13 | Join us on October 1st for the next Istio weekly episode where we'll talk with Istio maintainer Aditya Prerepa. 14 | 15 | In addition to being a member of the Istio networking working group, Aditya is also finishing high school this year. He’s worked on Istio for more than a year with a focus on Pilot and xDS as well as VM health checking, auto registration, and multitenancy. 16 | 17 | With Hacktoberfest coming up, we’ll discuss what Aditya is currently working on, how he started contributing to Istio and Envoy, his upcoming EnvoyCon talk, and any tips he has for anyone trying to start contributing to Istio/Envoy and other open-source projects. 18 | 19 | ## Episode notes 20 | 21 | - [EKS is Anywhere and so is Tetrate](https://www.tetrate.io/blog/tetrate-eks-anywhere/) 22 | - [Tetrate Academy (Istio fundamentals course)](https://academy.tetrate.io/collections) 23 | - [Envoycon 2021](https://events.linuxfoundation.org/envoycon-north-america/) 24 | 25 | - [Aditya's Twitter](https://twitter.com/APrerepa) 26 | - [Aditya's Github](https://github.com/adiprerepa) 27 | 28 | - [Istio Github](https://github.com/istio) 29 | - [Hacktoberfest](https://hacktoberfest.digitalocean.com/) 30 | - [func-e hacktoberfest issues](https://github.com/tetratelabs/func-e) 31 | 32 | ## Connect 33 | 34 | - Follow us on [Twitter](https://twitter.com/tetrateio) 35 | - Follow us on [LinkedIn](https://www.linkedin.com/company/tetrate) 36 | - Past episodes: https://istioweekly.com 37 | 38 | - Community page: https://istio.tetratelabs.io/community 39 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) 40 | 41 | ## Participate 42 | 43 | Suggest an episode: http://tetr8.io/istio-weekly-suggestions 44 | -------------------------------------------------------------------------------- /istio-weekly/013/013.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-weekly/013/013.png -------------------------------------------------------------------------------- /istio-weekly/013/README.md: -------------------------------------------------------------------------------- 1 | # Access Control for Microservices 2 | 3 | - Hosted by [Orion Letizi](https://twitter.com/orionletizi), [Peter Jausovec](https://twitter.com/pjausovec) 4 | - Guests: 5 | - [Ignasi Barrera](https://twitter.com/ignasibarrera) 6 | - Streamed live on November 18th, 11 am PST, 2021 7 | - Link: https://youtu.be/ItpCGpYupQQ 8 | 9 | ![episode image](013.png) 10 | 11 | ## Show notes 12 | 13 | Join us on November 18th for the next Istio weekly episode where we'll talk with Tetrate founding engineer, Ignasi Barrera. 14 | 15 | Ignasi leads the development of a modern security solution for the hybrid and multi-cloud worlds, based on NGAC - Next Generation Access Control. In this episode, we’ll talk about access control for microservices and we’ll explain what NGAC is and why it matters to you. 16 | 17 | ## Episode notes 18 | 19 | - [Building Secure Microservices-based Applications Using Service-Mesh Architecture (SP800-204A)](https://csrc.nist.gov/publications/detail/sp/800-204a/final) 20 | - [Attribute-based Access Control for Microservices-based Applications using a Service Mesh (SP800-204B - public draft)](https://csrc.nist.gov/publications/detail/sp/800-204b/draft) 21 | - Application of DevSecOps using a Service Mesh in Microservices-based Infrastructure(SP800-204C UPCOMING) 22 | - [Identity Management & Access Control in Multiclouds (Workshop and Conference)](https://www.nist.gov/news-events/events/2020/01/identity-management-access-control-multiclouds-workshop-and-conference) 23 | - [DevSecOps and Zero Trust Architecture (ZTA) for Multi-Cloud Environments](https://www.nist.gov/news-events/events/2021/01/devsecops-and-zero-trust-architecture-zta-multi-cloud-environments) 24 | 25 | 26 | - [Tetrate Academy (Envoy fundamentals course)](https://academy.tetrate.io/courses/envoy-fundamentals) 27 | 28 | ## Connect 29 | 30 | - Follow us on [Twitter](https://twitter.com/tetrateio) 31 | - Follow us on [LinkedIn](https://www.linkedin.com/company/tetrate) 32 | - Past episodes: https://istioweekly.com 33 | 34 | - Community page: https://istio.tetratelabs.io/community 35 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) 36 | 37 | ## Participate 38 | 39 | Suggest an episode: http://tetr8.io/istio-weekly-suggestions 40 | -------------------------------------------------------------------------------- /istio-weekly/014/014.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-weekly/014/014.png -------------------------------------------------------------------------------- /istio-weekly/014/README.md: -------------------------------------------------------------------------------- 1 | # Istio's new Wasm-based extension mechanism and ecosystem 2 | 3 | - Hosted by [Orion Letizi](https://twitter.com/orionletizi), [Peter Jausovec](https://twitter.com/pjausovec) 4 | - Guests: 5 | - [Takeshi Yoneda](https://twitter.com/mathetake) 6 | - Streamed live on November 24th, 4 pm PST, 2021 7 | - Link: https://www.youtube.com/watch?v=hkREEicBgDc 8 | 9 | ![episode image](014.png) 10 | 11 | ## Show notes 12 | 13 | Join us on November 24th for the next Istio weekly episode where we'll talk with Tetrate software engineer and Envoy proxy and Proxy Wasm maintainer Takeshi Yoneda. 14 | 15 | In this episode, Takeshi will give us an overview of WebAssembly (Wasm) in Istio and talk about exciting new Wasm-related features he worked on for the Istio 1.12 release. 16 | 17 | ## Episode notes 18 | 19 | - [New in Istio 1.12: Wasm-based extensions and ecosystem (tutorial + DEMO)](https://www.tetrate.io/blog/istio-wasm-extensions-and-ecosystem/) 20 | - [Istio Weekly EP07 - Developing Envoy Wasm Extensions](https://www.youtube.com/watch?v=JIq8wujlG9s&t=2s) 21 | - [Proxy-Wasm Go SDK examples](https://github.com/tetratelabs/proxy-wasm-go-sdk/tree/main/examples) 22 | - [Proxy-Wasm spec](https://github.com/proxy-wasm/spec) 23 | - [Istio Wasm Extensions Workshop](https://www.tetrate.io/istio-wasm-workshop/) 24 | 25 | ## Connect 26 | 27 | - Follow us on [Twitter](https://twitter.com/tetrateio) 28 | - Follow us on [LinkedIn](https://www.linkedin.com/company/tetrate) 29 | - Past episodes: https://istioweekly.com 30 | 31 | - Community page: https://istio.tetratelabs.io/community 32 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) 33 | 34 | ## Participate 35 | 36 | Suggest an episode: http://tetr8.io/istio-weekly-suggestions 37 | -------------------------------------------------------------------------------- /istio-weekly/015/015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-weekly/015/015.png -------------------------------------------------------------------------------- /istio-weekly/015/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Setting up Istio with external control plane 3 | 4 | - Hosted by [Peter Jausovec](https://twitter.com/pjausovec) 5 | - Streamed live on December 9th, 11 am PST, 2021 6 | - Link: https://www.youtube.com/watch?v=MaQ3PvXcT9c 7 | 8 | ![episode image](015.png) 9 | 10 | ## Show notes 11 | 12 | Join us on December 9th for the next Istio weekly episode, where we'll show you how to install Istio with an external control plane. 13 | 14 | The external control plane deployment model offers a clean separation between mesh operators and mesh administrators. Mesh operators install and manage Istio’s control plane on one cluster and then connect one or more remote clusters (data planes) to form a mesh. Mesh administrators can then configure the mesh as needed. 15 | 16 | ## Episode notes 17 | 18 | - [Setting up external control plane tutorial](https://istio.io/latest/docs/setup/install/external-controlplane/) 19 | 20 | - [Securing the ingress gateway](https://istio.io/latest/docs/tasks/traffic-management/ingress/secure-ingress/) 21 | 22 | 23 | At [23:22](https://youtu.be/MaQ3PvXcT9c?t=1401) when creating the TLS secret. The .zip from SSLForFree contains 3 files: 24 | 25 | 1. ca_bundle.crt 26 | 2. certificate.crt 27 | 3. private.key 28 | 29 | Instead of creating a secret and passing in certificate.crt for the --cert argument, you need to merge the ca_bundle with the certificate. So, create a new file called `combined.crt` paste in the contents of the `certificate.crt` file and then below that paste the contents of the `ca_bundle.crt` file. 30 | 31 | Then you can create the TLS secret and reference the `combined.crt` file instead: "kubectl create secret tls cp-istioweekly --key=private.key --cert=combined.crt". 32 | 33 | ## Connect 34 | 35 | - Follow us on [Twitter](https://twitter.com/tetrateio) 36 | - Follow us on [LinkedIn](https://www.linkedin.com/company/tetrate) 37 | - Past episodes: https://istioweekly.com 38 | 39 | - Community page: https://istio.tetratelabs.io/community 40 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) 41 | 42 | ## Participate 43 | 44 | Suggest an episode: http://tetr8.io/istio-weekly-suggestions -------------------------------------------------------------------------------- /istio-weekly/016/016.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tetratelabs/istio-weekly/ad69db3f12ec1ae2b6910c66b26f0e0c1af0762f/istio-weekly/016/016.png -------------------------------------------------------------------------------- /istio-weekly/016/README.md: -------------------------------------------------------------------------------- 1 | 2 | # How Istio configures Envoy proxies 3 | 4 | - Hosted by [Peter Jausovec](https://twitter.com/pjausovec) and Eitan Suez 5 | - Streamed live on January 20th, 11 am PST, 2021 6 | - Link: https://www.youtube.com/watch?v=8X_pSA5eRTY 7 | 8 | ![episode image](016.png) 9 | 10 | ## Show notes 11 | 12 | Join us on January 20th for the first Istio weekly episode in 2022. Eitan Suez will explore how Istio configures Envoy proxies. 13 | 14 | Have you ever wondered what happens when you deploy a VirtualService or a DestinationRule? We know Istio translates the high-level configuration to the low-level Envoy configuration, but do we really understand how the different concepts map to each other? Eitan will show us how to use Istio CLI, proxy-status, and proxy-config commands to inspect the parts of Envoy configuration. Join us! 15 | 16 | ## Upcoming events 17 | 18 | [January 26-27, 2022: ZTA and DevSecOps for Cloud-Native Applications]https://tetr8.io/nist-2022] 19 | [February 3, 2022: Istio Wasm Extensions Workshop](https://tetr8.io/wasm-workshop) 20 | [Febuary 17th, 2022: Istio 0 to 60 workshop (PST)](https://tetr8.io/istio-0-60-pst) 21 | [Febuary 17th, 2022: Istio 0 to 60 workshop (IST)](https://tetr8.io/istio-0-60-ist) 22 | 23 | ## Connect 24 | 25 | - Follow us on [Twitter](https://twitter.com/tetrateio) 26 | - Follow us on [LinkedIn](https://www.linkedin.com/company/tetrate) 27 | - Past episodes: https://istioweekly.com 28 | 29 | - Community page: https://istio.tetratelabs.io/community 30 | - Slack: https://slack.istio.io (search for the #GetIstio channel and join) 31 | 32 | ## Participate 33 | 34 | Suggest an episode: http://tetr8.io/istio-weekly-suggestions -------------------------------------------------------------------------------- /istio-weekly/playlist.md: -------------------------------------------------------------------------------- 1 | # Istio Weekly Playlist Index 2 | 3 | - [016: How Istio configures Envoy proxies](016) 4 | - [015: Setting up Istio with external control plane](015) 5 | - [014: Istio's new Wasm-based extension mechanism and ecosystem](014) 6 | - [013: Access Control for Microservices](013) 7 | - [012: How I started contributing to Istio and Envoy](012) 8 | - [011: Enterprise service mesh and why you need it](011) 9 | - [010: How to become a certified Istio expert](010) 10 | - [009: Customizing Istio metrics](009) 11 | - [008: External CA in Istio](008) 12 | - [007: Developing Envoy Wasm Extensions](007) 13 | - [006: Envoy fundamentals](006) 14 | - [005: Security in Istio](005) 15 | - [004: Deploying multiple Istio ingress gateways](004) 16 | - [003: SSL Certificates in Istio Ingress Gateway](003) 17 | - [002: Istio the Easy Way with GetIstio](002) 18 | - [001: Effortless Envoy and WASM with GetEnvoy](001) 19 | - [000: What is GetIstio - Inaugural Community Meetup](000) --------------------------------------------------------------------------------