Docker入门笔记(1)

Docker入门笔记(1)

容器技术入门

之前我的WIT问卷管理系统在阿里云上部署需要好多配置,各个环境耦合的比较紧密,花了不少时间去做部署和调配。

现在有了Docker以后,我们可以把各种组件配置好,然后打包成镜像使用Docker直接一键部署,实现开箱即用。

Docker部署

这里使用阿里云ECS作为Linux终端进行部署,系统为Ubuntu22.04。

  1. 安装工具

    sudo apt-get install ca-certificates curl gnupg lsb-release
    
  2. 安装GPG Key

    sudo mkdir -p /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    
  3. 将Docker的库添加到apt资源列表

    echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    
  4. 再次更新apt

  5. 安装Docker CE版本

  6. 将当前用户添加到Docker用户组

[案例]使用Docker部署Nginx

直接执行

sudo docker run -d -p 80:80 nginx

如果没有配置过安全组,记得在阿里云后台的安全组配置里开启HTTP的80接口访问权限,不然外网会访问失败

image-20240311143528906

轻松地部署好了Docker

从虚拟机到Docker

一般来说,服务器具有远超家用PC的资源,比如说CPU核心数量,网络带宽,内存大小等,为了让这些资源更高效的利用,我们就需要用到虚拟机。

我们可以通过虚拟化技术把物理硬件变成可以按需分配给每一台虚拟机,然后在虚拟机上运行我们编写的服务程序。

如果我们要部署一个大型项目,为了安全稳定和高效,就需要部署服务器集群,如果我们采用传统的部署方式,需要逐台调试每台虚拟机的环境,最后还需要联调,这会耗费我们大量的时间精力。

之前上线WIT问卷系统到阿里云时,由于是第一次部署项目上云,需要配置很多环境,比如说mysql,java,redis,rabbitmq,nginx的环境全都需要逐一配置,非常繁琐

随着云服务的发展繁荣,容器技术走上历史舞台,Docker应运而生。

Docker的集装箱是一只驮着集装箱的鲸鱼,它也表现了Docker一个最大的特性,每个集装箱其实是一个程序的环境+应用程序,他们可以基于Docker提供的环境在多平台上平稳运行,无需额外配置环境

我们可以通过Docker将一个组件打包成一个轻量级、可移植、自包含的容器,其可以运行在几乎所有的OS上

Docker工作机制简述

image-20220630184857540

Docker主要分为三个部分

  • Docker客户端:我们之前的docker指令是在客户端上执行的,客户端会把操作发送到服务端处理
  • Docker服务端:服务器是启动容器的主体,一般也是作为服务在后台运行,其支持远程连接
  • Register仓库:其可以存放Docker镜像,都看Docker了应该没有人没学过Maven吧,和maven一样,Docker也分为公有和私有,当需要时,Docker会从远程仓库下载Docker镜像到本地运行

当我们需要部署一个已经打包好的应用和环境,只需要通过docker下载已经打包好的镜像即可

我们之前输入sudo docker run -d -p 80:80 nginx后,Docker其实执行了以下操作

  1. Docker客户端将操作发送给服务端
  2. Docker服务端在本地仓库查找对应镜像,若没有,则从服务器上下载到本地
  3. 加载本地的镜像,启动容器开始运行(容器之间,容器与外部之间都是互相隔离的,互不影响)

一句话,Docker开箱即用


容器与镜像

初识容器镜像

简单了解一下镜像的相关操作,以官方提供的hello-world为例子

docker pull hello-world

一个镜像的名称是有两个部分组成的,repository和tag,tag表示版本

docker pull 名称:版本

pull之后镜像会存放在本地,需要的话需要run

docker run hello-world

不想要立刻执行容器,则可以换成

docker create hello-world

启动成功以后,可以输入ps查看容器列表

docker ps -a

这里的-a是为了看到所有容器,若不加-a,则只会显示当前正在运行的容器

我们在对某个容器进行操作的时候,需要输入容器的id或者名称,如果我们采用默认的名称,会难以记录和区分,我们可以在run时添加--name参数来为容器命名

docker run --name=hantou hello-world

我们可以手动使用start来开启处于停止状态的容器(我们在run一个非持续性的程序时,它执行完了就结束了,就会被终止;比如说之前的hello-world)

docker start <容器名称/id>

如果想手动停止容器直接输入stop就行了

docker stop <容器名称/id>

重启容器

docker restart <容器名称/id>

