2024程序员容器化上云之旅-第6集-Ubuntu-WSL2-Windows11版:艰难复活

故事梗概

Java程序员马意浓在互联网公司维护老旧电商后台系统。

渴望学习新技术的他在工作中无缘Docker和K8s。

他开始自学Vue3并使用SpringBoot3完成了一个前后端分离的Web应用系统,并打算将其用Docker容器化后用K8s上云。

8 复活重生

周末终于有点属于自己的学习时间了。

马意浓按下电脑电源按钮,进入Windows 11,启动了Docker Desktop。

他等着Docker Desktop界面左下角代表k8s的小舵轮的图标的背景,从正在启动的黄色,变成正常运行的绿色。

💔等了好一会儿,k8s图标的背景色却从黄色,变成了出现故障的红色。如图1。


图1 等了好一会儿,Docker Desktop k8s图标的背景色却从黄色,变成了出现故障的红色

他有点头大。因为这是第一次出现这种情况。

他记得在Docker Desktop界面右上方Settings小齿轮图标边上,好像有个表示bug的小虫子的图标。这或许与故障解决有关。

他于是点击那个小虫子的图标。果然进入了Troubleshoot界面。里面有Clean/Purge data等三个带红框的按钮。

他本想看看出错日志。但没有找到。

✅他于是上网搜了一下这个问题。发现有网友说,如果遇到Docker Desktop里的k8s启动失败,可以点Clean/Purge data按钮,清除所有数据来解决。这个帖子还有不少网友点赞。

他于是点了这个按钮。k8s小舵轮图标的背景色,就立即从红变黄。

又过了好一会儿,小舵轮背景色果然从黄变绿!他高兴地也去点了一个赞👍。

看到小舵轮背景色重新变绿,马意浓这才松了一口气。

但之前做过的k8s配置,就全丢失了。

不过好在所有命令都在笔记里。再重新手工运行一遍就好。无非是费点时间。

马意浓想,如此看来,虽然Docker Desktop里的k8s用起来很方便,但也只能临时体验一下,不能用于生产。

他想,趁着图标背景色目前还没变红,抓紧时间学k8s的关键概念吧。

8.1 K8s里的pod、node和cluster概念

马意浓自言自语:「node是k8s里面的什么概念?它和曾经读到过的pod、cluster、container、context之间,到底有什么关系?」

他于是问AIGC。AIGC很快给出了回答。

✅「k8s pod 是 k8s cluster中最小的部署、调度和执行单元。」

「在 K8s 中,container并不直接运行在cluster node上,而是一个或多个container被封装在一个pod中。 」

「对于运行应用程序的用户来说,按照微服务的设计理念,建议的做法是只在一个Pod中封装一个Container。」

「Pod 中的所有应用程序共享相同的资源和本地网络,从而简化了 Pod 中应用程序之间的通信。 」

「Pod 在每个node上利用一个称为 kubelet 的代理,来与 K8s API 和cluster的其余部分进行通信。」

✅「k8s node是 k8s cluster中最小的计算硬件单元。node可以是本地物理服务器,也可以是驻留在本地或云提供商处的虚拟机。」

「k8s有两种类型的node:一种是控制平面 (control plane) node,另一种是worker node。」

「控制平面node运行k8s内部服务。它们好比k8s用来思考和发令的大脑。」

「而worker node运行用户的应用程序。它们好比k8s用来为用户完成业务的手脚。」

✅「k8s cluster由node组成。每次使用 k8s,其实就是在管理cluster。」

「通常,当应用程序需要应对工作负载的变化并实现容量伸缩时,集群会利用多个节点来实现这一过程。」

「如果在cluster中添加或减少node,那么cluster将根据需要,自动重新分配工作负载。」

「比如,一个cluster可以有6个node。其中3个是控制平面node,另外3个是worker node。如图2。」


图2 一个cluster可以有6个node。其中3个是控制平面node,另外3个是worker node

「k8s的良好实践,是只在worker node上运行用户应用程序,而在控制平面node上只运行k8s系统服务。」

「这样能更好地实现高可用。因为一旦其中某个node失效,cluster还能依靠其他node继续工作。」

