Docker(一)

镜像和容器

利用docker安装应用时,Docker会自动搜索并下载应用镜像(image) 。镜像不仅包含应用本身,还包含应用运行所需要的环境、配置、系统函数库。Docker会在运行镜像时创建一个隔离环境,称为容器(container)

镜像仓库:存储和管理镜像的平台,Docker官方维护了一个公共仓库:Docker Hub

命令解读

端口映射时,前者是宿主机端口,后者是容器内端口

常见命令

docker run:创建并运行容器(每执行一次都会创建一个新的容器)

docker stop:停掉容器内的进程(容器还在)

docker start:启动容器内停掉的进程(不会创建容器 )

docker ps:查看当前容器的运行状态(有哪些容器以及容器的状态)

|----------------|--------------------------------------------------------|
| docker pull | 拉取镜像 |
| docker push | 推送镜像到DockerRegistry |
| docker images | 查看本地镜像 |
| docker rmi | 删除本地镜像 |
| docker run | 创建并运行容器(不能重复创建) |
| docker stop | 停止指定容器 |
| docker start | 启动指定容器 |
| docker restart | 重新启动容器 |
| docker rm | 删除指定容器(不能删除运行中的容器,但结尾加 -f可以强制删除) |
| docker ps | 查看容器状态(结尾加 -a查看所有容器,包括停掉的) |
| docker logs | 查看容器运行日志(后加 -f表示实时加载,后加 容器名) |
| docker exec | 进入容器(后加 -it表示添加一个可输入的终端,再加 容器名表示目标容器名,再加 bash表示用命令行交互) |
| docker save | 保存镜像到本地压缩文件 |
| docker load | 加载本地压缩文件到镜像(后加 -i 压缩包全名) |
| docker inspect | 查看容器详细信息 |

命名别名

vi /root/.bashrc

alias dps='docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"'
alias dis='docker images'

镜像原理

镜像本质

镜像是一种轻量级的、可执行的独立软件包。用来打包软件运行环境和基于运行环境的开发软件,它包含运行某个软件所需要的内容,包括代码、运行时、库、环境变量和配置文件。

Docker镜像加载原理

UnionFS(联合文件系统):UnionFS文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层一层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像,可以制作各种各样的应用镜像。

特性:一次同时加载多个文件系统,但是从外面开起来,只能看一个文件系统,联合加载会把各层文件系统叠加起来,最终的文件系统会包含所有的底层文件和目录。

docker的镜像实际上是由一层一层的文件系统组成,这种层级关系就叫UnionFS。
bootfs(boot file system)主要包括bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就在内存中了,此时内存的使用权由bootfs转交给内核,此时系统会卸载bootfs。

rootfs(root file system),在bootfs之上。包含的就是典型Linux系统的/dev, /proc, /bin, /etc等等标准文件。rootfs就是各种不同的操作系统发行版本,比如Ubuntu、CentOS等。

对于一个精简的OS,rootfs可以很小,只需要包含最基本的命令、工具和程序即可,因为底层直接用Host的kernel,自己只需要提供rootfs即可。由此可见不同的Linux发行版本,bootfs基本上是一致的,rootfs会有差别,所以不同的发行版可以公用bootfs,这也是一个镜像仅有几百MB的原因。

数据卷

数据卷是由 Docker 管理的存储,可以被一个或多个容器共享。它通常用于持久化数据并确保容器停止或删除时数据不会丢失。数据卷的优势是独立于容器生命周期,可以跨容器使用,并且易于备份和恢复。

数据卷是一个虚拟目录,是容器内目录与虚拟机宿主目录之间映射的桥梁。是一个双向自动映射,其中一方改变,另一方会自动改变。由于容器会自动配置其必须得依赖和环境,读写文件的编辑器一般不会被配置,所以本来无法再容器内直接读写文件,但是数据卷解决了这一问题。

卷就是目录或者文件,存在一个或者多个容器之中,由docker挂载到容器,但是不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或者共享数据的特性。

卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此docker不会再容器删除时删除其挂载的数据卷。

它还存在以下几种特点:

1、数据卷可在容器之间共享或者重用数据。

2、卷中的更改可以直接生效。

3、数据卷中的更改不会包含在镜像的更新中。

4、数据卷的生命周期一直持续到没有容器使用它为止。

我们创建了两个数据卷:

conf、html

  • Nginx容器内部的conf目录和html目录分别与两个数据卷关联。
  • 而数据卷conf和html分别指向了宿主机的/var/lib/docker/volumes/conf/_data目录和/var/lib/docker/volumes/html/_data目录,这样以来,容器内的conf和html目录就 与宿主机的conf和html目录关联起来,我们称为挂载。此时,我们操作宿主机的/var/lib/docker/volumes/html/_data就是在操作容器内的/usr/share/nginx/html/_data目录。只要我们将静态资源放入宿主机对应目录,就可以被Nginx代理了。

注意:容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建

