在Ubuntu上精通Docker:现实世界部署指南

如果您正在寻找如何在Ubuntu上安装Docker的信息,那么您来对地方了。不仅如此,作为一个额外的奖励,本教程还将教您如何通过基本的Docker命令来运行和管理容器。

利用Visual Studio(VS)Code的便捷功能,您还将学习如何提升您的SSH技能。让我们开始吧!

相关: 一个Windows用户在Linux世界中:VS Code和远程SSH

先决条件

如果您想一步一步地跟着进行操作,在本教程中,请确保您拥有以下内容:

  • A fresh install of Ubuntu Server LTS with SSH Enabled (This guide will be using Ubuntu Server LTS 20.04.1)
  • A Windows Machine with VSCode installed (This guide will be using Visual Studio Code 1.52.1)
  • 已安装并连接到您的Ubuntu服务器LTS安装的VSCode官方SSH扩展

在Ubuntu上安装Docker

让我们首先在Ubuntu上安装Docker。此时,教程假定您正在本地Windows计算机上,使用已通过SSH连接到Ubuntu服务器的VS Code。了解如何设置这个方便的环境,请参阅关于使用VS Code和SSH的最新文章

在下面的示例中,VSCode远程连接到Ubuntu,并打开home文件夹(在本例中为/home/homelab)作为工作区:

VSCode when SSHed into a Ubuntu Machine

在Ubuntu Server中安装Docker的实际过程只需两个命令。Ubuntu将Docker作为安装选项之一提供给用户,默认软件包管理器是随Ubuntu一起提供的apt

在VS Code的SSH终端窗口中,运行以下两个命令来安装Docker:

sudo apt update -y
sudo apt install docker.io -y

在Ubuntu Server安装过程中,可能已经提供了安装Docker的选项snap。如果是这样,请先通过运行sudo snap remove docker删除snap包。

您可以观看下面的动画来了解docker的安装:

The Installation Process for Docker on Ubuntu

Ubuntu会自动启用并设置服务在启动时启动,因此您已经准备好开始使用Docker了!

在Ubuntu上创建和运行Docker容器

现在您已经安装了Docker,您可以用它做些什么呢?让我们从创建一个Docker容器开始。本教程将设置一个静态Web服务器作为Docker容器的良好示例。在本节中,您将:

  • Docker Hub镜像库设置一个新的容器来运行HTTP服务
  • 使用端口映射将容器内的HTTP端口映射到您的Ubuntu主机
  • 设置绑定挂载以将容器内的重要数据映射到您的Ubuntu主机
  • 为您的容器设置持久性,以便在重新启动时保留

如果上述任何步骤听起来令人困惑,不用担心,我们将逐步介绍每个步骤,以帮助您理解整个过程。

下载Docker镜像

您首先要问的问题是,这个容器将来自何处?让我们来看看Docker Hub。

A large part of Docker is understanding image repositories. Rather than being distributed like packages, services in Docker get distributed as Docker Images.

A Docker Image is a snapshot of the software that the publisher wants to distribute and the entire filing system! This is analogous to creating .wim image of Windows.

这种文件系统捕获使Docker如此受欢迎:软件与整个操作环境一起捕获。这样做消除了由服务器环境之间的差异引入的问题。

最受欢迎的镜像存储库(也是默认的)之一是Docker Hub,也称为官方Docker存储库。镜像存储库是您可以下载成千上万个预创建的Docker镜像以作为容器运行的地方。

由于本教程正在设置静态Web服务器,您需要下载一个Web服务器镜像。目前最受欢迎的两个Web服务器是Apache httpdNginx,但为了稍微改变一下,并可能向您介绍一个新的Web服务器,让我们使用一个称为Caddy的服务器。

Caddy是一个以其简单性而闻名的Web服务器。许多有效的服务器配置可以使用文件中的一行部署。简单就是好,也是一个很好的基础示例。

  1. 首先,您需要找到 Docker 镜像。在您的 Windows 机器上,导航至 https://hub.docker.com。在页面的左上角执行对
  2. 应用程序的搜索。输入 caddy。您应该会看到类似以下的页面:
Searching for caddy on the Docker Hub

A benefit (and downside) of Docker Hub is that anyone, even you, can create and upload Docker Images to the site.

您必须小心确保您选择的镜像来自可信任的来源。任何人都可以选择在镜像中放置恶意软件并将其上传到 Docker Hub。

3. 记下镜像的名称。在上面的屏幕截图中,名称恰好是 caddy。您将需要此名称来在接下来的步骤中指定镜像名称。

在 Ubuntu 上使用 Docker 运行容器