删除容器(只有非运行状态的容器才能被删除)

docker rm <容器名称/id>

设置运行后自动删除容器

docker run --rm 镜像名称

删除镜像

docker rmi 镜像名称

查看本地镜像

docker images

镜像结构介绍

镜像是容器的基石,有了镜像才能创建容器实例,接下来我们就要浅浅研究一下镜像的基本结构

我们在打包项目的时候往往需要一个基本的环境,比如说数据库、缓存等等,这样我们才能基于这个系统来安装软件,这种基本的系统镜像我们称之为base镜像

一般的base镜像就是各个Linux系统的发行版,比如说Ubuntu、Centos等

我们还是以centos为例子

docker pull centos

这里解释下base镜像的机制

image-20240311234214834

Linux操作体系由内核和用户空间组成,内核空间是Linux的核心,Linux启动后会先加载bootfs文件系统,然后在加载完毕后卸载bootfs,然后再加载用户空间的文件系统,而这一层正是我们可以操作的部分

  • bootfs包含了BootLoader和Linux内核,用户无权修改
  • rootfs则包含了我们常常操作的较为熟悉的linux目录结构

base镜像底层会直接调用宿主机的内核,也就是说,镜像与宿主机linux内核保持一致

可以使用uname指令来查看当前内核版本

我们来启动下刚才下载的centos的base镜像

docker run -it centos

这里的-it是开启一个标准的数据接口并且分配一个伪tty设备,其可以支持终端登录,如果不同时使用这两个的话,base容器会在启动后自动终止

我们输入exit就可以退出base容器了

再次启动时需要加入-i才能在前台启动

docker start -i <容器名称/id>

image-20240311234816544

我们在基于base镜像的基础上,可以进行软件的安装与适配,我们可以一层一层的对镜像进行封装,这样的多层结构可以让软件环境自由的组合,让他们互相之间可以拼装使用。

可以看见图上的最上层有一层可写容器层,它有什么作用呢?

所有的镜像在组合后应该要叠加形成一个统一的文件系统,如果镜像之间的文件系统保持独立的话,那么一层一层的叠起来就很难操作

所以Docker为我们提供了可写容器层,我们可以通过修改读写层中的数据来访问下面镜像中的文件,各个操作如下

  • 文件读取:要读取一个文件,Docker会最上层往下依次寻找,找到后则打开文件。
  • 文件创建和修改:创建新文件会直接添加到可写容器层中,修改文件会从上往下依次寻找各个镜像中的文件,如果找到,则将其复制到可写容器层,再进行修改。
  • 删除文件:删除文件也会从上往下依次寻找各个镜像中的文件,一旦找到,并不会直接删除镜像中的文件,而是在可写容器层标记这个删除操作。

我们对容器内文件的操作,都是基于最上层的可写容器层来进行的,这样就可以保护镜像的完整性

构建镜像

我们可以手动的构建自己需要的镜像,构建镜像有两种方式

  • 使用commit命令来完成
  • 使用DockerFIle来完成

这里先看第一种

我们以Ubuntu镜像为例

首先从仓库中拉取ubuntu镜像

docker pull ubuntu

然后直接启动

docker run -it ubuntu

接着安装一下jdk8

apt install openjdk-8-jdk

完成安装后我们就可以使用commit来提交当前的容器,并保存为新的镜像

docker commit 容器名称/id 新的镜像名称

再查看一下镜像仓库,就可以看见我们刚才创建的带有jdk8的centos镜像了

image-20240311235957633

可以看见装了jdk的镜像比原来的镜像大了好几倍,但我们可以直接通过这个镜像来启动一个带有java环境的容器了。

虽然但是,Docker官方并不推荐这样创建新镜像,因为这种容器就是一个黑箱了,使用者很难知道这个镜像内有什么,安全性低;同时要一个一个的构建这样的镜像也很费事。

下面使用Dockerfile的形式来创建一个同样的镜像

首先新建一个名为Dockerfile的文件

vim Dockerfile

然后在里面编写如下的指令来告诉Docker我们需要什么

FROM ubuntu
RUN apt update
RUN apt install -y openjdk-8-jdk

其实文件里的内容刚跟之前手动执行的差不多

我们保存文件后来告诉Docker要按照这个文件来创建镜像

docker build -t <镜像名称> <构建目录>

按回车,Docker就会执行我们的文件内的指令

image-20240312002045647

