在Azure上部署Docker容器

预计阅读时间:19分钟

概述

Docker Azure集成使开发人员在构建云原生应用程序时可以使用本机Docker命令在Azure容器实例(ACI)中运行应用程序。新的体验在Docker桌面和Microsoft Azure之间提供了紧密的集成,从而使开发人员可以使用Docker CLI或VS Code扩展快速运行应用程序,从而从本地开发无缝切换到云部署。

此外,Docker与Microsoft开发人员技术之间的集成使开发人员可以使用Docker CLI进行以下操作:

  • 轻松登录Azure
  • 在一个Docker命令中设置ACI上下文,使您可以从本地上下文切换到云上下文,并快速,轻松地运行应用程序
  • 使用Compose规范简化单个容器和多容器应用程序的开发,从而使开发人员能够首次在云容器服务中原生地无缝调用完全兼容Docker的命令

也看到了容器的完整列表功能由ACI支持由ACI支持撰写功能完整列表

先决条件

若要在Azure上部署Docker容器,必须满足以下要求:

  1. 下载并安装最新版本的Docker Desktop。

    或者,安装适用于LinuxDocker Compose CLI

  2. 确保您具有Azure订阅。您可以开始使用Azure免费帐户

在ACI上运行Docker容器

Docker不仅在本地运行容器,而且还使开发人员能够使用命令docker run或在Compose文件中定义的多容器应用程序在ACI上无缝部署Docker容器docker compose up

以下各节包含有关如何在ACI上部署Docker容器的说明。另请参阅ACI支持的容器功能完整列表

登录到Azure

运行以下命令以登录到Azure:

docker login azure

这将打开您的Web浏览器,并提示您输入Azure登录凭据。如果Docker CLI无法打开浏览器,它将退回到Azure设备代码流,并允许您手动连接。请注意,Azure命令行登录与Docker CLI Azure登录分开。

或者,您可以使用Azure服务主体,而无需交互(通常在脚本或持续集成方案中)登录, docker login azure --client-id xx --client-secret yy --tenant-id zz

笔记

通过Azure服务提供商登录可获得在短时间内(通常为1h)有效的访问令牌,但不允许您自动透明地刷新此令牌。使用服务提供商登录时,如果访问令牌过期,则必须手动重新登录。

--tenant-id如果您在Azure中有多个可用租户,则也可以单独使用该选项来指定租户。

创建一个ACI上下文

登录后,需要创建与ACI关联的Docker上下文,以在ACI中部署容器。创建ACI上下文需要Azure订阅,资源组和区域。例如,让我们创建一个名为的新上下文myacicontext

docker context create aci myacicontext

此命令自动使用您的Azure登录凭据来标识您的订阅ID和资源组。然后,您可以交互方式选择要使用的订阅和组。如果你愿意,你可以使用以下标志指定的CLI这些选项:--subscription-id--resource-group,和--location

如果您的Azure帐户中没有任何现有资源组,则该docker context create aci myacicontext命令将为您创建一个资源组。您无需指定任何其他选项即可执行此操作。

创建ACI上下文后,可以通过运行以下docker context ls命令列出Docker上下文:

NAME                TYPE                DESCRIPTION                               DOCKER ENDPOINT                KUBERNETES ENDPOINT   ORCHESTRATOR
myacicontext        aci                 myResourceGroupGTA@eastus
default *           moby              Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                          swarm

运行一个容器

现在,您已经登录并创建了ACI上下文,您可以开始使用Docker命令在ACI上部署容器。

有两种使用新ACI上下文的方法。您可以将该--context标志与Docker命令一起使用,以指定要使用新创建的ACI上下文运行该命令。

docker --context myacicontext run -p 80:80 nginx

或者,您可以使用docker context use选择ACI上下文来更改上下文,以将其作为运行Docker命令的重点。例如,我们可以使用以下docker context use命令来部署ngnix容器:

docker context use myacicontext
docker run -p 80:80 nginx

切换到myacicontext上下文后,可以docker ps用来列出在ACI上运行的容器。

对于上面启动的演示nginx容器,ps命令的结果将在“端口”列中显示运行该容器的IP地址和端口。例如,它可能会显示52.154.202.35:80->80/tcp,并且您可以通过浏览来查看nginx欢迎页面http://52.154.202.35

