arrow_back

Docker 简介

加入 登录
Test and share your knowledge with our community!
done
Get access to over 700 hands-on labs, skill badges, and courses

Docker 简介

Lab 1 小时 universal_currency_alt 1 个积分 show_chart 入门级
Test and share your knowledge with our community!
done
Get access to over 700 hands-on labs, skill badges, and courses

GSP055

Google Cloud 自定进度实验

概览

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 控制台按钮
    • 剩余时间
    • 进行该实验时必须使用的临时凭据
    • 帮助您逐步完成本实验所需的其他信息(如果需要)
  2. 点击打开 Google 控制台。 该实验会启动资源并打开另一个标签页,显示登录页面。

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

    注意:如果您看见选择帐号对话框,请点击使用其他帐号
  3. 如有必要,请从实验详细信息面板复制用户名,然后将其粘贴到登录对话框中。点击下一步

  4. 请从实验详细信息面板复制密码,然后将其粘贴到欢迎对话框中。点击下一步

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

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

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

注意:您可以点击左上角的导航菜单来查看列有 Google Cloud 产品和服务的菜单。 “导航菜单”图标

激活 Cloud Shell

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

  1. 点击 Google Cloud 控制台顶部的激活 Cloud Shell “激活 Cloud Shell”图标

如果您连接成功,即表示您已通过身份验证,且当前项目会被设为您的 PROJECT_ID 环境变量所指的项目。输出内容中有一行说明了此会话的 PROJECT_ID

Your Cloud Platform project in this session is set to YOUR_PROJECT_ID

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

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

  2. 现在,输出的内容应如下所示:

输出:

ACTIVE: * ACCOUNT: student-01-xxxxxxxxxxxx@qwiklabs.net To set the active account, run: $ gcloud config set account `ACCOUNT`
  1. (可选)您可以通过此命令列出项目 ID:
gcloud config list project

输出

[core] project = <project_ID>

输出示例

[core] project = qwiklabs-gcp-44776a13dea667a6 Note: For full documentation of gcloud, in Google Cloud, refer to the gcloud CLI overview guide.

任务 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 容器:

Artifact Registry 的 node-app 部分

测试映像

您可以启动一个新的虚拟机,通过 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 日

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