Docker 初学者基础知识

2025-05-25

Docker 初学者基础知识

在我的最新文章中,我讨论了 Vagrant 以及它如何帮助我们在几分钟内创建虚拟机。但如果它能更快、更好、更可定制呢?让我们学习如何使用 Docker 轻松开发、部署和运行应用程序!

介绍

如果您使用 Google 搜索Docker,您会发现 Docker 是一个使用操作系统级虚拟化来创建自包含容器的软件平台。

幸运的是,在这里我将用简单的英语向您解释这是什么意思。

您可能之前使用 Oracle VM 或Vagrant创建过多个虚拟机。Docker 与之类似(但更胜一筹,稍后会详细介绍)。

使用 Docker,我们选择一个镜像(可以把 Docker 镜像想象成一个配方)并下载它。然后,我们创建该镜像或容器的实例,这非常类似于虚拟机。

图像:

用于创建一个或多个容器的包或模板

容器:

图像的实例彼此隔离,具有自己的环境。

让我们看看它的实际效果。这是一个 Docker 镜像代码:

FROM ubuntu:23.04
RUN apt-get update
RUN apt-get install -y curl nginx

还记得我说过 Docker 镜像就像一个菜谱吗?在这个镜像或菜谱中,Docker 获取了 Ubuntu 23.04 版本,更新了 SO,然后安装了curlnginx

当然,这是一个简短的 Docker 镜像版本,但它帮助我们直观地了解 Docker 的含义。

现在,有了这个图像,我们可以创建一个容器(想象一个虚拟机),它将创建一个已经更新的 Linux Ubuntu VM,带有 curl 和 nginx。

公司里的所有开发人员都可以使用同一个镜像来安装相同的程序、软件包和版本。再也不会出现“但是……它在我的电脑上能用!”的情况了;现在每台电脑的配置都一致了。

Docker 与虚拟机

但是...如果 Docker 创建了一个类似 VM 的容器,为什么我们不只使用虚拟机呢?

我可以从底层解释 Docker 容器为何比虚拟机更好,甚至可以从其他类似网站获取一些很酷的信息图表,并解释 Docker 对每个容器使用相同的内核,使其轻量且快速,只需几秒钟即可旋转一个容器:

图片描述

但是使用 Docker 和 Docker 容器有一个很大的好处:

假设您想要开发 21.1 NodeJS:您创建自己的 Docker 镜像,在其中获取 Ubuntu 镜像,更新它,安装所有与 NodeJS 相关的内容,然后将该镜像分发给开发团队。

在正常设置中,您必须上传 NodeJS 应用程序,将其部署到您的服务器上,并且您必须确保服务器具有所有依赖项并且其 NodeJS 与您的服务器兼容。

你不会想打赌的。

使用 Docker,我们可以创建一个 Docker 镜像,将其上传到与 Docker 兼容的服务器,就这样。

Docker 服务器并不关心你使用的是什么 Linux、安装了什么软件包,或者你的应用程序是什么语言:它只需要运行镜像。就是这样。

我要强调一下:我们不关心服务器安装了什么。我们只需上传并运行 Docker 镜像。这就是我们要做的。

安装

您可以安装 Docker Desktop(一个 GUI Docker 应用程序),但是我们这些坚韧的开发人员使用适当的终端工具,因此您将安装 Docker Engine(Docker 的终端版本)。

玩笑归玩笑,你可以安装任何你想要的:Docker DesktopDocker Engine,只要确保遵循操作系统的说明即可。例如,对于基于 Debian 的发行版(例如 Ubuntu):

卸载以前的 Docker 版本

sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

安装 Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh ./get-docker.sh

检查 Docker 是否已安装
sudo docker version

让我们进行测试。在终端中运行以下命令:

sudo docker run docker/whalesay cowsay boo

图片描述

重要提示:每个 Docker 命令都需要 sudo 权限。你可以将用户添加到docker组,但尽管如此,它仍然会不断请求 sudo 权限。我发现,运行该命令后sudo chmod 666 /var/run/docker.sock,就不会再要求你输入 sudo 权限了(你可以使用类似的命令,例如chmod +x)。

基本命令

我们已经启动并运行了 Docker。让我们看几个基本命令。如果你想要的话,这就是你的日常工作:

列出所有图像
docker images

从镜像下载或执行容器
docker run <IMAGE_NAME>

下载特定版本
docker run <IMAGE_NAME>:<VERSION>

在后台执行容器
docker run -d <IMAGE_NAME>

将容器从后台移到前台
docker run attach <ID>

