目的

使用 Docker API 管理 Docker 环境时,Portainer 代理是 Docker API 限制的解决方法。用户与特定资源(容器、网络、卷和图像)的交互仅限于 Docker API 请求所针对的节点上的可用资源。
Docker Swarm 模式引入了一个概念,即 Docker 节点的群集。它还添加作为群集感知资源的服务、任务、配置和机密。群集感知意味着,只要在管理器节点上执行 Docker API 请求,就可以查询服务列表或检查群集上任何节点内的任务。
容器、网络、卷和映像是节点特定的资源,不是群集感知资源。例如,当您想要列出群集内节点上的所有可用卷时,您需要向该特定节点发送查询。
代理的目的是允许以前节点特定的资源具有群集感知功能。同时保留 Docker API 请求格式。如前所述,这意味着您只需执行一个 Docker API 请求,从群集中的每个节点检索所有这些资源。在管理 Swarm 群集时,总之,可提供更好的 Docker 用户体验。

部署

有关如何部署代理以及如何将其连接到 Portainer 的说明。

将其部署为堆栈

查看 Swarm 群集内部的部署文档,通过快速部署部署代理和 Portainer 实例。docker stack deploy

手动部署

总体而言,该设置包含以下步骤:

  • 第 1 步:在 Swarm 群集中为代理创建新的叠加网络。
  • 第 2 步:将代理部署为群集中的全局服务(连接到覆盖网络)。
  • 第 3 步:使用代理的 IP:PORT 作为终结点,将 Portainer 实例连接到任何代理。

注意:此设置假定您正在 Swarm 管理器节点上执行以下说明。
步骤 1,在 Swarm 群集中创建新的叠加网络:

  1. $ docker network create --driver overlay --attachable portainer_agent_network

步骤 2,将代理部署为群集中的全局服务:

  1. $ docker service create \
  2. --name portainer_agent \
  3. --network portainer_agent_network \
  4. --mode global \
  5. --constraint 'node.platform.os == linux' \
  6. --mount type=bind,src=//var/run/docker.sock,dst=/var/run/docker.sock \
  7. --mount type=bind,src=//var/lib/docker/volumes,dst=/var/lib/docker/volumes \
  8. portainer/agent

步骤 3,将 Portainer 实例部署为服务:

  1. $ docker service create \
  2. --name portainer \
  3. --network portainer_agent_network \
  4. --publish 9000:9000 \
  5. --publish 8000:8000 \
  6. --replicas=1 \
  7. --constraint 'node.role == manager' \
  8. portainer/portainer -H "tcp://tasks.portainer_agent:9001" --tlsskipverify

步骤 4,部署所有 Windows 服务器节点的代理
由于 Docker 限制,您需要通过在每个节点上运行以下命令来将代理部署到所有 Windows 服务器节点。

  1. $ docker run -d --name portainer_agent --restart always --network portainer_agent_network -e AGENT_CLUSTER_ADDR=tasks.portainer_agent --mount type=npipe,source=\\.\pipe\docker_engine,target=\\.\pipe\docker_engine portainer/agent:windows1803-amd64

注意:如果您使用的是 Windows 服务器 1803,则可能需要打开 DNS 端口来支持其tasks.portainer_agent。参见: https://success.docker.com/article/swarm-internal-dns-is-inaccessible-on-windows-server-1803

将现有 Portainer 实例连接到代理

如果要将现有 Portainer 实例连接到代理,可以在创建新终结点时选择代理环境类型。
在部署代理时,请确保在 Swarm 群集中公开代理的端口,并且模式设置为主机(默认端口为 9001):

  1. $ docker service create \
  2. --name portainer_agent \
  3. --network portainer_agent_network \
  4. --publish mode=host,target=9001,published=9001 \
  5. --mode global \
  6. --mount type=bind,src=//var/run/docker.sock,dst=/var/run/docker.sock \
  7. --mount type=bind,src=//var/lib/docker/volumes,dst=/var/lib/docker/volumes \
  8. portainer/agent

