前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2024程序员容器化上云之旅-第6集-Ubuntu-WSL2-Windows11版:艰难复活

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

原创
作者头像
程序员吾真本
发布2024-02-28 09:24:19
2730
发布2024-02-28 09:24:19
举报

故事梗概

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

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

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

8 复活重生

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

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

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

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

图1 等了好一会儿,Docker Desktop k8s图标的背景色却从黄色,变成了出现故障的红色
图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
图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云集群上,并能顺利使用后,马意浓把整个容器化和上云之旅,写成系列文章,分享给其他程序员。


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

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 故事梗概
  • 8 复活重生
    • 8.1 K8s里的pod、node和cluster概念
      • 8.2 在k8s里运行前后端分离web应用与在docker compose里运行的差异
        • 8.3 在k8s中配置后端app的allowedOrigins时该如何配前端app对外域名和端口号以解决CORS问题?
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档


        http://www.vxiaotou.com