深入理解Docker,从入门到精通-Part1(基础使用)

一、Docker基本概念

Docker架构


基本组件的介绍

Docker Client 是用户界面,它支持用户与Docker Daemon之间通信
Docker Daemon Docker最核心的后台进程,运行于主机上,处理服务请求
Docker registry是中央registry,支持拥有公有与私有访问权限的Docker容器镜像的备份
Docker Containers负责应用程序的运行,包括操作系统、用户添加的文件以及元数据
Docker Images是一个只读模板,用来运行Docker容器
DockerFile是文件指令集,用来说明如何自动创建Docker镜像

三个基本概念

镜像

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等),镜像不包含任何动态数据,其内容在构建之后也不会被改变。

简单理解,镜像就是一个文件,特殊之处在于能被Docker加载运行

但实际上并不是由单个文件组成那么简单,背后是一个文件系统,采用分层存储。

分层存储指的是镜像是由一组文件系统组成,或者说,由多层文件系统联合组成。

关键技术就是Union FS,联合文件系统是(Union FS)是linux的存储技术,也是Docker镜像的存储方式, 它是分层的文件系统,将不同目录拉到同一个虚拟目录下,下图展示了Docker用Union FS 搭建的分层镜像:(比如最下层是操作系统的引导,上一层是Linux操作系统,再上一层是Tomcat,jdk,再上一层是应用代码)

镜像构建时,会一层层构建,前一层是后一层的基础,每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。(比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除,在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像,因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉)

容器

镜像和容器的关系,就像是面向对象程序设计中的 类 和 实例 一样

镜像是静态的定义,容器是镜像运行时的实体,容器可以被创建、启动、停止、删除、暂停等。

        容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间,因此容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。
        容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样,这种特性使得容器封装的应用比直接在宿主运行更加安全。
        前面讲过镜像使用的是分层存储,容器也是如此,每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。
        容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡,因此,任何保存于容器存储层的信息都会随容器删除而丢失。

仓库

镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜
像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。

一个 Docker Registry 中可以包含多个仓库( Repository );每个仓库可以包含多个标签
Tag );每个标签对应一个镜像。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本,我们
可以通过 < 仓库名>:<标签 > 的格式来指定具体是这个软件哪个版本的镜像,如果不给出标签,将以 latest 作为默认标签。
仓库名经常以 三段式路径 形式出现,比如 demo.com/nginx - proxy:tag ,前者往往意味着 Docker
Registry 多用户环境下的用户名,后者则往往是对应的软件名,但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务

二、Docker安装部署MySQL

1、下载镜像,这里以mysql5.7.41版本为例

docker pull mysql:5.7.41

2、 mysql配置

创建MySQL挂载目录,等会会解释什么是挂载路径

# 创建MySQL配置的文件夹
mkdir -p /tmp/etc/mysql
# 编辑my.cnf配置文件
vi /tmp/etc/mysql/my.cnf

配置MySQL忽略大小写,在我们创建的MySQL配置文件挂载点的目录的my.cnf文件加入如下内容

[mysqld]
lower_case_table_names=1

创建MySQL数据目录

因为默认MySQL启动后他的文件是在容器中的,如果我们删除容器,数据也将会消失,我们需要将数据挂载出来。

#创建mysql存储的目录
mkdir -p /tmp/data/mysql

启动MySQL

docker run -d -p 3306:3306 -v /tmp/etc/mysql:/etc/mysql/mysql.conf.d/ -v /tmp/data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql mysql:5.7.41

用docker ps查询,出现如下结果表明mysql启动成功

参数解释

  • -d:是指容器后台运行,如果不加-d,当用户断开客户端时容器会结束运行
  • -p:将容器的3306端口映射到主机的3306端口,用来暴漏端口的
  • -v:这个命令是用来挂载目录的,将本地目录挂载到容器中,这样容器操作的就是本地目录
  • -e:这个命令是配置环境参数的,这里MYSQL_ROOT_PASSWORD=root指的是用root用户运行mysql,可以登录Docker容器通过ENV命令查看
  • --name:这个命令是配置Mysql的容器名称的,如果不配置,默认是随机生成的名字

查看容器挂载的配置文件

可以通过docker exec -ti mysql /bin/bash命令登录容器,检查挂载的配置文件情况

我们可以看到我们修改的配置文件已经被挂载到了docker内部,这里面用到了exec命令,主要是在docker容器中运行命令

