Docker Inc.最近宣布Docker Desktop 将不再是大型组织的免费产品。对于个人和开源项目以及小于一定规模的组织,它将保持免费。通常这不是令人担忧的原因,因为收入超过 1000 万美元的公司将能够负担 Docker Desktop 每用户每月 5 美元的入门价格。这篇文章绝不会阻止组织付费,我相信 Docker Inc. 拥有将其产品货币化的所有权利。

抛开免责声明,让我们深入解释一下什么是免费的,什么是付费的,以及我们如何才能继续使用核心技术“容器”,而无需为 Docker Desktop 付费。


这个题外话解释了围绕 Docker 的术语。了解 Docker 的高手可以跳过这一部分。

Docker 可能意味着很多事情。我将尝试分解并解释每个术语。这绝不是对 Docker 工作原理的完整概念架构解释,我建议为此目的探索网络上的其他资源。这个题外话只是为了简化其余的讨论。

  • Docker Inc- 这是一家美国公司,生产一些开源和非开源软件,使在容器中开发、测试和运行应用程序变得更加容易。

  • Docker Engine- Docker 背后的核心技术。它是一个在 linux 上作为守护进程运行的开源软件,可以在 Linux 内核之上运行容器。它负责容器生命周期和容器可以访问的物理资源(计算、内存、存储)的隔离。该引擎可以在物理机或虚拟机上运行,但它只能在 Linux 内核之上运行,即任何具有 Linux 风格的操作系统。理解这一点很重要。 Docker 引擎仅在 Linux 上运行。

  • Docker CLI- 这是开发人员通常用来与 docker 引擎交互的 CLI。这包括dockerdocker-compose命令。同样,这是开源软件。

  • Docker Desktop- 由于 Docker 引擎仅在 Linux 上运行,因此使用 Windows 和 macOS 进行软件开发的开发人员在启动运行 linux 的虚拟机 (VM) 之前无法运行引擎。这就是 Docker Desktop 的用武之地。Docker Desktop 是一个闭源软件,它允许在 Windows/macOS 上工作的开发人员在他们的开发环境中无缝地使用容器技术,而无需管理操作虚拟机的复杂性和所有细节。随之而来(网络、虚拟化、Linux 知识等)。 Docker Desktop 是在软件开发过程中使用的,它不参与在类生产环境中运行的容器中,其中主要涉及仅 Docker 引擎。

Docker Desktop 并不是运行容器的核心技术,它只是为了让在 Windows/macOS 上开发运行在容器中的软件变得更加容易。因此,Docker Inc. 只是试图让大公司为 Docker Desktop 在开发应用程序时提供的便利付费。因此,我完全同情他们试图从他们的软件开发人员努力开发的产品中赚取收入的举动。公司的其他收入来自Docker Hub。


在 macOS 上继续为容器运行和构建应用程序的方法是在 Linux VM 上运行 Docker Engine。我讨论了我在我的开发环境(Macbook Pro 13" 2020 Intel 芯片)上尝试过的两种方法。这个列表并不详尽,他们可能有更多方法可以做到这一点。这篇文章确实假设了一些 Docker 的工作知识。

在执行此操作之前,请通过删除/Applications/Docker.app来卸载 Docker Desktop。有时这还不够,并且会留下某些内容,因此我建议搜索“在 macos 上卸载 docker desktop”并按照指南进行全面清理。

到目前为止,minikube已经成为 Docker Desktop 最简单的替代品。 minikube 用于在本地环境中运行 Kubernetes 集群。但它也运行一个可用于运行容器的 docker 守护进程。在 macOS 上,minikube 运行在很多虚拟化技术上,但是hyperkit是最容易使用的。

# Install hyperkit and minikube
brew install hyperkit
brew install minikube

# Install Docker CLI
brew install docker
brew install docker-compose

# Start minikube
minikube start

# Tell Docker CLI to talk to minikube's VM
eval $(minikube docker-env)

# Save IP to a hostname
echo "`minikube ip` docker.local" | sudo tee -a /etc/hosts > /dev/null

# Test
docker run hello-world

进入全屏模式 退出全屏模式

丑椅子

minikube stop- 停止 VM 和 k8s 集群。这不会删除任何数据。只需运行minikube start即可启动集群。

minikube delete- 这删除包含所有数据的集群。所有映射的卷都将丢失。在运行它之前知道你在做什么。如果您只想停止集群,请使用minikube stop

minikube ip- 运行集群和 docker 引擎的 VM 的 IP 地址。

minikube 运行 k8s 设置,因此运行许多不使用 k8s 时不需要的容器。我们可以运行minikube pause来暂停与 k8s 相关的容器,这样它们就不会最终消耗系统资源。

手动管理虚拟机

如果您已经在本地使用 Linux VM 用于其他目的,或者希望对设置进行更多控制,那么这可能是一个不错的选择。为此,我们将使用VirtualBox来运行 Linux VM,并使用Vagrant来简化 VM 的配置。我们将使用 Ubuntu 20.04 LTS 作为 VM 的基本操作系统。

# Install VirtualBox
brew install --cask virtualbox
brew install --cask virtualbox-extension-pack

# Install Vagrant and the vbguest plugin to manage VirtualBox Guest Additions on the VM
brew install vagrant
vagrant plugin install vagrant-vbguest

# Install Docker CLI
brew install docker
brew install docker-compose

# Create a Vagrantfile and a provisioning script
mkdir vagrant-docker-engine
echo \
"Vagrant.configure('2') do |config|
  config.vm.box = 'ubuntu/focal64'
  config.vm.hostname = 'docker.local'
    config.vm.network 'private_network', ip: '192.168.66.4'
  config.vm.network 'forwarded_port', guest: 2375, host: 2375, id: 'dockerd'
  config.vm.provider 'virtualbox' do |vb|
    vb.name = 'ubuntu-docker'
    vb.memory = '2048'
    vb.cpus = '2'
  end
  config.vm.provision 'shell', path: 'provision.sh'

  # Configuration for Port Forwarding
  # Uncomment or add new ones here as required
  # config.vm.network 'forwarded_port', guest: 6379, host: 6379, id: 'redis'
  # config.vm.network 'forwarded_port', guest: 3306, host: 3306, id: 'mysql'
end" | tee Vagrantfile > /dev/null
echo \
"# Install Docker
apt-get remove docker docker-engine docker.io containerd runc
apt-get update
apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release net-tools software-properties-common
curl -fsSL <https://download.docker.com/linux/ubuntu/gpg> | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] <https://download.docker.com/linux/ubuntu> focal stable' | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io

# Configure Docker to listen on a TCP socket
mkdir /etc/systemd/system/docker.service.d
echo \\
'[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock' | tee /etc/systemd/system/docker.service.d/docker.conf > /dev/null
echo \\
'{
  \"hosts\": [\"fd://\", \"tcp://0.0.0.0:2375\"]
}' | tee /etc/docker/daemon.json > /dev/null
systemctl daemon-reload
systemctl restart docker.service" | tee provision.sh > /dev/null
chmod +x provision.sh