✅「kubectl context是在kubeconfig文件中定义的描述cluster的一组配置集合,以便让kubectl知道该给哪个cluster发命令,以及使用哪些凭据进行用户身份验证等。」

「kubeconfig文件默认是~/.kube/config文件。其中的配置集合一般包括3类信息:cluster信息、user信息和namespace信息。」

「当你需要在不同的cluster之间进行切换,比如在开发环境、预生产环境和生产环境的cluster之间切换时,可以方便地运行kubectl config use-context <context-name>命令进行切换。」

他又问了AIGC如何运行kubectl命令,来查看这些概念的信息。

他决定先把这些记录在笔记中。等成功地把前后端分离的web应用部署到k8s后,再来运行。

8.2 在k8s里运行前后端分离web应用与在docker compose里运行的差异

搞清了k8s的一些基本概念后,他开始思考,如何将shopping list web app这个前后端分离的web应用,部署到k8s上。

⚠️能否用在本地docker compose上部署前后端分离的web应用的思路,来在k8s里部署呢?

马意浓思考了一下这个问题。他觉得一部分思路可行,而另一部分则不可行。

✅可行的,是CORS问题的解决思路。

因为无论docker compose还是k8s,在部署前后端分离的web应用时,都要面对CORS问题。两者的解决思路应该是一致。

❌不可行的,是在k8s的配置中,前端app、后端app和数据库的主机名,不能像在docker compose中那样,全都在代码里写死为localhost。

而应该能够在配置文件里灵活设置,以便将来部署到k8s集群后,能配置为服务的域名或对外ip地址。

8.3 在k8s中配置后端app的allowedOrigins时该如何配前端app对外域名和端口号以解决CORS问题?

⚠️既然pod是k8s cluster中最小的部署单元,那么能否将原来配置中的localhost,都改为pod的ip地址,以解决CORS问题?

通过阅读,马意浓认为这不可能。

因为pod虽然也有ip地址,但这些地址都是k8s自动分配的内部ip地址。无法对外使用。

另外,k8s会根据随时变化的容量伸缩需求,动态启动和关闭pod。另外,当pod失效后,k8s还会重启pod。这都使得pod所带有的内部ip地址,会发生动态变化。

而为后端app配置CORS时,却恰恰需要稳定的前端app对外ip地址或域名。这该怎么办?

✅马意浓在查阅了大量资料后了解到,在k8s中配置前后端分离web应用时,针对部署数据库、后端app和前端app这3个独立的微服务,每个微服务都需要先后执行两步配置:deployment配置和service配置。

他猜测,之所以分两步,或许是因为k8s所具备的实现容量动态伸缩的特点所决定的。

k8s的这个特点,在实现起来,一方面需要保证其中的微服务能对外提供稳定的服务,另一方面也需要根据随时变化的容量伸缩需求,动态地调整微服务的底层pod的数量。

既然要实现这两个方面,那么配置微服务时,相应地也可以分两步。

🦶第一步,执行deployment配置,可确保配置中指定数量的pod副本replica能够随时可用。

🦶第二步,执行service配置,以便将来访问这个微服务时,能有一个稳定的访问点,而无须关心下属每个pod变幻莫测的内部ip地址。

比如,在service配置中,可以设置访问这个微服务的类型type。

❤️如果将type设置为默认的ClusterIP,那么这个微服务就有了稳定的内部 IP 地址,以便集群内的其他组件可以访问它。 但它不允许外部流量直接访问。

这非常适合k8s集群内服务之间的内部通信。

❤️如果将type设置为LoadBalancer,那么这个微服务会使用云提供商的负载均衡器,向外部公开服务。

这非常适合需要固定和易于记住的入口点的应用程序,通常要使用云提供商提供的负载平衡和流量分配功能。

想到这里,马意浓的脑海中冒出一个念头,

😃既然service配置能够让微服务可以对外提供一个稳定的访问点,那么在k8s中配置那3个微服务时,能否把原先配置localhost的地方,都换成相应配置中的service名?

马意浓决定试一下。

他为那3个要部署到k8s的微服务,在infrastructure文件夹下,分别写了deployment-xxx.yml和service-xxx.yml配置文件。

