arrow_back

Docker 简介

登录 加入
访问 700 多个实验和课程

Docker 简介

实验 1 小时 universal_currency_alt 1 个积分 show_chart 入门级
info 此实验可能会提供 AI 工具来支持您学习。
访问 700 多个实验和课程

GSP055

概览

Docker 是一个用于开发、交付和运行应用的开放式平台。利用 Docker,您可以将应用与基础设施分开管理,并将基础设施作为托管式应用来处理。Docker 可帮助您加快代码的交付、测试和部署速度,并缩短从代码编写到运行的整个周期。

为了做到这一点,Docker 将内核容器化功能与用于管理和部署应用的工作流及工具相结合。

Docker 容器可以直接在 Kubernetes 中使用,方便您在 Kubernetes Engine 中运行它们。在学完有关 Docker 的基础知识后,您将能够开始开发 Kubernetes 应用和容器化应用。

目标

在本实验中,您将学习如何完成以下操作:

  • 构建、运行和调试 Docker 容器。
  • 从 Docker Hub 和 Google Artifact Registry 中拉取 Docker 映像。
  • 将 Docker 映像推送到 Google Artifact Registry。

前提条件

本实验是入门级实验。我们假定您几乎没有 Docker 和容器方面的相关经验。建议您先熟悉一下 Cloud Shell 和命令行,但不作强制要求。

设置和要求

点击“开始实验”按钮前的注意事项

请阅读以下说明。实验是计时的,并且您无法暂停实验。计时器在您点击开始实验后即开始计时,显示 Google Cloud 资源可供您使用多长时间。

此实操实验可让您在真实的云环境中开展实验活动,免受模拟或演示环境的局限。为此,我们会向您提供新的临时凭据,您可以在该实验的规定时间内通过此凭据登录和访问 Google Cloud。

为完成此实验,您需要:

  • 能够使用标准的互联网浏览器(建议使用 Chrome 浏览器)。
注意:请使用无痕模式(推荐)或无痕浏览器窗口运行此实验。这可以避免您的个人账号与学生账号之间发生冲突,这种冲突可能导致您的个人账号产生额外费用。
  • 完成实验的时间 - 请注意,实验开始后无法暂停。
注意:请仅使用学生账号完成本实验。如果您使用其他 Google Cloud 账号,则可能会向该账号收取费用。

如何开始实验并登录 Google Cloud 控制台

  1. 点击开始实验按钮。如果该实验需要付费,系统会打开一个对话框供您选择支付方式。左侧是“实验详细信息”窗格,其中包含以下各项:

    • “打开 Google Cloud 控制台”按钮
    • 剩余时间
    • 进行该实验时必须使用的临时凭据
    • 帮助您逐步完成本实验所需的其他信息(如果需要)
  2. 点击打开 Google Cloud 控制台(如果您使用的是 Chrome 浏览器,请右键点击并选择在无痕式窗口中打开链接)。

    该实验会启动资源并打开另一个标签页,显示“登录”页面。

    提示:将这些标签页安排在不同的窗口中,并排显示。

    注意:如果您看见选择账号对话框,请点击使用其他账号
  3. 如有必要,请复制下方的用户名,然后将其粘贴到登录对话框中。

    {{{user_0.username | "<用户名>"}}}

    您也可以在“实验详细信息”窗格中找到“用户名”。

  4. 点击下一步

  5. 复制下面的密码,然后将其粘贴到欢迎对话框中。

    {{{user_0.password | "<密码>"}}}

    您也可以在“实验详细信息”窗格中找到“密码”。

  6. 点击下一步

    重要提示:您必须使用实验提供的凭据。请勿使用您的 Google Cloud 账号凭据。 注意:在本实验中使用您自己的 Google Cloud 账号可能会产生额外费用。
  7. 继续在后续页面中点击以完成相应操作:

    • 接受条款及条件。
    • 由于这是临时账号,请勿添加账号恢复选项或双重验证。
    • 请勿注册免费试用。

片刻之后,系统会在此标签页中打开 Google Cloud 控制台。

注意:如需访问 Google Cloud 产品和服务,请点击导航菜单,或在搜索字段中输入服务或产品的名称。

激活 Cloud Shell

Cloud Shell 是一种装有开发者工具的虚拟机。它提供了一个永久性的 5GB 主目录,并且在 Google Cloud 上运行。Cloud Shell 提供可用于访问您的 Google Cloud 资源的命令行工具。

  1. 点击 Google Cloud 控制台顶部的激活 Cloud Shell

  2. 在弹出的窗口中执行以下操作:

    • 继续完成 Cloud Shell 信息窗口中的设置。
    • 授权 Cloud Shell 使用您的凭据进行 Google Cloud API 调用。