要查看容器中的日志,请运行:

docker logs <CONTAINER_ID>

要在正在运行的容器中执行命令,请运行:

docker exec -t <CONTAINER_ID> COMMAND

要停止并从ACI中删除容器,请运行:

docker stop <CONTAINER_ID>
docker rm <CONTAINER_ID>

您可以使用删除容器docker rm。要删除正在运行的容器,必须使用该--force标志,或者使用来停止容器,docker stop然后再将其删除。

笔记

在ACI上重新启动容器的语义与使用本地Docker上下文进行本地开发时的语义不同。在ACI上,容器将重置为初始状态并在新节点上启动。这包括容器的文件系统,因此所有未存储在卷中的状态将在重新启动时丢失。

运行撰写应用程序

您还可以使用以下docker compose命令将在Compose文件中定义的多容器应用程序部署和管理到ACI 。同一Compose应用程序中的所有容器都在同一容器组中启动。容器之间的服务发现使用在Compose文件中指定的服务名称进行工作。容器之间的名称解析是通过在/etc/hosts文件中写入服务名称来实现的,该文件由容器组中的所有容器自动共享。

另请参阅ACI支持的撰写功能完整列表

  1. 确保您使用的是ACI上下文。您可以通过指定--context myacicontext标志或使用命令设置默认上下文来执行此操作 docker context use myacicontext

  2. 运行docker compose updocker compose down启动,然后停止完整的Compose应用程序。

默认情况下,docker compose up使用docker-compose.yaml当前文件夹中的文件。您可以使用--workdir标志指定工作目录,也可以直接使用来指定Compose文件docker compose --file mycomposefile.yaml up

您还可以--project-name在部署期间使用该标志为Compose应用程序指定名称。如果未指定名称,则将从工作目录派生名称。

使用时,作为Compose应用程序一部分启动的容器将与单个容器一起显示docker ps。其容器ID的格式为:<COMPOSE-PROJECT>_<SERVICE>。这些容器不能单独停止,启动或删除,因为它们都是同一ACI容器组的一部分。您可以使用来查看每个容器的日志docker logs。您可以使用列出已部署的Compose应用程序docker compose ls。这将仅列出组合应用程序,而不列出以开头的单个容器docker run。您可以使用删除Compose应用程序docker compose down

笔记

当前的Docker Azure集成不允许从组成Compose应用程序的所有容器中获取合并的日志流。

更新应用程序

在已部署的Compose应用程序中,可以通过使用相同的项目名称重新部署来更新该应用程序docker compose --project-name PROJECT up

更新应用程序意味着将重新使用ACI节点,并且该应用程序将保留先前分配给公开端口的IP地址(如果有)。ACI对现有应用程序中可以更新的内容有一些限制(例如,您将无法更改CPU /内存预留),在这些情况下,您需要从头开始部署新应用程序。

如果您docker compose up在已部署的Compose文件上调用,则更新是默认行为,因为Compose项目名称是从Compose文件默认所在的目录派生的。您需要docker compose downdocker compose up再次运行之前显式执行,以完全重置Compose应用程序。

释放资源

可以使用以下docker prune命令从ACI中删除单个容器和Compose应用程序。该docker prune命令将删除当前未运行的部署。要删除运行中的款项,您可以指定 --force。该--dry-run选项列出了计划删除的部署,但实际上并未删除它们。

$ ./bin/docker --context acicontext prune --dry-run --force
Resources that would be deleted:
my-application
Total CPUs reclaimed: 2.01, total memory reclaimed: 2.30 GB

暴露端口

单个容器和Compose应用程序可以选择公开端口。对于单个容器,这是使用命令--publish-p)的()标志完成的。docker rundocker run -p 80:80 nginx

对于Compose应用程序,必须在Compose文件服务定义中指定公开的端口:

services:
  nginx:
    image: nginx
    ports:
      - "80:80"

笔记

ACI不允许端口映射(即,在公开端口时更改端口号)。因此,在部署到ACI时,源端口和目标端口必须相同。

同一Compose应用程序中的所有容器都部署在同一ACI容器组中。部署到ACI时,同一Compose应用程序中的不同容器无法公开同一端口。