执行中的每一步我们都可以很清晰直观的看见(Docker镜像有缓存机制,就算现在中途退出了,然后重新build一遍,Docker也会将之前构建好的镜像拿来用,需要注意的是,底层发生变化会导致其所有上层的缓存失效)

构建好了我们就可以在本地镜像仓库看见它了

image-20240312001650479

因为实际山执行的步骤和手动设置是一样的,所以他们打包的大小也几乎一致

但是我们可以使用histry来查看它的构建历史,它保存了我们刚才执行的操作和之前他人的操作

image-20240312002406181

而我们手动通过commit来创建的镜像则没有保存我们刚才手动提交的记录

image-20240312002532262

发布远程镜像到仓库

Docker这玩意某种意义上是不是跟Git很像?Git有GitHub,那我们Docker自然也得安排上DockerHub

首先在DockerHub官网上注册一个账号,然后创建一个仓库,创建过程不多赘述了,都学Docker了应该都用过github吧,大差不差的

这里我们创建好Docker仓库后,就可以上传本地的镜像了,最好把名称改的规范一点,这里使用tag来打标签

docker tag ubuntu-java-file:latest 用户名/仓库名称:版本

image-20240312003505435

接着我们需要登录一下docker

docker login user -u <用户名>

登录成功后就可以上传了

docker push <镜像名>:版本

阿里云的小水管上传了好久。。。

image-20240312003832450

最后上传好了就可以在之前创建的DockerHub仓库中看见了

刚才创建的仓库如果是公开仓库的话就可以被随意的下载,这里就可以先删除本地的镜像,然后从我们刚才创建的仓库中拉取镜像

先搜索一下仓库里存不存在这个镜像

docker search hantou/hantou_repo

image-20240312004437243

接下来选择我们要下载的

docker pull hantou/hantou_repo:1.0

由于镜像在上传后会被压缩,所以拉取下来的镜像比我们实际上传的600多m要小不少

这就是大概的DockerHub的基本操作


实战:使用IDEA构建SpringBoot程序的镜像

这里就以我之前写的WIT问卷管理系统为例子吧。

首先在之前写好的SpringBoot项目中新建一个DockerFile

在Dockerfile中写入我们的base镜像,之前我已经创建好了并且传到docker仓库了,这里就直接拉取

image-20240312095124511

接下来需要连接我们虚拟机/云服务器下的docker服务

这里我用的是阿里云

这里需要配置Docker的服务器,也就是我们在Ubuntu服务器安装的Docker,这里我们填写服务器相关信息,我们首选需要去修改一下Docker的一些配置,开启远程客户端访问:

sudo vim /etc/systemd/system/multi-user.target.wants/docker.service 

打开后,添加高亮部分:

image-20220701202846707

修改完成后,重启Docker服务

sudo systemctl daemon-reload
sudo systemctl restart docker.service 

由于我们用的是云服务器,需要在后台开放2375 TCP连接端口

image-20240312095308125

现在接着在IDEA中进行配置:

image-20240312095323016

先在edit中添加一个服务器链接

新增一个server,选择tcp链接,输入tcp://IP:2375即可

image-20240312095849222

添加好以后我们接着对Springboot包用maven打包

image-20240312100911598

打包完成后我们将构建好的jar包导入Dockerfile

COPY target/my-project-backend-0.0.1-SNAPSHOT.jar app.jar

这里是使用copy指令将文件拷贝到docker的默认路径中

然后设置在容器启动时开启我们的java程序,这里通过CMD完成

CMD java -jar app.jar

CMD命令可以设定容器启动后执行的命令,EXPOSE可以指定容器需要暴露的端口,但是现在我们还没有学习网络相关的知识,所以暂时不使用,这里指定为我们启动Java项目的命令。配置完成后在左侧点击运行,如果出现Failed to deploy XXX Dockerfile: Dockerfile': Not connected to docker错误,在排除服务器未开放的情况下,可能是idea权限不足导致的,退出idea再以管理员身份重新运行即可

image-20240312102248151

在构建成功后我们就可以在Docker 服务器中看到我们刚才传上来的新镜像了

image-20240312102622470

在镜像中可以看见我们刚才添加Springboot的操作

image-20240312102745769

接着在IDEA中启动镜像

image-20240312103111610

image-20240312103129637

点击启动即可,这里有点小翻车,因为我的项目用的是jdk17,而我们得镜像里只安装了jdk8

image-20240312103325574

只需要把之前添加jdk的操作版本换成17即可

image-20240312104128830

