我们现在已经到了一个阶段,希望您大致了解Docker是什么,以及它不是什么,现在是实际操作的时候了。让我们安装Docker,以便进行相关工作。安装Docker所需的步骤因您用于开发的平台和您用于生产中托管应用程序的Linux发行版而异。
在本章中,我们将讨论在大多数现代桌面操作系统上设置完整的Docker开发环境所需的步骤。首先,我们将在您的本地开发平台上安装Docker客户端,然后在Linux上运行Docker服务器。最后,我们将测试安装以确保其按预期工作。
尽管Docker客户端可以在Windows和macOS上运行以控制Docker服务器,但Linux容器只能在Linux系统上构建和启动。因此,非Linux系统将需要虚拟机或远程服务器来托管基于Linux的Docker服务器。本章后面将讨论Docker社区版、Docker Desktop和Vagrant,它们提供了一些方法来解决这个问题。在“Windows容器”中,我们也将具体讨论如何在Windows系统上本地运行Windows容器,但本书大部分内容将重点放在Linux容器上。
Docker客户端
Docker客户端原生支持64位版本的Linux、Windows和macOS。
大多数流行的Linux发行版可以追溯到Debian或Red Hat。Debian系统使用deb软件包格式和高级软件包工具(apt)来安装大多数预打包软件。另一方面,Red Hat系统依赖于RPM软件包管理器(rpm)文件和Yellowdog Updater,Modified(yum)或Dandified yum(dnf)来安装类似的软件包。Alpine Linux通常用于需要非常小的Linux占用空间的环境,它依赖于Alpine Package Keeper(apk)来管理软件包。
在macOS和Microsoft Windows上,本地GUI安装程序提供了安装和维护预打包软件最简便的方法。Homebrew用于macOS,而Chocolatey用于Windows,这两者也是技术用户中非常流行的选择。
您可以随时在Docker网站上找到最新的安装文档。
Linux
强烈建议您在最新版本的首选Linux发行版上运行Docker。虽然可能在一些旧版本上运行Docker,但稳定性可能会成为一个重大问题。通常需要3.8或更高版本的内核,并建议您使用您选择的发行版的最新稳定版本。以下说明假设您正在使用最新的稳定版本Ubuntu或Fedora Linux发行版。
Ubuntu Linux 22.04 (64-bit)
让我们来看看在64位版本的Ubuntu Linux 22.04上安装Docker所需的步骤。
这前两个命令将确保您不会运行旧版本的Docker。这些软件包已经多次更名,因此您需要在这里指定几个可能性:
$ sudo apt-get remove docker docker.io containerd runc
$ sudo apt-get remove docker-engine
接下来,您需要添加所需的软件依赖项和Docker Community Edition的apt存储库。这样我们就可以获取和安装Docker的软件包,并验证它们是否已签名:
$ sudo apt-get update
$ sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
$ sudo mkdir -p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg |\
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg
$ echo \
"deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" |\
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
现在您已经设置好了存储库,请运行以下命令来安装Docker:
$ sudo apt-get update
$ sudo apt-get install \
docker-ce \
docker-ce-cli \
containerd.io \
docker-compose-plugin
假设您没有收到任何错误消息,现在您已经成功安装了Docker!
Fedora Linux 36 (64-bit)
现在让我们来看看在64位版本的Fedora Linux 36上安装Docker所需的步骤。
这个第一个命令将确保您不会运行旧版本的Docker。与Ubuntu系统一样,该软件包已经多次更名,因此您需要在这里指定几个可能性:
$ sudo dnf remove -y \
docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
接下来,您需要添加所需的软件依赖项和Docker Community Edition的dnf存储库:
$ sudo dnf -y install dnf-plugins-core
$ sudo dnf config-manager \
--add-repo \
https://download.docker.com/linux/fedora/docker-ce.repo
现在您可以安装当前版本的Docker Community Edition:
$ sudo dnf install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-compose-plugin
macOS, Mac OS X
要在macOS上安装Docker,您应该使用官方的Docker Desktop安装程序。
GUI安装
下载最新的Docker Desktop for Mac安装程序,然后双击下载的程序图标。按照安装程序的提示进行操作,直到安装完成。Docker Desktop for macOS依赖于xhyve项目和Apple的Hypervisor框架,为Linux服务器组件提供本地轻量级虚拟化层,该组件用于启动可以构建Docker镜像和运行容器的Linux虚拟机。
Homebrew安装
您还可以使用macOS上流行的Homebrew软件包管理系统安装Docker CLI工具。如果选择这种方法,您可以考虑安装Vagrant来创建和管理Linux虚拟机。我们很快将在“非Linux虚拟机服务器”中讨论这一点。
Microsoft Windows 11
以下是在Windows 11上安装Docker Desktop所需的步骤。
下载最新的Docker Desktop for Windows安装程序,然后双击下载的程序图标。按照安装程序的提示进行操作,直到安装完成。
Chocolatey安装
你也可以使用流行的Windows软件包管理系统Chocolatey来安装Docker CLI工具。如果你选择这种方式,你应该考虑安装Vagrant来创建和管理你的Linux虚拟机。我们将在“Non-Linux VM-Based Server”部分讨论这个话题。
Docker服务器
Docker服务器是与客户端分开的独立二进制文件,用于管理Docker通常使用的大部分任务。接下来,我们将探讨管理Docker服务器的最常见方法。
基于systemd的Linux系统
当前的Fedora和Ubuntu版本使用systemd来管理系统中的进程。由于你已经安装了Docker,你可以通过输入以下命令来确保服务器在每次系统启动时启动:
$ sudo systemctl enable docker
这告诉systemd启用docker服务,并在系统启动或切换到默认运行级别时启动它。要启动Docker服务器,请输入以下命令:
$ sudo systemctl start docker
非Linux虚拟机服务器
如果你在Docker工作流中使用Microsoft Windows或macOS,你将需要一个虚拟机,这样你就可以设置一个Docker服务器进行测试。Docker Desktop是方便的,因为它使用这些平台上的本机虚拟化技术为你设置这个虚拟机。如果你正在运行较旧版本的Windows或由于其他原因不能使用Docker Desktop,你应该考虑使用Vagrant来帮助你创建和管理Docker服务器的Linux虚拟机。
除了使用Vagrant,你还可以根据个人偏好和需求,使用其他虚拟化工具,比如macOS上的Lima或任何标准的虚拟机监视器(hypervisor)来设置本地Docker服务器。
Vagrant支持多种虚拟机监视器,通常可用于模拟甚至最复杂的环境。在Docker开发中使用Vagrant的一个常见用例是支持在与生产环境匹配的镜像上进行测试。Vagrant支持广泛的发行版,如Red Hat Enterprise Linux和Ubuntu,还支持精细调整的原子主机发行版,如Fedora CoreOS。
你可以通过下载一个自包含的安装包,在大多数平台上轻松安装Vagrant。
你需要在你的系统上完全安装以下其中之一的虚拟机监视器(hypervisor):
-
VirtualBox
免费可用,支持大多数架构上的多平台
-
VMware Workstation Pro/Fusion
商业软件,支持大多数架构上的多平台
-
HyperV
商业软件,支持大多数架构上的Windows
-
KVM
免费可用,支持大多数架构上的Linux
默认情况下,Vagrant假设你正在使用VirtualBox虚拟机监视器,但你可以在使用vagrant命令时通过使用--provider标志来更改它。 在以下示例中,你将创建一个基于Ubuntu的Docker主机,运行Docker守护程序。然后,你将创建一个名为docker-host的主机目录,并进入该目录:
$ mkdir docker-host
$ cd docker-host
为了使用Vagrant,你需要找到一个与你的虚拟化软件和架构兼容的Vagrant Box(虚拟机镜像)。在这个示例中,我们将使用适用于VirtualBox虚拟化软件的Vagrant Box。
请继续,创建一个名为 "Vagrantfile" 的新文件,并将以下内容添加到其中:
puts (<<-EOT)
-----------------------------------------------------------------
[WARNING] This exposes an unencrypted Docker TCP port on the VM!!
This is NOT secure and may expose your system to significant risk
if left running and exposed to the broader network.
-----------------------------------------------------------------
EOT
$script = <<-SCRIPT
echo \'{"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]}\' | \
sudo tee /etc/docker/daemon.json
sudo mkdir -p /etc/systemd/system/docker.service.d
echo -e \"[Service]\nExecStart=\nExecStart=/usr/bin/dockerd\" | \
sudo tee /etc/systemd/system/docker.service.d/docker.conf
sudo systemctl daemon-reload
sudo systemctl restart docker
SCRIPT
Vagrant.configure(2) do |config|
# Pick a compatible Vagrant Box
config.vm.box = 'bento/ubuntu-20.04'
# Install Docker if it is not already on the VM image
config.vm.provision :docker
# Configure Docker to listen on an unencrypted local port
config.vm.provision "shell",
inline: $script,
run: "always"
# Port-forward the Docker port to
# 12375 (or another open port) on our host machine
config.vm.network "forwarded_port",
guest: 2375,
host: 12375,
protocol: "tcp",
auto_correct: true
end
你可以通过运行以下命令来获取完整的文件副本:
$ git clone https://github.com/bluewhalebook/\
docker-up-and-running-3rd-edition.git --config core.autocrlf=input
$ cd docker-up-and-running-3rd-edition/chapter_03/vagrant
$ ls Vagrantfile
确保你在包含Vagrantfile的目录中,然后运行以下命令来启动Vagrant虚拟机。
$ vagrant up
…
Bringing machine 'default' up with 'virtualbox' provider…
==> default: Importing base box 'bento/ubuntu-20.04'…
==> default: Matching MAC address for NAT networking…
==> default: Checking if box 'bento/ubuntu-20.04' version '…' is up to date…
==> default: A newer version of the box 'bento/ubuntu-20.04' for provider…
==> default: available! You currently have version '…'. The latest is version
==> default: '202206.03.0'. Run `vagrant box update` to update.
==> default: Setting the name of the VM: vagrant_default_1654970697417_18732
==> default: Clearing any previously set network interfaces…
…
==> default: Running provisioner: docker…
default: Installing Docker onto machine…
==> default: Running provisioner: shell…
default: Running: inline script
default: {"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]}
default: [Service]
default: ExecStart=
default: ExecStart=/usr/bin/dockerd
一旦虚拟机运行起来,你可以通过运行以下命令,并使用 -H 参数告诉Docker客户端它应该连接到哪里,来连接到Docker服务器:
$ docker -H 127.0.0.1:12375 version
Client:
Cloud integration: v1.0.24
Version: 20.10.14
API version: 1.41
…
Server: Docker Engine - Community
Engine:
Version: 20.10.17
API version: 1.41 (minimum version 1.12)
…
输出会提供有关构成Docker客户端和服务器的各个组件的版本信息。 每次想运行Docker命令时传入IP地址和端口并不理想,但幸运的是,可以使用docker context命令设置Docker知道多个Docker服务器。首先,让我们检查并查看当前正在使用的上下文。请注意带有星号(*)的条目,它表示当前上下文。
$ docker context list
NAME TYPE … DOCKER ENDPOINT …
default * moby … unix:///var/run/docker.sock …
…
你可以通过运行以下一系列命令,为Vagrant虚拟机创建一个新的上下文,并将其设置为活动状态:
$ docker context create vagrant --docker host=tcp://127.0.0.1:12375
vagrant
Successfully created context "vagrant"
$ docker context use vagrant
vagrant
如果你现在重新列出所有的上下文,你应该会看到类似于以下的输出:
$ docker context list
NAME TYPE … DOCKER ENDPOINT …
default moby … unix:///var/run/docker.sock …
vagrant * moby … tcp://127.0.0.1:12375 …
…
在当前的上下文设置为"vagrant"的情况下,运行不带额外"-H"参数的docker version命令仍然会连接到正确的Docker服务器并返回之前相同的信息。
要连接到Vagrant虚拟机上的shell,你可以运行以下命令:
$ vagrant ssh
…
Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0-91-generic x86_64)
…
vagrant@vagrant:~$ exit
在你有时间保护这个设置之前,最好是关闭虚拟机并将上下文设置恢复到原始状态:
$ vagrant halt
…
==> default: Attempting graceful shutdown of VM…
$ docker version
Cannot connect to … daemon at tcp://127.0.0.1:12375. Is the … daemon running?
$ docker context use default
default
测试设置
一旦你已经建立了可工作的客户端和服务器设置,你可以准备测试一切是否正常工作。你应该可以在本地系统上运行以下任意一个命令,告诉Docker守护进程下载最新的官方容器映像,并在其中启动一个运行中的Unix shell进程。
这一步非常重要,以确保所有组件都正确安装并按预期进行通信。它展示了Docker的一个功能:我们可以运行基于任何我们喜欢的Linux发行版的容器。在接下来的几个步骤中,我们将运行基于Ubuntu、Fedora和Alpine Linux的Linux容器。你不需要运行它们所有来证明这一点;运行其中一个就足够了。
Ubuntu
让我们尝试使用最新的Ubuntu Linux基础映像启动一个容器:
$ docker container run --rm -ti docker.io/ubuntu:latest /bin/bash
root@aa9b72ae1fea:/#
Fedora
在这个例子中,我们使用最新的Fedora Linux基础映像启动一个容器:
$ docker container run --rm -ti docker.io/fedora:latest /bin/bash
[root@5c97201e827b /]# exit
Alpine Linux
最后,我们可以测试使用最新的Alpine Linux基础映像启动一个容器:
$ docker container run --rm -ti docker.io/alpine:latest /bin/sh
/ # exit
探索Docker服务器
尽管Docker服务器通常会被安装、启用并自动运行,但手动在Linux系统上运行Docker守护进程也很简单,只需要输入类似以下的命令:
$ sudo dockerd -H unix:///var/run/docker.sock \
--config-file /etc/docker/daemon.json
这个命令启动Docker守护进程,创建并监听一个Unix域套接字(-H unix:///var/run/docker.sock),并从/etc/docker/daemon.json读取其余的配置。你通常不需要自己启动Docker服务器,但这是在幕后发生的事情。在非Linux系统上,你通常会有一个基于Linux的虚拟机来托管Docker服务器。Docker Desktop会在后台为你设置这个虚拟机。
在大多数情况下,通过SSH登录到你的新Docker服务器并查看其内容是非常容易的,但是在非Linux系统上使用Docker Desktop的无缝体验意味着通常并不明显Docker Desktop正在利用本地虚拟机来运行Docker守护进程。由于Docker Desktop虚拟机被设计得非常小且非常稳定,它不运行SSH守护进程,因此有点难以访问。 如果你很好奇或者有必要访问底层的虚拟机,也是可以的,但需要一些高级知识。我们将在“nsenter”中更详细地讨论nsenter命令,但目前,如果你想查看虚拟机(或底层主机),你可以运行以下命令:
$ docker container run --rm -it --privileged --pid=host debian \
nsenter -t 1 -m -u -n -i sh
/ # cat /etc/os-release
PRETTY_NAME="Docker Desktop"
/ # ps | grep dockerd
1540 root 1:05 /usr/local/bin/dockerd
--containerd /var/run/desktop-containerd/containerd.sock
--pidfile /run/desktop/docker.pid
--swarm-default-advertise-addr=eth0
--host-gateway-ip 192.168.65.2
/ # exit
这个命令使用一个特权的Debian容器,其中包含nsenter命令,用于操纵Linux内核的命名空间,以便我们可以访问底层虚拟机或主机的文件系统。
Docker守护进程的配置通常存储在/etc/docker/daemon.json中,但你可能会注意到在Docker Desktop虚拟机中它存在于类似/containers/services/docker/rootfs/etc/docker/daemon.json的位置。Docker对所有设置都使用合理的默认值,因此该文件可能非常小,甚至完全不存在。如果你正在使用Docker Desktop,你可以通过点击Docker图标并选择"Preferences..." -> "Docker Engine"来编辑这个文件,如图3-3所示。
总结
现在你已经有了一个运行中的Docker设置,你可以开始查看更多关于Docker的基本安装机制之外的内容。在下一章中,你将探索如何构建和管理Docker镜像,这些镜像是你使用Docker启动的每个容器的基础。