默认情况下,在为应用程序公开端口时,随机公共IP地址与支持已部署应用程序的容器组(单个容器或Compose应用程序)相关联。使用docker ps或使用列出容器时,可以获取此IP地址docker inspect

DNS标签名称

除了在随机IP地址上公开端口之外,您还可以指定DNS标签名称,以在以下形式的FQDN上公开您的应用程序<NAME>.region.azurecontainer.io

您可以--domainname在执行时通过标志设置此名称docker run,或者在执行时通过使用domainnameCompose文件中的字段来设置docker compose up

services:
  nginx:
    image: nginx
    domainname: "myapp"
    ports:
      - "80:80"

笔记

Compose应用程序的域只能设置一次,如果您domainname为多个服务指定 ,则该值必须相同。

FQDN<DOMAINNAME>.region.azurecontainer.io必须可用。

使用Azure文件共享作为ACI容器中的卷

您可以部署使用存储在卷中的持久性数据的容器或Compose应用程序。Azure文件共享可用于支持ACI容器的卷。

使用具有存储帐户名mystorageaccount 和文件共享名的现有Azure文件共享myfileshare,可以在部署run 命令中指定一个卷,如下所示:

docker run -v mystorageaccount/myfileshare:/target/path myimage

运行时容器将在中看到文件共享内容/target/path

在Compose应用程序中,卷规范必须在Compose文件中使用以下语法:

myservice:
  image: nginx
  volumes:
    - mydata:/mount/testvolumes

volumes:
  mydata:
    driver: azure_file
    driver_opts:
      share_name: myfileshare
      storage_account_name: mystorageaccount

笔记

不能使用Compose文件中的volume short语法,因为它是针对本地绑定安装的卷定义的。在Compose文件中使用卷驱动程序和驱动程序选项语法可使卷定义更加清晰。

在单容器或多容器部署中,Docker CLI将使用您的Azure登录名来获取存储帐户的密钥,并将此密钥与容器部署信息一起提供,以便容器可以访问该卷。可以使用Azure登录名访问的任何存储帐户中的任何文件共享中的卷。装入卷时,可以指定rw(读/写)或ro(只读)(rw默认设置)。

管理Azure卷

若要创建可在使用ACI Docker上下文时在容器或Compose应用程序中使用的卷,可以使用以下docker volume create命令,并指定Azure存储帐户名和文件共享名:

$ docker --context aci volume create test-volume --storage-account mystorageaccount
[+] Running 2/2
 ⠿ mystorageaccount  Created                         26.2s
 ⠿ test-volume       Created                          0.9s
mystorageaccount/test-volume

默认情况下,如果该存储帐户尚不存在,则此命令使用标准LRS作为默认SKU以及与Docker ACI上下文关联的资源组和位置创建一个新的存储帐户。

如果指定现有存储帐户,那么该命令将在现有帐户中创建一个新的文件共享:

$ docker --context aci volume create test-volume2 --storage-account mystorageaccount
[+] Running 2/2
 ⠿ mystorageaccount   Use existing                    0.7s
 ⠿ test-volume2       Created                         0.7s
mystorageaccount/test-volume2

或者,您可以使用Azure门户或az 命令行创建Azure存储帐户或文件共享。

您还可以列出可在容器或Compose应用程序中使用的卷:

$ docker --context aci volume ls
ID                                 DESCRIPTION
mystorageaccount/test-volume       Fileshare test-volume in mystorageaccount storage account
mystorageaccount/test-volume2      Fileshare test-volume2 in mystorageaccount storage account

若要删除卷和相应的Azure文件共享,请使用以下volume rm命令:

$ docker --context aci volume rm mystorageaccount/test-volume
mystorageaccount/test-volume

这将永久删除Azure文件共享及其所有数据。

在Azure中删除卷时,该命令将检查指定的文件共享是否是存储帐户中唯一可用的文件共享。如果使用该docker volume create命令创建docker volume rm了存储帐户,则当该存储帐户没有任何文件共享时,还将删除该存储帐户。如果您使用的存储帐户是在没有docker volume create命令的情况下创建的(az例如,通过Azure门户或使用命令行),docker volume rm 则即使该存储帐户具有零剩余文件共享,也不会删除该存储帐户。

环境变量