注意:请注意,这可能会打开代理供任何人使用的情况下,Docker 主机是可从互联网访问。在主机模式下发布代理端口 9001 基本上意味着在所有接口的 Docker 主机防火墙中打开此端口。因此,强烈建议使用环境变量定义共享密钥,请参阅共享密钥。代理实现”首次使用信任”(TOFU)原则,因此只有第一个要连接的 Portainer 才能使用它,但您希望避免攻击者殴打您。AGENT_SECRET
然后,您可以在代理 URL 字段中使用群集中任何节点的地址(使用代理端口)。
或者,您可以使用以下堆栈部署代理:

  1. version: '3.2'
  2. services:
  3. agent:
  4. image: portainer/agent
  5. volumes:
  6. - /var/run/docker.sock:/var/run/docker.sock
  7. - /var/lib/docker/volumes:/var/lib/docker/volumes
  8. ports:
  9. - target: 9001
  10. published: 9001
  11. protocol: tcp
  12. mode: host
  13. networks:
  14. - portainer_agent
  15. deploy:
  16. mode: global
  17. placement:
  18. constraints: [node.platform.os == linux]
  19. networks:
  20. portainer_agent:
  21. driver: overlay
  22. attachable: true

注意:如果与 Portainer 实例在同一 Swarm 覆盖网络中仅运行单个代理群集,则只能省略发布代理端口 9001。Portainer 和代理将能够在同一覆盖网络内相互通信,无需从外部访问代理。

配置

您可以使用变型代理配置实现不同的设置或启用特定功能。

共享密钥

默认情况下,代理将注册连接到它的第一个 Portainer 实例,并阻止来自任何其他实例的连接。
若要绕过此安全机制,可以在部署时配置 Portainer 和代理以使用共享密钥。此配置允许多个 Portainer 实例连接到同一代理终结点。
环境变量可用于定义共享密钥。AGENT_SECRET
将代理部署为服务时:

$ docker service create \
    --name portainer_agent \
    --network portainer_agent_network \
    --publish mode=host,target=9001,published=9001 \
    -e AGENT_SECRET=mysecrettoken \
    --mode global \
    --mount type=bind,src=//var/run/docker.sock,dst=/var/run/docker.sock \
    --mount type=bind,src=//var/lib/docker/volumes,dst=/var/lib/docker/volumes \
    portainer/agent

通过堆栈文件:

version: '3.2'
services:
  agent:
    image: portainer/agent
    environment:
      AGENT_SECRET: mysecrettoken
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes:/var/lib/docker/volumes
    ports:
      - target: 9001
        published: 9001
        protocol: tcp
        mode: host
    networks:
      - portainer_agent
    deploy:
      mode: global
      placement:
        constraints: [node.platform.os == linux]
networks:
  portainer_agent:
    driver: overlay
    attachable: true

部署 Portainer 时也必须指定:AGENT_SECRET

$ docker run -d -p 9000:9000 -p 8000:8000 --name portainer --restart always -e AGENT_SECRET=mysecrettoken -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer

启用主机管理功能

出于安全原因,默认情况下禁用了以下功能:

  • 能够管理代理运行的主机的文件系统
  • 能够检索有关代理运行的主机(PCI 设备/磁盘)的硬件信息

为了启用这些功能,必须按以下方式正确配置代理:

  • 通过环境变量启用主机管理功能CAP_HOST_MANAGEMENT
  • 绑定安装代理容器中主机的根目录(必须装入绑定/host)

通过堆栈文件部署代理时的示例:

version: '3.2'
services:
  agent:
    image: portainer/agent
    environment:
      CAP_HOST_MANAGEMENT: 1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes:/var/lib/docker/volumes
      - /:/host
    ports:
      - target: 9001
        published: 9001
        protocol: tcp
        mode: host
    networks:
      - portainer_agent
    deploy:
      mode: global
      placement:
        constraints: [node.platform.os == linux]
networks:
  portainer_agent:
    driver: overlay
    attachable: true

可用选项

您可以使用环境变量更改代理的配置。
可以调整以下环境变量:

  • AGENT_PORT:代理端口(默认值:9001)
  • LOG_LEVEL:代理日志级别(默认值:INFO)
  • AGENT_CLUSTER_ADDR:每个代理用于形成群集的地址。
  • AGENT_SECRET:用于授权 Portainer 实例连接到代理的共享密钥
  • CAP_HOST_MANAGEMENT:通过将值设置为 启用主机管理功能,启用主机管理功能1

    使用

    Api

    如果要使用 Portainer API 查询在 Swarm 群集内的特定节点上运行的容器,并且在使用 Portainer 代理设置时,可以在 HTTP 请求中指定标头以定位群集中的特定节点。该值必须设置为特定节点的名称,在查询群集资源(容器、卷…)时,可通过 属性检索该节点的名称。X-PortainerAgent-Target``NodeName
    https://www.portainer.io/documentation/how-to-use-the-agent/