万字长文K8s部署前后端分离web应用避坑指南之一:从源代码到dockercompose到k8s云集群(macOS2023版)腾讯云开发者社区

从2023年8月到10月,我花了3个月自学docker和k8s。踩了一路坑,到10月22日终于把一个带有vue.js3前端、springboot后端以及postgres数据库的shoppinglistwebapp,部署到azurek8sservice云上,并能正常运行。

“工作体验好,好事才能来。”

想想咱们做软件的人常说的下面几句话。

“在我这运行得好好的,怎么你那儿不行?”dockerimage能将代码的所有依赖库都打包到一起,并能让代码在容器中独立运行。这样就能实现你在测试环境中所测试的image,就是你在生产环境所部署的,从而能在很大程度上解决因为依赖库在不同环境下的差异,而导致这里能运行,那里不能运行的问题。

“这是谁改了配置又不告诉大家?”Docker和k8s都强调基础设施即代码,即配置不是靠做软件的人拍脑袋临时手工敲的,而是靠写成与代码同等地位的配置文件,通过团队代码评审,保存到版本库中,并让机器执行。这样能让配置的更改广而告之,配置的执行有据可查。同时也便于让机器读取,自动执行,而无须手工一遍一遍敲同样的命令。

“测试环境太少得排队使用。”有了本地dockercompose,做软件的人可以利用其占用存储空间小,运行速度快的特点,在本地电脑以dockerimage的方式,最大限度模拟生产环境的方式,测试要发布的软件,而无须排队等公司共享的测试环境。这样能更早地发现bug,减少因很晚才发现所导致的大量返工成本。同样,在内部使用了k8s云集群的企业,也能利用云的多租户特点,快速为需要测试环境的做软件的人,分配测试环境,从而解决测试环境少的问题。

可见,Docker和k8s能让咱们做软件的人,工作体验更好,好事才更能来。

“为何选用ShoppingListWebapp作为样例项目?”这个样例源自我在自学vue.js时所学的待办清单todolistapp样例,如图2所示。我把todolist改造为shoppinglist。两者的功能近似,都是为用户提供一个备忘清单,有一个web界面可以增删改查。这容易理解。此外,这个样例能代表前后端分离的webapp典型架构。另外,这个样例能表现最小化的云原生微服务之间的依赖关系,比如前端微服务依赖后端微服务,而后端微服务又依赖于数据库微服务。这便于学习如何使用新兴的故障注入实验工具,进行混沌工程实践。

K8s部署前后端分离的web应用避坑系列指南之一:在本地开发环境、本地dockercompose和k8s云集群里跑通购物清单应用(macOS/Windows10/Ubuntu-2023版分别写)

K8s部署前后端分离的web应用避坑系列指南之二:解读购物清单应用Dockerfile和docker-compose.yml文件

K8s部署前后端分离的web应用避坑系列指南之三:解读购物清单应用k8s的deployment、service和ingress配置文件

可以分三步:

第一步,在本地开发环境里跑通;

第二步,在本地dockercompose里跑通;

第三步,在k8s云集群里跑通。

为何不能一次就从源代码直接部署到k8s呢?当然这样做也可以,但前提是你确信部署上去后,将来再也没有新需求或修bug而去修改源代码并重新部署。对于坑坑洼洼的docker和k8s学习之旅,你觉得这可能吗?

所以你需要知道当新需求来了或要修bug时,该如何把修改过的代码,在本地开发环境里调试通。这是进行第一轮自测。毕竟,本地电脑是你的地盘儿。在本地电脑上调试程序,比在k8w云集群里要方便得多。这是第一步的意义。

之后,你需要知道如何将通过了第一轮自测的代码,构建成dockerimage,并在本地dockercompose里跑通,为之后将dockerimage部署到k8s做第二轮自测。毕竟,本地dockercompose也在你的地盘儿上。这是第二步的意义。