如果您连接成功,即表示您已通过身份验证,且项目 ID 会被设为您的 Project_ID 。输出内容中有一行说明了此会话的 Project_ID

Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}

gcloud 是 Google Cloud 的命令行工具。它已预先安装在 Cloud Shell 上,且支持 Tab 自动补全功能。

  1. (可选)您可以通过此命令列出活跃账号名称:
gcloud auth list
  1. 点击授权

输出:

ACTIVE: * ACCOUNT: {{{user_0.username | "ACCOUNT"}}} To set the active account, run: $ gcloud config set account `ACCOUNT`
  1. (可选)您可以通过此命令列出项目 ID:
gcloud config list project

输出:

[core] project = {{{project_0.project_id | "PROJECT_ID"}}} 注意:如需查看在 Google Cloud 中使用 gcloud 的完整文档,请参阅 gcloud CLI 概览指南

任务 1. Hello World

  1. 在 Cloud Shell 中输入以下命令,以运行 Hello World 容器来开始实验:
docker run hello-world

(命令输出)

Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 9db2ca6ccae0: Pull complete Digest: sha256:4b8ff392a12ed9ea17784bd3c9a8b1fa3299cac44aca35a85c90c5e3c7afacdc Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. ...

这个简单的容器在屏幕上返回 Hello from Docker! 消息。此命令看似很简单,但请注意输出中它执行的步骤数。Docker 守护程序先搜索了 hello-world 映像,但在本地未找到该映像,它随后从一个名为 Docker Hub 的公共注册表中拉取了该映像,并通过该映像创建了一个容器,最后为您运行了此容器。

  1. 运行以下命令,查看 Docker 守护程序从 Docker Hub 中拉取的容器映像:
docker images

(命令输出)

REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest feb5d9fea6a5 14 months ago 13.3kB

这就是从 Docker Hub 公共注册表中拉取的映像。“映像 ID”采用 SHA256 哈希格式,此字段指定预配的 Docker 映像。当 Docker 守护程序没有在本地找到映像时,默认情况下,它会在公共注册表中搜索该映像。

  1. 再次运行容器:
docker run hello-world

(命令输出)

Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: ...

请注意,第二次运行此容器时,Docker 守护程序会在您的本地注册表中找到该映像,并通过该映像来运行容器。这种情况下,它就不需要从 Docker Hub 中拉取映像。

  1. 最后,通过运行以下命令来查看正在运行的容器:
docker ps

(命令输出)

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

没有正在运行的容器。您已经退出之前运行的 hello-world 容器。

  1. 若要查看所有容器(包括执行完成的容器),请运行 docker ps -a
docker ps -a

(命令输出)

CONTAINER ID IMAGE COMMAND ... NAMES 6027ecba1c39 hello-world "/hello" ... elated_knuth 358d709b8341 hello-world "/hello" ... epic_lewin

此输出向您显示了 Container ID(容器 ID,即 Docker 生成的一个用于标识容器的 UUID),以及有关此次运行的更多元数据。容器 Names(名称)也是随机生成的,但也可以使用 docker run --name [container-name] hello-world 指定。

任务 2. 构建

在本部分中,您将基于一个简单的节点应用来构建 Docker 映像。

  1. 执行以下命令创建一个名为 test 的文件夹,并切换到此文件夹:
mkdir test && cd test
  1. 创建 Dockerfile
cat > Dockerfile <<EOF # Use an official Node runtime as the parent image FROM node:lts # Set the working directory in the container to /app WORKDIR /app # Copy the current directory contents into the container at /app ADD . /app # Make the container's port 80 available to the outside world EXPOSE 80 # Run app.js using node when the container launches CMD ["node", "app.js"] EOF

此文件指示 Docker 守护程序如何构建您的映像。

  • 第一行指定基础父级映像,在本例中即为节点版本长期支持 (LTS) 的 Docker 官方映像。
  • 第二行设置容器的工作(当前)目录。
  • 第三行将当前目录中的内容(通过 "." 指明)添加到容器中。
  • 之后显示容器的端口,以便它可以通过该端口来建立连接,最后运行节点命令以启动应用。
注意:请花些时间查看 Dockerfile 命令参考,以便理解 Dockerfile 中各行命令的含义。

现在您需要编写节点应用,完成后即可开始构建映像。

  1. 运行以下命令来创建该节点应用:
cat > app.js << EOF; const http = require("http"); const hostname = "0.0.0.0"; const port = 80; 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://%s:%s/", hostname, port); }); process.on("SIGINT", function () { console.log("Caught interrupt signal and will exit"); process.exit(); }); EOF