一旦您知道要下载的镜像的名称,就该下载它并从中创建一个容器了。

从镜像启动容器只需要一个命令。在连接到 Ubuntu 服务器的 SSH 终端中,运行以下 docker run 命令。

下面的命令检查本地机器上是否有 caddy 镜像。如果不存在,它将从 Docker Hub 下载该镜像,创建一个容器并启动它。下面的命令使用 -p 开关将 Ubuntu 服务器的监听端口 80 映射到容器的端口 80。此功能称为端口映射。

sudo docker run -p 80:80 caddy

大多数 Docker Hub 镜像遵循 <user>/<image name> 的命名约定。然而,由 Docker 标记为“官方”的镜像在其名称前面没有 <user>(如上面的 caddy)。

运行以上命令的输出如下,其中 caddy 的日志信息直接显示在终端:

Running the Caddy Docker container

您可能注意到几乎所有的 Docker 命令都以 sudo 为前缀,以强制命令以管理员身份运行。默认情况下,Docker 服务以 root 身份运行,您对容器或镜像的所有更改都必须以管理员身份完成。

然后,您已经成功运行了!就是这样简单。您是否为在 Ubuntu 上安装 Docker 而感到高兴呢?

现在在 Windows 计算机上导航至 http://<your-ip>,您应该看到 Caddy 的登陆页面。如下所示(此指南的 IP 已替换为 http://homelab-docker):

The default landing page for Caddy

caddy 容器现在正在运行,但您可能已经注意到一个问题。运行该 docker 命令将占用您的命令行。您无法运行更多的命令,如果会话结束,运行的容器也将停止。让我们通过在后台运行容器(也称为分离容器)来解决这个问题。

在后台运行 Docker 容器

现在您有一个正在运行的容器,但您的命令行已经卡住了。您什么都不能做。您需要更好的方法,通过在后台像服务一样运行容器。要做到这一点:

  1. 按下命令行中的 control+c 组合键停止当前容器。这应该会还原您的命令行。
  2. 现在,重新运行与之前相同的命令,只是这次加上-d参数,如下所示。您将看到Docker会返回一个容器ID,并将命令行传回给您。
sudo docker run -d -p 80:80 caddy
Running a detached container

使用Docker命令管理后台容器

一旦您运行了一个或多个后台Docker,您就需要以某种方式对其进行管理。Docker为您提供了一些使用docker container命令来实现的不同命令。

  • sudo docker container list -a:列出所有容器(包括运行和停止的)及其状态
  • sudo docker container stop <name>:通过名称(或ID)停止Docker容器
  • sudo docker container start <name>:通过名称(或ID)启动Docker容器
  • sudo docker container prune:销毁并移除所有已停止的容器

您可以在以下截图中看到上述所有命令的上下文使用:

Managing detached containers using docker container commands

还有许多其他Docker容器命令可用于查看、更改、检查甚至远程连接到服务器上的容器。您可以运行sudo docker container --help查看所有命令。

尽管您现在已经在后台运行一个包含Web服务器的容器,但仍然无法托管自定义内容。目前,Caddy只是提供默认的网页。

现在让我们看看如何使用一个叫做绑定挂载的概念来部署具有有意义数据的容器。

使用绑定挂载存储容器数据

Docker基于镜像(以及它们生成的容器)的概念,认为它们是一次性的或瞬态的。如果Caddy软件有更新,你不会更新服务,而是将整个内容与容器一起丢弃,然后从头开始使用全新的镜像。

像这样丢弃和重新创建容器的好处是显著的。随着时间的推移,软件的不稳定性可能会通过不断更新可能已有数年的软件而引入。通过每次使用全新的镜像,Docker为您提供了一个稳定、可靠的(可能经过测试的)基础,使得每次更新都是在这个基础上进行的。

这个概念相当于每次更新Windows应用软件时都使用全新安装的Windows。在Windows上不是一个有趣的想法,但在Docker中非常适用。

然而,一次性方法也存在明显的问题。当当前服务被清除时,您不希望重要数据被丢弃。Docker使用一个叫做绑定挂载的概念来解决这个问题。

现在让我们探讨如何为容器创建一个绑定挂载。

创建文件夹结构并清理

在您可以使用绑定挂载之前,您需要创建一个位置来存储这些数据。本教程将在您的主目录中创建一个文件夹。要在仍然连接到您的Ubuntu服务器的VS Code中执行此操作:

  1. 右键单击VS Code Explorer面板的空白区域,选择新建文件夹。

2. 给新文件夹命名为containers/caddy/files。