最后,你需要知道如何将通过了第二轮自测的dockerimage,部署到k8s云集群并跑通,为之后部署到生产k8s云集群环境做第三轮自测。这个项目的k8s云集群,我选用了微软的azurek8sservice,免费使用1个月。这也算是我的地盘儿。在这里自测,会比在运维团队地盘儿里的生产k8s云集群环境,要方便多了。这是第三步的意义。

2.3.1在本地开发环境里的架构

图3是站在整个webapp的边界,向外看的context图。在系统外,有user和admin这两种用户在使用系统。User使用系统来管理购物清单。Admin使用系统来管理购物清单数据。

图4是站在整个webapp的边界,向内看的container图。在系统内,有4个容器。注意c4model里的container的概念,和docker的container的概念,是不同的。前者是代表架构图中运行的应用或数据存储系统,后者代表封装了所有代码和依赖库能独立运行的软件运行单元。User通过前端shopping-list-front-end来查看和修改购物清单。而前端shopping-list-front-end将用户对购物清单的操作请求,发给后端shopping-list-api。后端shopping-list-api再访问数据库postgres查询和更新数据。Admin通过使用pgadmin数据库管理工具来直接管理postgres数据库中的数据。

2.3.2本地开发环境准备

我所使用的Mac,是AppleM1Pro,32G内存。对于在本机跑dockercompose和前后端应用,只要不同时开着intellijidea和webstorm,8G内存应该是够用了。

[小心坑!不要直接使用官网安装包安装工具]

我之前安装jdk的习惯,一直是先确定要装哪个版本的jdk,比如jdk11,然后在oracle官网上找到jdk11的下载页面,下载对应操作系统的安装包,然后解压或安装。

但后来发现,jdk版本更新得很频繁。如果想用现在的主流版本jdk17,就得再从官网下载并安装jdk17,然后手工在~/.zshrc或~/.bashrc里修改JAVA_HOME和PATH环境变量。这样才能从jdk11切换到jdk17。如果有老旧项目又需要用jdk11,又得手工修改环境变量。这太累了。

而像git这样的工具,虽然版本更新得不那么频繁,如果你也是从官网下载安装包安装,等过了几个月,想升级版本时,经常会忘记当初是如何安装的,导致难以卸载并重新安装。

如果你在macOS上的git、jdk和node.js/npm之前是直接使用官网安装包安装的,而没有使用包管理器来安装,那么推荐你设法把它们先卸载,然后使用下面的包管理器来安装。否则,你就要冒因工具版本与我所用的不一致,而导致各种问题的风险。而我下面描述的工具版本,是经过我测试过了的。

用包管理器homebrew安装文件版本管理工具git2.42.0以便下载本项目代码

验证git是否工作:运行命令`git-v`,我用的git版本是2.42.0。

以后就把`shoppling-list-web-app`叫做*项目文件夹*。

进入到这个文件夹,运行命令`ls-alF`,你会看到,这个文件夹里有3个子文件夹。

drwx------15binwustaff480Oct2316:22back-end/drwx------23binwustaff736Oct2313:47front-end/drwx------3binwustaff96Oct2308:27infrastructure/其中,

infrastructure文件夹存放了运行dockercompose和k8s的配置文件,如`docker-compose.yml`。

back-end存放了后端代码、后端Dockerfile和其他配置文件。

front-end存放了前端代码、前端Dockerfile和其他配置文件。

Dockerfile是一种配置文件,用于把源代码构建为dockerimage,以便以容器化的方式进行部署。

用包管理器sdkman安装后端开发工具jdk17.0.8.1-tem以便在本地进行后端构建

安装jdk:`sdkinstalljava`。

查看所安装的jdk版本:`sdklistjava`。

验证jdk是否工作:`java-version`。我用的jdk版本是openjdkversion"17.0.8.1"2023-08-24。

用包管理器nvm安装前端工具node.js和npm以便在本地进行前端构建

安装node.js/npm:`nvminstall--lts`。

验证前端工具node.js是否工作:`node-v`。我用的node.js版本是v18.18.0。

