目录
- 一:Docker 容器介绍
- 1、容器技术的发展
- 2、容器的关键技术
- 3、Docker 发展历程
- 4、容器的运行效率
- 二:Docker 安装方式
- 1、在线安装 Docker
- 2、离线安装 Docker
- 二:Docker 数据目录
- 1、数据存储路径
- 2、子目录的作用
- 三:Docker 配置文件
- 1、默认配置文件
- 2、docker info
- 四:Docker 优化策略
- 五:Docker 网络模式
- 1、宿主机 docker 0 网卡
- 2、Docker 三种默认网络
- 3、自定义 Docker 网络
- 4、docker network
- 六:Docker 镜像存储
- 1、Docker 镜像特点
- 2、镜像和容器关系
- 七:Docker 镜像管理命令
- 1、docker load
- 2、docker save
- 3、docker rmi
- 4、docker images
- 5、docker inspect
- 八:Docker 实现数据持久化
- 1、容器的可写层介绍
- 2、Docker 数据卷机制
- 九:Docker 两种方式制作镜像
- 1、基于现有运行容器构建镜像
- (1)构建流程:
- (2)docker commit
- 2、基于 Dockerfile 构建镜像
- (1)构建流程:
- (2)Docker build
- 十:Docker 数据拷贝说明
- 1、docker cp
- 2、ocker cp 特点
- 十一:Docker容器创建
- 1、docker run
- 2、docker run 常用选项
- 十二:Docker 容器管理命令
- 1、docker ps
- 2、docker inspect
- 3、docker logs
- 4、docker rm
- 十三:Docker 容器中的进程
- 1、器中PID为1的进程
- 2、容器中的应用进程需要是前台进程原因:
- 十四:Docker 容器交互说明
- 1、docker exec
- 2、docker exec 切换到容器环境原理
- 3、docker exec 使用说明:、
一:Docker 容器介绍
1、容器技术的发展
生活中的容器指的是一种归纳物品工具,用来归纳物品,例如集装箱、盒子等都是容器。IT领域的容器时一种轻量级虚拟化技术,这种虚拟化技术比传统的虚拟机更加轻量化,性能更好。
早在1979年出现的 chroot 技术就是一种容器技术,后来随着时间的发展,也出现过很多种容器技术的解决方案,但是也因为各种缺陷导致没有真正流行起来。2013年 dotCloud(后面的Docker Inc) 公司开源了Dodkcer项目,这才使得容器技术真正流行使用起来。Docker是目前最成熟最完整的容器技术解决方案。所以Docker成为了容器技术的代名词,就像以太网是局域网的代名词一样。
2、容器的关键技术
容器技术的实现,主要是利用Linux内核的两大核心技术:NameSpace和Cgroup来实现。
NameSpace
:提供进程、网络、文件系统等的隔离,这样使得不同的进程运行环境不会发生干扰。Cgroups
:提供资源限制(如CPU、内存、磁盘I/O等),限制容器内进程的资源使用。
3、Docker 发展历程
早在Docker技术未出现之前,Linux内核提供了一种容器技术叫作LXC(Linux Containers),LXC使用Linux内核的namespace和cgroups等技术来实现进程隔离和资源管理,而不需要虚拟化完整的硬件,但是LXC技术也存在一定的局限性,所以没有大规模流行起来。
Docker 刚开始 就是基于Linux内核提供的LXC技术实现的,通过对LXC的二次封装,从而实现更强大的功能。后面随着Docker的发展,它也开发出了自己的核心容器技术叫作runc(Container Runtime)。Docker官网:https://www.docker.com/
Docker 组成部分:
- Docker 客户端:用户通过Docker客户端与Docker引擎交互,允许用户创建、管理容器、镜像等。
- Docker 服务端:也叫做Docker 引擎,是一个后台进程,负责容器的生命周期管理,每个容器在宿主机上表现为守护进程的一个子进程。
- Docker 运行时:
- 高级运行时(containerd):负责管理多个容器的生命周期,能协调和管理多个容器,会调用runc来实际启动容器。
- 低级运行时(runc):是一个底层工具,直接与内核交互,利用Linux内核的机制来提供容器的隔离、资源管理等功能来创建和运行容器。
- Docker 镜像:是一个只读的、包含应用程序及其依赖、配置文件、环境等的软件包,容器是基于镜像创建的,通过镜像提供的文件系统和配置来启动容器进程。
4、容器的运行效率
操作系统说明:
- 操作系统内核:操作系统的核心,负责与硬件直接交互并提供相关接口(如内存管理、进程调度、文件系统操作等)。
- 系统服务软件:利用内核接口提供更高级的服务,如网络管理、用户管理、文件访问等。它们依赖操作系统内核提供的功能来运行。
物理机直接运行应用程序:
应用程序直接部署到物理服务器上,并且安装相关依赖和库文件直接运行。
- 优点: 应用程序直接调用物理机操作系统提供的API与硬件交互,所以效率高,性能号。
- 缺点: 运行多个应用进程,有可能会出现依赖冲突的情况,并且迁移不方便。
虚拟机运行应用程序:
物理机运行虚拟机管理软件,虚拟机管理软件创建虚拟机,每个虚拟机里面包含一个完整的操作系统和对应的应用程序
- 优点: 不用应用进程的依赖之间不会冲突,方便迁移。
- 缺点: 整体体积较大,这种全虚拟化的方式性能不是很高。
容器运行应用程序:
宿主机上运行管理容器的引擎,然后通过对应的模板来创建容器,容器不需要单独的操作系统内核,而是直接使用物理机的操作系统内核。
容器中放需要运行的程序代码。依赖也要位于容器中,容器中运行运行程序需要的库、系统服务等。所以操作系统的系统服务部分是做为依赖存在于容器中,只有应用程序需要的服务,才会被集成到容器中。
- 优点: 接使用物理机的内核来调用硬件资源,性能好,性能能达到直接在宿主机上运行的95%左右,并且体积占用小,迁移方便。
- 缺点: 隔离性没有虚拟机好,因为所有容器都是用的宿主机内核,要是宿主机内核出问题,所以容器都会收到影响。
二:Docker 安装方式
Docker从2017年开始就分为社区版(CE 版本)和企业收费版(EE版本),在Linux操作系统中,使用的都是社区版本(community)(
1、在线安装 Docker
- Docker 提供的官方源:https://docs.docker.com/engine/install/
- 清华镜像源:https://mirrors.tuna.tsinghua.edu.cn/help/docker-ce/
2、离线安装 Docker
Docker 是采用Golang开发而来的,所以官方提供了静态编译的二进制文件,只需要下载对应的二进制包,然后解压到指定目录下即可。
Docker 引擎安装后,会调用iptables工具来创建对应的流量规则,从而实现网络流量隔离或流量转发。容器能够访问外部网络,同时允许外部流量通过宿主机的端口映射到容器,就是依靠的NAT规则设置,所以不能将NAT规则给清掉了,如果清空了重启引擎即可恢复。所以如果宿主机没有iptables工具或者版本太低,会导致Docker引擎安装不成功。
- 文档链接:https://docs.docker.com/engine/install/binaries/
- 官方下载链接:https://download.docker.com/linux/static/
- 清华源下载地址:https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/static/stable/
- 阿里源下载地址:https://mirrors.aliyun.com/docker-ce/linux/static/stable/
二:Docker 数据目录
Docker的所有核心数据(包括镜像、容器、卷、网络等)默认都存储在 Docker 的数据目录下。
1、数据存储路径
- 查看Docker数据存储路径:
docker info | grep "Docker Root Dir"
- Docker默认数据存储路径:
/var/lib/docker
2、子目录的作用
image
:存放Docker镜像相关数据。containers
:存放容器数据(容器的可写层),每个容器都有一个以容器ID命名的子目录,存放容器运行时的文件系统和配置。volumes
:指定挂载卷时,如果没有明确指定将容器目录映射到宿主机的某个特定路径,Docker 会自动创建一个数据卷,并将其存储在宿主机上的 volumes 目录下,目录名称是也给哈希字符串。network
:存放Docker网络的相关配置文件。builder
:通过DockerFile构建Docker镜像的时,存储与 Docker 镜像构建有关的临时文件和缓存。containerd
:存储 Docker 容器的运行时信息和状态。每个容器都会在这个目录下有一个以容器 ID 命名的子目录。包含该容器的日志、配置等信息。plugins
:存储 Docker 插件(如网络插件、存储插件等)的配置和状态信息。swarm
:启用了 Docker Swarm 集群模式,该目录将存储与集群管理、服务和任务的状态信息相关的数据。
三:Docker 配置文件
1、默认配置文件
Docker 引擎启动后,如果 /etc/docker/daemon.json
存在,会默认读取/etc/docker/daemon.json
文件中的相关配置,如果该文件不存在或为空,则Docker 会使用默认的配置。
Docker 的配置文件内容采用json格式,所以修改配置文件的时候需要按照json规则进行修改。
2、docker info
通过 docker info
命令可以常看当前Docker 引擎的状态和配置。
docker info
显示的信息说明:
Client: # 列出客户端相关信息Debug Mode: falseServer: # 列出服务端相关信息Containers: 0 # 容器数量Running: 0 # 运行中的容器数量Paused: 0 # 暂停的容器数量Stopped: 0 # 停止的容器数量Images: 2 # 当前宿主机中的镜像数量Server Version: 19.03.15 # Docker 引擎的版本Storage Driver: overlay2 # Docker 使用的存储驱动类型Backing Filesystem: extfs # 当前宿主机底层文件系统是 extfs,即 ext4Supports d_type: trueNative Overlay Diff: trueLogging Driver: json-file # 表示Docker 容器的日志以 JSON 格式保存在文件中Cgroup Driver: systemd # Docker 使用 systemd 来管理 cgroupPlugins:Volume: local # 使用 local 存储驱动来管理卷Network: bridge host ipvlan macvlan null overlay # Docker 支持多种网络驱动Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslogSwarm: inactive # 当前 Docker 容器没有启用 Swarm 模式Runtimes: runc # 当前使用的低级运行时类型Default Runtime: runc # 默认的低级运行时类型Init Binary: docker-init # Docker 初始化进程containerd version: ea765aba0d05254012b0b9e595e995c09186427f # Docker 使用的 containerd 版本runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd # 当前 Docker 使用的 runc 版本init version: fec3683 # 当前 Docker 使用的初始化程序的版本Security Options: # Docker 安全选项apparmor # 表示启用了 AppArmor 安全模块seccomp # 表示启用了 seccomp(安全计算模式)Profile: default # 表示使用的是 Docker 默认的 seccomp 配置文件Kernel Version: 5.15.0-119-generic # 宿主机内核版本Operating System: Ubuntu 20.04.6 LTS # 宿主机操作系统版本OSType: linux # 物理机的操作系统类型Architecture: x86_64 # 物理的系统架构CPUs: 4 # CPU数量Total Memory: 15.48GiB # 宿主机内存大小Name: ubuntu # 系统主机名ID: M3AO:DMTW:XHF4:BNY2:UAK7:P4KR:3FIQ:BSHP:XYSK:O7LG:ITBJ:LOKH # 引擎自动生成的唯一标识符,用于区分不同的主机Docker Root Dir: /var/lib/docker # Docker 数据目录路径Debug Mode: falseRegistry: https://index.docker.io/v1/ # 默认的Docker仓库地址Labels:Experimental: falseInsecure Registries: # 指定 不使用 HTTPS(即不安全) 的镜像仓库(Registry)地址192.168.0.7quay.ioregistry.access.redhat.com127.0.0.0/8Registry Mirrors: # 镜像加速器地址,通过指定加速器的地址来替代直接从 Docker Hub 拉取镜像https://gxhflhms.mirror.aliyuncs.com/Live Restore Enabled: true #表示Docker启用了Live Restore功能,即使 Docker 守护进程重启,容器和服务仍然可以继续运行,避免中断。Product License: Community Engine # Docker 的许可信息,表示你使用的 Docker 引擎是 社区版(CE)
四:Docker 优化策略
常见优化策略:
- 将一块高速硬盘单独挂载到 Docker 数据目录下,这样可以优化 Docker 性能。
- 设置镜像加速,默认从国内的某个站点拉取镜像,优化镜像的拉取速度。
- 默认 Docker 客户端是不允许通过非 HTTPS 协议与它们通信,通过将仓库地址添加到 insecure-registries 列表。
- 对对容器的日志进行限制,以避免日志文件无限制地增长,消耗过多的磁盘空间。
- 启用 live-restore 功能。实现重启引擎时仍然保持容器的正常运行,一般默认开启
配置文件修改项:
vim /etc/docker/daemon.json
{"data-root": "/data/docker","storage-driver": "overlay2","exec-opts": ["native.cgroupdriver=systemd"],"registry-mirrors": ["https://cmhp6tte.mirror.aliyuncs.com"],"insecure-registries" : ["192.168.0.7"],"log-driver": "json-file","log-opts": { "max-size": "30m", "max-file": "2" },"live-restore": true
}
五:Docker 网络模式
1、宿主机 docker 0 网卡
docker0 功能介绍:
Docker 引擎安装完成后,在宿主机上会生成一个名为 docker0 的网卡。docker0 默认的IP地址:172.17.0.1/16
。docker0 网卡是容器和容器、容器和物理机之间通信的媒介。
docker0 本质上是一个虚拟网络接口,它既有交换机的功能,也有路由器的一部分功能,还有DHCP功能。
docker0 地址修改:
docker0 网卡的IP地址一般是使用子网中的第一个可用地址(通常是 x.x.x.1
)作为其 IP 地址,并将该地址作为使用桥接模式容器的默认网关,使得容器在和宿主机或其他容器进行通信时,能够通过 docker0
来路由流量。
# 在 /etc/docker/daemon.json 中指定以下配置
"bip": "172.24.20.1/24"
2、Docker 三种默认网络
Docker 引擎安装后,默认会创建三个网络:bridge、host 和 none。
Bridge 模式
Bridge 模式是桥接模式,虚拟网卡 docker0 充当了网桥的作用,如果创建容器时没有指定网络模式,默认采用的就是桥接模式。在桥接模式下,容器内会生成一个名为 vethX
的虚拟网卡,虚拟网卡的IP地址信息由docker0进行分配,地址是docker0所在网段的地址。
- 容器和容器:此时docker0就充当交换机的角色,可以理解为容器之间都通过vethX网卡互联在一个交换机上,从而实现通信。
- 容器和宿主机:此时docker0充当路由器的作用,容器将流量发送给docker0后,docker0将流量转发给宿主机,宿主机通过路由共嗯那个将流量交给特定容器。
- 容器和外部网络:容器的流量通过docker0转发给宿主机后,宿主机通过设置的NAT转发规则,将流量通过物理网卡转发出去。所以宿主机需要开启
net.ipv4.ip_forward=1
,这样才能转发网络流量。
Host 模式:
Host 模式可以理解为没有通过 Namespace 对网络进行隔离,因为容器直接使用宿主机的网络堆栈。在 Host 网络模式下,容器共享宿主机的 IP 地址和网络接口,因此容器与宿主机之间的网络隔离几乎不存在。所以Host模式下,没有使用docker0进行网络中转,效率会非常高。
None 模式:
使用none模式创建的容器,该容器不会进行任何网络配置,其没有网卡、没有IP 也没有路由,所以没法和宿主机还有外部容器通信。如果希望容器完全与外部网络隔离,避免它能够与宿主机或其他容器进行任何网络通信时,可以使用 none
网络模式。
3、自定义 Docker 网络
Docker 允许自定义除了以上三种网络类型外的其他网络,创建自定义网络时需要指定网络驱动,常用的网络驱动有以下三个:
bridge
:容器连接到该网络后,会被分配到一个虚拟子网,能够通过该子网的 IP 地址相互通信。host
:容器和宿主机共享相同的 IP 地址,因此容器不会被分配独立的 IP 地址。none
:不为容器分配网络接口,也不允许容器与外部进行通信。
Docker 创建自定义网络:
docker network create -d 驱动名称 --subnet 网络号 --gateway 网关 网络名称
说明:
-
网络名称不同但驱动相同的网络(例如 brd1 和 brd2,都使用 bridge 驱动)默认情况下是不能直接通信,因为 Docker 网络是隔离的,每个自定义网络(即使是使用相同驱动)会有自己的网络命名空间。
-
这种网络隔离通常是通过 宿主机的 iptables 规则来实现的。Docker 使用 iptables 来管理和控制容器之间、容器与宿主机之间的流量。
4、docker network
查看当前的网络类型:docker network ls
NETWORK ID
:网络的唯一标识符,是 Docker 创建网络时自动生成的哈希值。NAME
:网络的名称。DRIVER
:网络使用的网络驱动程序,决定了该网络的工作方式和功能。常见的三种驱动是Bridge、Host和none。SCOPE
:网络的作用范围。local表示网络仅在本地主机上有效。global表示适用于跨多个 Docker 主机的网络。
创建默认网络类型:docker netowork create
-d
:指定网络驱动名称--subnet
:指定网络号,x.x.x.x/x--gateway
:指定网关地址
六:Docker 镜像存储
1、Docker 镜像特点
在 Docker 中,镜像(Image)是一个轻量级、可执行的独立软件包,它包含了运行某个应用所需的一切:代码、运行时、库、环境变量、配置文件等。镜像是用来创建容器的模板。
- 采用分层结构:简单理解就是将镜像导入宿主机后,镜像文件存储在Docker 数据存储目录下的images子目录中,一个镜像的文件存储在多个目录下。Docker引擎通过联合文件系统,将这多个目录整合成一个虚拟文件系统,通过将这个虚拟文件系统挂载后,这个挂载点就可以读取这些不同目录中的文件了。
- 权限是只读的:Docker 镜像中的文件和配置都是只读的,不能更改镜像中的文件信息。
2、镜像和容器关系
镜像中是只读的,通过镜像创建容器后,可以修改镜像中的原因: 镜像的数据存储在宿主机的若干个目录下,具体目录是Docker数据目录下的contaier子目录中。
通过镜像创建容器后,首先Docker引擎会通过联合文件系统将存储在宿主机上的若干目录整合为一个虚拟文件系统,然后会给容器创建一个可写层,这个可写层对应的目录是Docker数据目录下的container子目录中,以镜像名命名。
Docker引擎采用的是写实复制机制,当涉及到对某个文件修改时,会将这个文件复制到可写层下,容器对文件系统的所有修改都会保存在这个层中。
镜像删除后,这个可写层也会跟着删除,这也就是为什么没有做数据持久化的情况下,删除容器,所有数据也会丢失的原因。
七:Docker 镜像管理命令
1、docker load
作用: 将某个镜像导入宿主机中,如果宿主机上存在同名Tag的镜像,则宿主机上的tag会被置为空。
命令:
docker load -i image_name
docker load < image_name
说明:
- 会将镜像对应的tar包中的每层(目录)解压到Docker的数据存储目录下。
2、docker save
作用: 将宿主机上的镜像导出为一个tar包文件。
命令:
docker save -o > image image_save_name.tar
docker save image > image_name.tar
3、docker rmi
作用: 通过 codkr rmi 可以删除宿主机上的某个镜像,如果一个镜像存在多个tag,通过tag方式删除时,只会删除指定的tag,镜像不会被真正删除。
格式: docker rmi image_naem/image_id
说明:
- 使用 Tag 删除镜像: 如果镜像有多个 tag,通过某个tag删除镜像时,删除某个 tag 并不会删除实际的镜像文件,只是移除了该标签的引用。只要该镜像还有其他 tag 或者有其他容器依赖它,镜像文件本身会继续存在。
- 使用 ID 删除镜像: Docker 会删除与该 ID 关联的镜像文件。即使该镜像有多个 tag,所有指向该镜像的标签都会被删除。
4、docker images
作用: 查看当前宿主机上的镜像列表
命令: docker images
显示信息:
-
REPOSITORY
:镜像所在的仓库名称,一般是镜像名称。 -
TAG
:显示的是镜像的标签信息。 -
IMAGE ID
:显示的是镜像的ID(哈希字符串)信息 -
CREATED
:表示镜像生成的时间 -
SIZE
:显示镜像的大小
5、docker inspect
作用: 查看某个镜像的属性信息。
命令: docker inspect <image_name_or_id>
显示信息:
-
Id
:镜像的哈希字符串,用于唯一表示也给镜像。 -
RepoTags
:镜像的标签名称。 -
Created
:镜像的制作时间。 -
Size
:镜像的大小 -
GraphDriver
:镜像中每一层在宿主机的存储路径
八:Docker 实现数据持久化
1、容器的可写层介绍
默认情况下,创建一个容器时,Docker 会在容器的文件系统上创建一个可写层。这个可写层是容器运行时的数据存储区域,所有对文件系统的更改(如文件的写入、删除等)都会保存在这个层中。
这些更改保存在宿主机的 /var/lib/docker/container/<container_id>/ 目录下的容器目录中,容器目录的名字通常是容器的 ID 或容器的名称。
所以删除容器时,Docker 会删除该容器的可写层,因此所有存储在容器内部的非持久化数据也会被删除。
2、Docker 数据卷机制
数据卷(Volume)是Docker 提供的一种解决数据持久化问题的机制,是将容器内的特定目录可以与宿主机上的目录或 Docker 管理的卷进行映射。
将容器内的某个目录映射到宿主机的指定目录后,这样容器在运行时会将数据存储在宿主机指定的目录,而不是默认的容器可写层中。因为独立于容器生命周期,即使容器被删除,数据卷仍然存在于宿主机上,不会被删除,从而实现数据的持久化存储。
数据卷的作用:
- 数据持久化存储:通过数据卷,可以将容器中的重要数据(例如数据库文件、应用生成的数据等)存储在宿主机的文件系统中。这样,即使容器被删除,数据依然保存在宿主机上,不会丢失。
- 配置文件管理:配置文件需要持久化存储,并且可以方便修改。如果将配置文件存储在数据卷中,配置文件就不会随着容器的删除而丢失。
- 实现数据共享:容器通过挂载相同的数据卷,可以访问相同的数据,从而实现容器之间的数据共享。
数据卷的使用
创建容器时,通过 ==-v <宿主机目录>:<容器目录>
==实现将容器的目录映射到宿主机指定目录下。
如果只指定容器目录时,Docker 会自动在宿主机的默认存储路径下(通常是 /var/lib/docker/volumes/
)创建一个数据卷,并将容器的目录映射到这个自动生成的宿主机目录。
例如:docker run -d -v /data/nginx/:/etc/nginx nginx
九:Docker 两种方式制作镜像
很多时候现有的镜像不能满足实际生产的需求,这个时候就需要我们构建自定义的镜像。镜像构建的原理就是先基于某个镜像创建一个容器,此时容器涉及到文件系统的更改就会存储在可写层中。通过将容器的可写层和镜像的现有层进行打包。这样就形成了一个新的镜像。
1、基于现有运行容器构建镜像
(1)构建流程:
- 需要通过某个基镜像创建一个容器,然后进入容器里面做对应的文件系统层次的更改。
- 使用
docker commit container-name imagename:tag
这样就构建了一个新的镜像。 - 构建的新镜像是存储在宿主机上的,需要使用
docker save image_name > image_name.tar
将镜像导出为一个tar包。
构建特点:
- 在修复现有镜像的某个问题时候使用这种方式比较方便,某个镜像只会在特定项目上使用。
- 因为这种方式只会保留文件系统的变更,也就是只会保留文件的更改部分,不会记录非文件系统层面的状态变更(例如定义一个环境变量),所以如果涉及到非系统层面的变更,这种方式就不大合适。
- 使用这种方式构建的镜像,通过 docker history 没法看到镜像该层的构建信息。
(2)docker commit
- 作用: 在容器运行时对容器做出更改,并将这些更改保存为新的镜像
- 格式:
docker commit [OPTIONS] CONTAINER name:tag
- 选项:
-a
:指定镜像作者的名字和电子邮件-m
:为提交添加提交信息,描述镜像的更改。
2、基于 Dockerfile 构建镜像
Dockerfile 是一个文本文件的名字,通过在这个文本文件中编写对应的规则,从而实现镜像的构建。
(1)构建流程:
- 需要创建一个独立的目录,然后再该目录下编写Dockerfile文件,文件中包含了对应的规则。
- 使用
docker build -t image-name:tag .
构建镜像 - 构建的新镜像是存储在宿主机上的,需要使用
docker save image_name > image_name.tar
将镜像导出为一个tar包。
构建特点:
- 只需要编写好 Dockerfile文件,会自动进行构建操作。
- Dockerfile中的每个指令都对应镜像的一层,即使不对文件系统进行变更的指令也会创建一层,但这些层不会增加镜像的体积
- 不依赖当前容器的运行状态,所以可以构建若干个相同环境的镜像。
构建指令:
# FROM需要是Dockerfile中的第一个指令
From # 指定基础镜像,后续的指令会基于该镜像进行构建。是每个 Dockerfile 中必须的第一条指令。COPY # 将宿主机的文件或目录复制到镜像中的指定路径。ADD # 与 COPY 类似,但 ADD 还支持从 URL 下载文件并自动解压 .tar 文件CMD # 指定容器启动时默认执行的命令。如果在 docker run 命令中提供了命令参数,CMD 指令会被覆盖。ENTRYPOINT # 定义容器启动时执行的固定命令。ENTRYPOINT 指定运行的进程不会被docker run时指定的参数覆盖。ENV # 设置环境变量,环境变量在容器中全局生效ExPOSE # 声明容器将监听的端口,只是一个说明,表示容器会在运行时使用该端口RUN # 在镜像构建过程中执行命令,通常用于安装软件包、配置环境等LABEL 设置镜像的属性标签MAINTAINER 设置作者信息等USER # 默认为root,一般写在RUN的下面。指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。这个用户必须在镜像中存在。WORKDIR # 只是一个说明,表示容器会在运行时使用该端口,如果目录不存在会自动创建
注意事项:
-
减少镜像层数(合并 RUN 命令):
-
每个
RUN
指令都会在镜像中创建一个新的层,每个层都会占用磁盘空间。因此,减少镜像层数可以有效节省存储空间和构建时间。 -
多个命令可以通过 && 符号连接在一个 RUN 指令中执行,这样所有命令都会在同一层中执行,避免产生多个层。
-
-
分阶段构建和临时容器检查:
-
在构建镜像时,可能会有多个指令,涉及复杂的环境配置或软件安装。为了避免错误,可以分阶段构建镜像。
-
可以先构建一个基础镜像,然后通过 docker run 启动一个临时容器,检查镜像是否按预期工作,确认无误后再继续添加其他步骤。这样确保每次构建时都能验证结果。这有助于调试并防止构建过程中出现难以追踪的错误。
-
-
构建二进制文件时的多容器构建:
- 在构建过程中使用临时容器生成二进制文件,然后将其拷贝到最终镜像中。
(2)Docker build
-
作用: 根据
Dockerfile
中定义的指令,构建出自定义的 Docker 镜像。 -
格式:
docker build [OPTIONS] /path
-
选项:
-
-t
:为构建的镜像指定标签(名称:标签) -
-f
:指定Dockerfile
文件的位置,默认情况下,docker build
会寻找当前目录中的Dockerfile
文件。 -
--rm
:在构建完成后,删除中间容器,默认就是这样的。 -
--squash
:在构建过程中将所有层压缩成一个单独的层,这样可以减少镜像的层数,但也会导致层的历史丢失。
十:Docker 数据拷贝说明
1、docker cp
作用: 实现将容器中的文件,或者宿主机上的文件拷贝到容器中。因为拷贝的数据都是放在容器的可写层中的,可写层存储在宿主机的某个目录下,所以不一定要容器处于中才能进行文件拷贝,容器停止也可以拷贝文件。但是通过 docker cp 进行文件拷贝,一次只能拷贝一个文件。
命令: docker cp SOURCE_PATH DEST_PATH
SOURCE_PATH
:要复制的文件或目录的路径。可以是宿主机路径或容器路径。DEST_PATH
:目标路径。可以是容器路径或宿主机路径,取决于操作方向。
2、ocker cp 特点
- 如果需要拷贝某个目录,直接加目录路径即可,会自动复制整个目录的内容。
- 一次只能复制一个文件或目录,每次
docker cp
操作只能针对一个源路径(文件或目录)进行操作。
十一:Docker容器创建
1、docker run
通过 docker run 命令可以基于某个镜像来创建容器。
docker run 语法格式: docker run [OPTIONS] IMAGE_NAME [COMMAND] [ARG...]
OPTIONS
:可选的命令行参数,用于配置容器的行为、资源限制、挂载等。IMAGE
:用于创建容器的镜像名称。如果镜像不存在,Docker 会从默认的镜像仓库(如 Docker Hub)拉取该镜像。COMMAND
:容器启动时执行的命令(可选)。如果没有指定,Docker 会使用镜像中指定的默认命令。ARG...
:传递给 COMMAND 的参数(可选)。
2、docker run 常用选项
-
-d
:让容器在后台运行,并返回容器 ID,否则容器是前台运行,进程的日志输出会打印到终端。 -
-it
:组合了-i
和-t
两个选项,-i
让容器保持标准输入流打开,-t
为容器分配一个伪终端。用于交互式会话。 -
--name
:指定容器的名称,如果不指定会随机分配一个容器名称 -
-p
:将容器的端口映射到宿主机的端口。-p <宿主机端口>:<容器端口>
,如果只指定也给端口,则这个端口是容器的端口,会映射到宿主机的一个随机端口上。 -
--rm
:容器停止后自动删除容器。 -
--restart
:设置容器的重启策略,默认进程运行完成后,容器停止,不会自动重启。-
no
:不自动重启(默认)。 -
always
:容器停止时总是重启。 -
on-failure
:只有容器非正常退出时才重启。 -
unless-stopped
:停止容器时不再自动重启。
-
十二:Docker 容器管理命令
1、docker ps
作用: 查看宿主机上的容器列表。
命令:
- 查看当前正在运行的容器:
dockder ps
- 查看当前宿主机上所有容器:
docker ps -a
输出信息:
CONTAINER ID
:一个哈希字符串,用于唯一表示一个容器。IMAGE
:容器时通过哪个镜像创建。COMMAND
:容器启动时运行的命令。如果容器启动时没有指定命令,COMMAND
会显示镜像中默认的命令。CREATED
:容器的创建时间。STATUS
:当前容器的状态PORTS
:构建容器时,通过EXPOSE申明的端口号NAMES
:容器名称
2、docker inspect
作用: 通过 docker inspect 可以查看某个容器的属性信息。
格式: docker inspect 容器名/容器ID
输出说明:
State
:容器当前的状态Config
:容器的配置信息NetworkSettings
:容器的网络配置信息Mounts
:容器的数据卷挂载信息HostConfig
:容器的主机配置,涉及到主机和容器的资源限制、网络模式、挂载点等LogPath
:容器的日志文件路径,通常显示容器日志的文件位置。
3、docker logs
作用: 容器中的应用进程都是以前台进程的形式运行,通过docker logs 可以查看容器中PID为1的进程的标准输出、标准错误信息,但是如果某个容器中进程的输出是写入日志文件或通过网络日志系统进行管理,则docker logs就没法看到输出信息。
格式: docker logs 容器名/容器ID
- docker logs 常用选项:
-
-f
:实时查看日志输出,类似于tail -f
命令 -
--tail
:只显示容器日志的最后几行,也可以指定显示最后多少行日志(例如,--tail 100
)。 -
-t
:为每一行日志添加时间戳,显示日志的产生时间。
-
4、docker rm
作用: 用于删除某个容器
命令:
docker rm container_name/container_ID
docker rm container_name/container_ID (删除运行中的容器)
说明:
- 容器删除后,容器对应的可写层(存放容器的数据信息等)也会跟着被删除,所以如果没有做数据持久化,需要谨慎操作。
十三:Docker 容器中的进程
1、器中PID为1的进程
在物理机上,PID 1 的进程是 init 进程,它是系统启动时内核启动的第一个用户空间进程,负责初始化系统并管理其他进程。
Docker 容器中,Docker 的设计思想是将容器中的应用进程作为 PID 1 进程启动。所以容器中的主进程必须是前台进程,以确保容器的正常管理和生命周期。
2、容器中的应用进程需要是前台进程原因:
- 容器生命周期依赖于 PID 1 进程: Docker 容器中,容器的生命周期是由容器中的 PID 1 进程决定,PID 1 的进程退出或崩溃,整个容器也会停止。因此,容器中的主进程必须持续运行,直到容器显式停止。
- Docker 信号处理机制决定: Docker 管理容器的方式是通过向容器的 PID 1 进程发送信号。如果容器中的进程是后台进程,它通常不会正确处理这些信号,可能导致容器无法优雅地停止或清理资源。
- 简化容器的状态监控: Docker 监控容器的状态是通过主进程的状态来判断的。如果应用进程在后台运行,而容器的 PID 1 进程是其他前台进程,Docker 将只监控 PID 1 进程的状态。假设应用进程崩溃或挂起,但 PID 1 进程仍然在运行,Docker 可能会误判容器仍然正常运行,从而导致容器状态的不准确。
十四:Docker 容器交互说明
1、docker exec
容器运行后,容器中的应用进程就像在宿主机上直接运行的一样,但由于 Docker 使用 Namespace 技术对容器进行环境隔离,所以容器内的进程拥有自己的进程空间、网络栈、挂载点等, 看起来就像是在独立的系统中运行。
如果要对容器的进程进行管理,需要通过 docker exec 命令切换到容器原本隔离的运行环境,这样才能实现在该进程的运行环境下对进程进行管理。
2、docker exec 切换到容器环境原理
- 执行 docker exec 命令时,Docker 会在指定的容器内启动一个新的进程。这个进程是容器内的 子进程,它会在容器的隔离环境中运行。
- 通过 -it 参数来将这个新启动进程的 标准输入(stdin)、标准输出(stdout) 和 标准错误(stderr)连接到宿主机,这样就实现了在宿主机终端与容器中隔离的环境进行交互。
3、docker exec 使用说明:、
作用: 通过切换到容器隔离的运行环境,然后在容器运行环境中运行一个指定的子进程
命令: docker exec -it container-name command
选项说明:
-i
:使由docker exec
启动的容器内进程的标准输入(stdin)保持打开状态,允许你向容器内的进程发送输入数据。没有-i
时,docker exec
启动的进程无法接收标准输入。-t
:为通过docker exec
启动的容器内进程分配一个伪终端(TTY)。没有-t
,启动的进程不会有交互式终端功能,像命令提示符、颜色显示等交互特性将不可用。