# Spin up the machine
vagrant up

# Save IP to a hostname
echo "192.168.66.4 docker.local" | sudo tee -a /etc/hosts > /dev/null

# Tell Docker CLI to talk to the VM
export DOCKER_HOST=http://docker.local:2375

# Optionally add it to your shell so don't need to repeat everytime
# echo "export DOCKER_HOST=http://docker.local:2375" | tee -a ~/.zshrc > /dev/null

# Test
docker run hello-world

进入全屏模式 退出全屏模式

流浪者备忘单

vagrant suspend- 停止 VM 以节省系统资源。这不会删除任何数据。只需运行vagrant up即可启动 VM。

vagrant reload- 用于重新加载 VM 以对配置进行任何更改,例如添加新的端口映射。

vagrant delete- 这删除包含所有数据的 VM。所有映射的卷都将丢失。在运行它之前知道你在做什么。如果您只想停止 VM,请使用vagrant suspend

对于我们想要在 macOS 主机上本地访问的每个端口,我们需要修改Vagrantfile以添加端口转发。更改文件后使用vagrant reloadVagrantfile中已经提供了一些示例供参考。

注意事项

访问端口

Docker Desktop 通过使所有内容在 localhost 上可用,可以非常方便地访问容器上运行的服务/应用程序。他们究竟是如何做到这一点的还不得而知,虽然它必须通过 hyperkit 进行一些端口映射,但我们必须手动进行。

在上面的 minikube 和 virtualbox 指南中,我们使 VM 的 IP 地址在docker.local主机名下可用,因此要访问任何服务,我们必须使用该主机名而不是使用 localhost。

使用 Vagrant 我们实际上可以进行双端口映射(在容器 ↔ linux 和 linux ↔ 主机之间)来访问 localhost 上的内容。这可以通过我在Vagrantfile中添加forwarded_port条目来完成,如上所述。

卷和数据持久性

由于 Docker 引擎在 VM 上运行,因此创建或映射的任何卷都将存在于 Linux VM 上,而不是 macOS(主机)上。 记住这一点非常重要。 这意味着通过破坏 VM,我们将无法访问卷中的数据。卷通常用于 MySQL、PostgreSQL 等持久性数据库。

vagrant允许您将文件夹映射到 VM 的方式有很多,这将再次像上面提到的端口一样是 3 层映射,但由于 Docker 工作方式中的权限问题而变得非常复杂。我尝试了很多,但无法使其适用于 MySQL。如果我花一些额外的时间,我可以,但关键是它很麻烦。

我的建议是将卷备份到 VM 上的某个位置,如果您使用的是minikube,则通过scp将该备份拉到主机,或者vagrant的默认驱动器映射为/vagrant,可用于备份。值得庆幸的是,备份卷很容易并且可以根据需要将其放入 VM/主机上的 cronjob 中。

性能

如果您使用的是minikube,则性能或多或少保持不变,因为正在使用相同的底层虚拟化技术 (hyperkit)。但由于一些奇怪的原因,我看到使用vagrant + virtualbox组合时 MySQL 的读/写性能有了巨大的提升。我没有深入研究它的原因,但它已经坚持下去了。我还没有尝试minikube + virtualbox组合。

minikube实际上在虚拟机上运行了一个 kubernetes 集群,所以如果不需要,执行minikube pause将确保与 k8s 集群相关的容器被挂起,这样它们就不会消耗任何系统资源。

Logo

云原生社区为您提供最前沿的新闻资讯和知识内容

更多推荐