验证前端构建工具npm是否工作:`npm-v`。我用的npm版本是9.8.1。

安装dockerdesktop以便用容器方式运行postgres数据库及其管理工具

验证dockerdesktop是否工作:看dockerdesktop是否能正常启动。

2.3.3在本地开发环境里跑通shoppinglistwebapp

启动dockerdesktop

在容器中运行postgres数据库和能查看数据库中数据的pgadmin以便在本地开发环境里运行gradle构建和测试

[小心坑!不要再使用官网安装包安装数据库和管理工具]

有人会问:容器里跑数据库,要是关闭或删除容器,那数据不就丢了?其实不用担心,你可以为数据库容器设置一个位于本地硬盘中的volume,以便保存持久化的数据。只要你不删除这个volume,数据库容器关闭后再启动,仍然能够获取之前的数据。

在本地开发环境里跑通shoppinglistwebapp,首先要把postgres数据库和pgadmin管理工具启动起来。因为之后的后端app在使用gradle进行构建时,会运行自动化测试,需要访问数据库。如果在后端app构建时不启动postgres数据库,那么gradle构建会失败。

验证容器:在dockerdesktop的container界面里,能看到运行起来的两个容器,如图5所示。

验证数据库:

鼠标右击Servers->Register->Server…->General里的Name:随便写一个,比如shopping-list->Connection里面的Hostname/address:postgres->Port:5432->Maintenancedatabase:postgres->Username:postgres->Password:postgres->允许Savepassword->点击Save按钮->点击刚刚创建的shopping-list服务器,就能在数据库出现问题时查看数据库里的数据,如图6所示。这里的Username和Password也是在docker-compose.yml文件中的postgres服务中设置好的。

在本地开发环境启动后端app

重新打开一个terminal,进入项目文件夹,然后进入后端代码文件夹:`cdback-end`。启动后端app:`./gradlewbootRun`。

在本地开发环境启动前端app

重新打开一个terminal,进入项目文件夹,然后进入前端代码文件夹:`cdfront-end`。先运行命令`npminstall`,安装package.json文件所设置的依赖库。

[小心坑!CORS问题导致前端无法访问后端]

此时还可以用快捷键Cmd+Option+I打开DeveloperTools界面,在Network页签的Console里,就看不到任何错误信息了。

[小心坑!dockerdesktop的kubernetes里的配置会捣乱]

仔细回忆,才想起来,前两天在dockerdesktop里试用了本地电脑kubernetes(简称k8s)集群功能,并在里面配置了名为`shopping-list-api-ingress`的ingress配置。ingress的解释,参见本文2.5.2。

看起来前端在访问后端时,使用了这个ingress,从而导致CORS错误。要是我把dockerdesktop里的kubernetes给关掉,是不是就会好了。于是在dockerdesktop的settings中,选择Kubernetes,再把EnableKubernetes的勾选项取消勾选,重启dockerdesktop。这样就删除了那个ingress。为了保险,再清除一下浏览器cache。再次访问前端。一切正常!

至此,shoppinglistwebapp就已经在本地开发环境里跑通了。

清理现场

2.4.1在本地dockercompose里的架构

架构图没变,还是见图3和图4.虽然Shoppinglistwebapp在本地dockercompose里的架构,与在本地开发环境里的架构,在c4model架构图中的画法相同,但在实现层面有差异。前者的前端和后端app,是运行在dockercontainer里的。而后者则运行在npm和gradle命令所启动的服务中。

2.4.2本地dockercompose环境准备

在macOS上,只要安装好了dockerdesktop,你就准备好了本地dockercompose运行环境。可以在dockerdesktop界面里查看dockercompose所启动的容器,以及相应的image。

2.4.3在本地dockercompose里跑通shoppinglistwebapp

免费注册Dockerhub账号以便推送dockerimage为部署k8s做准备