这是一个简单的 HTTP 服务器,用于侦听端口 80 并返回“Hello World”。

现在来构建映像。

  1. 再次提醒您注意 ".",它代表当前目录,因此您需要在 Dockerfile 所在的目录下运行这一命令:
docker build -t node-app:0.1 .

此命令可能需要几分钟的时间才能执行完成。完成后,屏幕上应显示类似于以下内容的输出:

+] Building 0.7s (8/8) FINISHED docker:default => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 397B 0.0s => [internal] load metadata for docker.io/library/node:lts

-t 用于使用 name:tag 语法来命名和标记映像。该映像的名称为 node-apptag0.1。强烈建议您使用此标记值来构建 Docker 映像。如果您未指定标记值,此标记将默认为 latest,这会导致更加难以区分新旧映像。另外还请注意,在构建映像的过程中,前面提到的 Dockerfile 中的各行是如何在容器中生成中间层的。

  1. 现在,运行以下命令来查看您构建的映像:
docker images

输出应类似于以下内容:

REPOSITORY TAG IMAGE ID CREATED SIZE node-app 0.1 f166cd2a9f10 25 seconds ago 656.2 MB node lts 5a767079e3df 15 hours ago 656.2 MB hello-world latest 1815c82652c0 6 days ago 1.84 kB

请注意,node 是基础映像,node-app 是您构建的映像。若要移除 node,您必须先移除 node-app。与虚拟机相比,映像相对较小。其他版本的节点映像(如 node:slimnode:alpine)可能更小,也更便于移植。请查看我们的“高级主题”,其中更详细地探讨了如何减小容器大小。您可以在节点的官方仓库中查看所有版本。

任务 3. 运行

  1. 基于您构建的映像,使用此代码来运行容器:
docker run -p 4000:80 --name my-app node-app:0.1

(命令输出)

Server running at http://0.0.0.0:80/

--name 标志允许您根据需要命名容器。-p 用于指示 Docker 将主机端口 4000 映射至容器端口 80。现在,您可以通过 http://localhost:4000 连接服务器。如果不映射端口,您将无法连接 localhost 上的容器。

  1. 打开另一个终端(在 Cloud Shell 中,点击 + 图标),然后测试服务器:
curl http://localhost:4000

(命令输出)

Hello World

只要初始终端在运行,容器就会运行。如果您希望容器在后台运行(不受终端会话限制),则需指定 -d 标志。

  1. 关闭初始终端,然后运行以下命令来停止并移除容器:
docker stop my-app && docker rm my-app
  1. 现在运行以下命令,在后台启动容器:
docker run -p 4000:80 --name my-app -d node-app:0.1 docker ps

(命令输出)

CONTAINER ID IMAGE COMMAND CREATED ... NAMES xxxxxxxxxxxx node-app:0.1 "node app.js" 16 seconds ago ... my-app
  1. 请注意,容器正在 docker ps 的输出中运行。您可以执行 docker logs [container_id] 以查看日志。
注意:只要最初的几个字符能够唯一标识容器,您就无需写下整个容器 ID。例如,如果容器 ID 是 17bcaca6f....,您就可以执行 docker logs 17b docker logs [container_id]

(命令输出)

Server running at http://0.0.0.0:80/

现在修改应用。

  1. 在 Cloud Shell 中,打开您在本实验前面步骤中创建的测试目录:
cd test
  1. 在您选择的文本编辑器(例如 nano 或 vim)中修改 app.js,将“Hello World”替换为另一个字符串:
.... const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Welcome to Cloud\n'); }); ....
  1. 构建此新映像并将其标记为 0.2
docker build -t node-app:0.2 .

(命令输出)

[+] Building 0.7s (8/8) FINISHED docker:default => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 397B 0.0s => [internal] load metadata for docker.io/library/node:lts 0.5s

请注意,在第 2 步中,您使用的是现有的缓存层。从第 3 步开始,这些层会被修改,因为您在 app.js 中做了更改。

  1. 使用新版本的映像运行另一个容器。请注意,这次我们映射的是主机端口 8080,而非端口 80。您不能使用主机端口 4000,因为它已被使用。
docker run -p 8080:80 --name my-app-2 -d node-app:0.2 docker ps

(命令输出)

CONTAINER ID IMAGE COMMAND CREATED xxxxxxxxxxxx node-app:0.2 "node app.js" 53 seconds ago ... xxxxxxxxxxxx node-app:0.1 "node app.js" About an hour ago ...
  1. 测试容器:
curl http://localhost:8080

(命令输出)