在前端app的service-shopping-list-front-end.yml文件中,他把type设置为LoadBalancer。这样前端app就有了对外的ip地址。

然后,他又把后端app的Java代码中的CORS配置改了一下,允许所有的origin。

他本想把代码中原先配置localhost的地方,都改成相应配置中的service名,但感觉service名应该也是k8s内部使用的,外部应该无法使用,所以就没改。

等配置好,并部署到Docker Desktop k8s后,他发现前端app的购物清单页面能够正常显示了。

❌但只要前端app一访问后端app获取数据,就会出现CORS问题。

马意浓只好求助AIGC。

但或许问题问得不好,AIGC这次回答,却语焉不详。让他摸不到头脑。

他又上网搜索。结果发现,网上所有在k8s上部署web应用的样例,都仅仅部署一个前端app。

他在网上找不到如何在k8s上部署前后端分离的web应用的代码样例。

这让马意浓犯了难。看来他要独自摸索了。

他在一筹莫展之际,只好把求助信息发到了朋友圈。

「万圈,在k8s里,前端app的pod,在访问后端app的pod的API时,解决CORS问题的推荐做法是什么?」

很快,他就收到了几位朋友的回复。

「用路径区分前后端。在ingress里做转发,转发到不同的后端。」

「后端挂在同域名的/api目录下。若匹配/api则转后端,否则就转前端。」

「印象中要加一层nginx来代理。」

根据朋友们的回复,马意浓上网搜索了ingress nginx controller的信息。并在笔记中做了记录。

✅Ingress是k8s的一个API对象,用于定义外部访问集群内服务的规则,如可以基于请求的 HTTP 路径或主机名,来路由流量到不同的服务。

Ingress 使得用户可以通过单一的 IP 地址向外提供k8s中的多个服务,并可以配置负载均衡等高级路由功能。

✅Ingress Controller 是一个守护进程。它根据 Ingress 中的配置,来处理进入集群的外部请求。它负责实现 Ingress 中定义的规则。

虽然 Ingress 定义了路由规则,但需要 Ingress Controller 来实际监控这些 Ingress 资源,并应用这些规则。

若没有 Ingress Controller,那么Ingress 资源本身不会生效。

✅Nginx 是一种流行的开源 Web 服务器和反向代理服务器。在 k8s 中,Nginx 可以被用作 Ingress Controller 的一种实现。

使用 Nginx 作为 Ingress Controller 时,Nginx 会配置为根据 Ingress 资源的定义,来路由外部请求到集群内的服务。

这允许利用 Nginx 的高性能和灵活的配置来管理 Kubernetes 集群的入口流量。

笔记写到这里,再回想几位朋友的那几条回复,马意浓很受启发。

😃如果在ingress nginx controller里,为前端app和后端app分别设置不同的path,那么就可利用ingress能用单一IP地址向外提供服务的特点,让前端app访问后端app时不再跨域,从而解决CORS问题。

虽然在k8s中,解决前后端分离的web应用的CORS问题的思路清楚了,但马意浓在接下来实现这个思路的过程中,有遇到了哪些挑战?且听下回分解。

未完待续


❤️欲读系列故事的全集内容,可搜用户“程序员吾真本”,找到“2024程序员容器化上云之旅”专栏阅读。

🔥后面连载内容大纲先睹为快

🔥8 复活重生

8.4 无意中用小黄鸭调试法解决k8s中前后端分离web应用的CORS问题

8.5 在k8s集群中的软件架构

8.6 新增k8s的deployment、service和ingress配置文件以便将postgres、shopping-list-api、shopping-list-front-end三个微服务和ingress部署到k8s上

8.7 构建后端app的docker image并推送到docker hub

8.8 在git代码库打同名的tag以对应刚刚构建的docker image版本

8.9 构建前端app的docker image并推送到docker hub

8.10 在k8s集群上配置postgres、shopping-list-api和shopping-list-front-end三个微服务和ingress并运行

8.11 在k8s上运行购物清单web应用

8.12 运行kubectl命令以查看k8s概念

8.13 清理现场

🔥9 取经归来

当最终把前后端分离的web应用成功部署到azure k8s云集群上,并能顺利使用后,马意浓把整个容器化和上云之旅,写成系列文章,分享给其他程序员。