Dockerhub是Docker公司搞的一个存储dockerimage的公共注册(registry)中心。Docker公司把容器化搞火了之后,很多做软件的公司,就把它们的软件产品,做成dockerimage,并推送到Dockerhub。你之前所用的postgres和pgadmin的image,都是从这个中心拉取的。你在Dockerhub上注册账号后,也可以把你构建的dockerimage推送到Dockerhub上。

构建后端dockerimage并推送到dockerhub

构建后端dockerimage,分为三步。

第一步,用gradle构建后端app,生成jar包。

先生成jar包,再构建dockerimage的好处,是能让image仅包含运行后端所需要的jar包。这样能让image文件尽量小。

进入项目文件夹,运行命令`cdinfrastructure`进入这个子文件夹。然后再运行命令`dockercomposeuppostgrespgadmin`启动postgres数据库和pgadmin管理工具。

然后新打开一个terminal窗口,进入项目文件夹,运行`cd../back-end`,进入后端文件夹。

运行命令`./gradlewcleanbuild`构建后端app。之后可以在文件夹`build/libs`里,找找所生成的jar包,文件名是shoppinglist-0.0.1-SNAPSHOT.jar。

第二步,构建dockerimage。

运行命令`dockerbuildxbuild--build-argJAR_FILE=build/libs/shoppinglist-0.0.1-SNAPSHOT.jar-t/shopping-list-api:v1.0.docker-compose.`来构建后端dockerimage。可以运行命令`dockerimagels`查看新构建的带有`v1.0.docker-compose`tag的image。

这个命令中,`dockerbuildxbuild`是对旧的`dockerbuild`命令的扩展,提供了后者所没有的缓存的导入和导出,以及并发构建多个image的功能。

在参数`-t/shopping-list-api:v1.0.docker-compose`中,`-t`指给image加一个tag。这个tag就是参数中`v1.0.docker-compose`,用于标识这个image。你要把替换为你的Dockerhub用户名。而整个`/shopping-list-api`,表示这个image将来推送到Dockerhub上的镜像库(repository)名称。

[小心坑!dockerbuildx命令最后的那个小数点不要忘了]

上面命令最后有一个不起眼的小数点。千万不要把它忘了。这代表把当前文件夹作为build的上下文,以找到诸如jar文件这样的构建资源。

[小心坑!如何知道所构建的image对应的是代码库中的哪些代码?]

我们知道,随着不断提交,代码库中的代码总是在不断变化。如果有一天,你推送到Dockerhub中的image里有bug,你想打开对应的源代码看一下。但距离你构建这个image已经过去好几天了,你也往代码库里提交了不少代码。当初构建这个image的代码也改了不少。此时你该如何在代码库中,还原当初构建这个image时的代码?解决的办法,就是你在运行上面的dockerbuildx命令,构建了dockerimage后,就立即运行命令`gittag-av1.0.docker-compose-m“v1.0.docker-compose”`,在git库里打一个同名的tag。这样通过识别这个tag,你就能把image和代码对应上了。最后别忘了运行命令`gitpushoriginv1.0.docker-compose`把这个tag推送到远程git库中。

第三步,把dockerimage推送到Dockerhub。

构建前端dockerimage并推送到dockerhub

构建前端dockerimage,分为两步。

第一步,构建dockerimage。

运行`cd../front-end`,进入前端文件夹。运行命令`dockerbuildxbuild-t/shopping-list-front-end:v1.0.docker-compose.`来构建后端dockerimage。这里的参数解读和前面讲的一样。可以运行命令`dockerimagels`查看新构建的带有`v1.0.docker-compose`tag的image。

第二步,把dockerimage推送到Dockerhub。

在本地dockercompose里跑通shoppinglistwebapp

至此,shoppinglistwebapp在本地dockercompose里跑通了。

进入项目文件夹,运行命令`cdinfrastructure`进入infrastructure子文件夹,再运行命令`dockercomposedown`可以停止和删除4个容器。

在k8s云集群里跑前后端分离的webapp,有两种选择。

