2024程序员容器化上云之旅-第4集-Ubuntu-WSL2-Windows11版:夺取宝剑

故事梗概

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

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

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

6 夺取宝剑

🔥阅读Nigel Poulton的书,自学完Docker后,马意浓知道,前后端App,各自都要制作成docker image,先部署到本地docker compose里,之后再部署到k8s云集群里。

✅这是因为Docker提供了一个完整打包app所有依赖项的一致的环境,确保应用在开发、测试和生产环境中的行为一致。

这就能实现在测试环境中所测试的image,就是在生产环境所部署的

这是解决“在我这运行得好好的,怎么在你那不行”的问题的关键。

✅此外,将前端和后端应用容器化,需要使用等同于代码的配置文件

这种基础设施即代码的实践,能让配置的更改广而告之,配置的执行有据可查

这是解决“谁改了配置又不告诉大家?”问题的关键。如图1。


图1 Docker能提供完整打包app所有依赖项的一致的环境,以及让配置的更改广而告之,配置的执行有据可查

6.1 前后端App均部署到本地docker compose中的架构图

马意浓稍微修改了之前绘制的前后端App部署到本地Gradle/npm开发环境的架构图。

其实只是将前后端App的部署环境,都改成了docker compose。如图2。


图2 前后端App的部署环境都改成了docker compose

该如何让前后端App,都在本地docker compose里运行起来呢?

马意浓启动了Docker Desktop,并确认已经用自己的docker hub账号登录。

6.2 用gradle构建后端app并生成jar包

马意浓想要让所生成的后端app的docker image,仅包含刚好够运行的jar包,及其依赖项。

这样的docker image就能做到尽可能地小,以节省将其推送到Docker Hub的时间。

他于是决定,先用gradle命令构建后端app并生成jar包,然后再设法将其构建为docker image。

他打开一个Ubuntu终端窗口,进入项目文件夹中的infrastructure子文件夹。

接着运行命令docker compose up postgres pgadmin,启动了postgres数据库和pgadmin管理工具,为gradle构建做好了准备。

他又新打开一个Ubuntu终端窗口,进入项目文件夹中的back-end子文件夹。

他运行命令sdk use java 17.0.10-tem,设置好jdk当前版本。

之后,他运行命令./gradlew clean build,开始构建后端app。

等到屏幕出现了BUILD SUCCESSFUL字样后,他在文件夹build\\libs里,找到了刚刚生成的jar包shoppinglist-0.0.1-SNAPSHOT.jar

6.3 构建后端app的docker image

马意浓又回到了back-end文件夹。因为他知道,这个文件夹里有运行docker命令所需的Dockerfile文件。

他打算使用docker buildx build命令,因为这是对旧的docker build命令的扩展。

他从资料中发现,相比后者,前者提供了多平台构建、改进的构建缓存机制以及灵活的构建结果输出等新功能。

他输入命令docker buildx build --build-arg JAR_FILE=build/libs/shoppinglist-0.0.1-SNAPSHOT.jar -t <docker-hub-username>/shopping-list-api:v1.1.local-docker-compose .,来构建后端docker image。

(注:需要把<docker-hub-username>换成你的docker hub账号名。下同。)

他特别留心命令最后的一个不起眼的小数点没有忘记写。

因为他知道,小数点代表把当前文件夹。

这作为build命令的上下文,以找到所需的jar文件,作为构建资源。

在执行这个命令前,他又仔细检查了参数-t <docker-hub-username>/shopping-list-api:v1.1.docker-compose

他知道,-t指的是,给image加一个tag,用于标识这个image。

如果以冒号:分界,这个参数的前半段<docker-hub-username>/shopping-list-api,是这个image将来要推送到的Docker Hub上的镜像库(repository)的名称。

他觉得把后端app的docker image命名为shopping-list-api,会更加简洁。

而参数的后半段v1.1.local-docker-compose,是这个image的tag,用来标识image的这次构建的版本号。

他按下回车,执行这个命令。

等这个命令执行完,他运行命令docker image ls,验证后端app的docker image是否构建成功。

屏幕显示出新构建的image,确实带有<docker-hub-username>/shopping-list-api的repository,以及v1.1.local-docker-compose 的tag。这表明image构建成功了。

他在Docker Desktop的Images里,也看到了这个新构建的后端app的docker image。如图3。