docker exec就是进入容器的命令,其中

-t 表示命令行交互模式      -i 表示展示容器输入信息STDIN

至此,MySQL安装部署成功

三、Docker安装部署Nacos

1、下载镜像,这里以nacos2.0.1版本为例

docker pull nacos/nacos-server:2.0.1

2、运行镜像

docker run -d -p 8848:8848 --name nacos --env MODE=standalone nacos/nacos-server:2.0.1

参数解释:

-d:后台进程运行

--name:容器名称

--env MODE=standlone:设置环境变量,这里表示单机模式启动

登录控制台,成功显示

至此,Nacos单机版安装部署成功

四、SpringBoot项目部署

将项目通过Maven进行打包,再去Target目录复制Jar包文件上传至服务器

 编写DockerFile文件

vi Dockerfile

具体内容如下:

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD learn-docker-storage-1.0-SNAPSHOT.jar app.jar
EXPOSE 8003
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar"]

命令解释:

  • FORM:定制的镜像都是基于 FROM 的镜像,这里的 openjdk 就是定制需要的基础镜像,后续操作都是基于openjdk
  • VOLUME:挂载一个数据卷,这里因为没有名称,所以是一个默认的数据卷(后面详细解释)
  • ADD:添加一层镜像到当前镜像,这里就是添加SpringBootTest镜像到当前层,并改名app.jar
  • EXPOSE:暴漏端口,因为我们的自己的端口是8003,所以我们暴漏8003
  • ENTRYPOINT:设定容器启动时第一个运行的命令及其参数,这里就是容器以启动就执行 java -jar /app.jar

写好DockerFile后就需要用docker build命令来构建我们的镜像了,这样就可以将我们的SpringBoot项目打包成一个镜像了

构建一个镜像需要使用以下命令

docker bulid -t 仓库名/镜像名:tag .
  • -t  镜像的名字及标签,一般命名规则是 仓库名/镜像名:tag,

    • 仓库名:一般是私服或者dockerhub等地址,如果忽略默认就是dockerhub的地址docker.io.library/
    • 镜像名称:就是我们的自己的服务名称,可以随意命名
    • tag:就是我们的版本号
  • .  这个 . 表示当前目录,这实际上是在指定上下文的目录是当前目录,docker build 命令会将该目录下的内容打包交给 Docker 引擎以帮助构建镜像。

docker build -t learn-docker-storage:0.0.1 .

 

构建完成如果出现Successfully说明已经构建成功了

可以查看我们构建的镜像

启动镜像:

# 运行容器
docker run -d -p 8003:8003 learn-docker-storage:0.0.1

 查看启动日志

docker logs -f container_id

至此,我们的打包镜像部署服务就已经大功告成了

五、日志挂载优化

存储卷优化

什么是存储卷

“卷”是容器上的一个或多个“目录”,此类目录可绕过联合文件系统,与宿主机上的某个目录“绑定
(关联)”;