第一种,是使用云厂商所提供的免费试用的服务。

第二种,是使用在本地电脑上运行的诸如minikube这样的单node的服务。

因为要真正体验上云,所以我选择了第一种。

各大云厂商都会提供1~3个月不等的k8s云集群免费试用。本文选用了微软的azurek8sservice。免费试用1个月,提供2个node。按照之前讲解的习惯,此时应该展示shoppinglistwebapp在k8s云集群里的架构。但为了再现我踩坑的经过,让讲解更有趣,我打算把架构放到最后再讲。

2.5.1K8s云集群环境准备

注册Azurek8sservice云平台账号

打开dockerdesktopkubernetes让kubectl能正常工作

接下来,你需要安装工具kubectl,以便从macOS连上k8s云集群。做法是在dockerdesktop里,点击settings,选择Kubernetes,然后把EnableKubernetes左边的勾选框勾上。之后点击Apply&reset按钮。

验证dockerdesktopk8s能否正常工作:等reset结束后,你能在dockerdesktop的主界面左下角的小鲸鱼图标上方,看到一个绿色背景的小横条,上面有k8s的舵轮图标。绿色背景,表示dockerdesktopk8s运行正常。另外,你可以打开一个terminal窗口,在里面输入命令`kubectlversion-oyaml`。如果能看到clientVersion和serverVersion,就说明操作k8s的命令kubectl能正常工作了。

连上azurek8sservice云平台

要从你的Mac连上azurek8sservice云平台,需要改一个配置文件。这个文件是你的mac电脑的`~/.kube`文件夹下的config文件。你可以用你喜欢用的编辑器,打开这个文件。里面只有你的dockerdesktop所提供的一个k8s集群,名字就是docker-desktop。你要连azurek8sservice云平台,就需要把这个文件,替换为azurek8sservice云平台的同名配置文件。或者在这个文件中,添加azurek8sservice云平台的配置。即这个文件可以有多个k8s集群的配置,此时就能用kubectl命令,在两个k8s集群之间切换。因为在本文中,我们不用dockerdesktopk8s所提供的单node的本地集群,所以为简单起见,可以把你mac上的`~/.kube/config`文件先备份,然后用azurek8sservice云平台的同名配置文件将其替换。

一旦改好了config文件,你就可以连接azurek8sservice云平台了。

运行命令`kubectlconfigget-contexts`,可以看到你所连接的azurek8sservice云平台。

运行命令`kubectlgetnodes`,可以查看azurek8sservice云平台给你分配了两个node,状态都是ready。

2.5.2在k8s云集群里跑通shoppinglistwebapp时踩坑

我是如何踩坑的

初次在k8s上部署前后端分离的webapp,最自然的方式,就是按照在dockercompose里部署的架构,来部署。但这样想,就踩进了一个坑。在讨论坑之前,先看看在k8s云集群里跑通与在本地跑通之间的差异。

在k8s云集群里跑通shoppinglistwebapp,与在本地dockercompose里跑通,有什么差异呢?有3个差异。

第一个差异,是后端app所依赖的数据库主机名,不再是localhost,而是k8s云集群里postgres数据库的内部service名。这需要改动back-end/src/main/resources/application.properties文件,将里面的localhost,替换为${DB_HOST}。即通过在下面介绍的deployment配置文件设置的DB_HOST环境变量,来确定postgres数据库的service名。

第三个差异,前端前端app所依赖的后端app的主机名和端口,也不再是localhost:8081,同样也变成了k8s云集群里后端app的service名。这需要改动前端代码的3个文件。首先,front-end/src/components/ShoppingList.vue文件中的localhost:8081,需要改为%%API_URL%%。这也是通过在下面介绍的deployment配置文件设置的API_URL环境变量,来确定后端app的服务名。为了能够在js代码中,替换后端app的服务名,需要改动front-end/Dockerfile和新增front-end/entrypoint.sh文件。

