目的
使用 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 群集中创建新的叠加网络:
$ docker network create --driver overlay --attachable portainer_agent_network
步骤 2,将代理部署为群集中的全局服务:
$ docker service create \
--name portainer_agent \
--network portainer_agent_network \
--mode global \
--constraint 'node.platform.os == linux' \
--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
步骤 3,将 Portainer 实例部署为服务:
$ docker service create \
--name portainer \
--network portainer_agent_network \
--publish 9000:9000 \
--publish 8000:8000 \
--replicas=1 \
--constraint 'node.role == manager' \
portainer/portainer -H "tcp://tasks.portainer_agent:9001" --tlsskipverify
步骤 4,部署所有 Windows 服务器节点的代理
由于 Docker 限制,您需要通过在每个节点上运行以下命令来将代理部署到所有 Windows 服务器节点。
$ 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):
$ docker service create \
--name portainer_agent \
--network portainer_agent_network \
--publish mode=host,target=9001,published=9001 \
--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
注意:请注意,这可能会打开代理供任何人使用的情况下,Docker 主机是可从互联网访问。在主机模式下发布代理端口 9001 基本上意味着在所有接口的 Docker 主机防火墙中打开此端口。因此,强烈建议使用环境变量定义共享密钥,请参阅共享密钥。代理实现”首次使用信任”(TOFU)原则,因此只有第一个要连接的 Portainer 才能使用它,但您希望避免攻击者殴打您。AGENT_SECRET
然后,您可以在代理 URL 字段中使用群集中任何节点的地址(使用代理端口)。
或者,您可以使用以下堆栈部署代理:
version: '3.2'
services:
agent:
image: portainer/agent
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 实例在同一 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/