Docker入门笔记(1)

news2024/12/23 10:18:56

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.coloradmin.cn/o/1513221.html

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

相关文章

docker部署Atheos云IDE平台

Codiad 是一个基于 Web 的 IDE 框架 部署 下载镜像 docker pull hlsiira/atheosvim docker-compose.yaml version: 3 services:atheos:image: hlsiira/atheosports:- 8565:80container_name: atheosrestart: always启动 docker-compose up -d访问 http://x.x.x.x:8565

【网络安全】 MSF生成木马教程

本文章仅用于信息安全学习&#xff0c;请遵守相关法律法规&#xff0c;严禁用于非法途径。若读者因此作出任何危害网络安全的行为&#xff0c;后果自负&#xff0c;与作者无关。 环境准备&#xff1a; 名称系统IP攻击机Kali Linux10.3.0.231客户端Windows 710.3.0.234 一、生…

1688商品详情数据采集(商品属性,规格,价格,详情图等)

京东商品详情数据采集是一个复杂但重要的过程&#xff0c;它涉及获取商品的详细信息&#xff0c;包括商品属性、规格、价格以及详情图等。以下是关于如何进行京东商品详情数据采集的基本步骤&#xff1a; 确定采集目标&#xff1a;首先&#xff0c;你需要明确需要采集的商品信…

#QT(显示组件、日期时间组件)

1.IDE&#xff1a;QTCreator 2.实验&#xff1a; 3.记录 4.代码 #include "widget.h" #include "ui_widget.h" #include <QDateTime> #include <QCalendar> #include <QCalendarWidget> Widget::Widget(QWidget *parent): QWidget(pare…

【Vue3】学习命名路由和嵌套路由

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

ARM 汇编指令:(五)CMP指令

目录 1.CMP比较指令 2.指令条件码 cond 1.CMP比较指令 CMP指令是计算机指令集中的一种比较指令&#xff0c;用于比较两个操作数的大小关系或相等性&#xff0c;并根据比较结果设置或更新条件码寄存器&#xff08;或程序状态字&#xff09;的标志位。 指令格式&#xff1a;C…

BEVFormer代码运行笔记

1. 代码下载 git clone https://github.com/fundamentalvision/BEVFormer.git 2. 环境配置 使用conda创建环境 conda create -n open-mmlab python3.8 -y 进入环境 conda activate open-mmlab 允许使用pip安装依赖库 export PIP_REQUIRE_VIRTUALENVfalse 安装pytorch和…

【C++算法模板】图的存储-邻接矩阵

文章目录 邻接矩阵洛谷3643 图的存储 邻接矩阵 邻接矩阵相比于上一篇博客邻接表的讲解要简单得多 数据结构&#xff0c;如果将二维数组 g g g 定义为全局变量&#xff0c;那默认初始化应该为 0 0 0 &#xff0c;如果题目中存在自环&#xff0c;可以做特判&#xff0c; m e …

300分钟吃透分布式缓存-28讲:如何构建一个高性能、易扩展的Redis集群?

Redis 集群的分布式方案主要有 3 种。分别是 Client 端分区方案&#xff0c;Proxy 分区方案&#xff0c;以及原生的 Redis Cluster 分区方案。 Client 端分区 Client 端分区方案就是由 Client 决定数据被存储到哪个 Redis 分片&#xff0c;或者由哪个 Redis 分片来获取数据。…

深度解析Kafka分区策略的精妙之处

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 深度解析Kafka分区策略的精妙之处 前言分区的基本概念1. Kafka 分区的定义&#xff1a;2. Kafka 分区的基本原理&#xff1a;3. 为何分区是 Kafka 消息传递的关键组成部分&#xff1a; 分区策略的选择…

数字化浪潮下的选择:ETU-LINK光模块写码板全新升级至400G

随着光模块市场的蓬勃发展&#xff0c;ETU研发团队致力于不断改进SFP编码工具&#xff0c;以满足日益增长的客户需求。经过不懈努力&#xff0c;我们成功推出了3.0版本的写码板&#xff0c;在硬件和软件方面都进行了全面升级&#xff0c;为用户带来了极大的便利。今天&#xff…

每日汇评:如果支撑位守住2145美元,黄金可能反弹至纪录高位

金价在周二因美国CPI数据火爆而暴跌后保持稳定&#xff1b; 美元和美债收益率在美元/日元下跌中暂停反弹&#xff1b; 随着美国CPI的出炉&#xff0c;市场焦点转向周四的零售销售和PPI数据&#xff1b; 金价在2160美元附近盘整&#xff0c;周二从2195美元的纪录高位回调约1%。由…

windows批处理脚本(cmd指令)

一、简介 最早期的电脑系统是DOS系统&#xff0c;DOS系统只有一个黑漆漆的窗口&#xff0c;需要自己输入命令&#xff0c;所以学习命令是很有必要的&#xff0c;那么CMD命令大全是什么?直到今天的Windows系统&#xff0c;还是离不开DOS命令的操作。如今懂得使用windows批处理脚…

C++ 作业 24/3/12

1、自己封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height),定义公有成员函数: 初始化函数:void init(int w, int h)更改宽度的函数:set_w(int w)更改高度的函数:set_h(int h) 输出该矩形的周长和面积函数:void show() #include <iostream>using …

TS271IDT运算放大器芯片中文资料PDF数据手册引脚图图片参数价格功能

产品描述&#xff1a; TS271 是一款低成本、低功耗的单通道运算放大器&#xff0c;设计用于采用单电源或双电源供电。该运算放大器采用意法半导体硅栅CMOS工艺&#xff0c;具有出色的消耗-速度比。该放大器非常适合低功耗应用。 电源可通过引脚 8 和 4 之间连接的电阻器进行外…

Kotlin 空类型,区间,数组

目录 1. 空类型 2. 区间 3. 数组 1. 空类型 我们知道任何一种数据类型都有为空或不为空两种状态&#xff0c;在 Kotlin 中&#xff0c;若允许一个数据为空&#xff0c;则需要使用 "?"&#xff0c;默认都不能为空。 代码举例说明 // 给 notNull赋值为空&#x…

硬件软件_驱动程序只有cat,inf,sys,怎么安装?

硬件软件_驱动程序只有cat&#xff0c;inf&#xff0c;sys&#xff0c;怎么安装&#xff1f; 右键点击inf文件 -》 安装 即可完成。

centos命令history设置记录10000行

今天在操作服务器的时候&#xff0c;用history查看操作记录的时候&#xff0c;发现只能查看10条&#xff0c;这样不行啊&#xff0c;我想查看所有人对服务器操作的命令。 [rootbogon ~]# history解决办法&#xff1a; #1、找到/etc/profile文件中的histsize 把10改成10000 […

pycharm 历史版本下载地址

pycharm 历史版本下载地址 老版本能用就行&#xff0c;不需要搞最新的&#xff0c;当然了&#xff0c;有些小伙伴就是喜欢新的&#xff08;最先吃螃蟹&#xff09; 博主就不搞最新了&#xff0c;哈哈 上菜&#xff1a; https://www.jetbrains.com/pycharm/download/other.html…

操作系统—自定义系统调用

文章目录 自定义系统调用1.实验基本环境(1).基本系统环境(2).选择替换WSL内核的起因(3).我尝试的改进措施 2.添加系统调用(1).系统调用位置(2).系统调用函数编写(3).添加系统调用号(4).添加编译参数并编译#1.一次极其失败的尝试#2.推倒重来 (5).尝试调用sys_mysyscall 3.后记参…