第二个差异,就是一个坑。后端的CORS的配置中的allowedOrigins,该如何配前端app在k8s云集群中的对外域名和端口号?我没有为这个项目申请域名。域名也不能写成内部service名,因为内部名无法用于外部访问。能把域名写成ip地址吗?在云集群中,ip地址经常会发生变化。每次ip变了就去改配置,多麻烦。这个坑该如何爬出来?

后来也是查了很多资料,在朋友圈求助,经过朋友们的提醒,并尝试了一下,发现为shoppinglistwebapp配置ingress能解决这个难题。

在k8s里,ingress是一种规则和配置的集合,它能帮助外部的网络请求,来查找到和访问集群内的服务。可以把它想象成一个交通指挥员,它知道如何根据特定的规则把外面来的车辆(网络请求)引导到正确的停车位(服务)。

2.5.3在k8s云集群里的架构

在k8s云集群里,就难以使用pgadmin数据库管理工具了。所以图8的context架构图只有user。

咱们这个webapp,用户不再直接访问前端app的对外IP和端口,而是直接访问ingressnginxcontroller的对外IP和端口。之后,ingressnginxcontroller会把用户的请求,根据请求的path不同,分发给前端app和后端app。而前后端app就不必拥有对外的IP和端口了。

既然用户所使用的浏览器,只看到ingressnginxcontroller所对外暴露的IP和端口,那么之后前端app访问后端app获取数据,就都在同一个ingressnginxcontroller所对外暴露的IP和端口下,这样对浏览器来说,就不存在CORS的跨域问题了。如图9所示。

2.5.4如何从坑里爬出来

要从坑里爬出来,就需要新增k8s的deployment、service和ingress的配置文件,以便使用kubectl命令将ingress和postgres、shopping-list-api和shopping-list-front-end这3个微服务部署到k8s上。

注意,ingress不是微服务,而是k8s里的一组规则。

另外,每个微服务的k8s部署,一般都需要一个deployment文件和一个service文件。前者供k8s为这个微服务创建pod,后者供k8s为这个微服务的pod分配稳定的ip地址以及DNS名称。即使容器实例被替换,ip地址以及DNS名称也不会改变。

Pod是k8s管理的最小单元,里面推荐只运行一个dockercontainer,这样才算微服务。

配置ingress需要一个ingress配置文件。因为要在k8s里配置3个微服务,所以需要新增3个deployment文件和3个service文件。

此外,原先在本地使用的pgadmin数据库管理工具,在k8s云集群中,就不再使用了。

改动的代码文件列表如下:

back-end/src/main/resources/application.properties(改动)Back-end/src/main/ShoppingListApplicationConfig.java(改动)front-end/Dockerfile(改动)front-end/src/components/ShoppingList.vue(改动)front-end/entrypoint.sh(新增)infrastructure/deployment-postgres.yml(新增)infrastructure/ingress.yml(新增)infrastructure/deployment-shopping-list-api.yml(新增)infrastructure/deployment-shopping-list-front-end.yml(新增)infrastructure/service-postgres.yml(新增)infrastructure/service-shopping-list-api.yml(新增)infrastructure/service-shopping-list-front-end.yml(新增)为了减轻你写代码的负担,我把这些改动和新增保存到了分支for-azure-k8s-service中。运行命令`gitcheckoutfor-azure-k8s-service`就能看到进行了这些改动和新增后的代码。

由于代码改动涉及后端和前端,所以要重新构建后端和前端的dockerimage。

首先把数据库跑起来,以便构建代码时运行测试。进入项目文件夹,运行命令`cdinfrastructure`进入这个子文件夹。然后再运行命令`dockercomposeuppostgrespgadmin`启动postgres数据库和pgadmin管理工具。

然后新打开一个terminal窗口,进入项目文件夹,运行`cd../back-end`,进入后端文件夹。因为后端app所依赖的数据库主机名,现在已经改为环境变量${DB_HOST}了,所以在构建前,需要在terminal窗口中,运行命令`exportDB_HOST=localhost`来设置环境变量。

