├── .github └── ISSUE_TEMPLATE │ └── docs.yaml ├── .gitignore ├── LICENSE ├── README.md ├── book.toml └── src ├── README.md ├── SUMMARY.md ├── admin-quick-start.md ├── app-store.md ├── b2i-war ├── b2i-war.md ├── image-20220520133457810.png ├── image-20220520134249980.png ├── image-20220520134547852.png ├── image-20220520134659172.png ├── image-20220520134704871.png ├── image-20220520135517989.png ├── image-20220520135843962.png ├── image-20220520140441194.png ├── image-20220520140721699.png ├── image-20220520141003289.png ├── image-20220520141124834.png ├── image-20220520141652350.png ├── image-20220520141732035.png ├── image-20220520141757630.png ├── image-20220520141827360.png ├── image-20220520142009915.png ├── image-20220520142100724.png ├── image-20220520142351376.png ├── image-20220520143850190.png ├── image-20220520143944470.png ├── image-20220520145158024.png ├── image-20220520145238801.png ├── image-20220520145741631.png ├── image-20220520145820197.png └── image-20220520150006127.png ├── bookinfo-canary.md ├── devops-online.md ├── hpa.md ├── ingress-canary ├── 1.png ├── 10.png ├── 11.png ├── 12.png ├── 13.png ├── 14.png ├── 15.png ├── 16.png ├── 17.png ├── 18.png ├── 19.png ├── 2.png ├── 20.png ├── 21.png ├── 22.png ├── 23.png ├── 24.png ├── 25.png ├── 26.png ├── 27.png ├── 28.png ├── 29.png ├── 3.png ├── 30.png ├── 31.png ├── 32.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── 8.png ├── 9.png └── index.md ├── ingress-demo ├── cgw-created.png ├── cgw-metrics.png ├── cgw-nodeport.png ├── index.md ├── ingress-demo.png ├── route-anno-add.png ├── route-anno-added.png ├── route-create-rule-https.png ├── route-create-rule.png ├── route-create.png ├── route-created-https.png ├── route-created.png ├── route-httpbin.png ├── route-prefix-httpbin.png ├── route-rule-edit.png ├── secret-create-data.png ├── secret-created.png ├── svc-create-container.png ├── svc-create-meta.png ├── svc-create-pod.png ├── svc-create.png └── svc-created.png ├── jenkinsfile-out-of-scm.md ├── job-quick-start.md ├── one-click-deploy.md ├── source-to-image.md └── wordpress-deployment.md /.github/ISSUE_TEMPLATE/docs.yaml: -------------------------------------------------------------------------------- 1 | name: 新增章节 2 | description: 新增一篇 KubeSphere 3.2.1 快速入门的文档 3 | body: 4 | - type: input 5 | id: chapter 6 | validations: 7 | required: true 8 | attributes: 9 | label: 章节 10 | - type: input 11 | id: reference 12 | validations: 13 | required: true 14 | attributes: 15 | label: 参考链接 16 | 17 | - type: markdown 18 | id: progress 19 | attributes: 20 | value: | 21 | ## 当前进度 22 | - type: input 23 | id: progress_2 24 | validations: 25 | required: true 26 | attributes: 27 | label: 已有人认领? 28 | description: 只能填写 `yes` 或者 `no` 29 | - type: input 30 | id: progress_3 31 | validations: 32 | required: true 33 | attributes: 34 | label: 已提交 PR? 35 | description: 只能填写 `yes` 或者 `no` 36 | - type: input 37 | id: progress_4 38 | validations: 39 | required: true 40 | attributes: 41 | label: 正在review? 42 | description: 只能填写 `yes` 或者 `no` 43 | - type: input 44 | id: progress_5 45 | validations: 46 | required: true 47 | attributes: 48 | label: 已发布? 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | book 2 | .DS_Store 3 | */.DS_Store 4 | -------------------------------------------------------------------------------- /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 | # KubeSphere 3.2.1 快速入门 2 | 3 | 本仓库的文档旨在通过多个快速入门的示例帮助您了解 KubeSphere 3.2.1 的基本使用流程,带您快速上手 KubeSphere 3.2.1。 4 | 5 | ## 贡献指南 6 | 7 | 本指南为纯静态网站,使用 [mdBook](https://github.com/rust-lang/mdBook) 构建,贡献步骤如下: 8 | 9 | ### 1. 认领章节 10 | 11 | 首先到 [Issue 页面](https://github.com/kubesphere-sigs/kubesphere-quick-start/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc)选择自己感兴趣章节相关的 Issue,在 Issue 下面回复认领。 12 | 13 | ### 2. Fork 该仓库 14 | 15 | Fork 该仓库,然后 Clone 到本地,假设你的用户名是 xxx,那么 Clone 命令就是:`git clone https://github.com/xxx/kubesphere-quick-start`。 16 | 17 | ### 3. 编译并预览 18 | 19 | 为了能够在本地即时预览文档,需要先[安装 mdBook](https://rust-lang.github.io/mdBook/guide/installation.html)。更新文档之后便可以执行命令 `mdbook serve --open` 来即时预览文档。 20 | 21 | ### 4. 提交更新 22 | 23 | 确认无误后,将更新提交到自己的仓库: 24 | 25 | ```bash 26 | $ git add . 27 | $ git commit "xxx" 28 | $ git push -u origin main 29 | ``` 30 | 31 | ### 5. 提交 PR 32 | 33 | 在浏览器中打开你的仓库页面,选择『Pull requests』--> 『New pull request』。 34 | 35 | ![](https://pek3b.qingstor.com/kubesphere-community/images/202205182220637.png) 36 | 37 | 确认无误后,点击『Create pull request』即可提交 PR。 38 | 39 | ![](https://pek3b.qingstor.com/kubesphere-community/images/202205182220990.png) 40 | -------------------------------------------------------------------------------- /book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | authors = ["Administrator"] 3 | language = "en" 4 | multilingual = false 5 | src = "src" 6 | title = "KubeSphere 3.2.1 快速入门" 7 | -------------------------------------------------------------------------------- /src/README.md: -------------------------------------------------------------------------------- 1 | # 入门必读 2 | 3 | 4 | 5 | 本章节旨在通过多个快速入门的示例帮助您了解 KubeSphere 容器平台的基本使用流程,带您快速上手 KubeSphere。建议参考示例文档的步骤动手实践操作一遍。为了帮助用户更快地了解 KubeSphere 并进一步理解底层 Kubernetes 的基础概念和知识,我们还精心准备了 [Kubernetes 入门视频教程](https://kubesphere.com.cn/videos/)。 6 | 7 | 8 | 9 | ## 多租户管理快速入门 10 | 11 | 若您是初次安装使用 KubeSphere 的集群管理员用户,请先参考 [多租户管理快速入门](../admin-quick-start),将引导新手用户创建企业空间、创建新的账户角色并邀请加入,它是创建工作负载和 DevOps 工程的前提条件。 12 | 13 | 14 | 15 | ## 应用路由与服务示例 16 | 17 | KubeSphere 在项目中为用户项目内置了一个全局的负载均衡器,即应用路由控制器 (Ingress Controller),为了代理不同后端服务 (Service) 而设置的负载均衡服务,用户访问 URL 时,应用路由可以把请求转发给不同的后端服务,[服务与应用路由示例](../ingress-demo) 在 KubeSphere 创建相关资源来说明这个应用路由的示例。 18 | 19 | 20 | 21 | ## 编排微服务应用 22 | 23 | 参考 [创建 Wordpress 应用并发布至 Kubernetes](../wordpress-deployment) 24 | 25 | 26 | 27 | ## 创建任务 28 | 29 | 任务 (Job) 是 Kubernetes 中用来控制批处理型任务的资源对象,定时任务 (CronJob) 是基于时间的任务,可以定时地执行 Job,当您熟悉了任务的使用示例,那么上手定时任务也就不是一件难事了。本文以创建一个并行任务去执行简单的命令计算并输出圆周率到小数点后 2000 位作为示例,说明任务的基本功能。 30 | 31 | 参考 [创建简单任务](../job-quick-start) 32 | 33 | 34 | 35 | ## 应用仓库与部署应用 36 | 37 | 参考 [一键部署应用](../one-click-deploy) 38 | 39 | 一键部署应用基于 KubeSphere 内置应用仓库,部署的应用一般包含相应的工作负载和服务。 40 | 41 | - [设置弹性伸缩 (HPA)](../hpa) 42 | 43 | 弹性伸缩 (HPA) 是高级版独有的功能,支持 Pod 的水平自动伸缩,本示例演示平台中如何设置 Pod 水平自动伸缩的功能。 44 | 45 | 46 | 47 | ## DevOps 快速入门 48 | 49 | - [Binary to Image](../b2i-war) 50 | 51 | Binary to Image 旨在帮助开发者和运维在项目打包成 WAR、JAR、Binary 这一类的制品后,快速将制品或二进制的 Package 打包成 Docker 镜像,并发布到 DockerHub 或 Harbor 等镜像仓库中。并且支持以创建服务的形式,一键将制品生成镜像推送到仓库,并创建其部署 (Deployment) 和服务 (Service) 最终自动发布到 Kubernetes 中。参考[Binary to Image](../b2i-war) 52 | 53 | - [Source to Image](../source-to-image) 54 | 55 | Source to Image(S2I) 是一个创建 Docker 镜像的工具。它可以通过将源代码放入一个单独定义的负责编译源代码的 Builder image中,来将编译后的代码打包成 Docker 镜像。参考[Source to Image](../source-to-image) 56 | 57 | - [基于Spring Boot项目构建流水线](../devops-online) 58 | 59 | 本示例演示如何通过 GitHub 仓库中的 Jenkinsfile 来创建 CI/CD 流水线,包括拉取代码、单元测试、代码质量检测、构建镜像、推送和发布版本,最终示例 Web 部署到 KubeSphere 集群中的开发环境和生产环境,并且能够通过公网访问。参考[基于Spring Boot项目构建流水线](../devops-online) 60 | 61 | - [图形化构建流水线(Jenkinsfile out of SCM)](../jenkinsfile-out-of-scm) 62 | 63 | 本示例演示如何在 KubeSphere 中使用图形编辑面板创建流水线。KubeSphere 在整个过程中将根据您在编辑面板上的设置自动生成 Jenkinsfile,您无需手动创建 Jenkinsfile。待流水线成功运行,它会相应地在您的开发环境中创建一个部署 (Deployment) 和一个服务 (Service),并将镜像推送至 Docker Hub。参考[图形化构建流水线(Jenkinsfile out of SCM)](../jenkinsfile-out-of-scm) 64 | 65 | 66 | 67 | ## Bookinfo 微服务的灰度发布示例 68 | 69 | KubeSphere 基于 Istio 提供了蓝绿部署、金丝雀发布、流量镜像等三种灰度策略,无需修改应用的业务代码,即可实现灰度、流量治理、Tracing、流量监控、调用链等服务治理功能。本示例演示基于 KubeSphere 快速创建一个微服务应用并对其中的服务组件进行灰度发布与熔断。参考[Bookinfo 微服务的灰度发布示例](../bookinfo-canary.md) 70 | 71 | 72 | 73 | ## 使用 Ingress-Nginx 进行灰度发布 74 | 75 | 本文将直接介绍和演示基于 KubeSphere 使用应用路由 (Ingress) 和项目网关 (Ingress Controller) 实现灰度发布。参考[使用 Ingress-Nginx 进行灰度发布](../ingress-canary.md) 76 | 77 | 78 | 79 | ## 应用商店 80 | 81 | KubeSphere 在 [OpenPitrix](https://github.com/openpitrix/openpitrix) 的基础上,为用户提供了一个基于 Helm 的应用商店,用于应用生命周期管理。OpenPitrix 是一个开源的 Web 平台,用于打包、部署和管理不同类型的应用。KubeSphere 应用商店让 ISV、开发者和用户能够在一站式服务中只需点击几下就可以上传、测试、安装和发布应用,参考 [应用商店](../app-store)。 82 | -------------------------------------------------------------------------------- /src/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | [入门必读](README.md) 4 | 5 | - [多租户管理快速入门](./admin-quick-start.md) 6 | - [应用路由与服务示例](ingress-demo/index.md) 7 | - [创建 Wordpress 应用并发布至 Kubernetes](./wordpress-deployment.md) 8 | - [一键部署应用](./one-click-deploy.md) 9 | - [创建任务计算圆周率](./job-quick-start.md) 10 | - [设置弹性伸缩](./hpa.md) 11 | - [Source to Image:无需 Dockerfile 发布应用](./source-to-image.md) 12 | - [Binary to Image:无需 Dockerfile 发布应用](./b2i-war/b2i-war.md) 13 | - [基于 Spring Boot 项目构建流水线](./devops-online.md) 14 | - [图形化构建流水线](./jenkinsfile-out-of-scm.md) 15 | - [Bookinfo 微服务的灰度发布示例](./bookinfo-canary.md) 16 | - [使用 Ingress-Nginx 进行灰度发布](./ingress-canary/index.md) 17 | - [应用商店](./app-store.md) 18 | -------------------------------------------------------------------------------- /src/admin-quick-start.md: -------------------------------------------------------------------------------- 1 | # 多租户管理快速入门 2 | -------------------------------------------------------------------------------- /src/app-store.md: -------------------------------------------------------------------------------- 1 | # 应用商店 2 | -------------------------------------------------------------------------------- /src/b2i-war/b2i-war.md: -------------------------------------------------------------------------------- 1 | # Binary to Image 2 | 3 | ## 什么是 Binary-to-image 4 | 5 | **Binary-to-image (B2I)** 可以理解为一个集成了多个工具的工作流,旨在帮助开发者和运维人员在项目打包成 War、Jar、Binary 这一类制品后,快速将制品打包成 Docker 镜像,发布到 DockerHub 或 Harbor 等镜像仓库中。同时 B2I 也支持以**创建服务**的形式,一键将制品生成镜像推送到镜像仓库后,创建其部署 (Deployment) 和服务 (Service) 并自动发布到 Kubernetes 集群中。 6 | 7 | 在 B2I 工作流中,您不需要编写 Dockerfile。这不仅能降低学习成本,也能提升发布效率,使您更加专注于业务。 8 | 9 | 10 | 11 | ## 使用 Binary-to-Image (B2I) 12 | 13 | 接下来用两个示例介绍 B2I 的两种使用方式。 14 | 15 | - **使用 Binary-to-Image (B2I) 创建服务** 16 | - **使用 Image Builder 构建镜像** 17 | 18 | > **以下提供 5 个供测试使用的制品包,您也可以提交个人打包的测试项目到 KubeSphere** [社区](https://github.com/kubesphere/tutorial)**。** 19 | 20 | | 示例包 | 示例项目(代码仓库) | 21 | | :----------------------------------------------------------- | :----------------------------------------------------------- | 22 | | [b2i-war-java8.war](https://github.com/kubesphere/tutorial/raw/master/tutorial 4 - s2i-b2i/b2i-war-java8.war) | [Spring-MVC-Showcase](https://github.com/spring-projects/spring-mvc-showcase) | 23 | | [b2i-war-java11.war](https://github.com/kubesphere/tutorial/raw/master/tutorial 4 - s2i-b2i/b2i-war-java11.war) | [SpringMVC5](https://github.com/kubesphere/s2i-java-container/tree/master/tomcat/examples/springmvc5) | 24 | | [b2i-binary](https://github.com/kubesphere/tutorial/raw/master/tutorial 4 - s2i-b2i/b2i-binary) | [DevOps-go-sample](https://github.com/runzexia/devops-go-sample) | 25 | | [b2i-jar-java11.jar](https://github.com/kubesphere/tutorial/raw/master/tutorial 4 - s2i-b2i/b2i-jar-java11.jar) | [java-maven-example](https://github.com/kubesphere/s2i-java-container/tree/master/java/examples/maven) | 26 | | [b2i-jar-java8.jar](https://github.com/kubesphere/tutorial/raw/master/tutorial 4 - s2i-b2i/b2i-jar-java8.jar) | [devops-java-sample](https://github.com/kubesphere/devops-java-sample) | 27 | 28 | 29 | 30 | ### 准备工作 31 | 32 | - 您需要启用 [KubeSphere DevOps 系统](https://kubesphere.com.cn/docs/pluggable-components/devops/)。 33 | - 您需要创建一个 [Docker Hub](http://www.dockerhub.com/) 帐户,也支持 GitLab 和 Harbor。 34 | - 您需要创建一个企业空间、一个项目和一个用户 (`project-regular`),请务必邀请该用户至项目中并赋予 `operator` 角色。有关更多信息,请参见[创建企业空间、项目、用户和角色](https://kubesphere.com.cn/docs/quick-start/create-workspace-and-project/)。 35 | - (可选)设置一个 CI 专用节点用于构建镜像。该操作不是必需,但建议开发和生产环境进行设置,专用节点会缓存依赖项并缩短构建时间。有关更多信息,请参见[为缓存依赖项设置 CI 节点](https://kubesphere.com.cn/docs/devops-user-guide/how-to-use/set-ci-node/)。 36 | 37 | 38 | 39 | ### 使用 Binary-to-Image (B2I) 创建服务 40 | 41 | 42 | 43 | 下图中的步骤展示了如何在 B2I 工作流中通过创建服务来上传制品、构建镜像并将其发布至 Kubernetes。 44 | 45 | ![20191023141324](https://pek3b.qingstor.com/kubesphere-docs/png/20191023141324.png) 46 | 47 | > - ① 在 KubeSphere 创建 B2I 类型的服务,上传制品或二进制包 48 | > - ② B2I 将在后台创建 K8s Job、Deployment 和 Service 49 | > - ③ 将制品自动打包成 Docker 镜像 50 | > - ④ 推送镜像至 DockerHub 或 Harbor 51 | > - ⑤ B2I Job 将在第二步创建的 Deloyment 中使用仓库中的镜像 52 | > - ⑥ 自动发布至 Kubernetes 53 | > 54 | > **说明:在上述流程中,B2I Job 还会在后台执行状态上报的功能** 55 | 56 | 57 | 58 | #### 步骤1:创建Docker Hub保密字典 59 | 60 | 您必须创建 Docker Hub 保密字典,以便将通过 B2I 创建的 Docker 镜像推送至 Docker Hub。以 `project-regular` 身份登录 KubeSphere,转到您的项目并创建一个 Docker Hub 保密字典。有关更多信息,请参见[创建常用保密字典](https://kubesphere.com.cn/docs/project-user-guide/configuration/secrets/#创建常用保密字典)。 61 | 62 | #### 步骤2:创建服务 63 | 64 | 1. 在该项目中,转到**应用负载**下的**服务**,点击**创建**。 65 | 66 | ![image-20220520134249980](./image-20220520134249980.png) 67 | 68 | 2. 下拉至**通过制品构建服务**,选择 **WAR**。本教程使用 [SpringMVC5](https://github.com/kubesphere/s2i-java-container/tree/master/tomcat/examples/springmvc5) 项目作为示例并上传 WAR 制品至 KubeSphere。设置一个名称,例如 `b2i-war-java11`,点击**下一步** 69 | 70 | ![image-20220520134547852](./image-20220520134547852.png)![image-20220520135843962](./image-20220520135843962.png) 71 | 72 | 3. 在**构建设置**页面,请提供以下相应信息,并点击**下一步**。 73 | 74 | **服务类型**:本示例选择**无状态服务**。有关不同服务的更多信息,请参见[服务类型](https://kubesphere.com.cn/docs/project-user-guide/application-workloads/services/#服务类型)。 75 | 76 | **制品文件**:上传 WAR 制品 ([b2i-war-java11](https://github.com/kubesphere/tutorial/raw/master/tutorial%204%20-%20s2i-b2i/b2i-war-java11.war))。 77 | 78 | **构建环境**:选择 **kubesphere/tomcat85-java11-centos7:v3.2.0**。 79 | 80 | **镜像名称**:输入 `/` 或 `/` 作为镜像名称。 81 | 82 | **镜像标签**:镜像标签,请输入 `latest`。 83 | 84 | **目标镜像仓库**:镜像会推送至 Docker Hub,故请选择 Docker Hub 保密字典。 85 | 86 | ![image-20220520140441194](./image-20220520140441194.png) 87 | 88 | 4. 在**容器组设置**页面,下拉至**端口设置**,为容器设置访问策略。**协议**选择 **HTTP**,自定义名称(例如 `http-port`),**容器端口**和**服务端口**都输入 `8080`。点击**下一步**继续。 89 | 90 | ![image-20220520140721699](./image-20220520140721699.png) 91 | 92 | > **备注** 93 | > 94 | > 有关如何在**容器设置**页面设置其他参数的更多信息,请参见[容器组设置](https://kubesphere.com.cn/docs/project-user-guide/application-workloads/container-image-settings/)。 95 | 96 | 5. 在**存储卷设置**页面,您可以为容器添加存储卷。有关更多信息,请参见[存储卷](https://kubesphere.com.cn/docs/project-user-guide/storage/volumes/)。 97 | 98 | 6. 在**高级设置**页面,选中**外部访问**并选择 **NodePort** 作为访问方式。点击**创建**完成整个操作过程。 99 | 100 | ![image-20220520141003289](./image-20220520141003289.png) 101 | 102 | 7. 点击左侧导航栏的**镜像构建器**,您可以看到正在构建示例镜像。 103 | 104 | ![image-20220520141124834](./image-20220520141124834.png) 105 | 106 | #### 步骤3:查看结果 107 | 108 | 1. 稍等片刻,您可以看到镜像构建器状态变为**成功**。 109 | 110 | ![image-20220520141652350](./image-20220520141652350.png) 111 | 112 | 2. 点击该镜像前往其详情页面。在**任务记录**下,点击记录右侧的 ![img](https://kubesphere.com.cn/images/docs/zh-cn/project-user-guide/image-builder/binary-to-image/down-arrow.png) 查看构建日志。如果一切运行正常,您可以在日志末尾看到 `Build completed successfully`。 113 | 114 | 3. 回到**服务**、**部署**和**任务**页面,您可以看到该镜像相应的服务、部署和任务都已成功创建。 115 | 116 | ![image-20220520141732035](./image-20220520141732035.png)![image-20220520141757630](./image-20220520141757630.png)![image-20220520141827360](./image-20220520141827360.png) 117 | 118 | 4. 在您的 Docker Hub 仓库,您可以看到 KubeSphere 已经向仓库推送了带有预期标签的镜像。 119 | 120 | ![image-20220520142009915](./image-20220520142009915.png) 121 | 122 | #### 步骤4:访问服务 123 | 124 | 1. 在**服务**页面,请点击 B2I 服务前往其详情页面,您可以查看暴露的端口号。 125 | 126 | ![image-20220520142100724](./image-20220520142100724.png) 127 | 128 | 2. 通过 `http://://` 访问服务。 129 | 130 | ![image-20220520142351376](./image-20220520142351376.png) 131 | 132 | > **备注** 133 | > 134 | > 取决于您的部署环境,您可能需要在安全组中放行端口并配置端口转发规则。 135 | 136 | 137 | 138 | ### 使用 Image Builder 构建镜像 139 | 140 | 前述示例通过**创建服务**来实现整个 B2I 工作流。除此之外,您也可以直接使用**镜像构建器**基于制品构建镜像。 141 | 142 | 与第一种方式不同,本方式**不会将镜像发布至 Kubernetes**。 143 | 144 | ![build-binary](https://kubesphere.com.cn/images/docs/zh-cn/project-user-guide/image-builder/binary-to-image/build-binary.png) 145 | 146 | > **备注** 147 | > 148 | > 请确保您已经创建了 Docker Hub 保密字典。有关更多信息,请参见[创建常用保密字典](https://kubesphere.com.cn/docs/project-user-guide/configuration/secrets/#创建常用保密字典)。 149 | 150 | 151 | 152 | #### 步骤1:上传制品 153 | 154 | 1. 以 `project-regular` 身份登录 KubeSphere,转到您的项目。 155 | 156 | 2. 在左侧导航栏中选择**镜像构建器**,然后点击**创建**。 157 | 158 | ![image-20220520143850190](./image-20220520143850190.png) 159 | 160 | 3. 在弹出的对话框中,选择 **二进制** 并点击**下一步**。 161 | 162 | ![image-20220520143944470](./image-20220520143944470.png) 163 | 164 | 4. 在**构建设置**页面,请提供以下相应信息,然后点击**创建**。 165 | 166 | **上传制品**:下载 [b2i-binary](https://github.com/kubesphere/tutorial/raw/master/tutorial%204%20-%20s2i-b2i/b2i-binary)并上传至 KubeSphere。 167 | 168 | **构建环境**:选择 **kubesphere/s2i-binary:v3.2.0**。 169 | 170 | **镜像名称**:自定义镜像名称。 171 | 172 | **镜像标签**:镜像标签,请输入 `latest`。 173 | 174 | **目标镜像仓库**:镜像会推送至 Docker Hub,故请选择 Docker Hub 保密字典。 175 | 176 | ![image-20220520145158024](./image-20220520145158024.png) 177 | 178 | 179 | 180 | 5. 在**镜像构建器**页面,您可以看到正在构建镜像。 181 | 182 | ![image-20220520145238801](./image-20220520145238801.png) 183 | 184 | #### 步骤2:检查结果 185 | 186 | 1. 稍等片刻,您可以看到镜像构建器状态变为**成功**。 187 | 188 | ![image-20220520145741631](./image-20220520145741631.png) 189 | 190 | 2. 点击该镜像构建器前往其详情页面。在**任务记录**下,点击记录右侧的 ![img](https://kubesphere.com.cn/images/docs/zh-cn/project-user-guide/image-builder/binary-to-image/down-arrow.png) 查看构建日志。如果一切运行正常,您可以在日志末尾看到 `Build completed successfully`。 191 | 192 | 3. 前往**任务**页面,您可以看到该镜像相应的任务已成功创建。 193 | 194 | ![image-20220520145820197](./image-20220520145820197.png) 195 | 196 | 4. 在您的 Docker Hub 仓库,您可以看到 KubeSphere 已经向仓库推送了带有预期标签的镜像。 197 | 198 | ![image-20220520150006127](./image-20220520150006127.png) 199 | 200 | -------------------------------------------------------------------------------- /src/b2i-war/image-20220520133457810.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520133457810.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520134249980.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520134249980.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520134547852.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520134547852.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520134659172.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520134659172.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520134704871.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520134704871.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520135517989.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520135517989.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520135843962.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520135843962.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520140441194.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520140441194.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520140721699.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520140721699.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520141003289.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520141003289.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520141124834.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520141124834.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520141652350.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520141652350.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520141732035.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520141732035.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520141757630.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520141757630.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520141827360.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520141827360.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520142009915.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520142009915.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520142100724.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520142100724.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520142351376.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520142351376.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520143850190.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520143850190.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520143944470.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520143944470.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520145158024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520145158024.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520145238801.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520145238801.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520145741631.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520145741631.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520145820197.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520145820197.png -------------------------------------------------------------------------------- /src/b2i-war/image-20220520150006127.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/b2i-war/image-20220520150006127.png -------------------------------------------------------------------------------- /src/bookinfo-canary.md: -------------------------------------------------------------------------------- 1 | # Bookinfo 微服务的灰度发布示例 2 | -------------------------------------------------------------------------------- /src/devops-online.md: -------------------------------------------------------------------------------- 1 | # 基于 Spring Boot 项目构建流水线 2 | -------------------------------------------------------------------------------- /src/hpa.md: -------------------------------------------------------------------------------- 1 | # 设置弹性伸缩 2 | -------------------------------------------------------------------------------- /src/ingress-canary/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/1.png -------------------------------------------------------------------------------- /src/ingress-canary/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/10.png -------------------------------------------------------------------------------- /src/ingress-canary/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/11.png -------------------------------------------------------------------------------- /src/ingress-canary/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/12.png -------------------------------------------------------------------------------- /src/ingress-canary/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/13.png -------------------------------------------------------------------------------- /src/ingress-canary/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/14.png -------------------------------------------------------------------------------- /src/ingress-canary/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/15.png -------------------------------------------------------------------------------- /src/ingress-canary/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/16.png -------------------------------------------------------------------------------- /src/ingress-canary/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/17.png -------------------------------------------------------------------------------- /src/ingress-canary/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/18.png -------------------------------------------------------------------------------- /src/ingress-canary/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/19.png -------------------------------------------------------------------------------- /src/ingress-canary/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/2.png -------------------------------------------------------------------------------- /src/ingress-canary/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/20.png -------------------------------------------------------------------------------- /src/ingress-canary/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/21.png -------------------------------------------------------------------------------- /src/ingress-canary/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/22.png -------------------------------------------------------------------------------- /src/ingress-canary/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/23.png -------------------------------------------------------------------------------- /src/ingress-canary/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/24.png -------------------------------------------------------------------------------- /src/ingress-canary/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/25.png -------------------------------------------------------------------------------- /src/ingress-canary/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/26.png -------------------------------------------------------------------------------- /src/ingress-canary/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/27.png -------------------------------------------------------------------------------- /src/ingress-canary/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/28.png -------------------------------------------------------------------------------- /src/ingress-canary/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/29.png -------------------------------------------------------------------------------- /src/ingress-canary/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/3.png -------------------------------------------------------------------------------- /src/ingress-canary/30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/30.png -------------------------------------------------------------------------------- /src/ingress-canary/31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/31.png -------------------------------------------------------------------------------- /src/ingress-canary/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/32.png -------------------------------------------------------------------------------- /src/ingress-canary/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/4.png -------------------------------------------------------------------------------- /src/ingress-canary/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/5.png -------------------------------------------------------------------------------- /src/ingress-canary/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/6.png -------------------------------------------------------------------------------- /src/ingress-canary/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/7.png -------------------------------------------------------------------------------- /src/ingress-canary/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/8.png -------------------------------------------------------------------------------- /src/ingress-canary/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-canary/9.png -------------------------------------------------------------------------------- /src/ingress-canary/index.md: -------------------------------------------------------------------------------- 1 | # 使用 Ingress-Nginx 进行灰度发布 2 | 在 [Ingress-Nginx (0.21.0 版本)](https://github.com/kubernetes/ingress-nginx/releases/tag/nginx-0.21.0) 中,引入了一个新的 `Canary` 功能,可用于为网关入口配置多个后端服务,还可以使用指定的 `annotation` 来控制多个后端服务之间的流量分配。 `KubeSphere` 在 [3.2.1](https://kubesphere.io/zh/docs/) 的版本 中,升级了项目网关 (Ingress Controller) 版本至 `v0.48.1`,支持基于 [Ingress-Nginx](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary) 的灰度发布。 3 | 4 | ## Ingress-Nginx Annotation 简介 5 | KubeSphere 基于 [Nginx Ingress Controller](https://github.com/kubernetes/ingress-nginx/#nginx-ingress-controller) 实现了项目的网关,作为项目对外的流量入口和项目中各个服务的反向代理。而 Ingress-Nginx 支持配置 Ingress Annotations 来实现不同场景下的灰度发布和测试,可以满足`金丝雀发布`、`蓝绿部署`与 `A/B 测试`等业务场景。 6 | 7 | > **Nginx Annotations 支持以下 5 种 Canary 规则:** 8 | > 9 | > - `nginx.ingress.kubernetes.io/canary-by-header`:基于 Request Header 的流量切分,适用于`灰度发布以及 A/B 测试`。当 Request Header 设置为 `always` 时,请求将会被`一直`发送到 Canary 版本;当 Request Header 设置为 `never` 时,请求`不会`被发送到 Canary 入口;对于任何其他 `Header` 值,将忽略 `Header`,并通过优先级将请求与其他金丝雀规则进行优先级的比较。 10 | > - `nginx.ingress.kubernetes.io/canary-by-header-value`:要匹配的 Request Header 的值,用于通知 `Ingress` 将请求路由到 `Canary Ingress `中指定的服务。当 `Request Header` 设置为此值时,它将被路由到 Canary 入口。该规则允许用户自定义 Request Header 的值,必须与上一个 annotation (即:`canary-by-header`) 一起使用。 11 | > - `nginx.ingress.kubernetes.io/canary-by-header-pattern`:要匹配的 Request Header 值的 PCRE 正则表达式,作用同上面的 `canary-by-header-value` 一样,当 `Request Header` 设置的值满足该正则表达式时,它将被路由到 Canary 入口,必须与 `canary-by-header` 一起使用。 12 | > - `nginx.ingress.kubernetes.io/canary-weight`:基于服务权重的流量切分,适用于蓝绿部署,权重范围 `0` - `100`按百分比将请求路由到 `Canary Ingress` 中指定的服务。权重为 `0` 意味着该金丝雀规则不会向 Canary 入口的服务发送任何请求,权重为 `100` 意味着所有请求都将被发送到 Canary 入口。 13 | > - `nginx.ingress.kubernetes.io/canary-by-cookie`:基于 `cookie` 的流量切分,适用于`灰度发布与 A/B 测试`。用于通知 Ingress 将请求路由到` Canary Ingress `中指定的服务的 `cookie`。当 `cookie` 值设置为 `always` 时,它将被路由到 Canary 入口;当 cookie 值设置为 `never` 时,请求不会被发送到 Canary 入口;对于任何其他值,将忽略 cookie 并将请求与其他金丝雀规则进行优先级的比较。 14 | > 15 | > **注意:金丝雀规则按优先顺序进行如下排序:** 16 | > 17 | > `canary-by-header` - > `canary-by-cookie` - > `canary-weight` 18 | 19 | 把以上的五个 `annotation` 规则可以总体划分为以下两类: 20 | - 基于权重的 Canary 规则 21 | ![基于权重](28.png) 22 | - 基于用户请求的 Canary 规则 23 | ![基于用户请求](29.png) 24 | 25 | ## 前提条件 26 | - 准备`KubeSphere v3.2.1 `集群,如果没有可以参考[快速入门](https://kubesphere.io/zh/docs/quick-start/)快速搭建一个测试集群。 27 | - 开启项目网关或者集群网关,具体参考文档[项目网关](https://kubesphere.io/zh/docs/project-administration/project-gateway/)。 28 | - 使用 `project-admin` 登录创建测试项目 `test` 并进入该项目工作空间,具体可以参考入门必读 [1. 多租户管理快速入门]()。 29 | 30 | ## 测试镜像说明 31 | 本章节内容以 `hub.deri.org.cn/library/test-ingress-nginx-canary` 镜像为后端服务,`v1` 版本为生产版本,`v2` 版本为灰度测试版本。两个镜像查询版本的 `/version` 接口返回内容是不一样的。 32 | ```bash 33 | # v1版本接口返回内容 34 | this is version 1. 35 | # v2版本接口返回内容 36 | this is version 2. 37 | ``` 38 | 39 | ## 第一步:网关设置 40 | 进入到 `test` 项目空间,打开`网关设置`: 41 | ![网关设置](1.png) 42 | > 网关这里采用 `NodePort` 方式暴露测试,注意 `HTTP` 端口号:`31897` ,后面的服务请求都是通过这个端口。 43 | > 44 | > 注意: `NodePort` 端口号 `31897` 可能会随着环境的不同而改变。 45 | 46 | ## 第二步:创建 Production 版本的应用 47 | - 选择`服务`,点击`创建` 48 | ![服务](2.png) 49 | - 选择`无状态服务` 50 | ![无状态](3.png) 51 | - 输入`名称` 52 | ![名称](4.png) 53 | - 下一步,`添加容器` 54 | ![添加容器](5.png) 55 | - 输入测试镜像名称 `hub.deri.org.cn/library/test-ingress-nginx-canary:v1` ,回车,选择`使用默认端口`,点击右下角 `√` 56 | ![添加容器](6.png) 57 | - `容器组设置`其余配置选择默认,点击`下一步` 58 | - `存储卷设置`选择默认,点击`下一步` 59 | - `高级设置`选择默认,点击`创建` 60 | - 创建完成,可以看到 `service` 的 `ClusterIP` 是 `10.233.53.192` 61 | > 备注:`ClusterIP` 以您的实际环境为准 62 | 63 | ![创建完成](7.png) 64 | - 点击刚刚创建的服务名 `app-production` 查看服务详情,确认服务运行正常 65 | ![运行状态](8.png) 66 | - 选择服务 `app-production` ,`编辑外部访问` 67 | 68 | ![外部访问](30.png) 69 | - 选择 `NodePort` 访问方式,点击`确认` 70 | ![外部访问](31.png) 71 | - 查看给服务 `app-production` 分配的 `NodePort` 端口是 `30391` 72 | ![外部访问](32.png) 73 | > 注意:`NodePort` 端口号 `30391` 可能会随着环境的不同而改变。 74 | - 通过集群节点的 `IP` 和 `NodePort` 端口访问服务测试 75 | ```bash 76 | # 172.16.0.23 是集群的一个节点的 IP 地址,这里需要换成你的集群节点 IP 77 | [root@master1 ~]# curl 172.16.0.23:30391/version 78 | this is version 1. 79 | ``` 80 | 81 | ## 第三步:创建 Canary 版本 82 | - 参考[第二步:创建 Production 版本的应用](/ingress-canary/index.html#第二步创建-production-版本的应用)步骤创建 `Canary` 版本应用,注意镜像选择 `hub.deri.org.cn/library/test-ingress-nginx-canary:v2` 83 | - 创建完成,可以看到两个服务: `app-production` 和 `app-canary` 84 | ![创建完成](9.png) 85 | 86 | ## 第四步:创建 Production 应用路由 87 | - 选择`应用路由`,点击`创建` 88 | ![应用路由](10.png) 89 | - 输入`名称`: `ingress-production` ,点击`下一步` 90 | ![应用路由](11.png) 91 | - 点击`添加路由规则` 92 | ![添加路由规则](12.png) 93 | - 配置`路由规则`,选择指定域名,输入测试域名 `kubesphere.io` ,协议使用 `HTTP` ,路径中服务选择 `app-production` ,端口选择服务端口 `8080` 94 | ![配置路由规则](13.png) 95 | > 生产环境协议建议使用 `HTTPS` ,服务和端口配置实际业务的`名称`和`端口号`。 96 | - 点击右下角`√`确定配置,点击`下一步` 97 | ![配置路由规则](14.png) 98 | - 应用路由高级配置使用默认配置,点击`创建` 99 | - 创建完成后刷新页面,就能看到刚刚创建的`应用路由`及分配的`网关地址` 100 | ![路由](15.png) 101 | - 点击应用路由名称进入查看详情 102 | ![路由](16.png) 103 | - 测试 Production 版本应用路由 104 | ```bash 105 | # 注意,加上 --resolve 参数则无需在本地配置 /etc/hosts 中的 IP 与域名映射,否则需要预先在本地配置域名映射,其中 172.16.0.23 是项目内的网关地址。 106 | [root@master1 ~]# curl --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version 107 | this is version 1. 108 | ``` 109 | 110 | ## 第五步:创建 Canary 应用路由 111 | > 注意:要开启 `Ingress-Nginx` 灰度发布机制,首先需设置 `nginx.ingress.kubernetes.io/canary: "true"` 启用 `Canary`,具体通过相关 `Annotation` 规则配置。 112 | 113 | 配置 `Canary` 应用路由过程参考[第四步:创建Production应用路由](/ingress-canary/index.html#第四步创建-production-应用路由),注意以下几点: 114 | - 配置`路由规则`,选择指定域名,输入测试域名 `kubesphere.io` ,协议使用 `HTTP` ,路径中服务选择 `app-canary` ,端口选择服务端口 `8080` 115 | ![路由](17.png) 116 | - 应用路由`高级配置`,选择`添加元数据` 117 | ![添加元数据](18.png) 118 | - 在`注解`右下角点击`添加`,左边输入 `nginx.ingress.kubernetes.io/canary` ,右边输入 `true` ,开启 `Canary` 119 | ![添加元数据](19.png) 120 | > 其余 `Annotation` 规则根据你采用的灰度发布规则来使用。 121 | - 点击创建,此时可以看到 2 个应用路由 122 | ![添加元数据](21.png) 123 | 124 | ### 基于权重 (Weight) 125 | 基于权重的流量切分的典型应用场景就是`蓝绿部署`,可通过将权重设置为 `0` 或 `100` 来实现。例如,可将 `Green` 版本设置为主要部分,并将 `Blue` 版本的入口配置为 `Canary` 。最初,将权重设置为 `0` ,因此不会将流量代理到 `Blue` 版本。一旦新版本测试和验证都成功后,即可将 `Blue` 版本的权重设置为 `100` ,即所有流量从 `Green` 版本转向 `Blue`。 126 | - 在`第五步:创建Canary应用路由`,高级配置中添加注解 127 | - 在`注解`右下角点击`添加`,左边输入 `nginx.ingress.kubernetes.io/canary-weight` ,右边输入 `0` ~ `100` 的权重,开启基于权重的灰度发布 128 | ![基于权重](20.png) 129 | > 注意:默认总权重为 `100`,可以通过注解 `nginx.ingress.kubernetes.io/canary-weight-total` 修改成其他值。 130 | 如上图,将 `Canary` 版本权重设置为 `0` ,及所有的请求都不流入 `Canary` 版本。我们使用命令测试 131 | ```bash 132 | # 返回结果全是 this is version 1. 证明流量全部到了 production 版本 133 | [root@master1 ~]# for i in $(seq 1 10); do curl -s --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version; done 134 | this is version 1. 135 | this is version 1. 136 | this is version 1. 137 | this is version 1. 138 | this is version 1. 139 | this is version 1. 140 | this is version 1. 141 | this is version 1. 142 | this is version 1. 143 | this is version 1. 144 | ``` 145 | - 选择应用路由 `ingress-canary` ,选择`编辑注解`,修改 `Canary` 权重为 `30` ,意思是将分配 `30%` 的流量请求发送至 `Canary` 版本。 146 | ![基于权重](22.png) 147 | ![基于权重](23.png) 148 | - 继续使用命令测试 149 | > 应用的 `Canary` 版本基于权重 (30%) 进行流量切分后,访问到 `Canary` 版本的概率接近 30%,流量比例可能会有小范围的浮动。 150 | ```bash 151 | # 部分结果返回了 this is version 2. 证明部分流量到了 canary 版本 152 | [root@master1 ~]# for i in $(seq 1 10); do curl -s --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version; done 153 | this is version 1. 154 | this is version 1. 155 | this is version 2. 156 | this is version 1. 157 | this is version 1. 158 | this is version 2. 159 | this is version 1. 160 | this is version 1. 161 | this is version 2. 162 | this is version 1. 163 | ``` 164 | - 将 `Canary` 权重修改为 `100` ,意思是所有流量请求发送至 `Canary` 版本 165 | ```bash 166 | [root@master1 ~]# for i in $(seq 1 10); do curl -s --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version; done 167 | this is version 2. 168 | this is version 2. 169 | this is version 2. 170 | this is version 2. 171 | this is version 2. 172 | this is version 2. 173 | this is version 2. 174 | this is version 2. 175 | this is version 2. 176 | this is version 2. 177 | ``` 178 | 179 | ### 基于Request Header 180 | 基于 `Request Header` 进行流量切分的典型应用场景即`灰度发布或 A/B 测试场景`。参考以下截图,在 `KubeSphere` 给 `Canary` 版本的应用路由 (`Ingress`) 新增一条 `annotation nginx.ingress.kubernetes.io/canary-by-header: canary` (这里的 `annotation` 的 `value` 可以是任意值),使当前的 `Ingress` 实现基于 `Request Header` 进行流量切分。 181 | > 说明:金丝雀规则按优先顺序 `canary-by-header` - > `canary-by-cookie` - > `canary-weight`进行如下排序,因此以下情况将忽略原有 `canary-weight` 的规则。 182 | 183 | ![基于Header](24.png) 184 | 185 | > 说明: 186 | > 187 | > 举两个例子,如开篇提到的当 `Request Header` 设置为 `never` 或 `always` 时,请求将`不会`或`一直`被发送到 `Canary` 版本; 188 | > 189 | > 对于任何其他 `Header` 值,将忽略 `Header` ,并通过优先级将请求与其他 `Canary` 规则进行优先级的比较(如下第二次请求已将基于 `30%` 权重作为第一优先级)。 190 | 191 | 使用命令测试: 192 | ```bash 193 | [root@master1 ~]# for i in $(seq 1 10); do curl -s -H "canary: never" --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version; done 194 | this is version 1. 195 | this is version 1. 196 | this is version 1. 197 | this is version 1. 198 | this is version 1. 199 | this is version 1. 200 | this is version 1. 201 | this is version 1. 202 | this is version 1. 203 | this is version 1. 204 | [root@master1 ~]# for i in $(seq 1 10); do curl -s -H "canary: always" --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version; done 205 | this is version 2. 206 | this is version 2. 207 | this is version 2. 208 | this is version 2. 209 | this is version 2. 210 | this is version 2. 211 | this is version 2. 212 | this is version 2. 213 | this is version 2. 214 | this is version 2. 215 | [root@master1 ~]# for i in $(seq 1 10); do curl -s -H "canary: other-value" --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version; done 216 | this is version 1. 217 | this is version 2. 218 | this is version 1. 219 | this is version 1. 220 | this is version 1. 221 | this is version 2. 222 | this is version 2. 223 | this is version 1. 224 | this is version 1. 225 | this is version 1. 226 | ``` 227 | 此时可以在上一个 `annotation` (即 `canary-by-header` )的基础上添加一条 `nginx.ingress.kubernetes.io/canary-by-header-value: user-value` 。用于通知 `Ingress` 将请求路由到 `Canary Ingress` 中指定的服务。 228 | ![基于Header](25.png) 229 | 如下访问应用的域名,当 `Request Header` 满足此值时,所有请求被路由到 `Canary` 版本(该规则允许用户自定义 `Request Header` 的值),不满足此值时继续按照 `30%` 权重随机分配。 230 | ```bash 231 | [root@master1 ~]# for i in $(seq 1 10); do curl -s -H "canary: user-value" --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version; done 232 | this is version 2. 233 | this is version 2. 234 | this is version 2. 235 | this is version 2. 236 | this is version 2. 237 | this is version 2. 238 | this is version 2. 239 | this is version 2. 240 | this is version 2. 241 | this is version 2. 242 | [root@master1 ~]# for i in $(seq 1 10); do curl -s -H "canary: other-value" --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version; done 243 | this is version 1. 244 | this is version 1. 245 | this is version 1. 246 | this is version 1. 247 | this is version 2. 248 | this is version 2. 249 | this is version 2. 250 | this is version 2. 251 | this is version 1. 252 | this is version 2. 253 | ``` 254 | 255 | `canary-by-header-value` 的值是支持 `PCRE` 正则表达式的,具体可以通过注解 `nginx.ingress.kubernetes.io/canary-by-header-pattern` 来设置。 256 | > 注意:如果 `canary-by-header-value` 已经设置了, `canary-by-header-pattern` 这个注解就会被忽略;如果正则表达式在处理的过程中出现错误也会认为不匹配。 257 | 258 | ![基于Header](27.png) 259 | 如上图配置,Header canary 的值如果满足 `user-value-*` 正则表达式则将流量转入 `Canary` 版本,负责按照 `30%` 权重随机分配。 260 | ```bash 261 | [root@master1 ~]# for i in $(seq 1 10); do curl -s -H "canary: user-value-2" --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version; done 262 | this is version 2. 263 | this is version 2. 264 | this is version 2. 265 | this is version 2. 266 | this is version 2. 267 | this is version 2. 268 | this is version 2. 269 | this is version 2. 270 | this is version 2. 271 | this is version 2. 272 | [root@master1 ~]# for i in $(seq 1 10); do curl -s -H "canary: user-value-3" --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version; done 273 | this is version 2. 274 | this is version 2. 275 | this is version 2. 276 | this is version 2. 277 | this is version 2. 278 | this is version 2. 279 | this is version 2. 280 | this is version 2. 281 | this is version 2. 282 | this is version 2. 283 | [root@master1 ~]# for i in $(seq 1 10); do curl -s -H "canary: test-value" --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version; done 284 | this is version 2. 285 | this is version 1. 286 | this is version 1. 287 | this is version 1. 288 | this is version 1. 289 | this is version 1. 290 | this is version 2. 291 | this is version 1. 292 | this is version 1. 293 | this is version 1. 294 | [root@master1 ~]# for i in $(seq 1 10); do curl -s -H "canary: ce-value" --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version; done 295 | this is version 1. 296 | this is version 1. 297 | this is version 1. 298 | this is version 2. 299 | this is version 1. 300 | this is version 2. 301 | this is version 1. 302 | this is version 1. 303 | this is version 1. 304 | this is version 1. 305 | ``` 306 | 307 | ### 基于 Cookie 308 | 与基于 `Request Header` 的 `annotation` 用法规则类似。例如在 `A/B 测试场景`下,需要让地域为北京的用户访问 `Canary` 版本。那么当 `cookie` 的 `annotation` 设置为 `nginx.ingress.kubernetes.io/canary-by-cookie: "users_from_Beijing"` ,此时后台可对登录的用户请求进行检查,如果该用户访问源来自北京则设置 cookie `users_from_Beijing` 的值为 `always` ,这样就可以确保北京的用户仅访问 `Canary` 版本。 309 | ```bash 310 | [root@master1 ~]# for i in $(seq 1 10); do curl -s --cookie "users_from_Beijing=always" --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version; done 311 | this is version 2. 312 | this is version 2. 313 | this is version 2. 314 | this is version 2. 315 | this is version 2. 316 | this is version 2. 317 | this is version 2. 318 | this is version 2. 319 | this is version 2. 320 | this is version 2. 321 | [root@master1 ~]# for i in $(seq 1 10); do curl -s --cookie "users_from_Beijing=never" --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version; done 322 | this is version 1. 323 | this is version 1. 324 | this is version 1. 325 | this is version 1. 326 | this is version 1. 327 | this is version 1. 328 | this is version 1. 329 | this is version 1. 330 | this is version 1. 331 | this is version 1. 332 | [root@master1 ~]# for i in $(seq 1 10); do curl -s --cookie "users_from_Beijing=unknow" --resolve kubesphere.io:31897:172.16.0.23 kubesphere.io:31897/version; done 333 | this is version 1. 334 | this is version 2. 335 | this is version 2. 336 | this is version 1. 337 | this is version 1. 338 | this is version 1. 339 | this is version 1. 340 | this is version 1. 341 | this is version 1. 342 | this is version 1. 343 | ``` 344 | 345 | ## 总结 346 | 灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以对新版本进行测试、发现和调整问题,以保证其影响度。本文通过多个示例演示和说明了基于 `KubeSphere` 使用应用路由 ( `Ingress` ) 和项目网关 ( `Ingress Controller` ) 实现灰度发布,并详细介绍了 `Ingress-Nginx` 的五种 `Annotation` ,还未使用 `Istio` 的用户也能借助 `Ingress-Nginx` 轻松实现灰度发布与金丝雀发布。 347 | 348 | ## 参考 349 | - [NGINX Ingress Controller - Annotations](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary) -------------------------------------------------------------------------------- /src/ingress-demo/cgw-created.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/cgw-created.png -------------------------------------------------------------------------------- /src/ingress-demo/cgw-metrics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/cgw-metrics.png -------------------------------------------------------------------------------- /src/ingress-demo/cgw-nodeport.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/cgw-nodeport.png -------------------------------------------------------------------------------- /src/ingress-demo/index.md: -------------------------------------------------------------------------------- 1 | # 应用路由与服务示例 2 | 3 | 本文档介绍了如何在 KubeSphere 上开启集群网关,以及如何创建、使用和编辑应用路由。 4 | 5 | KubeSphere 上的应用路由和 Kubernetes 上的 [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/#what-is-ingress) 相同,您可以使用应用路由和单个 IP 地址来聚合和暴露多个服务。 6 | 7 | 本文将构建一个比较完整的应用路由案例,它的大致架构如下图所示: 8 | 9 | ![Case Study Overview](ingress-demo.png) 10 | 11 | > 注意:上图中的多个 `httpbin` 服务可以是同一个服务,也可以是完全不同的服务。 12 | 13 | ## 准备工作 14 | 15 | ### 准备企业空间、项目及用户 16 | 17 | 您需要创建一个企业空间(例如 `playground`)、一个项目(例如 `demo`)以及两个用户(例如,`admin` 和 `operator`)。 18 | 19 | 在本教程中,`admin` 用户必须具有 `platform-admin` 角色;`operator` 用户必须至少具有 `platform-regular` 角色,并已被添加到 `playground` 企业空间的 `demo` 项目中(项目角色至少为 `operator`)。 20 | 21 | 关于企业空间、项目及用户的更多信息,请参见 [多租户管理快速入门](../admin-quick-start.md)。 22 | 23 | ### 部署 httpbin 示例服务 24 | 25 | 由于需要演示网关的访问控制能力,我们必须要先有一个可以访问的应用作为网关的后台服务。这里我们使用 [httpbin.org](http://httpbin.org/) 提供的 [kennethreitz/httpbin](https://hub.docker.com/r/kennethreitz/httpbin/) 容器应用作为演示应用。 26 | 27 | 在 KubeSphere 中,我们可以先创建新的项目或使用已有的项目,进入项目页面后,选择「应用负载」下的「服务」直接创建「无状态服务」并生成配套的服务。 28 | 29 | ![Create Stateless Service](svc-create.png) 30 | 31 | 使用 `kennethreitz/httpbin` 容器默认的 `80` 端口作为服务端口,创建 2 个容器组副本,完成后确保在「工作负载」和「服务」页面下都可以看到 `httpbin` 的对应条目,大致过程及最终结果如下图所示(图中未展示的部分默认「下一步」即可)。 32 | 33 | ![Create Service - Metadata](svc-create-meta.png) 34 | 35 | ![Create Service - Container](svc-create-container.png) 36 | 37 | ![Create Service - Pod](svc-create-pod.png) 38 | 39 | ![Service Created](svc-created.png) 40 | 41 | ### 启用集群网关 42 | 43 | > KubeSphere 从 3.1 版本开始支持项目级别的网关,进而在 3.2.0 版本中开始支持集群级别的全局网关,所有项目可共用同一个网关,之前已创建的项目网关也不会受到集群网关的影响。 44 | > 45 | > 如果您在开始实验本文的案例前已经部署了 Ingress Controller,那么不管集群网关还是项目网关都不是必须的。为了更完整的讲解应用路由的使用,此处仍会概述如何启用 KubeSphere 集群网关。 46 | 47 | [项目网关](https://kubesphere.com.cn/docs/project-administration/project-gateway/) 是 KubeSphere 3.0 以来就有的功能:“KubeSphere 项目中的网关是一个 [NGINX Ingress 控制器](https://www.nginx.com/products/nginx-ingress-controller/)。KubeSphere 内置的用于 HTTP 负载均衡的机制称为 [应用路由](https://kubesphere.com.cn/docs/project-user-guide/application-workloads/routes/),它定义了从外部到集群服务的连接规则。如需允许从外部访问服务,用户可创建路由资源来定义 URI 路径、后端服务名称等信息。” 48 | 49 | 进入 KubeSphere 3.2.0 版本之后,我们更推荐大家使用集群网关的功能来统一整个集群的应用路由。要启用集群网关其实也非常简单:使用具备集群管理权限的账号(如本文中的 `admin`),进入其可管理的某个集群(我们这里以 `default` 集群为例),在「集群设置」的「网关设置」中即可「开启网关」。 50 | 51 | 方便起见,本例中直接选择 `NodePort` 作为「访问方式」,完成开启后回到设置页面,稍等片刻后刷新页面,可以得到如下图这样的部署完成状态,可以看到 NodePort 默认被赋予了两个节点端口,并且通过右上角的「管理」按钮我们可以「查看详情」。 52 | 53 | ![Cluster Gateway Created](cgw-created.png) 54 | 55 | 在系统中建立各类应用路由并使用一段时间后,即可通过「查看详情」看到如下图所示的监控数据面板: 56 | 57 | ![Cluster Gateway Metrics](cgw-metrics.png) 58 | 59 | #### 为网关指定 NodePort 节点端口 60 | 61 | 对于公有云环境,如果使用 NodePort 方式向外暴露访问能力,开放的端口通常会是有限的、受控的、甚至是固定的,因此对于网关所使用的 NodePort 我们需要能够对它进行修改。 62 | 63 | 由于网关是被 KubeSphere 统一管理的,要修改网关服务的 NodePort,需要具备访问 `kubesphere-controls-system` 项目的权限。进入该项目后,通过「应用负载」的「服务」页面即可找到命名为 `kubesphere-router-kubesphere-system` 且外部访问已开放 NodePort 的网关服务。NodePort 服务端口需要通过「编辑 YAML」来直接修改。 64 | 65 | ![Cluster Gateway NodePort Customization](cgw-nodeport.png) 66 | 67 | ## 应用路由的创建及使用 68 | 69 | > 下文将以 `demo` 项目中的 `httpbin` 服务为例,讲解如何配置及使用 KubeSphere 应用路由。 70 | 71 | ### 创建及使用 HTTP 路由 72 | 73 | 从「应用负载」进入「应用路由」页面,开始「创建」路由。为路由取名为 `httpbin` 后,我们指定一个方便测试的域名(例如 `httpbin.io`),并设置「路径」为 `/`, 选择「服务」`httpbin` 和「端口」`80`,点击下一步跳过「高级设置」后即完成路由创建。 74 | 75 | ![Route Create](route-create.png) 76 | 77 | ![Route Create - Rules](route-create-rule.png) 78 | 79 | > 通过集群、项目(或自建的)网关从私有网络外部访问应用路由时,您需要特别注意您的网络环境: 80 | > 81 | > - 您可能需要在基础设施环境中配置流量转发和防火墙规则,以便访问应用路由的网关地址和端口号。 82 | > - 若在配置路由规则中选择「自动生成」,则可能需要手动编辑路由规则将路由域名中的网关地址改为您私有网络的外部 IP 地址。 83 | > - 若在配置路由规则中选择「指定域名」,则可能需要改变 DNS 服务器上或者客户端机器上的域名配置(如 Linux / macOS 系统中的 `etc/hosts` 文件),以便将域名解析为您私有网络的外部 IP 地址。 84 | 85 | 回到「应用路由」页面,点击刚刚创建的 `httpbin` 路由,即可进入详情页面。 86 | 87 | ![Route Created - HTTP](route-created.png) 88 | 89 | 您可以在「资源状态」标签页上通过右侧的「访问服务」按钮访问 httpbin 页面,在域名解析配置正确的情况下,可以得到下图的页面结果。 90 | 91 | ![Route - httpbin.io](route-httpbin.png) 92 | 93 | ### 创建及使用 HTTPS 路由 94 | 95 | 由于要在应用路由中绑定的域名为 HTTPS 协议,因此需要预先创建一个携带 TLS 证书的 Kubernetes Secret。 96 | 97 | 首先,我们回到项目首页,在「配置」下的「保密字典」中创建一个名为 `httpbin-tls` 的保密字典(即 Kubernetes Secret)。如下图所示,选择字典「类型」为 `TLS 信息`。 98 | 99 | ![Secret Create - Data](secret-create-data.png) 100 | 101 | 在「凭证」和「私钥」文本框中填入您的凭证和私钥数据。 102 | 103 | > 注意,您可以使用任意您熟悉的工具来创建 TLS 证书密钥,本例也会提供一份实验用凭证和私钥,请勿在生产环境中使用! 104 | > 105 | > ```plain 106 | > -----BEGIN CERTIFICATE----- 107 | > MIIDLjCCAhYCCQDAOF9tLsaXWjANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJV 108 | > UzELMAkGA1UECAwCQ0ExITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 109 | > ZDEbMBkGA1UEAwwSY2FmZS5leGFtcGxlLmNvbSAgMB4XDTE4MDkxMjE2MTUzNVoX 110 | > DTIzMDkxMTE2MTUzNVowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMSEwHwYD 111 | > VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxGTAXBgNVBAMMEGNhZmUuZXhh 112 | > bXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCp6Kn7sy81 113 | > p0juJ/cyk+vCAmlsfjtFM2muZNK0KtecqG2fjWQb55xQ1YFA2XOSwHAYvSdwI2jZ 114 | > ruW8qXXCL2rb4CZCFxwpVECrcxdjm3teViRXVsYImmJHPPSyQgpiobs9x7DlLc6I 115 | > BA0ZjUOyl0PqG9SJexMV73WIIa5rDVSF2r4kSkbAj4Dcj7LXeFlVXH2I5XwXCptC 116 | > n67JCg42f+k8wgzcRVp8XZkZWZVjwq9RUKDXmFB2YyN1XEWdZ0ewRuKYUJlsm692 117 | > skOrKQj0vkoPn41EE/+TaVEpqLTRoUY3rzg7DkdzfdBizFO2dsPNFx2CW0jXkNLv 118 | > Ko25CZrOhXAHAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAKHFCcyOjZvoHswUBMdL 119 | > RdHIb383pWFynZq/LuUovsVA58B0Cg7BEfy5vWVVrq5RIkv4lZ81N29x21d1JH6r 120 | > jSnQx+DXCO/TJEV5lSCUpIGzEUYaUPgRyjsM/NUdCJ8uHVhZJ+S6FA+CnOD9rn2i 121 | > ZBePCI5rHwEXwnnl8ywij3vvQ5zHIuyBglWr/Qyui9fjPpwWUvUm4nv5SMG9zCV7 122 | > PpuwvuatqjO1208BjfE/cZHIg8Hw9mvW9x9C+IQMIMDE7b/g6OcK7LGTLwlFxvA8 123 | > 7WjEequnayIphMhKRXVf1N349eN98Ez38fOTHTPbdJjFA/PcC+Gyme+iGt5OQdFh 124 | > yRE= 125 | > -----END CERTIFICATE----- 126 | > ``` 127 | > 128 | > ```plain 129 | > -----BEGIN RSA PRIVATE KEY----- 130 | > MIIEowIBAAKCAQEAqeip+7MvNadI7if3MpPrwgJpbH47RTNprmTStCrXnKhtn41k 131 | > G+ecUNWBQNlzksBwGL0ncCNo2a7lvKl1wi9q2+AmQhccKVRAq3MXY5t7XlYkV1bG 132 | > CJpiRzz0skIKYqG7Pcew5S3OiAQNGY1DspdD6hvUiXsTFe91iCGuaw1Uhdq+JEpG 133 | > wI+A3I+y13hZVVx9iOV8FwqbQp+uyQoONn/pPMIM3EVafF2ZGVmVY8KvUVCg15hQ 134 | > dmMjdVxFnWdHsEbimFCZbJuvdrJDqykI9L5KD5+NRBP/k2lRKai00aFGN684Ow5H 135 | > c33QYsxTtnbDzRcdgltI15DS7yqNuQmazoVwBwIDAQABAoIBAQCPSdSYnQtSPyql 136 | > FfVFpTOsoOYRhf8sI+ibFxIOuRauWehhJxdm5RORpAzmCLyL5VhjtJme223gLrw2 137 | > N99EjUKb/VOmZuDsBc6oCF6QNR58dz8cnORTewcotsJR1pn1hhlnR5HqJJBJask1 138 | > ZEnUQfcXZrL94lo9JH3E+Uqjo1FFs8xxE8woPBqjZsV7pRUZgC3LhxnwLSExyFo4 139 | > cxb9SOG5OmAJozStFoQ2GJOes8rJ5qfdvytgg9xbLaQL/x0kpQ62BoFMBDdqOePW 140 | > KfP5zZ6/07/vpj48yA1Q32PzobubsBLd3Kcn32jfm1E7prtWl+JeOFiOznBQFJbN 141 | > 4qPVRz5hAoGBANtWyxhNCSLu4P+XgKyckljJ6F5668fNj5CzgFRqJ09zn0TlsNro 142 | > FTLZcxDqnR3HPYM42JERh2J/qDFZynRQo3cg3oeivUdBVGY8+FI1W0qdub/L9+yu 143 | > edOZTQ5XmGGp6r6jexymcJim/OsB3ZnYOpOrlD7SPmBvzNLk4MF6gxbXAoGBAMZO 144 | > 0p6HbBmcP0tjFXfcKE77ImLm0sAG4uHoUx0ePj/2qrnTnOBBNE4MvgDuTJzy+caU 145 | > k8RqmdHCbHzTe6fzYq/9it8sZ77KVN1qkbIcuc+RTxA9nNh1TjsRne74Z0j1FCLk 146 | > hHcqH0ri7PYSKHTE8FvFCxZYdbuB84CmZihvxbpRAoGAIbjqaMYPTYuklCda5S79 147 | > YSFJ1JzZe1Kja//tDw1zFcgVCKa31jAwciz0f/lSRq3HS1GGGmezhPVTiqLfeZqc 148 | > R0iKbhgbOcVVkJJ3K0yAyKwPTumxKHZ6zImZS0c0am+RY9YGq5T7YrzpzcfvpiOU 149 | > ffe3RyFT7cfCmfoOhDCtzukCgYB30oLC1RLFOrqn43vCS51zc5zoY44uBzspwwYN 150 | > TwvP/ExWMf3VJrDjBCH+T/6sysePbJEImlzM+IwytFpANfiIXEt/48Xf60Nx8gWM 151 | > uHyxZZx/NKtDw0V8vX1POnq2A5eiKa+8jRARYKJLYNdfDuwolxvG6bZhkPi/4EtT 152 | > 3Y18sQKBgHtKbk+7lNJVeswXE5cUG6EDUsDe/2Ua7fXp7FcjqBEoap1LSw+6TXp0 153 | > ZgrmKE8ARzM47+EJHUviiq/nupE15g0kJW3syhpU9zZLO7ltB0KIkO9ZRcmUjo8Q 154 | > cpLlHMAqbLJ8WYGJCkhiWxyal6hYTyWY4cVkC0xtTl/hUE9IeNKo 155 | > -----END RSA PRIVATE KEY----- 156 | > ``` 157 | 158 | 创建完成后,可以在「保密字典」页面看到如下图所示的 `httpbin-tls` 字典项已经被生成。 159 | 160 | ![Secret Created](secret-created.png) 161 | 162 | 然后,我们再次回到「应用路由」页面,再新建一个名为 `httpbin-tls` 的路由,并为它设置路由规则为:`HTTPS` 协议,使用 `httpbin-tls` 保密字典,域名绑定改为 `httpbin.tls`。 163 | 164 | ![Route Create - HTTPS Rules](route-create-rule-https.png) 165 | 166 | 同样跳过「高级设置」后创建路由,返回路由列表后点击刚刚生成的 `httpbin-tls` 路由来到详情页面,如下面所示。 167 | 168 | ![Route Created - HTTPS](route-created-https.png) 169 | 170 | 点击「访问服务」可以同样成功打开 httpbin 服务的页面。至此,我们成功的为同一个服务同时配置了 HTTP 和 HTTPS 路由。本例虽然使用同一个服务作为应用路由的最终端点,但也可以任意替换成不同的服务,包括使用不同的路由路径。 171 | 172 | 同时,您可能也注意到了:虽然对于客户端访问我们已经启用了 HTTPS,但网关访问 httpbin 服务仍然是通过 `80` 的 HTTP 应用端口,这就是 TLS 终止(TLS Termination)。 173 | 174 | > TLS 终止代理(或 SSL 终止代理,或 SSL 卸载)是充当客户端和服务器应用程序之间的中间点的代理服务器,用于终止和/或建立 TLS(或 DTLS)通过解密和/或加密通信来建立隧道。这与 TLS 传递不同 —— 通过代理在客户端和服务器之间转发加密的 (D)TLS 流量而不终止隧道。 175 | > 176 | > —— [TLS termination proxy](https://en.wikipedia.org/wiki/TLS_termination_proxy),维基百科 177 | 178 | ### 通过路由注释实现高级配置 179 | 180 | > KubeSphere 的集群及项目网关本身是基于 Kubernetes 官方提供的 [NGINX Ingress Controller](https://kubernetes.github.io/ingress-nginx/) 实现的,目前业内各类 Ingress Controller 在 Ingress 标准以外提供各自更为丰富的能力,这些能力主要是通过 Ingress 资源的注释([Annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/))来体现的。 181 | 182 | KubeSphere 应用路由的「高级配置」能力便是提供了 Ingress 注释的编辑功能,所以最后我们通过一个案例来展示如何在应用路由中使用 NGINX Ingress Controller 的一些扩展能力。 183 | 184 | 让我们来看一个现实世界中经常出现的需求:为您的服务路径绑定一个特定的前缀。例如在本文的案例中,我们现在希望更改我们 HTTPS 的应用路由的访问方式为 `https://httpbin.tls/prefix`,即: 185 | 186 | - 当请求 `https://httpbin.tls/prefix` 或 `https://httpbin.tls/prefix` 时,仍然可以得到 httpbin 服务的首页 187 | - 当请求 `https://httpbin.tls/prefix/`(例如 `https://httpbin.tls/prefix/ip`)时,仍然得到对应的 httpbin 资源路径下的页面 188 | 189 | > 在开始实验前,让我们先访问 `https://httpbin.tls/ip` 获取数据作为后续的目标结果:`{"origin": "10.0.169.20"}`。 190 | 191 | 回到「应用路由」页面,找到并点击 `httpbin-tls` 路由项进入详情页面。在左侧的「更多操作」拉下按钮中,我们首先选择「编辑注释」。 192 | 193 | ![Route Annotations](route-anno-add.png) 194 | 195 | 如下图所示,注释是一组或多组键值对。我们可以搜索 `rewrite`,找到并使用 `nginx.ingress.kubernetes.io/rewrite-target` 键;在值的部分填入 `/$2` 后即可保存注释(稍后我们会介绍这个值的含义)。 196 | 197 | ![Route Annotations Added](route-anno-added.png) 198 | 199 | > KubeSphere 的应用路由提供了很棒的注释键搜索和自动补全功能,您也可以查阅 NGINX Ingress Controller 官方文档中对于所有 [注释](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/) 的详细说明。 200 | 201 | 完成注释添加后,我们再回到详情页面,同样找到「更多操作」按钮,这次我们选择「编辑路由规则」。进入编辑面板后选择已有的这个路由规则进行编辑: 202 | 203 | ![Route Rule Edit](route-rule-edit.png) 204 | 205 | 这里我们把「路径」修改为 `/prefix(/|$)(.*)`。可以注意到这里实际使用了正则表达式的语法,由此也不能理解在注释中的 `$2` 的含义,即指代了第二个匹配组,即 `(.*)` 部分所匹配的内容,也就是 `/prefix` 前缀后的 URI 资源。那么 `rewrite-target: /$2` 即表示将前缀后匹配到的 URI 作为新的请求路径发送给后端服务;如果匹配不到,则一直请求 `/` 路径。 206 | 207 | 同时正则路径中第一个匹配组 `(/|S)` 表示新的根路径既可以是 `/prefix` 也可以是 `/prefix/`。由此,我们前文所提到的两个路由前缀需求都得到了满足。 208 | 209 | 保持路由更改后让我们打开浏览器,直接输入地址 即可检验更新后的路由已经生效,您也可以使用其它 httpbin 服务的资源路径来检验,比如 会返回您的请求头信息。 210 | 211 | > **路由更新后 httpbin 服务首页为何显示不正常?** 212 | > 213 | > ![Route with Proxy - httpbin.tls](route-prefix-httpbin.png) 214 | > 215 | > 相信细心的您一定还会发现虽然 可以访问,但是界面好像和之前不太一样。没错,这是因为页面的静态资源文件都没有获取到的缘故。 216 | > 217 | > 我们不是已经设置了前缀路由了吗?是的,但这个路由的能力生效的前提是请求也必须带上 `/prefix` 这个前缀。很可惜,我们页面中的静态资源仍然是以 `/` 为根路径来加载的,所以它们没办法被正确的路由。要解决这个问题还需要前端的支持,现在一般主流的前端框架都支持为静态资源设定根访问路径,将其和路由规则对齐后即可解决这个问题。 218 | -------------------------------------------------------------------------------- /src/ingress-demo/ingress-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/ingress-demo.png -------------------------------------------------------------------------------- /src/ingress-demo/route-anno-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/route-anno-add.png -------------------------------------------------------------------------------- /src/ingress-demo/route-anno-added.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/route-anno-added.png -------------------------------------------------------------------------------- /src/ingress-demo/route-create-rule-https.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/route-create-rule-https.png -------------------------------------------------------------------------------- /src/ingress-demo/route-create-rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/route-create-rule.png -------------------------------------------------------------------------------- /src/ingress-demo/route-create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/route-create.png -------------------------------------------------------------------------------- /src/ingress-demo/route-created-https.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/route-created-https.png -------------------------------------------------------------------------------- /src/ingress-demo/route-created.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/route-created.png -------------------------------------------------------------------------------- /src/ingress-demo/route-httpbin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/route-httpbin.png -------------------------------------------------------------------------------- /src/ingress-demo/route-prefix-httpbin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/route-prefix-httpbin.png -------------------------------------------------------------------------------- /src/ingress-demo/route-rule-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/route-rule-edit.png -------------------------------------------------------------------------------- /src/ingress-demo/secret-create-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/secret-create-data.png -------------------------------------------------------------------------------- /src/ingress-demo/secret-created.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/secret-created.png -------------------------------------------------------------------------------- /src/ingress-demo/svc-create-container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/svc-create-container.png -------------------------------------------------------------------------------- /src/ingress-demo/svc-create-meta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/svc-create-meta.png -------------------------------------------------------------------------------- /src/ingress-demo/svc-create-pod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/svc-create-pod.png -------------------------------------------------------------------------------- /src/ingress-demo/svc-create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/svc-create.png -------------------------------------------------------------------------------- /src/ingress-demo/svc-created.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-sigs/kubesphere-quick-start/2d3ce4ae5c2e60ba5a87df4ccb612c0ee8a1a61a/src/ingress-demo/svc-created.png -------------------------------------------------------------------------------- /src/jenkinsfile-out-of-scm.md: -------------------------------------------------------------------------------- 1 | # 图形化构建流水线 (Jenkinsfile out of SCM) 2 | -------------------------------------------------------------------------------- /src/job-quick-start.md: -------------------------------------------------------------------------------- 1 | # 创建任务计算圆周率 2 | -------------------------------------------------------------------------------- /src/one-click-deploy.md: -------------------------------------------------------------------------------- 1 | # 一键部署应用 2 | -------------------------------------------------------------------------------- /src/source-to-image.md: -------------------------------------------------------------------------------- 1 | # Source to Image:无需 Dockerfile 发布应用 2 | -------------------------------------------------------------------------------- /src/wordpress-deployment.md: -------------------------------------------------------------------------------- 1 | # 创建 Wordpress 应用并发布至 Kubernetes 2 | --------------------------------------------------------------------------------