Docker基础知识整理单
注:整理Docker基础的概念、原理、常用命令和常见问题和解决方法,作为备忘,也方便广大学生学习参考。
一、什么是Docker
Docker是一种开源的容器化平台,允许开发者将应用程序及其所有依赖项打包到一个标准化的单元中,称为容器。这个容器可以在任何支持Docker的环境中运行,提供了一种轻量级、可移植、自给自足的解决方案。
小结一下:一次配置,处处运行,开箱即用!
二、为什么需要Docker
一致的运行环境:
- Docker可以确保应用程序在开发、测试和生产环境中具有一致的运行环境,消除了“在我的机器上可以运行,而在你的机器上却不行……”的问题。
轻量级的虚拟化:
- Docker容器与传统虚拟机相比更轻量,更快速启动,占用更少的系统资源,提高了系统的利用率。
快速部署与扩展:
- Docker容器可以在几秒钟内启动,比传统的虚拟机更为迅速。同时,容器可以轻松水平扩展,适应不同的负载需求。
环境隔离与安全性:
- Docker利用容器技术提供了良好的隔离性,确保应用程序互不影响。每个容器都运行在其独立的命名空间中,降低了安全风险。
简化配置与持续集成:
- Docker通过Dockerfile提供了简单而强大的配置方式,使得应用的部署变得更为简便。与持续集成工具(如Jenkins)结合,可以实现自动化的构建与部署流程。
更高的资源利用率:
- 由于容器共享主机内核,避免了虚拟机的资源浪费,提高了系统资源的利用率。
三、Docker与VM虚拟机的对比
上图显示Docker与VM架构的上的不同。
下表做一些对比归纳:
VM | DOCKER | |
---|---|---|
底层引擎 | Hpyervisor | Docker引擎 |
封装类型 | 包含操作系统OS | 包含程序运行的环境(类、库) |
存储大小 | 大(一般以GB为单位) | 小(一般以MB为单位) |
启动速度 | 慢(跟操作系统启动一样) | 快 |
可集成性 | 比较独立,难集成! | 容易搭配其他Docker一起部署服务 |
是不是一目了然?
四、Docker的特点与核心概念
Docker技术特性
- 进程隔离
- 定义: 进程隔离是容器化技术的核心概念之一,它确保一个容器内的进程不会影响到其他容器或主机系统。每个容器都有自己独立的进程空间,运行在隔离的用户空间。
- 优势: 提高安全性,确保容器内的应用程序不会干扰其他容器或主机上运行的进程。
- 文件系统隔离
- 定义: 文件系统隔离确保每个容器都有自己独立的文件系统,不受其他容器的影响。容器内的文件系统是轻量的,包含应用程序及其依赖项。
- 优势: 确保容器内的应用程序能够以自己的方式组织和管理文件,不会相互干扰。
- 网络隔离
- 定义: 网络隔离确保每个容器都有独立的网络命名空间,拥有自己的网络接口、IP地址和端口。这使得容器可以独立运行,并在网络上互不干扰。
- 优势: 提供了更灵活的网络配置选项,容器之间的通信不会直接影响到其他容器。
- 资源隔离
- 定义: 资源隔离是确保容器在使用系统资源(如CPU、内存)时不会影响其他容器或主机的关键方面。通过资源限制和分配,每个容器都获得了一定的资源份额。
- 优势: 提高系统的稳定性和可靠性,防止容器之间的资源争夺导致性能下降。
Docker的核心概念
- 镜像(Images)
- 定义: 镜像是Docker的基本构建块,它包含了运行应用程序所需的一切,包括代码、运行时、系统工具、库以及设置。镜像是只读的,是静态存档。
- 作用: 镜像是容器的基础,通过镜像可以创建运行相同环境的容器实例。
- 操作: 镜像可以从仓库拉取,也可以通过Dockerfile构建。
- 容器(Containers)
- 定义: 容器是由镜像创建的运行实例,是一个轻量级、独立、可执行的软件包,包含运行一个应用程序所需的所有内容,可以说是动态运行的。
- 作用: 容器提供了一种隔离的执行环境,使应用程序在不同的环境中具有一致的运行表现。
- 操作: 容器可以启动、停止、删除,也可以与外部系统进行交互。
- 仓库(Registry)
- 定义: 仓库是用于存储和组织镜像的地方,可以是公共的,也可以是私有的。Docker Hub是一个常用的公共仓库,而私有仓库则可以在内部搭建。
- 作用: 仓库使得镜像的分享、存储、版本控制更加方便。
- 操作: 镜像可以从仓库拉取,也可以推送到仓库。
- Dockerfile
- 定义: Dockerfile是一个包含了一组指令的文本文件,通过这些指令可以构建一个Docker镜像。它描述了如何从基础镜像构建自定义的镜像。可以理解为构建Docker镜像的脚本,可以无限回放(生成多个镜像)。
- 作用: Dockerfile提供了一种自动化、可重复的构建镜像的方式,使得镜像的创建过程变得可控。
- 操作: Dockerfile中包含了一系列指令,如FROM、RUN、COPY等,用于指导构建过程。
五、Docker的安装与配置(以CentOS7为例)
- 安装 Docker
首先,确保已经卸载了旧版本的 Docker。
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
接下来,安装 Docker 的依赖包。
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
添加 Docker 的官方仓库。
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
安装 Docker。
sudo yum install docker-ce docker-ce-cli containerd.io
- 启动 Docker 服务
sudo systemctl start docker
- 设置 Docker 开机自启
sudo systemctl enable docker
- 验证 Docker 安装
运行一个简单的测试容器,例如 hello-world
。
sudo docker run hello-world
如果看到 “Hello from Docker!” 字样,说明 Docker 已经成功安装并运行。
- Docker 配置加速器(可选)
在国内使用 Docker 时,建议配置镜像加速器以加速镜像的下载。
编辑 Docker 配置文件。
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
EOF
重启 Docker 服务。
sudo systemctl restart docker
六、Docker镜像的管理
1. 搜索镜像
查找 Docker Hub 上的镜像。
docker search <image_name>
2. 拉取镜像
从 Docker Hub 拉取指定镜像。
docker pull <image_name>:<tag>
3. 列出本地镜像
查看已经下载到本地的镜像列表。
docker images
#输出结果如下:
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 123456789abc 2 days ago 200MB
hello-world latest abcdef123456 3 weeks ago 1.84kB
nginx latest xyz987654321 1 month ago 400MB
- REPOSITORY: 镜像的仓库名称,表示该镜像是从哪个仓库获取的。在这个例子中,有
centos
、hello-world
和nginx
。 - TAG: 镜像的标签,表示镜像的版本或者标识符。在这个例子中,有
latest
表示最新版本。 - IMAGE ID: 镜像的唯一标识符,通常使用 SHA256 哈希值表示。用于唯一标识该镜像。
- 注意:你可以使用这个ID的前4位来“调用”这个镜像。比如 使用docker inspect xyz9可以查看nginx镜像信息。
- CREATED: 镜像创建的时间,表示该镜像是何时构建的。
- SIZE: 镜像的大小,以字节、千字节、兆字节等为单位。表示该镜像占用的磁盘空间大小。
4. 删除本地镜像
删除本地的一个或多个镜像。
docker rmi <image_id or image_name>
5. 标记镜像
给本地的镜像添加标签,方便管理和版本控制。
docker tag <image_id or image_name> <new_image_name>:<tag>
6. 构建镜像
使用 Dockerfile 构建一个新的镜像。
docker build -t <new_image_name>:<tag> <path_to_dockerfile>
7. 查看镜像详细信息
显示关于特定镜像的详细信息。
docker inspect <image_id or image_name>
8. 查找被删除的镜像
查看被删除但尚未清理的镜像 ID。
docker image ls -q -f dangling=true
9. 清理被删除的镜像
清理被删除但尚未清理的所有镜像。
docker image prune
10. 清理不再使用的镜像
清理所有不再被容器使用的镜像。
docker image prune -a
11.清理不再使用的镜像:**
docker image prune -a
示例操作
拉取并运行 Nginx 镜像:
docker pull nginx:latest
docker run -d -p 80:80 --name mynginx nginx:latest
七、Docker容器的管理
Docker 容器管理常用命令
1. 启动容器
启动一个停止的容器。
docker start <container_name or container_id>
2. 停止容器
停止正在运行的容器。
docker stop <container_name or container_id>
3. 重启容器
停止并重新启动一个容器。
docker restart <container_name or container_id>
4. 查看运行中的容器
显示当前正在运行的容器列表。
docker ps
#输出正在运行的容器清单如下:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
abc123456789 nginx:latest "nginx -g 'daemon of…" 2 hours ago Up 2 hours 0.0.0.0:8080->80/tcp mynginx
5. 查看所有容器
使用docker ps -a 显示所有容器,包括正在运行的和已经停止的。
docker ps -a
6. 进入容器
进入正在运行的容器的 shell。
docker exec -it <container_name or container_id> /bin/
#docker attach 也能进入容器,但退出时会造成容器停止,不推荐!
7. 查看容器日志
查看容器的日志输出。
docker logs <container_name or container_id>
8. 删除容器
删除一个或多个停止的容器。
docker rm <container_name or container_id>
9. 强制删除容器
强制删除一个运行中的容器。
docker rm -f <container_name or container_id>
10. 查看容器详细信息
显示有关特定容器的详细信息。
docker inspect <container_name or container_id>
示例操作
启动一个 Nginx 容器:
docker run -d -p 8080:80 --name mynginx nginx:latest
查看运行中的容器:
docker ps
进入正在运行的容器的 shell:
docker exec -it mynginx /bin/
停止并删除容器:
docker stop mynginx
docker rm mynginx
是不是忘了一点:容器运行的时候做了配置改动,怎么保存?!
八、Docker容器的保存和备份
Docker 容器的存档和备份可以通过两种主要方式进行:导出容器为存档文件(tarball)和保存容器快照。
以下是这两种方法的示例和必要说明:
- 导出容器为存档文件
命令:
docker export <container_id or container_name> > container_archive.tar
示例:
docker export mynginx > mynginx_archive.tar
说明:
docker export
命令用于将容器的文件系统导出为一个 tar 文件。<container_id or container_name>
是要导出的容器的 ID 或名称。> container_archive.tar
将导出的内容保存到一个 tar 文件中。注意这个大于号’<’
- 保存容器快照
命令:
docker commit <container_id or container_name> <image_name>:<tag>
示例:
docker commit mynginx mynginx_backup:latest
说明:
docker commit
命令用于创建一个新的镜像,该镜像基于现有容器的文件系统快照。<container_id or container_name>
是要保存快照的容器的 ID 或名称。<image_name>:<tag>
是新创建的镜像的名称和标签。
注意事项:
- 导出容器为存档文件:
- 这种方式只包含容器的文件系统,并不包含容器的元数据(如启动配置等)。
- 可以通过
docker load
命令将 tar 文件导入到新的容器中。
- 保存容器快照:
- 这种方式包含容器的整个文件系统和元数据,创建的新镜像可以直接用于启动新的容器。
- 快照通常较大,因为包含了整个文件系统。
从存档文件导入容器
如果使用了 docker export
导出容器为存档文件,可以使用以下命令将存档文件导入到新的容器中:
docker import container_archive.tar <image_name>:<tag>
例如:
docker import mynginx_archive.tar mynginx_backup:latest
这个命令将存档文件导入为一个新的镜像,然后可以使用 docker run
启动一个新的容器。
问题:VM虚拟机有几种保存或备份方式的?你熟悉吗?
九、Dockerfile原理、应用和示例
Dockerfile 是一个文本文件,包含了一系列用于构建 Docker 镜像的指令和配置信息。通过编写 Dockerfile,用户可以定义一个自定义的、可重复构建的 Docker 镜像,从而实现应用程序的容器化。Dockerfile 提供了一种自动化、可控的构建镜像的方式。
Dockerfile 应用场景
- 自定义应用环境: 使用 Dockerfile 可以定义包含特定软件、库和配置的自定义应用环境,确保应用在不同环境中具有一致的运行表现。
- 多阶段构建: Dockerfile 支持多阶段构建,可以在不同阶段执行不同的操作,以减小最终镜像的体积,提高镜像的安全性。
- 版本控制和可重复性: 将 Dockerfile 存储在版本控制系统中,可以确保团队成员、CI/CD 系统和其他自动化流程能够使用相同的构建过程。
- 快速部署: Dockerfile 定义了应用的构建和运行环境,使得部署新应用或更新应用变得快速、简便。
Dockerfile 常用命令示范
以下是一个简单的 Dockerfile 示例,包含了常用的一些命令:
dockerfile
# 使用官方基础镜像
FROM ubuntu:20.04
# 设置工作目录
WORKDIR /app
# 复制本地文件到容器中
COPY . .
# 安装依赖
RUN apt-get update && \
apt-get install -y python3 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 设置环境变量
ENV APP_NAME myapp
# 暴露端口
EXPOSE 80
# 容器启动时执行的命令
CMD ["python3", "app.py"]
命令解释:
FROM
: 指定基础镜像,本例中使用官方的 Ubuntu 20.04 镜像。WORKDIR
: 设置工作目录,后续的命令都在该目录下执行。COPY
: 复制本地文件到容器中,可以用于添加应用代码。RUN
: 在镜像中执行命令,用于安装依赖、配置环境等。ENV
: 设置环境变量,用于配置应用运行时的参数。EXPOSE
: 暴露容器的端口,供外部访问。CMD
: 容器启动时执行的默认命令,可以被覆盖。
构建 Docker 镜像
使用以下命令在 Dockerfile 所在目录下构建镜像:
docker build -t myapp:latest .
这个命令将在当前目录下查找名为 Dockerfile
的文件,并使用其中定义的步骤构建镜像。最终的镜像名为 myapp:latest
。
注意:实际操作中,我们发现docker commit 生成的镜像不是那么稳定,经常会启动故障。推荐使用dockerfile来构建Docker镜像。
十、Docker compose原理、应用和示例
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过一个单独的 docker-compose.yml
文件,用户可以配置和启动多个服务、网络、卷等 Docker 容器,实现容器化应用的编排和管理。Docker Compose 主要用于简化多容器应用的部署和管理,提高开发和测试的效率。
10.1 Docker Compose 应用场景
- 多容器应用编排: Docker Compose 可以定义和运行多个相互关联的容器,形成一个完整的应用程序,便于管理多个容器之间的关系。
- 开发环境搭建: 在开发环境中,通过 Docker Compose 可以快速搭建包含数据库、后端服务、前端服务等的完整开发环境,方便开发人员进行本地开发和测试。
- 持续集成和持续部署: Docker Compose 文件可以被集成到持续集成(CI)和持续部署(CD)流程中,使得应用的构建和部署过程更加自动化。
10.2 Docker Compose 示例和必要说明
以下是一个简单的 docker-compose.yml
文件的示例,以运行一个使用 Node.js 和 Redis 的简单 Web 应用为例:
yaml
version: '3'
services:
web:
image: node:14
volumes:
- ./app:/app
ports:
- "8080:8080"
depends_on:
- redis
environment:
- REDIS_HOST=redis
redis:
image: "redis:alpine"
说明:
version
: 指定 Docker Compose 文件的版本。services
: 定义了各个服务(容器)的配置。web
: Node.js 应用的服务配置。image
: 使用的镜像。volumes
: 挂载本地目录到容器内。ports
: 将容器的 8080 端口映射到主机的 8080 端口。depends_on
: 指定该服务依赖于redis
服务。environment
: 定义环境变量。
redis
: Redis 服务的配置。
10.3 Docker Compose 常用命令示范
在 Docker Compose 文件所在目录执行以下命令:
- 启动服务:
docker-compose up
这将启动所有定义的服务。
- 启动服务并在后台运行:
docker-compose up -d
- 停止服务:
docker-compose down
这将停止并删除所有相关的容器、网络和卷。
- 查看服务状态:
docker-compose ps
显示所有定义的服务的状态。
docker-compose ps
与 docker ps 还是有一些差异,主要是:
docker-compose ps 仅显示与当前 Docker Compose 项目相关的服务状态;而docker ps
显示主机上所有正在运行的容器状态,无论这些容器是否与 Docker Compose 项目相关。
此外,使用 docker-compose ps
更方便查看服务状态和端口映射。
- 构建服务:
docker-compose build
按照 docker-compose.yml
文件中的配置构建镜像。
Docker Compose 提供了更多的命令和配置选项,具体使用取决于应用的需求。使用 Docker Compose 可以更方便地定义、运行和管理多容器应用。
敲黑板小结一下:
Dockerfile 用于构建单个容器的镜像,用户可以定义和自动化构建自己的 Docker 镜像。
Docker Compose 用于定义和运行多个容器的应用系统,通过
docker-compose.yml
文件,用户可以配置多个相关服务的容器,确保它们可以一起协同工作,形成一个完整的应用系统。一般用 Dockerfile 构建单个容器镜像,然后通过 Docker Compose 管理多容器的协同工作。
十一、常见问题及排查方法(持续更新ing)
1 . 问题: “Docker daemon is not running”
● 解决方法:
1 . 首先,检查 Docker 守护进程是否正在运行。
sudo systemctl status docker
2 . 如果守护进程未运行,启动它。
sudo systemctl start docker
2 . 问题: “Got permission denied while trying to connect to the Docker daemon socket”
● 解决方法:
1 . 将当前用户添加到 docker 用户组中。
sudo usermod -aG docker $USER
2 . 重新登录或者注销,以使用户组更改生效。
3 . 问题: "Error response from daemon: pull access denied for , repository does not exist or may require
‘docker login’"
● 解决方法:
1 . 登录到 Docker Hub。
docker login
2 . 提供用户名和密码,或者使用令牌进行身份验证。
4 . 问题: “ERROR: for Cannot start service : port is already allocated”
● 解决方法:
1 . 使用 -p 标志指定一个未被占用的端口。
docker-compose -f docker-compose.yml -p <project_name> up -d
5 . 问题: “Error: No space left on device”
● 解决方法:
1 . 清理无用的容器、镜像和卷。
docker system prune -a
2 . 如果宿主机磁盘空间不足,考虑扩展磁盘或清理其他不必要的文件。
6.问题: “WARNING: IPv4 forwarding is disabled. Networking will not work”
● 解决方法:
启用 IPv4 转发。 sudo sysctl net.ipv4.ip_forward=1
7. 问题: “Bind for 0.0.0.0:8080 failed: port is already allocated”
● 解决方法:
1 . 查找占用端口 8080 的进程。 sudo lsof -i :8080
2 . 杀死占用该端口的进程,或更改 Docker 配置使用另一个端口。
(持续更新吧……有问题可以留言探讨哦~!)