之后,可以运行命令`./gradlewcleanbuild`来生成后端jar包。

然后运行命令`dockerbuildxbuild--build-argJAR_FILE=build/libs/shoppinglist-0.0.1-SNAPSHOT.jar-t/shopping-list-api:v1.1.k8s.`来构建后端dockerimage。注意,为了和之前为dockercompose构建image做区分,上面命令中的tag改为`v1.1.k8s`。可以运行命令`dockerimagels`查看新构建的带有`v1.1.k8s`tag的image。

[小心坑!如果用arm64架构的mac构建image而不做架构设定会怎样?]

我按之前为dockercompose构建前端dockerimage的方式,为azurek8sservice构建了前端dockerimage。但等我把前端的deployment文件apply到k8s云集群时,pod在启动时总是报一个奇怪的错误:exec/usr/local/bin/docker-entrypoint.sh:execformaterror。

把这个image拉下来,运行一个容器,然后进去看文件docker-entrypoint.sh的内容,也看不出所以然。后来查了半天,才知道原因在于我用arm64架构的mac在构建image时,没有指定所构建的image应该是amd64架构的。

如果用arm64架构的mac构建image,而不在命令中做架构设定,那么所构建的image就只能用于arm64架构的容器运行系统里,这也是我之前能正常在mac上的dockercompose里运行不带架构设定而构建出的image的容器的原因。但我在azurek8sservice云集群里所申请的资源,一般都是只能运行amd64架构的容器。

要爬出这个坑需要做两件事。

第一,需要在~/.docker/config.json文件中,增加下面的配置,以便让dockerbuildx能够支持在Macarm64架构的电脑上,构建amd64架构的image。

`{"experimental":"enabled"}`

第二,在dockerbuildx命令中,增加指定架构的参数。可以在项目文件夹中,运行`cd../front-end`,进入前端文件夹。运行命令`dockerbuildxbuild--platformlinux/amd64-t/shopping-list-front-end:v1.1.k8s.amd64.`来构建前端dockerimage。可以运行命令`dockerimagels`查看新构建的带有`v1.1.k8s.amd64`tag的image。还可以运行命令`dockerinspectwubin28/shopping-list-front-end:v1.1.k8s.amd64|grep“Architecture"`查看这个image是否真的是amd64架构的。

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

我们在k8s云集群里为这个webapp所创建的资源,最好都放到一个namespace里,这样便于管理。将来不用云服务了,要删除一个namespace里所有资源以便省钱,也就是运行一条命令的事儿。具体如何做,见下文“清理现场”。

因为每个命令一般都有挂上$NAMESPACE,所以把它设置到环境变量里比较方便:`exportNAMESPACE=shopping-list-web-app`。然后可以运行`kubectlcreatenamespace$NAMESPACE`来创建这个namespace。

前面讲到,在一个操作系统里安装工具,最好用包管理器。这样便于维护工具的版本。对于云计算操作系统k8s来说,helm就是这样的包管理工具。我们可以用helm来安装ingress-nginx:

接下来就可以用kubectl,运行下面命令,来往k8s云集群里部署postgres、shopping-list-api、shopping-list-front-end和ingress了。

运行命令`kubectldeletenamespace$NAMESPACE`,就可以删除该namespace下所有资源。

如果你的azurek8sservice云服务免费试用快到期了,记得删除下面的资源:my-k8s-cluster-1、my-azure-resource-group-1和Azuresubscription1。

[小心坑!在免费期到期前不要忘记删除k8s云集群中的所有资源]

在微软、谷歌、亚马逊、阿里、腾讯这样的云平台申请了带有免费试用期的账号,如果暂时不用,在试用期到期前,一定记得删除k8s云集群中的所有资源,否则就太破费了。你会遇到云刺客。

