1 冒险召唤
【你去Causium了?】
【嗯。上周去的。】
【恭喜!🎉🎉🎉】
Java程序员马意浓在微信中祝贺了前同事全绽园后,心里如打翻了五味瓶,百味杂陈。
一年多前,马意浓和全绽园在同一家公司的同一个组里一起编写Java代码。
后来,马意浓跳槽去了现在的这家国内互联网公司。
过了一阵,他在朋友圈看到全绽园分享的云原生相关技术文章,并且发现全绽园还在一个云原生编程训练营当主讲老师。
马意浓花了一些钱,报名参加了这个训练营。
但是由于每天加班到很晚,他只听了训练营的开头几节课就没能继续了。
昨天,他在朋友圈看到全绽园发布的Causium公司招聘微服务软件工程师的信息,于是就有了上面的微信对话。
Causium是几年前成立的一家主推开源平台和云服务产品的外企。
这家云服务软件公司是新成立的。这意味着程序员使用的技术栈都是最新的。
马意浓看着墙上贴着他名字的任务卡,不禁叹了口气。
他已经在这家互联网公司工作了一年多。他的职责是维护公司的一套老旧Java电商后台系统。
维护老旧系统意味着他每天都要面对诗山系统中的众多bug。
他所使用的技术栈还是10年前的那一套,比如JDK6、JSP、Maven和Ant。
他只能在技术文章中看看最近几年兴起的Docker容器化和K8s上云的技能,过过眼瘾。
看到下面两个论断,他心头一紧。
🔥Docker是云原生应用的基础和构建块。
🔥Kubernetes/K8s是云计算的操作系统。
但在工作中,他却没有任何机会体验这两门代表云计算的新技术。如图1。
他几乎每天都会更新自己的Windows 11操作系统。
然而,考虑到自己所掌握的技术慢慢过时,他认为程序员的技能升级不能再拖了。
1.1 Docker容器化和K8s上云能解决程序员三大痛点
基于所阅读的材料,他总结了Docker容器化和K8s上云,能解决程序员三大痛点。
❌第一,“在我这运行得好好的。怎么在你那不行?”
这是马意浓在看到测试人员给自己开了一个bug后经常说的话。
这个问题,在很大程度上是因为依赖库在不同环境下存在差异所导致的。
✅他了解到,docker image能将代码的所有依赖库都打包到一起,并能让代码在容器中独立运行。
这样就能实现在测试环境中所测试的image,就是在生产环境所部署的。
这样就能解决因为依赖库在不同环境下的差异,而导致这里能运行,而那里不能运行的问题。
❌第二,“这是谁改了配置又不告诉大家?”
这是马意浓、测试人员和运维人员,在发现Bug是由错误配置所导致时,经常说的一句话。
✅他了解到,Docker和K8s都强调基础设施即代码,即配置不是靠做软件的人拍脑袋临时手工敲的。
而是靠写成与代码同等地位的配置文件,通过团队代码评审,保存到版本库中,并让机器执行。
这样能让配置的更改广而告之,配置的执行有据可查。
同时也便于让机器读取,自动执行,而无须手工一遍一遍敲同样的命令。
❌第三,“测试环境太少得排队等很久才能使用。”
这是马意浓在修改了代码并需要在测试环境上验证时,经常说的一句话。
✅他了解到,有了本地docker compose,他就可以利用其占用存储空间小,运行速度快的特点,在本地电脑以docker image的方式,最大限度模拟生产环境,测试要发布的软件。
这样就无须排队等公司共享的测试环境。这样能让他更早地发现bug,减少因很晚才发现Bug所导致的大量返工时间。
同样,在企业内部如果使用了K8s云集群的,那么就能利用云的多租户特点,快速为需要测试环境的程序员和测试人员,分配测试环境,从而解决测试环境少的问题。
马意浓很想自学Docker容器化和K8s上云这些新技术,但苦于没人指导。
最近,能帮助程序员学习写代码的AIGC横空出世。
这让他看到了自学Docker容器化和K8s上云新技术的曙光。
2 跨越边界
作为Java后端程序员的马意浓,花了半个月的业余时间,跟着一个讲经典的todo list项目的视频,自学了vue3。
然后,他再配合使用SpringBoot3,完成了一个前后端分离的web应用系统。
他打算将这个Web应用系统,用docker容器化后,再用K8s上云。
这样就能让自己提升这两方面的技能。
2.1 选择编程练习Shopping List Web App的原因
马意浓在学Vue3时,所做的那个todo list前端app项目,其实是一个网页版的有增删改查的待办列表。
为了让自己能够完整地练习一遍所学的知识,他就把需求从待办列表,改成了购物清单。
他还给这个Web应用起了个名字:Shopping List Web App。
这个Web应用,能代表前后端分离的Web应用的典型架构。
这个架构能表现最小化的云原生微服务之间的依赖关系。
比如前端微服务app依赖后端微服务app。而后端微服务app又依赖于数据库微服务app。
这便于学习如何使用新兴的故障注入实验工具,进行混沌工程实践。
2.2 Shopping List Web App需求描述
当想到这个Web应用的需求描述时,马意浓脑海中出现了下面的场景。
一天,他发现家里的瓶装水快没了,就想着晚上下班路过超市时,顺便买几瓶。
但这时老板来微信喊他开会。他很快就把买瓶装水的事情忘掉干干净净。
等下班路过超市,他光顾着给老婆买打折的巧克力。等到家要喝水了,发现水没买。
这个Shopping List Web App,就能为他解决上面的痛点。
当他想要买水时,就可以马上在app里添加一条买水的购物项。
过了一会儿又想买点香蕉,那就再加一条。
等他到了超市,再查看一下这个清单,要买的东西就不会忘了。如图2。
2.3 容器化与上云之旅的三步走
在跟着Todo List视频自学了vue3后,为了掌握Docker容器化和K8s上云,马意浓需要学习这两门技术。
他喜欢看英文资料。因为内容比较新。
他在亚马逊购物网站上,用关键词docker和k8s搜了一下书。对比了一下评分。查看了一下读者评论。
最后,他发现Nigel Poulton所著的下面三本书,是2023年市面上讲这两门技术口碑最好的书。
Docker Deep Dive (2023 Edition) Quick Start Kubernetes (2023 Edition) The Kubernetes Book (2023 Edition)
他花了1个月时间,读了这3本书,运行了书中的命令,并做了笔记。
有了这些准备,他觉得可以开启前后端分离Web应用Docker容器化与Kubernetes/K8s上云之旅了。
这个旅程,该如何开启呢?
他觉得可以分三步走。
🦶第一步,在本地Gradle/npm开发环境里成功运行Web应用。
🦶第二步,在本地Docker Compose里成功运行Web应用。
🦶第三步,在K8s云集群里成功运行Web应用。
❓Docker Container与Docker Compose有什么区别呢?
马意浓从书中了解到下面区别。
✅前者是后者的构建块。
✅就使用场景来说,前者供程序员在本地电脑进行单容器/微服务的开发、构建和测试。而后者则在本地电脑进行多容器/微服务的开发、构建和测试。
✅就目的来说,前者将所开发的微服务通过容器轻松运行在本地电脑上,以便程序员在开发时自测,并在自测通过后直接将其用于后续的生产发布和运行。
而后者以基础设施即代码的方式,用一个声明性的docker-compose.yml文件,描述一个应用系统所包含的多个微服务所对应的多个容器,以便自动化地构建、发布和运行应用系统。
✅就配置文件来说,前者使用Dockerfile
,而后者使用docker-compose.yml
。
✅就关注点来说,前者关注基础镜像、依赖环境、源代码和运行命令。而后者关注容器、service和 volume。
✅就差异点来说,前者只关注某个镜像及其容器,而不考虑与其他容器之间的访问。而后者可根据docker-compose.yml文件中的声明,使用Dockerfile构建镜像。
✅就部署来说,两者有一个共同点,就是1个容器只部署1个微服务,每个微服务都只运行在1个容器上。
马意浓也曾打算一次就把源代码直接部署到K8s云集群里。
但这样做的前提,是一旦部署上去后,将来再也没有新需求或修bug,而去修改源代码并重新部署。
对于马意浓这个Docker和K8s新手来说,他觉得不可行。
他敏锐地意识到,当新需求来了或要修bug时,应该知道如何把修改过的代码,在本地Gradle/npm开发环境里调试通。也就是进行第一轮自测。
毕竟,本地电脑是他的地盘。在本地电脑上调试程序,总比在K8s云集群里要方便得多。这是第一步的意义。
之后,他需要知道如何将通过了第一轮自测的代码,构建成docker image,并在本地docker compose里成功运行,为之后将docker image部署到K8s做第二轮自测。
毕竟,本地docker compose也在他的地盘上。这是第二步的意义。
最后,他需要知道如何将通过了第二轮自测的docker image,部署到K8s云集群并成功运行,为之后部署到生产环境的K8s云集群做第三轮自测。
马意浓通过上网搜索,了解到目前市面上主流的K8s云集群,按照面世的先后顺序,有以下三种。
🔥谷歌的Google Kubernetes Engine (GKE),2014年面世
🔥微软的Azure Kubernetes Service (AKS),2017年面世
🔥亚马逊的Amazon Elastic Kubernetes Service (EKS),2018年面世
他从易访问的角度考虑了一下,决定选用微软的Azure K8s Service。可以免费使用1个月。
这也算是他的地盘。在这里自测,会比在运维团队地盘里的生产K8s云集群环境,要方便多了。
2.4 在本地Gradle/npm开发环境中的软件架构
马意浓是个做事严谨的人。
他在运行这个Web应用之前,用C4 Model画出了Shopping List Web App在本地Gradle/npm开发环境里运行时的架构。如图3和图4。
图3是站在整个Web应用的边界,向外看的context图。
在系统外,有User和Admin这两种用户在使用系统。
User使用系统来管理购物清单。Admin使用系统来管理购物清单数据。
图4是站在整个web app的边界,向内看的container图。
在系统内,有4个container。
马意浓提醒自己,c4 model里的container的概念,和docker的container的概念,是不同的。
前者是代表架构图中运行的应用或数据存储系统,后者代表封装了所有代码和依赖库能独立运行的软件运行单元。
User通过前端shopping-list-front-end来查看和修改购物清单。
而前端shopping-list-front-end将用户对购物清单的操作请求,发给后端shopping-list-api。
后端shopping-list-api再访问数据库postgres查询和更新数据。
Admin通过使用pgadmin数据库管理工具来直接管理postgres数据库中的数据。
马意浓从阅读Docker Deep Dive那本书里得知,数据库及其管理工具,可以使用docker compose直接拉取docker image并运行相应的docker容器来安装,而无需大费周章地下载安装包来安装。
这样做,除了方便安装,还能方便卸载和切换不同的版本。
🔥【未完待续。明天开始休假1周。之后再继续连载。】
⚠️要想获得本文及后续连载内容不断改进的最新版,可以随时在评论区给我留言,我会发你最新版。
🔥后面连载内容大纲先睹为快:
🔥3 工具准备
3.1 使用包管理器安装git以方便版本切换和升级以及下载代码
3.2 源代码介绍
3.3 使用包管理器安装jdk以方便版本切换和升级以及在本地进行后端app构建
3.4 使用包管理器安装node.js和npm以方便版本切换和升级以及在本地进行前端app构建
🔥4 接近深洞
4.1 使用docker desktop以容器方式运行数据库及其管理工具以便简化数据库安装步骤
4.2 在本地Gradle/npm开发环境启动后端app
4.3 在本地Gradle/npm开发环境启动前端app
🔥5 历经磨难
5.1 在用本地Gradle/npm开发环境自测时面临前端无法访问后端的CORS问题的挑战
5.2 清理现场
🔥6 夺取宝剑
6.1 在本地docker compose里的软件架构
6.2 免费注册Docker hub账号以便推送docker image为部署k8s做准备
6.3 构建后端docker image并推送到docker hub
6.4 构建前端docker image并推送到docker hub
6.5 在本地docker compose里运行shopping list web app
6.6 清理现场
🔥7 上云之路
7.1 注册Azure k8s service云平台账号
7.2 打开docker desktop kubernetes让kubectl能正常工作
🔥8 复活重生
8.1 在k8s云集群中运行shopping list web app时如何配置前端app在k8s云集群中的对外域名和端口号以解决CORS问题
8.2 在全绽园的帮助下为前端app配置ingress后解决了这个问题
8.3 在k8s云集群中的软件架构
8.4 如何新增k8s的deployment、service和ingress的配置文件,以便使用kubectl命令将ingress和postgres、shopping-list-api和shopping-list-front-end这3个微服务部署到k8s上
8.5 构建后端docker image并推送到docker hub
8.6 构建前端docker image并推送到docker hub
8.7 在k8s云集群上配置postgres、shopping-list-api和shopping-list-front-end三个微服务和ingress并运行
8.8 清理现场
🔥9 取经归来
当最终把前后端分离的web应用成功部署到azure k8s云集群上,并能顺利使用后,马意浓把整个容器化和上云之旅,写成系列文章,分享给其他程序员。
❤️如果喜欢本文,那么你的点赞、评论和转发,就是对我的最大支持😃🤝🙏。
我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!