近年来,Docker已成为希望简化其应用程序开发过程的开发人员的流行工具。在这篇博客文章中,我们将深入研究Docker的基础知识,包括其核心组件以及与虚拟机的比较。我们还将涉及关键术语和概念,这些术语和概念将帮助您了解Docker如何彻底改变您的工作流程。
现在什么是Docker?
Docker是一个平台,旨在简化建筑物,运行和运输应用程序的过程。它通过利用容器化技术来实现这一目标,该技术使开发人员可以为运行应用程序创建称为容器的孤立环境。
想象您正在搬到新房子,并且有一个带有特定家具,装饰和设置的房间,您想在新地方重新创建。单独运输所有物品,确保没有损坏任何东西,然后在新房子中再次设置所有东西可能是一个乏味且耗时的过程。
在这种情况下,将Docker视为便携式房间,您可以将其用来将所有物品包装在一起。 Docker允许您将家具,装饰品和设置放入容器中,然后将其密封并运送到新房子,而不必担心兼容性或损坏。到达后,您只需“解开”容器,您的房间就完全按原样设置了。
在软件开发领域,Docker以类似的方式工作。应用程序通常取决于特定的库,配置和运行时环境。手动对不同系统(例如开发,测试和生产环境)手动设置这些依赖项可能会很复杂且耗时,并可能导致不一致或错误。
Docker容器封装了应用程序需要运行的所有内容,包括操作系统,库,依赖项和应用程序代码。这确保了应用程序在不同环境中始终如一地运行,而不论基础系统如何。使用Docker,开发人员可以一次构建一个容器,然后将其部署到开发过程的各个阶段(例如测试,分期和生产),而不必担心兼容性问题或差异。
总而言之,就像便携式房间使您能够轻松,一致地在房屋之间移动物品一样,Docker使开发人员能够在各种环境中始终构建,运行和运输应用程序,从而简化部署过程并减少潜在错误。 P>
容器与虚拟机
虽然容器和虚拟机(VM)在孤立的环境中启用运行应用程序,但它们的基础体系结构和资源消耗都有很大差异。
虚拟机是硬件资源的抽象,由虚拟机管理程序(例如VirtualBox,VMware或Hyper-V(仅Windows))创建和管理。 VM效仿了一个完整的系统,包括操作系统,并且可以是资源密集型且开始缓慢的系统。
另一方面,容器轻巧并快速启动,因为它们不包括成熟的操作系统并共享主机的操作系统,尤其是内核,只需要使用自己的文件系统一个操作系统流程。与VM相比,这会导致更有效的资源利用和更快的启动时间。
内核是操作系统的核心组成部分,负责管理应用程序和硬件资源。
Docker架构
Docker使用客户端服务器体系结构进行操作,该体系结构由客户组件和通过REST API通信的服务器组件组成。该服务器(也称为Docker Engine)在后台运行,处理构建和运行容器的任务。 Docker确实有以下组件:
docker客户端: docker客户端是用户与docker交互的主要接口。它提供了一个命令行接口(CLI),并允许用户发布命令以构建,运行和管理容器。客户通过RESTFULE API与Docker Daemon(或Docker Engine)进行通信,以执行各种任务,例如创建容器,拉图像和管理容器生命周期。除了CLI外,Docker还提供了用于Windows和MacOS用户的Docker Desktop的图形用户界面(GUI),这使得更易于视觉管理容器和图像。
docker守护程序(发动机):码头守护程序(也称为Docker Engine)是一个背景过程,可在主机机器上运行并管理容器的整个生命周期。守护程序从Docker客户端聆听API请求,并执行所需的任务,例如构建图像,创建容器和管理容器生命周期。它负责在Docker系统中执行实际工作,包括管理集装箱隔离,网络和存储。
docker图像: docker图像是容器的构建块。它们是仅包含操作系统,运行时环境,库和应用程序代码的仅阅读模板。图像可以从Dockerfile创建,该脚本包含用于构建图像的说明。可以通过Docker注册表(例如Docker Hub或私人注册表)存储和共享Docker图像,从而使用户可以轻松地在不同的环境中分发和部署应用程序。
docker容器: docker容器是用于运行应用程序的轻巧,便携式和隔离的运行时环境。它们是由Docker Images创建的,并在图像顶部具有可写的层,这使他们可以存储运行时数据并维护其状态。容器相互隔离,仅共享主机的内核,这使其与虚拟机相比高效。可以使用Docker命令来轻松管理容器,例如Docker Start,Docker Stop和Docker RM。
docker网络:
Docker提供了一个强大的网络模型,该模型可以在容器与外界之间进行通信。它支持多个网络驱动程序,例如桥梁,主机,叠加层和麦克弗兰,它们提供了不同级别的隔离和性能。默认情况下,Docker创建了一个称为桥梁网络的虚拟网络,该网络允许容器彼此和主机进行通信。用户还可以创建自定义网络以隔离容器或将其连接到外部网络。docker卷和存储:
Docker提供了一个灵活的存储系统,用于管理容器中的数据。它支持各种存储驱动程序,例如Overlay2,AUFS和BTRF,这些驱动程序确定了如何在主机系统上存储和管理数据。 Docker还支持卷,这是一种持久由容器生成并在容器之间共享数据的方法。可以使用Docker命令来管理卷Docker注册表:存储和共享Docker图像的存储库。 Docker Hub是最受欢迎的注册表,为存储和分发图像提供了一个平台。
docker容器与图像
Docker术语中的一个基本区别是容器和图像之间的差异。图像是一个仅读取模板,其中包括运行应用程序所需的操作系统,运行时环境,库和应用程序代码。另一方面,容器是图像的运行实例。当从图像创建容器时,添加了一个可写的图层,允许容器存储运行时数据并维护其状态。
安装Docker
要在计算机上安装Docker,请按照操作系统的官方安装指南:
:Docker容器生命周期
Docker容器的生命周期通常由几个阶段组成:
创建:使用docker create
或docker run
命令创建一个容器。创建时,容器具有Docker Daemon分配的唯一ID。
开始:可以使用docker start
命令启动创建的容器,也可以使用docker run
在单个命令中创建并启动它。启动后,容器运行DockerFile中指定的入口处命令(或docker run
命令中提供的自定义命令)。
暂停/简历:可以使用docker pause
命令暂停容器,该命令暂时暂停容器内的所有进程。要恢复暂停的容器,请使用docker unpause
命令。
停止:可以使用docker stop
命令停止运行容器。此命令将 sigterm 信号发送到容器内部的主过程,从而使其可以执行优雅的关闭。宽限期之后,如果容器尚未退出,则发送 sigkill 信号以有力终止容器。
重新启动:可以使用docker restart
命令重新启动停止的容器,该命令会停止并再次启动容器。
删除:可以使用docker rm
命令去除不再需要的容器。这将永久删除容器及其可写的层,从而释放了系统资源。
开发工作流程
-
编写应用程序代码并创建一个Dockerfile:首先编写您的应用程序代码并创建一个定义用于构建Docker Image的说明的
Dockerfile
。
Dockerfile是一个文本文件,其中包含Docker使用的一系列指令来构建新图像。它自动化设置环境,安装依赖项并在容器中配置应用程序的过程。 Docker从Dockerfile读取说明并按顺序执行它们,从而创建一个新图像。
-
构建docker映像:使用
docker build
命令从dockerfile创建docker映像。 -
运行容器:使用Docker Run命令从Docker Image启动一个容器。
-
测试应用程序:测试在容器内运行的应用程序,以确保其按预期运行。
-
发布Docker映像:如果应用程序按预期工作,请将Docker Image发布到Docker Hub等注册表。
-
部署容器:使用Docker Compose,Kubernetes或其他编排平台等工具将容器部署到所需的环境中。
dockerizing node.js应用程序
创建一个node.js应用程序:首先创建一个使用app.js文件和package.json文件的简单node.js应用程序。
这是一个简单的node.js应用程序,可提供“ Hello,World!”端口3000上的消息。
-
首先,请确保您在系统上安装了node.js。如果没有,您可以从官方Node.js网站下载并安装它。
-
为您的node.js应用程序创建一个新目录,然后在终端或命令提示符中导航到它。
-
通过运行以下命令:
初始化一个新的node.js项目
npm init -y
这将创建一个带有默认值的package.json
文件。
- 在项目目录中创建一个名为app.js的新文件,并添加以下代码:
const http = require('http');
const hostname = '0.0.0.0';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello, World!\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
此代码创建了一个基本的HTTP服务器,该服务器在端口 3000 上听,并以“ Hello,World!”做出响应。对于任何传入的请求。
- 更新package.json文件以包含一个启动脚本。将以下行添加到脚本部分:
"start": "node app.js"
您的软件包文件现在应该看起来像这样:
{
"name": "your-project-name",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "node app.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
要在本地运行node.js应用程序,请执行以下命令:
npm start
您应该在终端中看到"Server running at http://0.0.0.0:3000/"
的消息。打开您的网络浏览器,然后导航到http://localhost:3000/
查看“ Hello,World!”消息。
现在您有了一个简单的node.js应用程序,您可以继续创建一个dockerfile并将其扩展到应用程序。
创建一个Dockerfile:
在与Node.js应用程序同一目录中,创建一个具有以下内容的DockerFile:
# Set the base image
FROM node:latest
# Set the working directory
WORKDIR /app
# Copy package.json and package-lock.json to the working directory
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy the application code to the working directory
COPY . .
# Expose the application port
EXPOSE 3000
# Start the application
CMD ["npm", "start"]
此DockerFile使用最新的官方node.js映像作为基础,将工作目录设置为 /app,复制package.json和package-lock.json文件,安装所需的依赖项,复制应用程序代码,公开端口端口3000,并运行NPM启动命令。
这是Dockerfile中使用的一些常见说明的简要概述:
来自:指定要用作新图像的起点的基本图像。示例包括Ubuntu,Alpine或Node等官方图像。
FROM node:latest
workdir :设置容器中的工作目录。使用相对路径的任何后续指令将相对于此目录执行。
WORKDIR /app
复制:将文件或目录从本地计算机(构建上下文)复制到容器的文件系统。
COPY package.json .
add :类似于复制,但它也可以从URL下载文件并提取压缩文件。
ADD https://example.com/file.tar.gz /app
运行:在容器中执行命令,通常用于安装软件包或运行构建脚本。
RUN npm install
cmd :提供启动容器时运行的默认命令。如果用户在运行容器时指定命令,则将覆盖此默认命令。 Dockerfile中只能有一个CMD指令。
CMD ["npm", "start"]
entrypoint :类似于CMD,但是当用户在运行容器时指定命令时,它不会被覆盖。这对于定义容器的默认可执行文件很有用。
ENTRYPOINT ["npm"] CMD ["start"]
env :在容器内设置一个环境变量,可以通过在容器内运行的应用程序使用。
ENV NODE_ENV=production
公开:通知Docker,该容器在运行时在指定的网络端口上听。这实际上并未发布端口;它用作文档,并提醒运行容器时使用-P标志发布端口。
EXPOSE 80
音量:为容器外部的数据持续存在一个安装点。这对于删除容器时在容器之间共享数据或保留数据很有用。
VOLUME /app/data
- 构建Docker映像:在终端中运行以下命令:
docker build -t your-image-name .
用图像的描述名称替换您的图像名称。
- 运行Docker容器:使用以下命令启动容器:
docker run -p 3000:3000
将此Docker图像推到Docker Hub
Docker Hub是一项公共注册表服务,可让您存储和共享Docker图像。要将Docker图像推到Docker Hub,您需要按照以下步骤操作:
创建一个Docker Hub帐户:如果您还没有Docker Hub帐户,请在注册一个帐户。您需要Docker ID和密码以进行后续步骤。
登录Docker Hub:打开终端或命令提示
docker login
提示时输入您的Docker ID和密码。您应该看到一条消息,表明您已成功登录。
标记您的Docker映像:在将图像推向Docker Hub之前,您需要使用Docker Hub用户名和存储库名称标记它。使用以下命令标记您的图像:
docker tag your-image-name your-docker-id/your-repository-name:your-tag
用您在步骤4中构建的图像的名称替换您的图像名称,带有Docker Hub用户名,带有所需存储库名称的您的repository-name,并带有一个版本的标签或任何描述性标签(例如,'最新')。
例如:
docker tag myapp-image johnsmith/myapp:latest
将Docker图像推到Docker Hub:最后,使用以下命令将标记的图像推到Docker Hub:
docker push your-docker-id/your-repository-name:your-tag
用步骤5中使用的值替换您的docker-id,repository-name和您的标签。Docker会将您的图像上传到Docker Hub帐户。
例如:
docker push johndoe/myapp:latest
验证Docker Hub上的图像:登录到您的Docker Hub帐户并导航到“存储库”部分。您应该看到存储库下列出的新推出的图像。
现在,您的Docker映像已成功地推到Docker Hub,并且可以使用docker pull
命令轻松地将其拉动和运行,然后是docker run
。
Docker容器的好处
Docker容器提供了比传统部署方法和虚拟机的几个优点:
一致性:容器包装所有应用程序依赖性和配置,确保从开发到生产的各种环境的一致行为。
隔离:容器在孤立的环境中运行,防止冲突并确保每个应用程序都可以访问其所需的资源。
可移植性: Docker图像可以轻松地在任何系统上使用Docker安装在任何系统上运行,从而易于在不同平台上部署应用程序。
资源效率:容器共享主机操作系统的内核和资源,与虚拟机相比,间接费用较小。这可以实现更高的密度和更有效的资源利用。
可伸缩性:可以轻松地将容器缩放或向下缩放以满足应用程序不断变化的需求,从而更容易构建和部署微服务和分布式应用程序。
版本控制和回滚: docker映像可以版本化,可以在需要时轻松回滚到以前的版本。对于引入错误或性能问题的应用程序更新,这可能特别有用。
总而言之,Docker容器为应用程序部署提供了有效,便携式且一致的环境。通过利用容器化,开发人员和运营团队可以简化开发,测试和部署流程,最终导致更可靠和可维护的软件。