文件夹名称由您决定,只要在即将出现的docker命令中正确定义即可。通过使用斜杠,VS Code将其解释为创建三个文件夹。 files文件夹是caddy的子目录,caddycontainers的子目录。您不必使用此文件夹结构,但在同一服务器上有多个容器时,该结构更有意义。

如果之前未完成,请使用以下命令停止并删除以前创建的任何容器:

# 停止并删除所有当前运行的容器。
# $(sudo docker ps -q)动态获取所有正在运行的容器ID
sudo docker container stop $(sudo docker ps -q)
sudo docker container prune

您可以在下面的截图中看到此命令:

Using the VSCode Explorer Window

使用Bind Mounts部署Caddy容器

现在,在Ubuntu服务器上构建了文件夹结构。是时候创建一个带有绑定挂载的Caddy容器了。

  1. 在进行得太远之前,首先要弄清楚您正在使用的容器存储持久数据的位置。该位置将取决于谁创建了Docker镜像以及其用途是什么。

你找到持久数据存储的最佳选择是查看所讨论的镜像在 Docker Hub 内的文档。对于 Caddy,你可以在这里找到文档: 这里:

The Caddy documentation on Docker Hub

2. 使用以下命令启动容器。参数 -v ~/containers/caddy/files:/usr/share/caddy 将冒号前面的路径 (~/containers/caddy/files) 映射到容器内的文件夹 (/usr/share/caddy)。这与端口映射命令非常相似:只是你在映射文件夹而不是端口。这种类型的命令称为 Bind Mount

# 将主机上的文件夹(冒号前面的路径)绑定到
# 容器内的 /usr/share/caddy
sudo docker run -d -p 80:80 -v ~/containers/caddy/files:/usr/share/caddy caddy

上述代码中的波浪符(~)表示主目录。在本文中,这相当于 /home/homelab

3. 打开浏览器,导航回服务器的 http 地址。你会注意到服务器现在正在提供一个 404 页面。这是正常的,因为你当前在 ~/containers/caddy/files 中没有 index.html 文件。

4. 在 Ubuntu 服务器的 VS Code Explorer 窗口中的 ~/containers/caddy/files 中创建一个如下所示的 index.html 文件:

<body><h2>hello world!</h2></body>

5. 导航到服务器的 HTTP 地址,确认容器现在正在提供你的新 index.html 页面。

您可以在以下动画中查看上述所有内容:

container is now serving your new index.html page.

与docker管理命令不同,您创建的文件(如index.html)不需要管理员权限。这是因为您拥有caddy服务器正在提供的内容,它们位于您的主目录中。

验证绑定挂载

太棒了!您不仅使用了一个全新的Docker容器,而且该容器正在提供保存在您主目录中的本地内容!您可以通过运行以下命令来证明这一点:

  1. 停止并删除正在运行的容器。这一步骤会彻底删除所有内容,包括如果您没有使用绑定挂载,则会删除index.html文件。
sudo docker container stop $(sudo docker ps -q)
sudo docker container prune

2. 创建一个全新的容器。

sudo docker run -d -p 80:80 -v ~/containers/caddy/files:/usr/share/caddy caddy

3. 验证新容器是否仍在http://<your server>地址上提供index.html文件。

创建持久性Docker容器

A container isn’t that useful if it stops when the server reboots. By default, that’s what is going to happen if you don’t make it happen. To prevent this, let’s generate a new caddy container again but this time once that restarts when the Docker host, Ubuntu in this case, restarts.

  1. 停止并删除所有正在运行的容器。
# 停止并删除当前正在运行的所有容器
sudo docker container stop $(sudo docker ps -q)
sudo docker container prune

2. 使用--restart always参数重新启动caddy容器,以在主机重新启动时设置此新容器启动。通过使用--restart always标志,您的容器现在的行为类似于一个正确的服务:在启动时自动启动。

sudo docker run -d -p 80:80 -v ~/containers/caddy/files:/usr/share/caddy --restart always caddy

3. 重新启动服务器。

4. 现在验证新容器是否启动并仍在http://<your server>地址上提供index.html文件。

您可以查看下面应用的命令:

Setting caddy to restart on boot

继续

在这个阶段,您应该已经具备了一个可用的Docker环境,并对镜像和容器有基本的了解。您可以拉取、启动、停止并对容器进行基本管理。您还成功地使用绑定挂载和端口映射创建了一个运行中的Web服务容器。

关于Docker,还有很多内容需要覆盖:敬请关注this space,因为下一篇文章将介绍使用Docker Compose进行高级Docker管理。

Source:
https://adamtheautomator.com/docker-ubuntu/