THE END
1.基于python+django+mysql的超市管理系统源码+项目说明(计算机毕设本资源是一个基于Python、Django和MySQL的超市管理系统源码及项目说明,旨在为计算机专业的学生提供一个实际项目的参考案例。通过这个项目,学生可以学习到如何使用Django框架进行Web开发,以及如何与MySQL数据库进行交互。该超市管理系统涵盖了商品管理、库存管理、销售记录等功能模块,帮助学生理解一个完整的电商系统的运作流程https://download.csdn.net/download/2401_87429224/90098215
2.Python版超市管理系统源代码Python版超市管理系统源代码汽车电子技术 ? 来源:Python代码大全 ? 作者: Python代码狂人 ? 2023-02-24 09:59 ? 1640次阅读 Python版超市管理系统源代码,基于django+mysql安装步骤1、在mysql中创建名为demo_django_supermarket的数据库,修改config/setting.py中数据库用户及密码https://www.elecfans.com/d/2017966.html
3.WPF超市管理系统+源代码+详细说明WPF超市管理系统 + 源代码 + 详细说明!点赞(0) 踩踩(0) 反馈 所需:3 积分 电信网络下载 u012905769 2019-03-18 14:53:59 评论 11年的老代码源码下载及讨论地址:http://www.51aspx.com/Code/SuperMarketManageSysu011645524 2018-04-13 15:08:41 评论 很简单,入门可以看下https://www.coder100.com/index/index/content/id/974780
4.超市账单管理系统练习源代码司徒魏源早几天,老师让我们做一个超市账单管理系统,做了一半之后,不想做了,发奋一样上网找源代码做参考,结果全部都要钱,或积分,逗~吐血~~~ 硬着头皮坐下来了,不容易啊,对于初学者来说. 先写属性 Bill属性 Provider属性 User属性 dao层 BillDao接口 ProviderDao接口 https://www.cnblogs.com/stwy/p/7862339.html
5.简单收银系统完整源代码Java单机超市管理系统源代码,很适合大一,大二朋友的课程设计参考,内容只有Java语言,不含其它知识点。 上传者:u011330132时间:2014-08-15 旺旺收银管理系统源码.rar 旺旺收银管理系统源码.rar,资料齐全,带有数据库 上传者:weixin_44953966时间:2021-05-23 https://www.iteye.com/resource/qq_36947556-10634356
6.超市商品管理系统源代码20220528122322.doc超市商品管理系统源代码.doc 14页内容提供方:74642836 大小:57 KB 字数:约1.53万字 发布时间:2022-05-30发布于湖南 浏览人气:97 下载次数:仅上传者可见 收藏次数:0 需要金币:*** 金币 (10金币=人民币1元)超市商品管理系统源代码.doc 关闭预览 想预览更多内容,点击免费在线预览全文 免费在线预览https://max.book118.com/html/2022/0528/7145112053004125.shtm
7.淼迈云收银是超市收银系统便利店收银系统源码提供商!可定制开发淼迈云收银是一款适用于大型超市收银管理,小型超市收银管理,连锁店、便利店收银管理的超市收银系统支持定制开发。提供最人性化的超市收银软件,无人超市收银系统解决方案。淼迈云收银软件支持多种支付方式:会员余额、现金结算、微信支付、支付宝支付、优惠券、积分抵用、http://miaomaiyun.com/
8.3.2.1管理员登录10职场大变样社区职场大变样社区是一个学习资源分享社区,提供编程视频、项目源代码、毕业设计、编程书籍、中小学电子课本等学习资料,意在打造一个高质量的线上学习资源分享论坛社区http://www.zcdby.com/
9.springboot酒店预订管理管理springboot超市管理系统spring接网站建设、小程序、H5、APP、各种系统等,单片机、嵌入式也可以做 选题+开题报告+任务书+程序定制+安装调试+论文+答辩ppt 都可以做 序号项目github地址 作者微信:grapro666 QQ:931708230 (支持修改、 部署调试、 支持代做毕设) 接javaweb、python、小程序、H5、APP、各种管理系统、单片机、嵌入式等开发 https://github.com/ynwynw/allProject