执行命令
docker run ubuntu cat /etc/*release*
docker run ubuntu sleep 15

下载图像以便稍后运行
docker pull <IMAGE_NAME>

在docker容器内执行命令
docker exec <COMMAND>

连接到容器的 bash
docker run -it <IMAGE_NAME> bash

列出所有正在运行的容器
docker ps

列出所有容器,无论是否正在运行
docker ps -a

运行一个容器并链接到另一个容器:
docker run -p <PORT_LOCAL>:<PORT_DEFAULT> --link <IMAGE_NAME_TO_LINK>:<IMAGE_NAME_TO_LINK> <IMAGE_NAME>
docker run -p 5000:80 --link redis:redis voting-app

以 JSON 格式获取图像或容器的详细信息
docker inspect <NAME_OR_ID>

从后台运行的容器获取日志
docker logs <NAME_OR_ID>

获取图像的所有图层
docker history <IMAGE_NAME>

停止容器
docker stop <IMAGE_NAME_OR_ID>

永久移除容器
docker rm <IMAGE_NAME_OR_ID>

永久删除未使用的图像
docker rmi <IMAGE_NAME>

从 Dockerfile 构建镜像
docker build . -t <NAME>

环境变量
docker run -e <VARIABLE>=<VALUE> <IMAGE_NAME>
docker run -e APP_COLOR=blue simple-webapp-color

示例:Jenkins 容器

让我们使用一个现实生活中的例子:使用 Jenkins 容器。

在以后的文章中,我将更深入地讨论 Jenkins 及其功能,但 Jenkins 是一款出色的 DevOps CI/CD 工具。让我们下载 Jenkins 并在计算机上运行它:

docker run jenkins/jenkins # This downloads and runs jenkins
docker ps # Get the container ID and port
docker inspect <CONTAINER_ID> # Get the container IP

使用以下命令在您的虚拟机中打开浏览器:
docker run -p 8080:8080 jenkins/jenkins # Map the port

使用以下命令在主机中打开浏览器:

在这里,我们在 Ubuntu 虚拟机中安装并下载 Docker 镜像并运行它。我们可以通过打开浏览器并使用 Docker 容器的 IP 和端口在虚拟机中查看 Jenkins,但通过映射端口,我们可以在主机上打开 Jenkins。

其结构如下:

带有 Windows 的主机 -> Linux VM -> 在 Linux 中运行的 Docker 容器

现在,Linux 正在运行一个轻量级的 Docker 容器,我们可以从 Windows 机器访问它。是不是很棒?

数据持久化

我们停止了 Jenkins 容器,第二天又恢复它继续工作。但是我们丢失了所有内容。发生了什么???

Docker 本身不具备数据持久性。

容器使用自己的文件夹(Jenkins 上的/var/jenkins_home文件夹,MySQL 上的/var/lib/mysql 文件夹等等),但是当你停止容器并再次运行镜像时,你实际上是在从头创建一个容器。我们该怎么办?

我们可以通过链接运行 Docker 的操作系统中的文件夹和容器的文件夹来实现数据持久化。

mkdir my_jenkins_data
docker run -p 8080:8080 -v /home/<USERNAME>/my_jenkins_data:/var/jenkins_home jenkins/jenkins

在这里,我们创建了一个名为my_jenkins_data的文件夹,并将其与 Jenkins 文件夹/var/jenkins_home链接,Docker 将任何更改存储在该文件夹中。

因此,如果我们再次运行该命令,我们将创建一个新的容器,链接存储的信息,就像我们正在恢复我们的容器一样。

卷的数据持久性

我们可以简化这个过程。我们不需要为文件夹指定一个长字符串,而是可以让 Docker 通过在/var/lib/docker/volumes/*中创建卷来管理它们

创建卷
docker volume create test_volume

这将在 /var/lib/docker/volumes/test_volume 中创建一个卷
docker run -v test_volume:var/lib/mysql mysql

我们也可以使用现代方法,它更长但更具声明性和详细性:
docker run / --mount type=bind, source=/data/mysql, target=/var/lib/mysql mysql

最后的想法

正如我们刚刚看到的,Docker 之所以优秀,有以下几个原因:

  1. 隔离性:Docker 可以让应用程序与底层系统隔离,保证不同环境下的一致性。

  2. 效率:通过使用容器化来优化资源利用率,从而更有效地利用系统资源。

  3. 可移植性:Docker 容器可以在任何安装了 Docker 的机器上运行,从而可以轻松地跨不同环境部署应用程序。

  4. 可扩展性:使用 Docker,可以根据需求增加或减少容器数量,轻松扩展应用程序。

  5. 一致性:Docker 确保开发、测试和生产环境一致,减少了“它在我的计算机上可以正常工作”的问题。

  6. 生态系统:Docker 拥有丰富的生态系统,其中包含补充容器化的各种工具和服务,使其成为应用程序部署和管理的多功能平台。

  7. 部署:Docker 使部署更加轻松、安全。我们无需管理软件包及其版本,只需将 Docker 镜像上传到服务器即可。

资源

原始帖子

Vagrant 初学者教程

Docker 桌面

Docker 引擎

Docker 在 DevOps 中的作用

Docker 中心

文章来源:https://dev.to/davidmm1707/docker-basics-for-beginners-49l9
PREV
掌握 Node.js 的 Docker:高级技术和最佳实践
NEXT
Rust GUI:简介,也就是 Rust GUI 库的现状(截至 2021 年 1 月)Rust GUI 的现状如何?自述文件 工作 完全不工作! 其他问题 结论