😃你能否跟着马意浓一步步做下来?在阅读中有任何疑问,欢迎在留言区留言。我会一一回复

❤️如果喜欢本文,那么点赞留言,并转发给身边有需要的朋友,就是对我的最大支持😃🤝🙏。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/705445.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【书籍分享 • 第三期】虚拟化与容器技术

文章目录 一、本书内容二、读者对象三、编辑推荐四、前言4.1 云计算技术的发展4.2 KVM、Docker4.3 本书内容简介4.4 作者简介 五、粉丝福利 一、本书内容 《虚拟化与容器技术》通过深入浅出的方式介绍KVM虚拟化技术与Docker容器技术的概念、原理及实现方法&#xff0c;内容包括…

Linux之安装Nginx、前后端分离项目部署

目录 一、安装Nginx 1.1先一键安装4个依赖 1.2下载并解压安装包 1.3安装nginx&#xff0c;一般我们在nginx都是要安装ssl证书的 1.4 启动nginx服务 1.5开放80端口 1.6配置nginx自启动 1.7修改/etc/rc.d/rc/local的权限 二、多个tomcat负载加后端部署 2.1创建多个tomca…

Windows已经安装了QT 6.3.0,如何再安装一个QT 5.12

要在Windows上安装Qt 5.12&#xff0c;您可以按照以下步骤操作&#xff1a; 下载Qt 5.12&#xff1a;访问Qt官方网站或其他可信赖的来源&#xff0c;下载Qt 5.12的安装包。 下载安装地址 下载安装详细教程 安装问题点 qt安装时“Error during installation process(qt.tools…

react useRef用法

1&#xff0c;保存变量永远不丢失 import React, { useState,useRef } from react export default function App() { const [count,setcount] useState(0) var mycount useRef(0)//保存变量永远不丢失--useRef用的是闭包原理 return( <div> <button onClick{()>…

跨境电商营销进化史:从传统广告到智能化策略的全面探析

随着全球化的不断推进和互联网技术的飞速发展&#xff0c;跨境电商在过去几年里取得了显著的发展。在这个竞争激烈的市场中&#xff0c;企业们纷纷调整营销策略以应对不断变化的消费者需求和市场趋势。本文Nox聚星将和大家探讨跨境电商营销策略的演变过程&#xff0c;从传统的推…

MySQL基础(二)

文章目录 MySQL基础&#xff08;二&#xff09;1. 数据库操作-DQL1.1 介绍1.2 语法1.3 基本查询1.4 条件查询1.5 聚合函数1.6 分组查询1.7 排序查询1.8 分页查询1.9 案例1.9.1 案例一1.9.2 案例二 2. 多表设计2.1 一对多2.1.1 表设计2.1.2 外键约束 2.2 一对一2.3 多对多2.4 案…

Python爬虫中的单线程、多线程问题(文末送书)

前言 在使用爬虫爬取数据的时候&#xff0c;当需要爬取的数据量比较大&#xff0c;且急需很快获取到数据的时候&#xff0c;可以考虑将单线程的爬虫写成多线程的爬虫。下面来学习一些它的基础知识和代码编写方法。 一、进程和线程 进程可以理解为是正在运行的程序的实例。进…

【Flink精讲】Flink反压调优

Flink 网络流控及反压的介绍&#xff1a; Apache Flink学习网 反压的理解 简单来说&#xff0c; Flink 拓扑中每个节点&#xff08;Task&#xff09;间的数据都以阻塞队列的方式传输&#xff0c;下游来不及消费导致队列被占满后&#xff0c;上游的生产也会被阻塞&#xff0c;…

GaussDB SQL调优:选择合适的分布列

一、背景 GaussDB是华为公司倾力打造的自研企业级分布式关系型数据库&#xff0c;该产品具备企业级复杂事务混合负载能力&#xff0c;同时支持优异的分布式事务&#xff0c;同城跨AZ部署&#xff0c;数据0丢失&#xff0c;支持1000扩展能力&#xff0c;PB级海量存储等企业级数…

Netty NIO 非阻塞模式