图3 他在Docker Desktop的Images里,也看到了shopping-list-api这个新构建的后端app的docker image

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

马意浓紧接着,运行命令git tag -a v1.1.local-docker-compose -m "v1.1.local-docker-compose",在git库里打了一个与docker image的tag同名的tag。

他知道,随着不断提交,代码库中的代码总是在不断变化。

总有一天,他推送到Docker Hub中的image会有bug。那时若想打开对应的源代码看一下,那该看git代码库中哪一次提交后的代码?

但如果他当时在构建docker image后,立即在git库里打一个同名的tag,那么就好定位代码了。

他又运行命令git push origin v1.1.local-docker-compose,把这个tag推送到远程git库中。

他接着运行命令git ls-remote --tags origin,确认这个tag已经成功推送到远程git库中了。

6.5 将后端app的docker image推送到docker hub

因为已经在Docker Desktop里登录Docker Hub了,所以马意浓直接运行命令docker push <docker-hub-username>/shopping-list-api:v1.1.local-docker-compose,将构建好的image推送到Docker hub。

等命令执行完,没有看到错误信息,他就在浏览器访问自己的Docker hub页面。

他在自己的shopping-list-api这个repository里,找到了tag是v1.1.local-docker-compose的image。这表明image推送成功。

下一步,他要构建前端app到docker image,并将其推送到docker hub。

6.6 用Dockerfile里的npm构建前端app的docker image

马意浓知道,构建前端app的docker image的过程,与后端app有些不同。

不同点就是前端app的构建命令npm run build,已经纳入前端app的Dockerfile文件里了。而不像后端app那样,构建命令在Dockerfile之外。

他运行命令进入前端文件夹front-end。

他又运行命令docker buildx build -t <docker-hub-username>/shopping-list-front-end:v1.1.local-docker-compose .,来构建前端app的docker image。

等命令执行完,他运行命令docker image ls,查看新构建的image,确实带有<docker-hub-username>/shopping-list-front-end的repository,以及v1.1.local-docker-compose 的tag。

这表明image构建成功了。

他在Docker Desktop里的Images里,也看到了这个新构建的前端app的docker image。

按理说,构建完前端app后,也应该在git代码库打同名的tag,以对应刚刚构建的docker image版本。

但他觉得从现在到上次在git库打tag这段时间,没有改代码,而且tag的名称也没变,所以他决定省略这一步。

6.7 将前端app的docker image推送到docker hub

马意浓运行命令docker push <docker-hub-username>/shopping-list-front-end:v1.1.local-docker-compose,将构建好的image推送到Docker hub。

他访问自己的Docker hub,在自己的shopping-list-front-end这个repository里,找到了tag是v1.1.local-docker-compose的image。这表明image推送成功。

6.8 在本地docker compose里运行前后端App

做足了前面的功课,马意浓知道,现在该是享受胜利果实的时候了。

因为在本地docker compose里运行前后端app的命令,超级简单。

他进入项目文件夹,然后运行命令cd infrastructure,进入这个子文件夹,

他打开docker-compose.yml文件,仔细确认了shopping-list-apishopping-list-front-endimage中配置的v1.1.local-docker-compose这样的tag,确实与之前的命令中的tag一致。

他又检查了一下docker desktop的Containers界面,发现之前为后端app打包而准备的postgres和pgadmin容器还在运行,于是他运行清理现场的命令docker compose down,将两个容器关闭并删除。

之后他运行命令docker compose up,来启动docker-compose.yml文件中配置好的那4个容器。

他特意在这个命令中,没有添加表示detach-d参数,以便观察命令执行中的输出信息是否有错误。

屏幕输出没有任何错误信息,而且最后显示Started ShoppingListApplication字样。这表示前后端App已经成功运行。

他在docker desktop里,能看到这4个容器都在正常运行。

他于是在里面用鼠标点击shopping-list-front-end-1那一行右侧的8080:8080链接,浏览器应声打开,显示了购物清单Web应用的界面。

🔥他在里面添加了一个购物项an apple。这个购物项便顺利地出现在下面的购物清单中!

他兴奋地挥拳庆贺。

至此,前后端分离的Shopping List Web App在本地docker compose里运行成功了。

6.9 清理现场

