如何推广网站,怎么做网站和服务器吗,.简述网站开发的流程,wordpress媒体库数据故事梗概
Java程序员马意浓在互联网公司维护老旧电商后台系统。
渴望学习新技术的他在工作中无缘Docker和K8s。
他开始自学Vue3并使用SpringBoot3完成了一个前后端分离的Web应用系统#xff0c;并打算将其用Docker容器化后用K8s上云。
8 复活重生
周末终于有点属于自己的…故事梗概
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云集群上并能顺利使用后马意浓把整个容器化和上云之旅写成系列文章分享给其他程序员。 你能否跟着马意浓一步步做下来在阅读中有任何疑问欢迎在留言区留言。我会一一回复。
❤️如果喜欢本文那么点赞和留言并转发给身边有需要的朋友就是对我的最大支持。