Docker 中,要想实现数据的持久化(所谓 Docker 的数据持久化即 数据不随着 Container 的结束
而结束 ),需要将数据从宿主机挂载到容器中。这些数据比如Mysql的数据、redis的数据、日志数据等等
Docker 管理宿主机文件系统的一部分,默认位于 /var/lib/docker/volumes 目录中;( 最常用的方

存储卷的使用

 查看存储卷

docker volume ls

 

我们发现都是匿名的存储卷,如何来确定都是那个呢,可以通过 docker inspect 容器 ID 来查看
存储信息
docker inspect 2041965c3e87|grep Mounts -A20

# 进入文件挂载目录 
cd /var/lib/docker/volumes/d35de1b7e4631908b05635db4c1f114ab3aafbdf25a9843c068696e6 6a779c75/_data 
# 输出日志 
tail -f learn-docker-storage.log

 当删除了容器,发现存储卷所挂载的目录数据依然还存在

bind挂载共享存储

什么是bind

Bind mounts模式和Volumes非常相似,不同点在于Bind mounts模式是将宿主机上的任意文件或文件夹挂载到容器,而Volumes本质上是将Docker服务管理的一块区域(默认是/var/lib/docker/volumes下的文件夹)挂载到容器。

共享存储

经过上面的测试,我们发现每一个容器都是单独用一个存储卷,用于临时文件没有问题的,但是如果要让容器都用同一个存储路径怎么办呢,这个时候就用到了 bind挂载了,可以使用-v进行挂载挂载刚才的存储卷。

# 级联创建文件夹
mkdir -p /tmp/data/logs
# 运行容器,指定挂载路径 
docker run -d -v /tmp/data/logs:/logs \
-p 8003:8003 --name learn-docker-storage \
learn-docker-storage:0.0.2

 用-v来指定需要挂载的目录,这也是我们用的最多的一种方式

使用docker inspect命令来检查容器详情

docker inspect learn-docker-storage|grep Mounts -A20

volume和bind的区别

对于多个容器需要共享访问同一数据目录,或者需要持久化容器内数据(如数据库)时,我们都是采用挂载目录形式(bind mounts),将宿主机的某一目录挂载到容器内的指定目录,这种方式能解决问题,但这种方式也一直有一些缺点

  • 容器在不同的服务器部署需要根据实际磁盘挂载目录修改路径
  • 不同操作系统的文件和目录权限会搞得你昏头转向,火冒三丈 ?

 bind mount和volume其实都是利用宿主机的文件系统,不同之处在于volume是docker自身管理的目录中的子目录,所以不存在权限引发的挂载的问题,并且目录路径是docker自身管理的,所以也不需要在不同的服务器上指定不同的路径,你不需要关心路径。

六、网络优化

我们先用一张图来说明为什么要进行网络优化

所以Docker的容器是否可以直接通过Docker的网卡进行直接通信呢?

答案是当然可以,这就叫做网络优化。

Docker网络原理

        Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关,因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。

       Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接Container-IP访问到容器,如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。

Docker网络模式

Docker网络模式配置说明
host模式–net=host容器和宿主机共享Network namespace。
container模式–net=container:NAME_or_ID容器和另外一个容器共享Network namespace。 kubernetes中的pod就是多个容器共享一个Network namespace。
none模式–net=none容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。
overlay模式-- driver overlayDocker跨主机通信模式,使用分布式计算机架构后需要使用overlay网络模式
bridge模式–net=bridge(默认为该模式)

 Docker 的 bridge 模式是 Docker 容器网络的默认模式,它提供了一种简单而强大的方式来为容器分配独立的 IP 地址,并使它们能够在同一主机上相互通信。下面是对 bridge 模式的简要介绍:

桥接网络模式实战

查看网络列表

可以通过docker network ls命令查看网络列表

# 查看网络列表
docker network ls

创建一个桥接网络

默认容器启动会自动默认接入bridge的桥接网络,为了区分我们的服务也防止各种网络问题,我们创建一个专用网络,可以通过docker network create 网络名称来创建一个默认的桥接网络

# 创建一个桥接网络
docker network create learn-docker-network
# 查看网络列表
docker network ls

停止并删除原有容器

停止和删除我们的微服务以及mysql服务

# 删除当前运行中的容器
docker rm -f learn-docker-storage nacos mysql

创建MySQL

因为我们的微服务依赖MySQL先启动MySQL并接入网络,因为MySQL不需要通过宿主机访问,所有也不需要映射端口了,--network 是配置接入哪一个网络

docker run -d \
-v /tmp/etc/mysql:/etc/mysql/mysql.conf.d/ \
-v /tmp/data/mysql:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
--name mysql --network=learn-docker-network \
mysql:5.7.38

这里需要注意:为什么重新建了个新的MySQL容器,能拿到以前的数据?因为我们做了存储卷映射,所以数据可以持久化

创建Nacos

我们的nacos是需要暴露端口的,因为我们需要外部能够看到nacos页面,但是我们也需要我们的nacos连接到当前网络

docker run -d  \
--network=learn-docker-network \
-p 8848:8848 \
--name nacos --env MODE=standalone \
nacos/nacos-server

查看网络详情

可以通过docker network inspect 网络名称可以查看当前的网络的详细信息

docker network inspect learn-docker-network

修改微服务配置

因为需要使用自定义网络访问mysql容器以及nacos容器,需要修改微服务数据库连接地址,

docker 网络访问 可以通过IP或者通过服务名称都是可以的,这里我们通过服务名称访问,因为我们使用了maven打包的方式,我们只需要将pom文件修改就可以

<properties><mysql.addr>mysql:3306</mysql.addr><nacos.addr>nacos:8848</nacos.addr>
</properties>

重新打包服务

将打包的文件上传服务器后按照上面步骤同上面打包,打包版本为 0.0.3

docker build -t learn-docker-storage:0.0.3 .

创建微服务

下面就按部就班的创建微服务就可以,只是注意需要加入网络,这里这个端口需要映射外网访问

docker run -d \
-v /tmp/data/logs:/logs \
-p 8003:8003 \
--name learn-docker-storage \
--network=learn-docker-network \
learn-docker-storage:0.0.3

测试微服务

到现在微服务已经启动,我们尝试访问以下

 curl http://192.168.64.153:8003/storage/employe/findByID/10001 | python -m json.tool

访问测试数据没有问题,到现在我们服务已经搭建完成,并且使用网络进行了优化

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

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

相关文章

在macOS的多任务处理环境中,如何平衡应用的性能与用户体验?这是否是一个复杂的优化问题?如何优化用户体验|多任务处理|用户体验|应用设计

目录 一 多任务处理与应用性能 1. macOS中的多任务处理机制 2. 性能优化的基本策略 二 用户体验的关键要素 1. 响应速度 2. 界面友好性 3. 功能的直观性 三 平衡性能与用户体验的策略 1. 资源管理 2. 优化数据加载 3. 使用合适的线程模型 4. 实时监测和调整 四 使…

lvm逻辑卷管理

分区类型&#xff1a; 主分区扩展分区逻辑分区系统引导分区&#xff1a;存放系统的引导文件和linux的内核文件swap分区&#xff1a;交换分区&#xff0c;系统的物理内存不足时&#xff0c;从一些长时间未运行的程序当中释放一部分内存&#xff0c;释放出来的内存保存到swap分区…

openai api 文件分析/联网/画图代码示例

目的 使用https://4o.zhangsan.shop的API进行文件分析等功能。 完整代码 # pip install openai0.28 # 注意下方代码必须使用该版本 import openaidef query_gpt4(question):openai.api_key "sk-aQR1wbTsLpySgJDq3fFb026c225a44C8924750C1B67bCeD5"openai.api_ba…

Android编译环境构建(二)(可用于物理机、虚拟机、容器化Jenkins环境)

文章目录 需求环境要求文件下载Gradle Version:7.5cmdline-tools至此普通物理环境的Android编译环境已部署完毕 部署maven(可选)Jenkins配置Android构建环境 说明&#xff1a; 物理环境&#xff1a;物理机、虚拟机等 容器化环境&#xff1a;docker等 需求 Gradle Version:7.5 …

WPF+MVVM案例实战(十)- 水波纹按钮实现与控件封装

文章目录 1、运行效果1、封装用户控件1、创建文件2、依赖属性实现2、使用封装的按钮控件1.主界面引用2.按钮属性设置3 总结1、运行效果 1、封装用户控件 1、创建文件 打开 Wpf_Examples 项目,在 UserControlLib 用户控件库中创建按钮文件 WaterRipplesButton.xaml ,修改 Us…

Spring Boot解决 406 错误之返回对象缺少Getter/Setter方法引发的问题

目录 前言1. 问题背景2. 问题分析2.1 检查返回对象 3. 解决方案3.1 确保Controller返回Result类型3.2 测试接口响应 4. 原理探讨5. 常见问题排查与优化建议结语 前言 在Spring Boot开发中&#xff0c;接口请求返回数据是系统交互的重要环节&#xff0c;尤其在开发RESTful风格的…

FineReport 单元格的特殊应用场景

1、实现鼠标点击的行变色 创建报表 1.1、鼠标点击某行时该行高亮显示 JavaScript 代码如下&#xff1a; _g().addEffect(highlightRow, {color: red,trigger: mousedown, });结果 1.2、鼠标悬浮某行时该行变色&#xff0c;离开时恢复 其他一样&#xff0c;就改代码 JavaScr…

MacOS的powermetrics命令查看macbook笔记本的耗能情况,附带查看ANE的工作情况

什么是 powermetrics&#xff1f; powermetrics 是 macOS 系统自带的一个命令行工具&#xff0c;用于收集和分析系统能源消耗数据。通过它&#xff0c;我们可以深入了解 Mac 的硬件性能、软件行为以及能源使用情况&#xff0c;从而优化系统配置&#xff0c;提高电池续航时间。…

系统架构师-一文搞定架构风格

架构风格分类 五大架构风格简介子风格数据流风格面向数据流&#xff0c;按照一定的顺序从前向后执行程序批处理、管道-过滤器调用/返回风格构件与构件之间存在相互调用的关系&#xff0c;一般是显示的调用主程序/子程序、面向对象、层次结构&#xff08;层次型架构风格&#x…

第13课 数据处理

数轴是一维的&#xff0c;平面直角坐标系是二维的。单个学生的成绩是一维的&#xff0c;全班同学的成绩是二维的。 Python是强大的数据处理工具&#xff0c;可以处理多种数据文件。最基础的数据文件包括一维数据、二维数据、CSV格式数据文件。 这节课重点学习一维数据、二维数据…

3D人体建模的前沿探索:细数主流模型与技术进展

文章目录 一、前言二、主要内容SMPL文献内容&#xff1a;文献信息&#xff1a; SMPLX文献内容&#xff1a;文献信息&#xff1a; STAR文献信息&#xff1a; SCAPE文献内容&#xff1a;文献信息&#xff1a; BfSNet3. 文献内容&#xff1a; SMPLR文献内容&#xff1a;文献信息&a…

闪存学习_1:Flash-Aware Computing from Jihong Kim

闪存学习_1&#xff1a;Flash-Aware Computing from Jihong Kim 前言一、Storage Media&#xff1a;NAND Flash Memory1、概念2、编程和擦除操作3、读操作4、异地更新操作&#xff08;Out-Place Update&#xff09;5、数据可靠性6、闪存控制器&#xff08;SSD主控&#xff09;7…

【真题笔记】15年系统架构设计师要点总结

【真题笔记】15年系统架构设计师要点总结 分布式数据库中各种透明RAID 5IPv6 IPv4电子商务系统项目配置管理IPO图&#xff08;输入加工输出图&#xff09;桥接模式的UML图面向对象设计原则软件测试 在15年真题练习中&#xff0c;对错题模棱两可的考点进行重点记录与内容延申。…

软件测试基础知识总结

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 基础篇 1. 什么是软件测试&#xff1f; 软件测试&#xff08;Software Testing&#xff09;的经典定义是&#xff1a;在规定的条件下对程序进行操作&#xff…

「微服务」持续测试如何做?

如今&#xff0c;软件开发对于速度和灵活性的持续追求&#xff0c;催生了各种超越传统界限的方法和实践。而作为现代 DevOps 实践的基石&#xff0c;持续测试的出现与发展&#xff0c;正好满足了加速软件交付的需求。下面&#xff0c;我将和您探讨持续测试的最新发展&#xff0…

智能家居10G雷达感应开关模块,飞睿智能uA级别低功耗、超高灵敏度,瞬间响应快

在当今科技飞速发展的时代&#xff0c;智能家居已经逐渐成为人们生活中不可或缺的一部分。从智能灯光控制到智能家电的联动&#xff0c;每一个细节都在为我们的生活带来便利和舒适。而在众多智能家居产品中&#xff0c;10G 雷达感应开关模块以其独特的优势&#xff0c;正逐渐成…

中国大学慕课视频资源分析

右键查看视频信息 关注点在 urls 这个参数&#xff0c;仔细分析就会发现其实是由若干个.ts拓展名和一个.m3u8拓展名的视频文件&#xff0c;每一个.ts视频文件的时长在10秒钟左右。 中国大学MOOC将课程的视频文件拆分成若干个这样的.ts片段&#xff0c;并且用.m3u8记录这些片段…

T4--侯豆病毒识别

导入需要使用的包包括 from tensorflow import keras from tensorflow.keras import layers,models import os, PIL, pathlib #加载文件使用的 import matplotlib.pyplot as plt import tensorflow as tfdata_dir "第四周"data_dir pathlib.Path(da…

Chromium HTML5 新的 Input 类型tel对应c++

一、Input 类型: tel <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>test</title> </head> <body><form action"demo-form.php">电话号码: <input type"tel" name…

Python批量查找包含多个关键词的PDF文件

在信息爆炸的时代&#xff0c;数据管理变得愈发重要。U盘作为一种便携式存储设备&#xff0c;常常承载着我们大量的个人和工作数据。然而&#xff0c;随着文件数量的增加&#xff0c;在U盘中快速找到特定文件常常成为一个令人头疼的难题。我们通常可以采用everything来快速查找…