Docker学习笔记【从入门到精通】
目录
一、Docker是什么
二、Docker容器部署项目
三、Docker的核心特点
四、Docker的应用场景和使用方式
五、Docker安装部署
1.Docker引擎
2.Docker组成
(1)Docker Daemon
(2)Rest接口
(3)Docker Client
3.Docker平台组成
(1)镜像 Images
(2)容器 Container
(3)仓库 Registry
六、Docker镜像原理
七、Docker常用命令
1.帮助命令
2.镜像命令
(1)docker images
(2)docker search(搜索镜像)
(3)docker pull(下载镜像)
(4)docker rmi(删除镜像)
3.容器命令
(1)新建容器并启动
(2)列出所有运行的容器
(3)退出容器
(4)删除容器
(5)启停容器
(6)其他命令
八、Docker镜像
1.Docker镜像的主要特点
2.镜像底层原理
(1)联合文件系统(UnionFS)
3.镜像加载原理
九、容器数据卷
1.数据卷的主要优点:
(1)数据持久化
(2)数据共享
(3)性能优化
2.创建和管理数据卷
(1)创建数据卷
(2)查看数据卷
(3)删除数据卷
3.在容器中使用数据卷
(1)启动容器时挂载数据卷
(2)使用匿名数据卷
(3)使用 Docker Compose
4.数据卷的类型
(1)普通数据卷
(2)绑定挂载(Bind Mounts)
(3)临时卷(tmpfs)
十、Dockerfile
1.Dockerfile 的基本结构
2.Dockerfile 常用指令
3.构建和运行镜像
一、Docker是什么
Docker是一种开源的应用容器引擎,它允许开发者将应用程序及其依赖打包进容器中,以便在任何安装了Docker引擎的服务器上运行。
Docker基于操作系统层级的虚拟化技术,使用Linux内核的cgroup和namespace功能来实现容器隔离。
Docker容器具有轻量级、便携性和高效性,使得应用程序可以在不同的环境中一致地运行,减少了环境差异带来的问题。
二、Docker容器部署项目
三、Docker的核心特点
- 轻量级虚拟化:Docker利用操作系统的容器化技术,不需要模拟完整的操作系统,因此性能开销小。
- 隔离性:每个容器运行在独立的环境中,互不干扰。
- 便携性:容器可以在任何安装了Docker引擎的机器上运行。
- 一致性:无论在开发、测试还是生产环境,应用程序的行为应该一致。
- 标准化:通过Dockerfile定义和构建容器,使得部署过程标准化。
四、Docker的应用场景和使用方式
- 应用部署:可以将应用及其依赖打包成容器,在任何地方部署和运行。
- 持续集成/持续部署(CI/CD):通过Dockerfile自动化构建和部署过程。
- 微服务架构:每个服务运行在独立的容器中,提高系统的可扩展性和可靠性。
- 多环境一致性:确保开发、测试和生产环境的一致性,减少错误。
五、Docker安装部署
1.Docker引擎
Docker Engine是C/S架构的。
2.Docker组成
Docker是由几个部件组成的。
(1)Docker Daemon
安装使用Docker,必须先运行Docker Daemon进程,用于管理Docker,如:
- 镜像images
- 容器containers
- 网络network
- 数据卷Data Volumes
(2)Rest接口
提供与Daemon交互的API接口
(3)Docker Client
客户端使用REST API和Docker Daemon进行访问。
3.Docker平台组成
(1)镜像 Images
镜像是一个只读模板,用于创建容器,也可以通过Dockerfile文本描述镜像的内容。镜像的概念类似于编程开发里面向对象的类,从一个基类开始(基础镜像Base Image)。构建容器的过程,就是运行镜像,生成容器实例。
Docker镜像的描述文件是Dockerfile,包含了如下的指令
- FROM:定义基础镜像
- RUN:运行Linux命令
- ADD:添加文件/目录
- ENV:环境变量
- CMD:运行进程
(2)容器 Container
容器是一个镜像的运行实例,镜像>容器。
创建容器的过程
- 获取镜像,如docker pull centos ,从镜像仓库拉取
- 使用镜像创建容器
- 分配文件系统,挂载一个读写层,在读写层加载镜像
- 分配网络/网桥接口,创建一个网络接口,让容器和宿主机通信
- 容器获取IP地址
- 执行容器命令,如/bin/bash
- 反馈容器启动结果
(3)仓库 Registry
Docker镜像需要进行管理,docker提供 了Registry仓库,其实它也是一个容器。可以基于该容器运行私有仓库,也可以使用Docker Hub互联网公有镜像仓库。
六、Docker镜像原理
docker pull redis
拉取镜像
docker images
查看下载好的镜像
七、Docker常用命令
1.帮助命令
docker version # 显示docker的版本信息
docker info # 显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help # 帮助命令
2.镜像命令
(1)docker images
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的id
CREATED 镜像的创建时间
SIZE 镜像的大小
命令参数可选项
-a, --all # 显示所有镜像(docker images -a)
-q,--quiet # 仅显示镜像id(docker images -q)
(2)docker search(搜索镜像)
命令参数可选项
--filter=STARS=5000 # 搜索出来的镜像就是stars大于5000的
(3)docker pull(下载镜像)
docker pull 镜像名[:tag]
如果不写tag,默认就是latest,最新的版本。也可以指定版本下载
(4)docker rmi(删除镜像)
docker rmi -f 镜像id # 删除指定的镜像
docker rmi -f 镜像id 镜像id 镜像id # 删除多个镜像(空格分隔)
docker rmi -f $(docker images -aq) # 删除全部的镜像
3.容器命令
(1)新建容器并启动
docker run [可选参数] image
--name="name" 容器名字:用来区分容器
-d 后台方式运行:相当于nohup
-it 使用交互式运行:进入容器查看内容
-p 指定容器的端口(四种方式)小写字母p
-p ip:主机端口:容器端口
-p 主机端口:容器端口
-p 容器端口
容器端口
-P 随机指定端口(大写字母P)
(2)列出所有运行的容器
docker ps # 列车当前正在运行的容器
-a # 列出当前正在运行的容器+历史运行过的容器
-n=? # 显示最近创建的容器(可以指定显示几条,比如-n=1)
-q # 只显示容器的编号
(3)退出容器
exit # 容器直接停止,并退出
ctrl+P+Q #容器不停止,退出
(4)删除容器
docker rm 容器id # 删除容器(不能删除正在运行的容器)如果要强制删除:docker rm -f 容器id
docker rm -f $(docker ps -aq) # 删除全部容器
docker ps -a -q|xargs docker rm # 删除所有容器
(5)启停容器
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前容器
(6)其他命令
docker run -d 镜像名 # 后台启动容器
docker logs -tf --tail number 容器id # 查看日志, -tf:显示日志, --tail number:要显示的日志条数
docker top 容器id # 查看容器中进程的信息
docker inspect 容器id # 查看镜像的元数据
docker exec -it 容器id /bin/bash # 进入当前正在运行的容器,进入容器后开启一个新的终端,可以在里面操作(常用)
docker attach 容器id # 进入容器正在执行的终端,不能启动新的进程
docker cp 容器id:容器内路径 目的主机的路径 # 从容器内拷贝文件到主机
八、Docker镜像
Docker 镜像是用于创建 Docker 容器的只读模板。每个镜像都是由一系列的层(layers)组成,这些层是通过 Dockerfile 中的一系列指令构建而来的。镜像可以包含任何东西,从操作系统到预装软件再到配置好的环境。当启动一个容器时,实际是基于这个镜像来运行一个独立的、隔离的进程。
1.Docker镜像的主要特点
- 轻量级:Docker 镜像通常比传统的虚拟机镜像要小得多,因为它们共享宿主机的操作系统内核。
- 可移植性:Docker 镜像可以在支持 Docker 的任何平台上运行,这使得应用程序的部署更加简单和一致。
- 版本控制:通过 Dockerfile 文件,可以方便地对镜像进行版本控制,就像对待代码一样。
- 快速启动:由于 Docker 容器几乎不需要启动时间,基于镜像启动的容器可以在几秒钟内完成启动。
- 资源隔离:Docker 镜像保证了容器之间以及容器与宿主机之间的资源隔离。
2.镜像底层原理
(1)联合文件系统(UnionFS)
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。
Union 文件系统是Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
我们下载的时候看到的一层层的就是联合文件系统。
3.镜像加载原理
UnionFS分为两个部分:
bootfs(boot file system):主要包含bootloader和kernel(linux内核),bootloader主要是引导加载kernel,linux刚启动时会加载bootfs文件系统,而在Docker镜像的最底层就是bootfs这一层,这与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs(root file system):rootfs在bootfs之上。包含的就是典型Linux系统中的/dev,proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
我们可以理解成一开始内核里什么都没有,操作一个命令下载debian,这时就会在内核上面加了一层基础image;再安装一个emacs,会在基础镜像上叠加一层image;接着再安装一个apache,又会在images上面再叠加一层image。最后它们看起来就像一个文件系统即容器的rootfs。
在Docker的体系里把这些rootfs叫做Docker的镜像。但是,此时的每一层rootfs都是只读read-ony的,我们此时还不能对其进行操作。当我们创建一个容器,也就是将Docker镜像进行实例化,系统会在一层或是多层read-only的rootfs之上分配一层空的可读可写read-write的rootfs。
简单举例理解:
例如基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层,如果在该镜像中添加Python包,就会在基础镜像之上创建第二个镜像层,如果继续添加一个安全补丁,就会创建第三个镜像层。
平时我们安装到虚拟机的CentOS都是好几个G,为什么Docker这里才200M呢?
对于一个精简的OS,rootfs可以很小,只需要最基本的命令,工具和程序库就可以了。因为底层直接用Host的Kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。
九、容器数据卷
容器数据卷(Docker Volumes)是一种用于持久化数据的技术,它允许您将数据存储在独立于容器生命周期的地方。数据卷可以被多个容器共享,并且在容器停止或删除后仍然存在。使用数据卷有以下几个主要优点:
1.数据卷的主要优点:
(1)数据持久化
- 独立于容器:数据卷中的数据独立于容器的生命周期,即使容器被删除,数据卷中的数据仍然保留。
- 备份和恢复:可以轻松地对数据卷进行备份和恢复,而不影响容器的运行。
(2)数据共享
- 多容器共享:多个容器可以同时挂载同一个数据卷,实现数据共享。
- 跨主机共享:在集群环境中,可以使用分布式文件系统(如 NFS、GlusterFS)来实现跨主机的数据共享。
(3)性能优化
- 性能更好:数据卷通常比绑定挂载(bind mounts)具有更好的性能,特别是在处理大量 I/O 操作时。
2.创建和管理数据卷
(1)创建数据卷
使用 docker volume create
命令创建一个新的数据卷:
docker volume create my-volume
(2)查看数据卷
使用 docker volume ls
命令列出所有的数据卷:
docker volume ls
使用 docker volume inspect
命令查看特定数据卷的详细信息:
docker volume inspect my-volume
(3)删除数据卷
使用 docker volume rm
命令删除一个数据卷:
docker volume rm my-volume
3.在容器中使用数据卷
(1)启动容器时挂载数据卷
使用 -v
或 --volume
参数在启动容器时挂载数据卷。例如:
docker run -d -v my-volume:/data --name my-container nginx
在这个例子中,my-volume
是数据卷的名称,/data
是容器内的挂载点。
(2)使用匿名数据卷
如果不指定数据卷的名称,Docker 会自动创建一个匿名数据卷:
docker run -d -v /data --name my-container nginx
(3)使用 Docker Compose
在 docker-compose.yml
文件中定义数据卷:
version: '3'
services:
web:
image: nginx
volumes:
- my-volume:/data
volumes:
my-volume:
4.数据卷的类型
(1)普通数据卷
普通的 Docker 数据卷,默认存储在 Docker 主机的文件系统中。
(2)绑定挂载(Bind Mounts)
绑定挂载将主机上的一个文件或目录挂载到容器中。这种方式适用于开发环境,因为它可以直接访问主机上的文件:
docker run -d -v /host/path:/container/path --name my-container nginx
(3)临时卷(tmpfs)
临时卷将数据存储在主机的内存中,不会写入磁盘。这种方式适用于需要高速访问临时数据的场景:
docker run -d --tmpfs /tmp --name my-container nginx
十、Dockerfile
Dockerfile
是一个文本文件,其中包含了用于构建 Docker 镜像的一系列命令。通过Dockerfile
,您可以自动化镜像的构建过程,确保每次构建出的镜像都是一致的。
1.Dockerfile 的基本结构
一个典型的 Dockerfile
包括以下部分:
- 基础镜像:指定构建新镜像所基于的基础镜像。
- 维护者信息:(可选)指定镜像的作者信息。
- 安装软件包:安装运行应用程序所需的所有依赖项。
- 复制文件:将应用程序文件复制到镜像中。
- 设置工作目录:指定容器启动后的工作目录。
- 暴露端口:指定容器运行时需要开放的端口。
- 默认命令:指定容器启动时默认执行的命令。
2.Dockerfile 常用指令
(1)FROM:指定基础镜像。第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令。
FROM python:3.10-slim
(2)MAINTAINER:维护人信息(可选)。
(3)LABEL:添加元数据标签。
LABEL maintainer="yourname@example.com"
(4)WORKDIR:设置工作目录。
WORKDIR /app
(5)COPY:复制文件或目录到镜像中。
COPY . /app
(6)RUN:执行命令。
RUN pip install --no-cache-dir -r requirements.txt
(7)EXPOSE:声明容器运行时需要开放的端口。
EXPOSE 8080
(8)CMD:指定容器启动时默认执行的命令。两种格式:
exec格式(数值格式):ENTRYPOINT["要运行的程序","参数1","参数2"]
shell格式:ENTRYPOINT 命令 选项 参数
启动容器时默认执行的命令或者脚本,Dockerfile只能有-条CMD命令。如果指定多条命令,只执行最后一条命令。
如果在docker run时指定了命令或者镜像中有ENTRYPOINT,那么cmd就会被覆盖。
CMD可以为ENTRYPOINT 指令提供默认参数
命令在容器执行的优先级
docker run --entrypoint命令>ENTRYPOINT 命令>docker run 命令>CMD 命令
CMD ["python", "app.py"]
(9)ENTRYPOINT:配置容器启动时运行的可执行文件或命令。两种格式:
exec格式(数值格式):ENTRYPOINT["要运行的程序","参数1","参数2"]
shell格式:ENTRYPOINT 命令 选项 参数
设定容器启动时第一个运行的命令及其参数。
可以通过使用命令docker run --entrypoint 来覆盖镜像中的ENTRYPOINT指令的内容。
ENTRYPOINT ["python", "app.py"]
(10)ENV:环境变量值。设置一个环境变量的值,后被后面的RUN使用。
(11)ADD:将源文件复制到镜像中,源文件要与Dockerfile位于相同目录中,或者是一个URL。
ADD和COPY的共同点:
ADD和COPY都可以复制本地文件到镜像中。
ADD和COPY的区别:
ADD可以将本地tar包解压后复制到镜像目录,也支持下载源文件。但不支持下载和解压同时使用。
COPY不支持解压,不支持下载。
3.构建和运行镜像
(1)构建镜像:
docker build -t my-app:latest .
(2)运行容器:
docker run -d -p 8080:8080 my-app:latest
你学废了吗?