使用时docker run,可以使用该--env标志将环境变量传递到ACI容器。对于Compose应用程序,可以使用environmentenv-file服务字段或--environment命令行标志在Compose文件中指定环境变量。

健康检查

您可以使用带有的--healthcheck-前缀标志来指定容器的运行状况检查docker run,或者使用healthcheck服务的部分在Compose文件中指定容器的运行状况检查。

运行状况检查将转换为ACI LivenessProbe。ACI会定期运行运行状况检查命令,如果失败,则该容器将被终止。

除了重新启动策略外,还必须使用运行状况检查,以确保随后在终止时重新启动容器。默认的重新启动策略docker runno不会重新启动容器。Compose的默认重新启动策略是any始终尝试重新启动服务容器。

使用示例docker run

docker --context acicontext run -p 80:80 --restart always --health-cmd "curl http://localhost:80" --health-interval 3s  nginx

使用撰写文件的示例:

services:
  web:
    image: nginx
    deploy:
      restart_policy:
        condition: on-failure
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:80"]
      interval: 10s

私有Docker Hub映像并使用Azure容器注册表

您可以将由任何容器注册表托管的私有映像部署到ACI。docker login在运行docker run或之前,您需要使用登录到相关的注册表docker compose up。Docker CLI将获取已部署映像的注册表登录信息,并将凭据以及映像部署信息发送到ACI。对于Azure容器注册表,命令行将尝试通过Azure登录名自动将您登录到ACR。如果您的Azure登录名可以访问ACR,则无需先手动登录到ACR注册表。

使用ACI资源组作为名称空间

您可以创建与ACI关联的多个Docker上下文。每个上下文必须与唯一的Azure资源组关联。这使您可以将Docker上下文用作名称空间。您可以使用切换名称空间docker context use <CONTEXT>

运行docker ps命令时,它仅列出当前Docker上下文中的容器。两个Docker上下文之间的容器名称或Compose应用程序名称不会有任何争用。

在Linux上安装Docker Compose CLI

Docker Compose CLI添加了对在Azure容器实例(ACI)上运行和管理容器的支持。

安装先决条件

安装脚本

您可以使用安装脚本来安装新的CLI:

curl -L https://raw.githubusercontent.com/docker/compose-cli/main/scripts/install/install_linux.sh | sh

手动安装

您可以从最新版本页面下载Docker ACI集成CLI 。

然后,您需要使其可执行:

chmod +x docker-aci

要启用使用本地Docker Engine并使用现有Docker上下文,您必须将现有Docker CLIcom.docker.cli放在中 PATH。您可以通过从现有Docker CLI创建符号链接来做到这一点:

ln -s /path/to/existing/docker /directory/in/PATH/com.docker.cli

笔记

PATH环境变量是从左至右优先目录的冒号分隔的列表。您可以使用查看它 echo $PATH。您可以使用找到现有Docker CLI的路径 which docker。您可能需要root权限才能建立此链接。

已经安装了Docker Engine的Ubuntu 20.04的全新安装中 :

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
$ which docker
/usr/bin/docker
$ sudo ln -s /usr/bin/docker /usr/local/bin/com.docker.cli

您可以通过检查新的CLI是否与默认上下文一起工作来验证此方法是否有效:

$ ./docker-aci --context default ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
$ echo $?
0

要将此带有ACI集成的CLI设置为默认的Docker CLI,必须将其移动到您PATH现有目录中比现有Docker CLI更高优先级的目录中。

同样,在新的Ubuntu 20.04上:

$ which docker
/usr/bin/docker
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
$ sudo mv docker-aci /usr/local/bin/docker
$ which docker
/usr/local/bin/docker
$ docker version
...
 Azure integration  0.1.4
...

支持的命令

安装Docker ACI集成CLI后,运行--help以查看当前命令列表。

卸载

要删除泊坞Azure集成CLI,您需要删除您下载的和二进制com.docker.cli从你的PATH。如果使用脚本进行安装,则可以按照以下步骤进行操作:

sudo rm /usr/local/bin/docker /usr/local/bin/com.docker.cli

反馈

感谢您试用Docker Azure集成。您的反馈对我们来说很重要。通过在compose-cli GitHub存储库中创建问题,让我们知道您的反馈。

DockerAzure集成ACI上下文编写cli部署容器