1.概要 1.1 说明 使用非阻塞的模式&#xff0c;就可以用一个现场&#xff0c;处理多个客户端的请求了 1.2 要点 ssc.configureBlocking(false);if(sc!null){ sc.configureBlocking(false); channels.add(sc); }if(len>0){ byteBuffer.flip(); 2.代码 2.1 服务端代码 …

Springboot 多级缓存设计与实现

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&…

StarRocks之扩容缩容

扩缩容 FE 集群 StarRocks FE 节点分为 Follower 节点和 Observer 节点。Follower 节点参与选举投票和写入&#xff0c;Observer 节点只用来同步日志&#xff0c;扩展读性能。 注意&#xff1a; 所有 FE 节点的 http_port 必须相同。 Follower FE 节点&#xff08;包括 Leader…

超真诚婚礼邀请函小程序

结婚了&#xff0c;自己写个婚礼邀请函小程序&#xff0c;含泪省下&#xffe5;49.9&#xff1b;程序员的浪漫&#xff01; 1、定位直达 2、背景音乐 3、倒计时 4、CSDN图床 页面代码如下&#xff1a; <cu-custom bgColor"bg-yellow-light" isBack"{{fal…

基于HT32的智能家居demo(蓝牙上位机)

参加合泰杯作品的部分展示&#xff0c;基于HT32的智能家居&#xff0c;这里展示灯光的相关控制&#xff0c;是用蓝牙进行的数据透传&#xff0c;参考了一些资料&#xff0c;美化封装了一下之前的上位机界面。 成果展示 点击主界面的蓝牙设置&#xff0c;进行连接&#xff0c;下…

Rust调用同级目录中的rs文件和调用下级目录中的rs文件

一、Rust调用同级目录中的rs文件 Rust新建工程demo02&#xff0c;src文件夹下面新建test.rs文件&#xff0c;这样main.rs文件与它属于同级目录中。 关键点&#xff1a;导入test文件和test文件中的Ellipse模块 mod test;//导入test模块&#xff08;文件&#xff09; use test…

iview碰到的一些问题总结

iview tabs嵌套使用问题 tabs嵌套使用的时候不是直接套用行了&#xff0c;直接套用会出现内层tab都集成到一级tab去&#xff0c;需要设置该属性指向对应 Tabs 的 name 字段(需要版本大于3.3.1) <Tabs name"tab1" ><TabPane label"标签1" tab&qu…

【程序员英语】【美语从头学】初级篇(入门)(笔记)Lesson 16 At the Shoe Store 在鞋店

《美语从头学初级入门篇》 注意&#xff1a;被 删除线 划掉的不一定不正确&#xff0c;只是不是标准答案。 文章目录 Lesson 16 At the Shoe Store 在鞋店对话A对话B笔记会话A会话B替换 Lesson 16 At the Shoe Store 在鞋店 对话A A: Do you have these shoes in size 8? B:…

FL Studio All Plugins Edition2024中文完整版Win/Mac

FL Studio All Plugins Edition&#xff0c;常被誉为数字音频工作站&#xff08;DAW&#xff09;的佼佼者&#xff0c;是音乐制作人和声音工程师钟爱的工具。它集音频录制、编辑、混音以及MIDI制作为一体&#xff0c;为用户提供了从创作到最终作品输出的完整工作流程。这个版本…

第 1 章 微信小程序与云开发从入门到实践从零开始做小程序——开发认识微信小程序

小北的参考工具书 小程序开发的图书并不少&#xff0c;这本书仍然值得你拥有&#xff01; 首先&#xff0c;这是一本全栈小程序开发教程&#xff0c;循序渐进&#xff0c;由浅入深&#xff0c;介绍了小程序开发你想了解的方方面面&#xff0c;包括近其小程序开发的各种新技术应…

如何避免在绩效考核评分时“脸盲”

对于大型企业来说&#xff0c;如何保证在绩效考核评分时准确快速地回忆起员工的日常表现&#xff0c;已经成为困扰管理者的难题。由于大型企业员工数量众多且业务模块繁杂&#xff0c;公司领导很难对每个员工的工作情况都了如指掌。这导致在绩效考核评分时&#xff0c;公司领导…