Welcome to Cloud
  1. 现在,测试您创建的第一个容器:
curl http://localhost:4000

(命令输出)

Hello World

任务 4. 调试

现在,您已经熟悉了容器的构建和运行,接下来了解一些有关调试的做法。

  1. 您可以使用 docker logs [container_id] 命令来查看容器日志。如果要在容器运行过程中跟踪日志输出,请使用 -f 选项。
docker logs -f [container_id]

(命令输出)

Server running at http://0.0.0.0:80/

有时,您可能会希望在运行中的容器内启动交互式 Bash 会话。

  1. 此时,只需使用 docker exec 命令。打开另一个终端(在 Cloud Shell 中,点击“+”图标),然后输入以下命令:
docker exec -it [container_id] bash

-it 标志可分配一个伪 TTY,并确保 stdin 保持打开状态,让您可以与容器进行交互。请注意,Bash 会话是在 Dockerfile 中指定的 WORKDIR 目录 (/app) 下运行的。在此处,您需要对容器内的一个交互式 Shell 会话进行调试。

(命令输出)

root@xxxxxxxxxxxx:/app#
  1. 查看目录
ls

(命令输出)

Dockerfile app.js
  1. 退出 Bash 会话:
exit
  1. 使用 Docker inspect 命令检查 Docker 中的容器元数据:
docker inspect [container_id]

(命令输出)