他又新打开一个Ubuntu终端窗口,进入项目文件夹中的infrastructure子文件夹,然后运行命令docker compose down

他打开docker desktop,看到Containers界面已经没有任何容器在运行了。现场清理结束。

😃马意浓很兴奋。现在前后端分离的Web应用的容器化这把宝剑,他已经拿到手里了。

接下来,他要挥剑,向k8s上云的新目标迈进。

💔但他心里隐隐有些不安。

因为对他来说,K8s云集群是个完全陌生的环境。他预感会碰到更大的障碍。

🔥【未完待续


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

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

🔥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云集群上,并能顺利使用后,马意浓把整个容器化和上云之旅,写成系列文章,分享给其他程序员。


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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Coursera吴恩达机器学习专项课程02:Advanced Learning Algorithms 笔记 Week01

Advanced Learning Algorithms Week 01 笔者在2022年7月份取得这门课的证书&#xff0c;现在&#xff08;2024年2月25日&#xff09;才想起来将笔记发布到博客上。 Website: https://www.coursera.org/learn/advanced-learning-algorithms?specializationmachine-learning-in…

3. Java中的锁

文章目录 乐观锁与悲观锁乐观锁(无锁编程,版本号机制)悲观锁两种锁的伪代码比较 通过 8 种锁运行案例,了解锁锁相关的 8 种案例演示场景一场景二场景三场景四场景五场景六场景七场景八 synchronized 有三种应用方式8 种锁的案例实际体现在 3 个地方 从字节码角度分析 synchroni…

亿道推出重磅加固平板!为行业发展注入新动力

随着科技生产力的不断发展&#xff0c;各行各业都得到质的飞跃。产品的迭代速度也大大加快&#xff0c;作为全球领先的加固行移动终端一站式提供商&#xff0c;亿道信息跟紧时代潮流&#xff0c;推出EM-I10J、EM-I20J两款均衡型加固平板&#xff0c;为行业发展注入新动力。 接地…