绑定挂载

  • 执行docker run命令时,使用-v 数据卷名称:容器内目录 可以完成数据卷挂载(自动映射)
  • 当创建容器时,如果挂载了数据卷且数据卷不存在,会自动创建数据卷

为什么不让容器目录直接指向宿主机目录呢?

  • 因为直接指向宿主机目录就与宿主机强耦合了,如果切换了环境,宿主机目录就可能发生改变了。由于容器一旦创建,目录挂载就无法修改,这样容器就无法正常工作了。
  • 但是容器指向数据卷,一个逻辑名称,而数据卷再指向宿主机目录,就不存在强耦合。如果宿主机目录发生改变,只要改变数据卷与宿主机目录之间的映射关系即可。

本地目录挂载

数据卷的目录结构较深,如果我们去操作数据卷目录会不太方便。在很多情况下,我们会直接将容器目录与宿主机指定目录挂载

  • 执行docker run命令时,使用 -v 本地目录:容器内目录 可以完成本地目录挂载
  • 本地目录必须以"/"或"./"开头,如果直接以名称开头,会被识别为数据卷而非本地目录

例:

-v mysql:/var/lib/mysql 会被识别为一个数据卷叫mysql

-v ./mysql:/var/lib/mysql 会被识别为当前目录下的mysql目录

  • 挂载 /root/mysql/data到容器内的/var/lib/mysql目录
  • 挂载 /root/mysql/init到容器内的/docker-entrypoint-initdb.d目录(初始化的SQL脚本目录)
  • 挂载 /root/mysql/conf到容器内的/etc/mysql/conf.d目录(这个是MySQL配置文件目录)

这样做的好处,当这个mysql容器关闭之后(理论上容器mysql的相关数据都被删除,但本地目录中的还在),再次创建一个新的mysql容器时(并指定与本地目录挂载),mysql中的数据依然存在。

自定义镜像

Dockerfile

Dockerfile是一个文本文件,其中包含一个个的指令,用 指令来说明要执行什么操作来构建镜像,将来Docker可以根据Dockerfile帮我们构建镜像。

Dockerfile构建过程

dockerfile的关键字建议使用大写,它是从上往下按照循序执行的,在dockerfile中,#代表注释。我们可以通过这个脚本来生成镜像,脚本中的每一个命令,都是一层镜像。

我们先通过下面这张图片来理解一下镜像的构成以及运行过程。

在这里我们来整理一下docker容器、dockerfile、docker镜像的关系:

  • dockerfile是面向开发的,发布项目做镜像的时候就要编写dockerfile文件。
  • dockerfile:构建文件,定义了一切的步骤,源代码。
  • dockerImanges:通过dockerfile构建生成的镜像,最终发布和运行的产品。
  • docker容器:容器就是镜像运行起来提供服务的。

构建镜像

编写好Dockerfile后,可以(在jar包所在目录下)用下面命令来构建镜像,将jar包构建成一个镜像)

容器网络互联

docker安装后,会在宿主机内创建一个虚拟网卡docker0,所有容器默认通过桥接连接到这个网卡,不同容器属于一个网段,相互之间可以传输信息。

由于容器的ip地址每次启动会发生改变,所以默认写死ip地址会造成问题。

解决方案:ip地址会变但容器名不会变,让容器之间通过容器名互相访问,加入自定义网络的容器才可以通过容器名互相访问,Docker的网络操作命令如下:

启动容器时,使用 --network 网桥名,指定容器使用的网桥(可以替换默认网桥)

DockerCompose

通过一个单独的docker-compose.yml模版文件(yaml格式)来定义一组相关联的应用容器,帮助我们实现多个相互关联的Docker容器的快速部署。这个模版文件中定义了容器的一系列配置,包括端口映射、环境变量、数据卷挂载、网桥、指定dockerfile(来构建镜像)等信息,可以利用DockerCompose文件进行一键部署

左侧是docker run命令,右侧是docker-compose.yml

部署

相关推荐
神秘的土鸡1 小时前
丹摩征文活动 | AI创新之路,DAMODEL助你一臂之力GPU
云原生·云计算·aigc·gpu算力·安全架构
漫天转悠4 小时前
Docker保存镜像和导入镜像文件(图文详解)
ubuntu·docker
fen_fen4 小时前
Docker如何运行一个python脚本Hello World
运维·docker·容器
檀越剑指大厂5 小时前
【Docker系列】Docker 构建多平台镜像:arm64 架构的实践
docker·容器·架构
阿moments6 小时前
Docker - 速成
运维·docker·云原生·容器
落寞书生6 小时前
docker安装mysql 实现主从同步
运维·mysql·docker·主从同步·docker 安装mysql
给我买个墨镜戴7 小时前
黑马商城微服务复习(5)
微服务·云原生·架构
寰梦7 小时前
Docker(Nginx) 部署 uniapp
nginx·docker·uni-app
尚雷55808 小时前
云计算IaaS-PaaS-SaaS三种服务模式转至元数据结尾
云原生·云计算·paas