[ { "Id": "xxxxxxxxxxxx....", "Created": "2017-08-07T22:57:49.261726726Z", "Path": "node", "Args": [ "app.js" ], ...
  1. 使用 --format 检查返回的 JSON 中的特定字段。例如:
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [container_id]

(输出示例)

192.168.9.3

请务必查看以下 Docker 文档资源,了解有关调试的更多信息:

任务 5. 发布

现在,您需要将映像推送到 Google Artifact Registry。推送完成后,您要移除所有容器和映像,以便模拟一个全新的环境,然后拉取和运行容器。这将证明 Docker 容器具备可移植性。

若要将映像推送到 Artifact Registry 托管的私有注册表,需要使用注册表名称来标记映像。其格式为:<regional-repository>-docker.pkg.dev/my-project/my-repo/my-image

创建目标 Docker 代码库(使用 Cloud 控制台)

您必须先创建一个仓库,然后才能向其推送映像。推送映像不会触发系统创建仓库,而且 Cloud Build 服务账号也没有创建仓库的权限。

  1. 导航菜单的“CI/CD”下,依次点击 Artifact Registry > 仓库

  2. 点击仓库旁边的 + 创建仓库图标。

  3. 指定 my-repository 作为仓库名称。

  4. 选择 Docker 作为格式。

  5. 在“位置类型”下,选择区域,然后选择位置:

  6. 点击创建

配置身份验证

如需推送或拉取映像,请将 Docker 配置为使用 Google Cloud CLI 对向 Artifact Registry 发出的请求进行身份验证。

  1. 若要设置对区域中的 Docker 仓库执行身份验证,请在 Cloud Shell 中运行以下命令:
gcloud auth configure-docker {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev
  1. 在出现提示时输入 Y

该命令将更新您的 Docker 配置。现在,您可以在 Google Cloud 项目中与 Artifact Registry 连接以推送和拉取映像。

注意:您也可以使用 gcloud CLI 采用简化的命令行方法。

创建 Artifact Registry 代码库(使用 CLI)

  1. 运行以下命令来创建 Artifact Registry 仓库。
gcloud artifacts repositories create my-repository --repository-format=docker --location={{{ project_0.default_region | "REGION" }}} --description="Docker repository" 注意:首次进行 Google Cloud API 调用,或者第一次将需要提供凭据的命令行工具(如 gcloud CLI、bq 或 gsutil)与 Cloud Shell 结合使用时,Cloud Shell 会显示为 Cloud Shell 提供授权对话框,提示您进行授权。 如需允许该工具使用凭据进行调用,请点击授权

将容器推送到 Artifact Registry

  1. 切换到 Dockerfile 所在的目录。
cd ~/test
  1. 运行以下命令,将映像标记为 node-app:0.2
docker build -t {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/{{{ project_0.project_id | "PROJECT_ID" }}}/my-repository/node-app:0.2 .
  1. 运行以下命令,检查所构建的 Docker 映像。
docker images

(命令输出)

REPOSITORY TAG IMAGE ID CREATED node-app 0.2 76b3beef845e 22 hours {{{project_0.default_region | "REGION"}}}-....node-app:0.2 0.2 76b3beef845e 22 hours node-app 0.1 f166cd2a9f10 26 hours node lts 5a767079e3df 7 days hello-world latest 1815c82652c0 7 weeks
  1. 将此映像推送到 Artifact Registry。
docker push {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/{{{ project_0.project_id | "PROJECT_ID" }}}/my-repository/node-app:0.2

命令输出(您的输出可能会有所不同):

The push refers to a repository [{{{project_0.default_region | "REGION"}}}-docker.pkg.dev/{{{project_0.project_id | "PROJECT_ID"}}}/my-repository/node-app:0.2] 057029400a4a: Pushed 342f14cb7e2b: Pushed 903087566d45: Pushed 99dac0782a63: Pushed e6695624484e: Pushed da59b99bbd3b: Pushed 5616a6292c16: Pushed f3ed6cb59ab0: Pushed 654f45ecb7e3: Pushed 2c40c66f7667: Pushed 0.2: digest: sha256:25b8ebd7820515609517ec38dbca9086e1abef3750c0d2aff7f341407c743c46 size: 2419
  1. 推送完成后,在导航菜单的“CI/CD”下,依次点击 Artifact Registry > 仓库

  2. 点击 my-repository。您应该会看到所创建的 node-app Docker 容器:

测试映像

您可以启动一个新的虚拟机,通过 SSH 连接到该虚拟机,然后安装 gcloud。为了简化过程,您只需移除所有容器和映像,以便模拟一个全新的环境。

  1. 停止并移除所有容器:
docker stop $(docker ps -q) docker rm $(docker ps -aq)

您必须先移除 node:lts 的子映像,然后才能移除该节点映像。

  1. 运行以下命令,移除所有 Docker 映像。
docker rmi {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/{{{ project_0.project_id| "PROJECT_ID" }}}/my-repository/node-app:0.2 docker rmi node:lts docker rmi -f $(docker images -aq) # remove remaining images docker images

(命令输出)

REPOSITORY TAG IMAGE ID CREATED SIZE

至此,您应该已经具有了伪全新环境。

  1. 拉取并运行映像。
docker run -p 4000:80 -d {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/{{{ project_0.project_id| "PROJECT_ID" }}}/my-repository/node-app:0.2
  1. 对运行中的容器运行 curl 命令。
curl http://localhost:4000

(命令输出)

Welcome to Cloud

验证您已完成的任务

点击检查我的进度以验证您已完成的任务。如果您将容器映像成功发布到 Artifact Registry,将会看到一个评估分数。

将容器映像发布到 Artifact Registry

这可以证明容器具有可移植性。只要将 Docker 安装到主机(无论是本地主机还是虚拟机)上,它就会从公共注册表或私有注册表中拉取映像,并基于该映像来运行容器。除了 Docker 外,不需要在主机上安装其他应用依赖项。

恭喜!

恭喜!在本实验中,您参与完成了多项实践活动,包括基于 Docker Hub 中的公共映像运行容器。您还构建了自己的容器映像,并将它们成功推送到了 Google Artifact Registry。另外,本实验还教您学习了如何有效调试运行中的容器。不仅如此,您还学习了如何基于从 Google Artifact Registry 拉取的映像运行容器,并获得了相关经验,同时进一步加强了对 Docker 的理解和熟练使用程度。

后续步骤/了解详情

Google Cloud 培训和认证

…可帮助您充分利用 Google Cloud 技术。我们的课程会讲解各项技能与最佳实践,可帮助您迅速上手使用并继续学习更深入的知识。我们提供从基础到高级的全方位培训,并有点播、直播和虚拟三种方式选择,让您可以按照自己的日程安排学习时间。各项认证可以帮助您核实并证明您在 Google Cloud 技术方面的技能与专业知识。

上次更新手册的时间:2024 年 2 月 29 日

上次测试实验的时间:2024 年 2 月 29 日

版权所有 2025 Google LLC 保留所有权利。Google 和 Google 徽标是 Google LLC 的商标。其他所有公司名和产品名可能是其各自相关公司的商标。

准备工作

  1. 实验会创建一个 Google Cloud 项目和一些资源,供您使用限定的一段时间
  2. 实验有时间限制,并且没有暂停功能。如果您中途结束实验,则必须重新开始。
  3. 在屏幕左上角,点击开始实验即可开始

此内容目前不可用

一旦可用,我们会通过电子邮件告知您

太好了!

一旦可用,我们会通过电子邮件告知您

一次一个实验

确认结束所有现有实验并开始此实验

使用无痕浏览模式运行实验

请使用无痕模式或无痕式浏览器窗口运行此实验。这可以避免您的个人账号与学生账号之间发生冲突,这种冲突可能导致您的个人账号产生额外费用。