.[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞

有朋友oracle数据库所在机器被加密,扩展名为&#xff1a;.[hudsonLcock.li].mkp,数据文件类似&#xff1a; 通过专业工具分析,确认这次运气非常好,每个文件就加密破坏前面31个block 通过研发的Oracle数据文件勒索恢复工具进行恢复 顺利数据库并且导出数据 mkp勒索病毒预…

【大厂AI课学习笔记NO.55】2.3深度学习开发任务实例(8)模型训练

作者简介&#xff1a;giszz&#xff0c;腾讯云人工智能从业者TCA认证&#xff0c;信息系统项目管理师。 博客地址&#xff1a;https://giszz.blog.csdn.net 声明&#xff1a;本学习笔记来自腾讯云人工智能课程&#xff0c;叠加作者查阅的背景资料、延伸阅读信息&#xff0c;及学…

CDQ分治详解,一维、二维、三维偏序

文章目录 零、偏序关系一、一维偏序二、二维偏序三、三维偏序(CDQ)3.1CDQ分治3.2CDQ分治解决三维偏序的流程 四、OJ练习4.1三维偏序模板题4.1.1原题链接4.1.2AC代码 4.2老C的任务4.2.1原题链接4.2.2解题思路4.2.3AC代码 4.3动态逆序对4.3.1原题链接4.3.2解题思路4.3.3AC代码 零…

C# 学习第二弹

一、变量 存储区&#xff08;内存&#xff09;中的一个存储单元 &#xff08;一&#xff09;变量的声明和初始化 1、声明变量——根据类型分配空间 ①声明变量的方式 —变量类型 变量名 数值&#xff1b; —变量类型 变量名&#xff1b; 变量名 数值&#xff1b; —变…

使用R语言进行主成分和因子分析

一、数据描述 数据来源2013年各地区水泥制造业规模以上企业的各主要经济指标&#xff0c;原始数据来源于2014年&#xff08;《中国水泥统计年鉴》&#xff09;&#xff0c;试对用主成分和因子进行经济效益评价。 地区,企业个数&#xff08;亿元&#xff09;,流动资产合计&…

python Matplotlib Tkinter-->最终框架一

3D雷达上位机实例(能够通过点击柱状图来展示3D雷达数据)2024.2.26 环境 python:python-3.12.0-amd64 包: matplotlib 3.8.2 pillow 10.1.0 import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk impor…

基于Springboot + Vue 母婴商城系统

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 二、开发技术与环…

基于Java SSM框架实现驾校预约管理系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现驾校预约管理系统演示 摘要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff0c;驾校预约管理系统当然也不能排除在外&#xff0c;随着网络市场的不断成熟&#xff0c;带动了驾校…

【BUG 记录】史诗级 BUG - MYSQL 删库删表却没有备份如何恢复数据

【BUG 记录】史诗级 BUG - MYSQL 删库删表却没有备份如何恢复数据 1. 问题描述2. 解决方案&#xff08;binlog&#xff09;2.1 构造测试环境2.2 查看 MySQL 环境是否开启 binlog2.3 查看所有的 binlog 日志记录2.4 查看当前正在使用的是哪一个 binlog 文件2.5 查看此时的 binlo…

设计并实现一个并发安全的LRU(Least Recently Used,最近最少使用)缓存结构

文章目录 前言实战演示写在最后 前言 相信很多人都使用过LinkedHashMap&#xff0c;LinkedHashMap中的removeEldestEntry可以删除老旧的元素&#xff0c;我们可以以此来实现一个LRU缓存结构&#xff0c;并结合java中JUC包中的各种多线程锁机制来保证多线程安全。 以下是我遇见…

C# OpenCvSharp DNN Yolov8-OBB 旋转目标检测

目录 效果 模型信息 项目 代码 下载 C# OpenCvSharp DNN Yolov8-OBB 旋转目标检测 效果 模型信息 Model Properties ------------------------- date&#xff1a;2024-02-26T08:38:44.171849 description&#xff1a;Ultralytics YOLOv8s-obb model trained on runs/DOT…

Windows常用协议

LLMNR 1. LLMNR 简介 链路本地多播名称解析(LLMNR)是一个基于域名系统(DNS)数据包格式的协议,可用于解析局域网中本地链路上的主机名称。它可以很好地支持IPv4和IPv6&#xff0c;是仅次于DNS 解析的名称解析协议。 2.LLMNR 解析过程 当本地hosts 和 DNS解析 当本地hosts 和 …

Linux浅学笔记04

目录 Linux实用操作 Linux系统下载软件 yum命令 apt systemctl命令 ln命令 日期和时区 IP地址 主机名 网络传输-下载和网络请求 ping命令 wget命令 curl命令 网络传输-端口 进程 ps 命令 关闭进程命令&#xff1a; 主机状态监控命令 磁盘信息监控&#xff1a…

2018-02-14 新闻内容爬虫【上学时做论文自己爬新闻数据,原谅我自己懒发的图片】

2018-02-14新闻内容爬虫【上学时做论文自己爬新闻数据&#xff0c;原谅我自己懒发的图片】资源-CSDN文库https://download.csdn.net/download/liuzhuchen/88878591爬虫过的站点&#xff1a; 1QQ新闻 1&#xff0c;准备爬取滚动新闻页面 2 通过F12 开发工具查找发现&#xff…

Qt项目:网络1

文章目录 项目&#xff1a;网路项目1&#xff1a;主机信息查询1.1 QHostInfo类和QNetworkInterface类1.2 主机信息查询项目实现 项目2&#xff1a;基于HTTP的网络应用程序2.1 项目中用到的函数详解2.2 主要源码 项目&#xff1a;网路 项目1&#xff1a;主机信息查询 使用QHostI…

SIMON 32/64加密电路的实现(System Verilog)

关于SIMON加密电路的原理&#xff0c;参考之前发布的博文【SIMON加密算法的原理】 1.总览与电路介绍 1.1 电路总体结构图 1.2 模式配置介绍 SIMON加密算法的分组长度、密钥长度以及必要的参数配置如下图&#xff1a; 本次需要实现的是SIMON 32/64&#xff0c;即分组长度2n3…

【数据结构】B树,B+树,B*树

文章目录 一、B树1.B树的定义2.B树的插入3.B树的中序遍历 二、B树和B*树1.B树的定义2.B树的插入3.B*树的定义4.B树系列总结 三、B树与B树的应用 一、B树 1.B树的定义 1. 在内存中搜索效率高的数据结构有AVL树&#xff0c;红黑树&#xff0c;哈希表等&#xff0c;但这是在内存…