1. 概念
容器是一种虚拟化技术,用于在操作系统级别隔离应用程序和其依赖的运行环境。它将应用程序及其所有依赖项(如库、运行时环境、配置文件等)打包到一个独立的、可移植的单元中,称为容器。容器可以在不同的计算机上运行,而无需担心环境差异和依赖冲突。
Docker 是一种开源的容器化平台,用于构建、部署和运行应用程序。它基于容器化技术,通过将应用程序及其所有依赖项打包到一个独立的、可移植的容器中,实现了应用程序的快速交付、可移植性和可扩展性。
2. Docker 容器虚拟化的优点
Docker 容器虚拟化具有许多优点,使其成为现代应用程序开发和部署的首选解决方案。以下是 Docker 容器虚拟化的一些主要优点:
- 轻量级和高性能:Docker 容器是基于操作系统级别的虚拟化,与传统的完整虚拟机相比,容器更加轻量级。容器共享宿主机的操作系统内核,因此启动更快、占用更少的资源,并且具有更低的性能开销。
- 可移植性:Docker 容器提供了一种可移植的应用程序打包和交付方式。容器包含了应用程序及其所有依赖项,可以在不同的环境中运行,无论是开发、测试还是生产环境,都能保持一致的运行行为。
- 隔离性:Docker 容器提供了隔离的运行环境,使应用程序和其依赖之间相互隔离。每个容器都有自己的文件系统、进程空间和网络接口,使应用程序之间不会相互干扰,减少了依赖冲突和环境差异的问题。
- 可扩展性:Docker 容器可以根据需要进行水平扩展,以满足不同负载和流量的需求。通过简单地复制和启动多个相同的容器实例,可以实现应用程序的弹性扩展。
- 简化部署和管理:Docker 提供了一套简单而强大的工具和命令,使应用程序的部署、管理和维护变得更加容易。通过 Docker,可以轻松地创建、启动、停止、暂停和销毁容器,而不会影响其他容器或宿主机系统。
- 生态系统和社区支持:Docker 拥有庞大的生态系统和活跃的社区支持。有许多公共的镜像注册中心(如 Docker Hub)可供使用,可以方便地获取和共享常用的容器镜像。此外,社区提供了大量的文档、教程和支持资源,使学习和使用 Docker 变得更加容易。
3. Docker 安装
# 如果安装过docker先卸载
sudo yum remove docker docker-common docker-selinux docker-engine -y
# 安装依赖包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加国内yum软件源
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装docker-ce
sudo yum -y install docker-ce
# 设置开机启动 Docker CE
sudo systemctl enable docker
sudo systemctl start docker
# 配置国内镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors" :
[
"https://u5l3r88m.mirror.aliyuncs.com",
"https://docker.m.daocloud.io",
"https://docker.udayun.com",
"https://noohub.ru",
"https://huecker.io",
"https://dockerhub.timeweb.cloud"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
# 查看容器版本
docker version
Bash4. Docker 镜像相关常用命令
4.1. 搜索镜像命令 search
docker search 命令用于在 Docker Hub 上搜索 Docker 镜像。它允许您根据关键字搜索镜像,并获取与搜索条件匹配的镜像列表。
# 格式
docker search [OPTIONS] TERM
# OPTIONS:可选参数,用于进一步定制搜索行为。常用的选项包括 --filter、--format 等。
# TERM:要搜索的关键字或表达式。
# 常用的 docker search 命令示例:
# 搜索特定关键字的镜像:
docker search ubuntu
# 使用过滤器筛选搜索结果:
# 搜索官方镜像
docker search --filter "is-official=true" ubuntu
# 搜索收藏数大于等于600的镜像
docker search --filter "stars=600" ubuntu
# 指定输出格式:
docker search --format "table {{.Name}}\t{{.Description}}" ubuntu
# 限制搜索结果的数量:
docker search --limit 5 ubuntu
Bash4.2. 拉取镜像命令 pull
docker pull 命令用于从 Docker 镜像仓库中拉取(下载)一个或多个镜像到本地系统。
# 格式
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
# OPTIONS:可选参数,用于进一步定制拉取行为。常用的选项包括 --all-tags、--platform 等。
# NAME[:TAG|@DIGEST]:要拉取的镜像的名称、标签或摘要。
# 拉取指定版本的镜像:
docker pull ubuntu:20.04
# 拉取最新版本的镜像:
docker pull ubuntu:latest
Bash4.3. 查看本地镜像命令 images
# 格式
docker images 或者 docker image ls
# 参数
-q : 只显示镜像ID
docker images -q
621ceef7494a
Bash4.4. 查看镜像详细信息命令 inspect
# 格式
docker inspect [镜像名称或镜像id]
# 参数
-f : 格式化输出
docker inspect -f '{{.Id}}' 621ceef7494a
sha256:621ceef7494adfcbe0e523593639f6625795cc0dc91a750629367a8c7b3ccebb
docker inspect -f '{{.ContainerConfig.Hostname}}' redis
16535cfaf84a
Bash4.5. 登录镜像仓库命令 login
# 格式
docker login
# 注:默认情况下,docker login登录的是官方仓库,如果登录其他镜像仓库则需要指定镜像仓库的URL连接。
# 参数
--username|-u : 指定用户名
--password|-p : 指定密码
docker login -u 1426115933
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
docker login --username=pingk registry.cn-hangzhou.aliyuncs.com
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
cat .docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "MTQyNjExNTkzMzpXdTE1NTg4MTk4OTA5LjA="
},
"registry.cn-hangzhou.aliyuncs.com": {
"auth": "5q2m5a6c5biFOld1MTU1ODgxOTg5MDkuMA=="
}
}
}
Bash4.6. 镜像添加标签命令 tag
# 镜像标签的构成
docker.io/library/redis:latest
docker.io # 镜像仓库的URL
library # 镜像仓库命名空间
redis # 镜像名称
latest # 镜像版本号
# 打标签
# 格式
docker tag [镜像ID] 镜像标签
# 示例
docker tag 621ceef7494a registry.cn-hangzhou.aliyuncs.com/wxyuan/test/redis:v1
Bash4.7. 上传镜像命令 push
# 格式
docker push [镜像标签]
# 注:要想上传镜像,首先得登录镜像仓库,其次设置对应镜像仓库的tag
docker push registry.cn-hangzhou.aliyuncs.com/wxyuan/test/redis:v1
The push refers to repository [registry.cn-hangzhou.aliyuncs.com/wxyuan/test/redis]
3480f9cdd491: Pushed
a24a292d0184: Pushed
f927192cc30c: Pushed
1450b8f0019c: Pushed
8e14cb7841fa: Pushed
cb42413394c4: Pushed
v1: digest: sha256:7ef832c720188ac7898dbd8d1e237b0738e94f94fc7e981cb7b8efe84555e892 size: 1572
Bash4.8. 删除镜像命令 rmi
# 格式
docker rmi [镜像名称或者镜像ID]
# 示例
docker rmi redis
Untagged: redis:latest
Untagged: redis@sha256:0f97c1c9daf5b69b93390ccbe8d3e2971617ec4801fd0882c72bf7cad3a13494
# 参数
-f : 强制删除
# 示例
docker rmi -f 621ceef7494a
Bash4.9. 清空本地镜像命令 image prune
docker image prune 命令用于清理不再使用的 Docker 镜像。
# 格式
docker image prune [OPTIONS]
# OPTIONS:可选参数,用于进一步定制清理行为。常用的选项包括 -a、--filter、--force 等。
# 示例
# 清理所有无用的镜像:
docker image prune
# 清理所有无用的镜像及其关联的未使用的镜像层:
docker image prune -a
# 根据过滤条件清理镜像:
# 清理过去24小时未使用的镜像
docker image prune --filter "until=24h"
# 强制清理镜像而不进行确认提示:
docker image prune --force
Bash4.10. 查看镜像构建历史命令 history
# 格式
docker history [镜像ID或镜像名称]
# 示例
docker pull alpine
Using default tag: latest
latest: Pulling from library/alpine
596ba82af5aa: Pull complete
Digest: sha256:d9a7354e3845ea8466bb00b22224d9116b183e594527fb5b6c3d30bc01a20378
Status: Downloaded newer image for alpine:latest
docker.io/library/alpine:latest
docker history alpine:latest
Bash4.11. 保存容器为镜像命令 commit
# 保存正在运行的容器直接为镜像
# 格式:
docker commit [容器ID|容器名称] 保存名称:版本
# 参数
-a 镜像作者
-p 提交期间暂停容器
-m 容器说明
# 示例
docker commit -a "xiaowu" -m "小武的容器" -p ebb852aefe0a test:v1
sha256:a9297902755a4ede3ce38c2717515626c678b6deae50206071a0a29ebcd208a9
Bash4.12. 保存容器为镜像包 export/import
# export保存正在运行的容器为镜像包
## 保存容器为镜像
docker export [容器的ID] > [包名称]
# 实例
docker export ebb852aefe0a > nginx:v1.tar
ll
-rw-r--r-- 1 root root 135403008 Mar 18 21:05 nginx:v1.tar
# import 将镜像包解为镜像
## docker import [包名称] [自定义镜像名称]
# 实例
docker import nginx:v1.tar nginx:v2
sha256:59bde51898fa443281782320b194d5e139c37ece32528843bb26d444800265ab
Bash4.13. 保存镜像为镜像包 save/load
# save保存镜像为镜像包
# 保存镜像的格式:
docker save [镜像名称|镜像ID] > [包名称]
# 示例
docker save alpine > alpine.tar
ll
-rw-r--r-- 1 root root 5889024 Mar 18 21:10 alpine.tar
-rw-r--r-- 1 root root 135403008 Mar 18 21:05 nginx:v1.tar
# load 将镜像包导入为镜像
docker load < [包名称]
# 示例
docker load < alpine.tar
Loaded image: alpine:latest
# 注:save/load保存镜像无法自定义镜像名称,save保存镜像时如果使用ID保存则load导入镜像无名称,使用名称导入时才有名称
Bash5. Docker 容器相关常用命令
5.1. 拷贝容器内文件
docker cp
命令只能用于运行中或已停止的容器,不能直接操作镜像内的文件。
# 本地文件拷贝到容器
docker cp /tmp/a.txt test:/usr/share/nginx/html/a.txt
# 容器test的文件拷贝到本地
docker container cp test:/usr/share/nginx/html/a.txt /tmp/
Bash5.2. 运行容器命令
# 基本语法
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
# 常用选项
## 容器运行模式
-d, --detach # 后台运行容器
--rm # 容器退出时自动删除
-it # 交互式运行(通常组合使用 -i 和 -t)
## 容器命名与标识
--name # 为容器指定名称
--hostname # 设置容器主机名
## 网络配置
-p # 映射容器端口到主机
--network # 连接容器到指定网络
--dns # 设置自定义 DNS 服务器
## 资源限制
-m, --memory # 内存限制
--memory-swap # 内存+交换分区限制
--cpus # CPU 数量限制
## 存储与卷
-v, --volume # 挂载卷
## 环境变量
-e, --env # 设置环境变量
--env-file # 从文件读取环境变量
## 安全选项
--user # 指定运行用户
--read-only # 以只读模式运行容器
# 使用示例
# 运行一个简单的容器并立即退出
docker run ubuntu echo "Hello World"
# 运行后自动删除容器
docker run --rm alpine echo "This container will self-destruct"
# 以交互模式运行容器
docker run -it ubuntu bash
# 后台运行 Nginx 并映射端口,主机端口:容器端口
docker run -d -p 8080:80 --name mynginx nginx
# 挂载主机目录作为数据卷
docker run -v /host/path:/container/path some-image
# 设置环境变量并限制内存
docker run -e MYVAR=value -m 512m some-image
Bash5.3. 容器挂载目录与挂载卷
在 Docker 中,挂载目录(Bind Mounts) 和 挂载卷(Volumes) 都是将主机文件系统中的数据映射到容器内部的方式,但它们在实现、管理和使用场景上有重要区别。
- 挂载目录
- 直接绑定主机文件系统的某个目录到容器,依赖于主机的文件系统结构。
- 特点
- 路径直接映射:必须指定主机的绝对路径和容器的目标路径。
- 依赖主机目录结构:如果主机目录不存在,Docker 不会自动创建(某些情况下会报错)。
- 性能较高:直接访问主机文件系统,适合频繁读写的场景。
- 适合开发调试:修改主机文件会直接影响容器,反之亦然。
- 适用场景
- 开发环境(代码热更新)
- 需要直接修改主机配置文件(如
nginx.conf
) - 共享主机上的特定数据(如日志、临时文件)
- 使用方式
docker run -v /host/path:/container/path image_name
Bash- 挂载卷
- 由 Docker 管理的存储方式,存储在 Docker 的存储目录(
/var/lib/docker/volumes/
),与主机文件系统隔离。 - 特点
- Docker 管理:卷由 Docker 创建和管理,不依赖主机路径。
- 自动创建:如果卷不存在,Docker 会自动创建。
- 跨容器共享:多个容器可以挂载同一个卷。
- 备份和迁移方便:支持
docker volume
命令管理(如docker volume create
)。 - 适合生产环境:更安全,不受主机目录变化影响。
- 适用场景
- 数据库存储(如 MySQL、PostgreSQL)
- 持久化应用数据(如配置文件、用户上传文件)
- 多个容器共享数据(如日志聚合)
- 使用方式
- 由 Docker 管理的存储方式,存储在 Docker 的存储目录(
docker run -v volume_name:/container/path image_name
Bash5.4. docker volume 命令
# 创建 Volume
docker volume create [OPTIONS] <VOLUME_NAME>
# 示例:这会创建一个名为 my_volume 的 Docker 卷,存储在 /var/lib/docker/volumes/ 下。
docker volume create my_volume
# 查看已创建的 Volume
docker volume ls
# 输出示例:
DRIVER VOLUME NAME
local my_volume
# 查看 Volume 详细信息
docker volume inspect my_volume
# 输出示例:
[
{
"CreatedAt": "2023-10-05T12:00:00Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my_volume/_data",
"Name": "my_volume",
"Options": {},
"Scope": "local"
}
]
# Mountpoint 是卷在主机上的实际存储路径(默认在 /var/lib/docker/volumes/)。
# 删除 Volume
docker volume rm my_volume
# 注意:如果卷正在被容器使用,需先删除容器。
# 高级选项
## 指定驱动(Driver),默认使用 local 驱动,但可以指定其他存储驱动(如 nfs、azurefile)
docker volume create --driver local my_volume
## 添加标签(Labels)
docker volume create --label env=prod db_volume
## 设置权限,某些存储驱动支持权限配置,以 nfs 为例
docker volume create --opt type=nfs --opt device=:/nfs/share --opt o=addr=192.168.1.1 nfs_volume
Bash5.5. 操作容器相关命令
# 查看容器
docker ps -a # -a 包括停止运行的容器
docker container ls -a # 与上述命令功能完全相同
# 进入容器
docker exec -it test sh
# 停止与启动
docker stop test
docker start test
docker restart test
# 删除
docker container rm -f test
Bash6. 制作镜像
构建镜像推荐使用 Dockerfile 文件。Dockerfile 是一个文本文件,包含了一系列用于构建 Docker 镜像的指令。下面详细介绍 Dockerfile 的语法、指令等。
6.1. Dockerfile 基本结构
一个典型的 Dockerfile 包含以下部分:
- 基础镜像声明
- 元数据信息
- 系统依赖安装
- 应用代码复制
- 运行时配置
6.2. 常用指令详解
FROM
指定基础镜像,必须是 Dockerfile 的第一条指令(除 ARG 外)。
FROM ubuntu:20.04
# 或者
FROM python:3.9-slim
DockerfileLABEL
为镜像添加元数据,以键值对形式表示。
LABEL maintainer="your.email@example.com"
LABEL version="1.0"
LABEL description="This is a custom Docker image"
DockerfileRUN
执行命令并创建新的镜像层,常用于安装软件包。
RUN apt-get update && apt-get install -y \
package1 \
package2 \
&& rm -rf /var/lib/apt/lists/*
DockerfileCOPY
把宿主机上 Dockerfile 所在的目录下的某个文件拷贝的容器内。
COPY ./app /app
COPY requirements.txt /tmp/
DockerfileADD
类似于 COPY,但功能更多(支持 URL 和解压 tar 文件)。
ADD https://example.com/file.tar.gz /tmp/
ADD file.tar.gz /tmp/
DockerfileWORKDIR
设置工作目录,相当于 cd
命令。
WORKDIR /app
DockerfileENV
设置环境变量。
ENV NODE_ENV=production
ENV APP_PORT=3000
DockerfileARG
定义构建时的变量,构建结束后不会保留。
ARG APP_VERSION=1.0
DockerfileEXPOSE
用于声明容器在运行时监听的网络端口,它的主要作用是文档化和辅助通信,但不会自动将端口映射到宿主机。EXPOSE
只是声明,如果容器内的服务没有真正监听该端口,声明无效。
EXPOSE 80
EXPOSE 443
DockerfileCMD
指定容器启动时运行的命令(只能有一个 CMD,多个时最后一个生效)。
CMD ["python", "app.py"]
DockerfileENTRYPOINT
配置容器启动时运行的命令(与 CMD 配合使用)。
ENTRYPOINT ["python"]
CMD ["app.py"]
DockerfileVOLUME
创建挂载点,用于持久化数据。启动容器时会在宿主机上自动创建匿名卷,然后关联到下述的容器目录中。
VOLUME /data
# 创建多个匿名卷,然后分别挂载到列表中指定的多个目录下
VOLUME ["/aaa","/bbb","/ccc","/var/www/html","/var/lib/mysql"]
DockerfileUSER
指定运行容器时的用户名或 UID。
USER appuser
Dockerfile6.3. 示例
Dockerfile 文件:
# 使用官方Python运行时作为基础镜像
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 设置环境变量
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# 安装系统依赖
RUN apt-get update \
&& apt-get install -y --no-install-recommends gcc \
&& rm -rf /var/lib/apt/lists/*
# 安装Python依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 8000
# 运行命令
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app.wsgi"]
Dockerfile构建镜像:
docker build -t myapp:latest .
Bash6.4. Dockerfile 多阶段构建
Docker 17.05 版本以后,支持了多阶段构建,允许一个 Dockerfile 中出现多个 FROM 指令,每个 FROM 对应一个阶段,最后生成的镜像以最后一个 FROM 为准。FROM 指令中能够将前置阶段中的文件拷贝到后边的阶段中。示例:
# 构建阶段
FROM golang:1.16 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .
# 运行阶段
FROM scratch
WORKDIR /root/
# 拷贝编译阶段中的编译结果到当前镜像中
COPY --from=builder /app/myapp .
CMD ["./myapp"]
# scratch 是内置关键词,并不是一个真实存在的镜像。FROM scratch 会使用一个完全干净的文件系统,不包含任何文件。因为Go语言编译后不需要运行时,也就不需要安装任何的运行库。FROM scratch可以使得最 后生成的镜像最小化,其中只包含了server程序。
Dockerfile使用场景:
- 最大的使用场景是将编译环境和运行环境分离,最终的镜像里只有执行程序就行,其他编译过程需要的包都扔掉了,可以显著精简镜像。