更换后再次启动,就发现成功运行在docker里了,不过我这个项目还用到了Redis,Mysql和RabbitMQ,那些还没有在base镜像里配置,所以功能还无法完全实现,但是总而言之确实在docker里跑起来了

image-20240312104330393

我们尝试访问一下8080端口,会发现无法访问,这是因为docker容器内部和外部的网络是隔离的,如果我们想要访问容器的服务器,就需要将对应端口绑定在宿主机上,同时让宿主机也开放这个端口,这样才能实现容器内的网络连接

docker run -p 8080:8080 -d wit-questionnaire:1.1

配置完成后,点击重新创建容器

image-20240312105540935

这下端口映射成功了,这里再次强调,如果是云服务器,需要去安全组中开启对应的端口

image-20240312105336101

为了方便以后使用,我们还是可以把它推送到DockerHub去

直接在IDEA上操作

image-20240312105631278

image-20240312105640965

填写之前Dockerhub仓库的对应信息,点击ok就可以push到远程仓库了


参考视频:Docker 容器技术 已完结(2022 最新版)4K蓝光画质+杜比音效 从内卷到开摆

视频教程文档:Docker容器技术

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用ScottPlot库在.NET WinForms中快速实现大型数据集的交互式显示

前言 在.NET应用开发中数据集的交互式显示是一个非常常见的功能&#xff0c;如需要创建折线图、柱状图、饼图、散点图等不同类型的图表将数据呈现出来&#xff0c;帮助人们更好地理解数据、发现规律&#xff0c;并支持决策和沟通。本文我们将一起来学习一下如何使用ScottPlot库…

websocket逆向案例

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、案例地址二、分析流程三、逆向参数四、webSocket 交互位置总结 前言 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供…

OPPO后端二面,凉了!

这篇文章的问题来源于一个读者之前分享的 OPPO 后端凉经&#xff0c;我对比较典型的一些问题进行了分类并给出了详细的参考答案。希望能对正在参加面试的朋友们能够有点帮助&#xff01; Java String 为什么是不可变的? public final class String implements java.io.Seri…

‘UnityEngine.Application‘ does not contain a definition for isBatchMode

unity 2017.4.37f1. 解决办法: Try to replace Application.isBatchMode with UnityEditorInternal.InternalEditorUtility.inBatchMode

Ps:拾色器

在 Adobe 拾色器中&#xff0c;可以使用四种颜色模型来设置颜色&#xff1a;HSB、RGB、Lab 和 CMYK。 使用“拾色器”对话框可以设置前景色、背景色、填充颜色、文本颜色及专色等的颜色值。 ◆ ◆ ◆ 常用操作方法与技巧 1、注意观察“拾色器”对话框标题栏中括号里的内容&am…

Kafka MQ 生产者

Kafka MQ 生产者 生产者概览 尽管生产者 API 使用起来很简单&#xff0c;但消息的发送过程还是有点复杂的。图 3-1 展示了向 Kafka 发送消息的主要步骤。 我们从创建一个 ProducerRecord 对象开始&#xff0c;ProducerRecord 对象需要包含目标主题和要发送的内容。我们还可以…

windows ffmpeg 编译环境搭建

编译ffmpeg https://www.msys2.org/ https://www.ffmpeg.org/platform.html#Microsoft-Visual-C_002b_002b-or-Intel-C_002b_002b-Compiler-for-Windows 1.安装msys2 2.安装yasm或者nasm 打开VC 本地环境命令行 唤醒msys2界面 配置编译环境变量参数 export PATH"/d/vs…

Dynamo处理Excel——调用Microsoft.Office.Interop.Excel教程

你好&#xff0c;这里是BIM的乐趣&#xff0c;我是九哥~ 今天我们来聊聊如何通过Dynamo处理Excel数据以及格式&#xff0c;Dynamo自带的节点肯定是不行&#xff0c;所以我们需要来用Python解决&#xff08;当然有个节点包 Bumblebee&#xff0c;我在案例百解教程里有过介绍&a…

如何实现sam(Segment Anything Model)|fastsam模型

sam是2023年提出的一个在图像分割领域的大模型&#xff0c;其具备了对任意现实数据的分割能力&#xff0c;其论文的介绍可以参考 https://hpg123.blog.csdn.net/article/details/131137939&#xff0c;sam的亮点在于提出一种工作模式&#xff0c;同时将多形式的prompt集成到了语…

短剧在线搜索源码(全网首发)

一个非常哇塞的在线短剧搜索页面&#xff0c;接口已经对接好了&#xff0c;上传源码到服务器解压就能直接用&#xff0c;有能力的可以自己改接口自己写自己的接口 接口文档地址&#xff1a;doc.djcat.sbs 源码下载地址&#xff1a;https://pan.xunlei.com/s/VNstN8C6N3VK1a1k…

使用Docker在windows上安装IBM MQ

第一步、安装wsl 详见我另一篇安装wsl文章。 第二步、安装centos 这里推荐两种方式&#xff0c;一种是从微软商城安装&#xff0c;一种是使用提前准备好的镜像安装&#xff0c;详见我另一篇windos下安装centos教程。 第三步、安装windows下的Docker desktop 详见我另一篇wind…

【牛客】HJ62 查找输入整数二进制中1的个数

题目链接&#xff1a;查找输入整数二进制中1的个数_牛客题霸_牛客网 (nowcoder.com) 解题思路&#xff1a; 解法一: 可以举一个八位的二进制例子来进行分析&#xff0c;对于二进制操作&#xff0c;我们直到&#xff0c;除以一个2&#xff0c;原来的数字会减少一个0.如果除的过程…

Window API 使用的一些注意事项

文章目录 1、LPCWSTR类型2、LPCTSTR类型3、LPCSTR类型4、LPCTSTR和LPCWSTR区别5、LPCTSTR和LPCSTR、LPCWSTR三者区别6、_T(" ")7、DWORD类型转换为std::wstring类型8、char类型转换为LPCSTR类型9、获取当前时间戳(毫秒)10、std::wstring和LPCSTR区别11、std::wstring…

2024年【危险化学品生产单位安全生产管理人员】复审考试及危险化学品生产单位安全生产管理人员模拟试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品生产单位安全生产管理人员复审考试根据新危险化学品生产单位安全生产管理人员考试大纲要求&#xff0c;安全生产模拟考试一点通将危险化学品生产单位安全生产管理人员模拟考试试题进行汇编&#xff0c;组成…

Midjourney新算法来袭!解决你角色形象一致性的大难题——亲测猫与女孩跨场景表现

嘿&#xff0c;朋友们&#xff0c;你们想过这个问题吗&#xff1f; 当你在制作一部电影或写一部小说时&#xff0c;你总希望同一个角色能在不同的场景和背景下出现&#xff0c;对吧&#xff1f; 但这时&#xff0c;一个难题冒出来了&#xff1a;如何确保这个角色的形象在各个…

AWS的CISO:GenAI只是一个工具,不是万能钥匙

根据CrowdStrike的年度全球威胁报告,尽管研究人员预计人工智能将放大对防御者和攻击者的影响,但威胁参与者在其行动中使用人工智能的程度有限。该公司上个月在报告中表示:“在整个2023年,很少观察到GenAI支持恶意计算机网络运营的开发和/或执行。” 对于GenAI在网络安全中的…

专升本 C语言笔记-08 goto语句

goto语句 无条件跳转运算符(凡是执行到goto语句会直接跳转到 定义的标签) 缺点&#xff1a;滥用goto语句将会导致逻辑混乱&#xff0c;导致系统崩溃等问题! ! ! 代码演示 int i 0; //定义标签 jump(名字随便起哦) jump:printf("%d ",i); i; if(i < 10)goto j…

Android Studio字体大小调节

外观页面字体调节 settings->Appearance->User cunstom font 代码字体调节 Settings->Editor->Font此时logcat窗口、Build窗口和Ternimal窗口字体大小也会同步调节&#xff08;2023.2.1版本上验证&#xff09;

HDFSRPC协议详解

本文主要阐述HDFSRPCserver端一个socket连接接收字节流的构成&#xff0c;帮助读者理解HDFSRPC协议。注意hadoop版本为3.1.1。 写在前面 关于proto写入和读取&#xff0c;使用writeDelimitedTo和read&#xff0c;应该是通用的方式&#xff0c;不作过多的介绍。 处理rpc各种情…

《智能便利,畅享便利柜平台的架构奇妙之旅》

便利柜平台作为一种智能化、便捷的自助服务解决方案&#xff0c;正在逐渐走进人们的生活。本篇博客将深入探讨便利柜平台的架构设计理念、优势和实践&#xff0c;帮助读者了解如何构建智能便利柜平台&#xff0c;提供更便捷的自助服务体验。 ### 便利柜平台架构设计 #### 1. …