在容器中运行第三方应用
要在 Junos OS 演化版上运行自己的应用,可以选择将其部署为 Docker 容器。容器在 Junos OS Evolved 上运行,应用在容器中运行,使其与主机作系统保持隔离。容器安装在挂载在 /var/extensions 的单独分区中。容器在重启和软件升级后仍然存在。
Docker 容器未集成到 Junos OS 演化版中,而是使用 Docker 命令完全通过 Linux 创建和管理。有关 Docker 容器和命令的更多信息,请参阅 Docker 官方文档: https://docs.docker.com/get-started/
容器对可从系统使用的资源有默认限制:
-
Storage – /var/extensions 分区的大小由平台驱动:8GB 或 /var 总大小的 30%,以较小者为准。
-
Memory – 容器的默认组合物理内存限制为 2 GB。这是可以更改的。
-
CPU – 容器的默认组合 CPU 限制为 1 个 CPU 核心的 20%。这是可以更改的。
如有必要,可以修改容器的资源限制。请参阅 修改容器的资源限制。
部署 Docker 容器
要部署 Docker 容器,请执行以下作:
管理 Docker 容器
Docker 容器通过标准 Docker Linux 工作流进行管理。 docker ps使用 或 ps top Linux 命令显示正在运行的 Docker 容器,并使用 Docker 命令管理容器。有关 Docker 命令的详细信息,请参阅: https://docs.docker.com/reference/cli/docker/
Junos OS 演化版 Docker 容器中的自定义应用程序不支持高可用性功能,如果应用程序具有高可用性功能,则应在每个 RE 上运行应用程序,以确保它可以自行同步。这样的应用程序需要具有所需的业务逻辑来管理自身并与所有实例进行通信。
在容器中启用 Netlink 或 PacketIO
如果您的容器需要额外的功能(如 Netlink 或 PacketIO),则需要向 Docker 命令提供额外的参数。您还需要启用 nlsd 服务以在某些版本上启用 Netlink 功能。以下示例说明如何通过向 Docker 命令添加参数来激活容器的 Netlink 或 PacketIO 功能:
启动 Docker 服务时创建只读名称持久卷。挂载
jnet卷将通过 WAN/数据端口挂载 PacketIO 和 Netlink 功能所需的库:--mount source=jnet,destination=/usr/evo
与容器共享主机的网络和 IPC 命名空间。需要通过 WAN/数据端口实现 PacketIO 和 Netlink 功能的容器需要位于主机网络和 IPC 命名空间中:
--network=host --ipc=host
系统重新启动时自动启动容器:
--restart=always
启用 Netlink 和 PacketIO 库所需的网络管理功能:
--cap-add=NET_ADMIN
启用通过 WAN/数据端口实现 Netlink 和 PacketIO 所需的环境变量:
--env-file=/run/docker/jnet.env
将 jtd0 设备从主机挂载到容器以帮助处理 PacketIO:
--device=/dev/jtd0
将主机的 /dev/shm 目录挂载到容器中,以便通过 WAN/数据端口实现 Netlink 和 PacketIO:
-v /dev/shm:/dev/shm
如果容器应用程序需要组播组管理,请将 /dev/mcgrp 目录从主机挂载到容器:
-v /dev/mcgrp:/dev/mcgrp
在 Junos OS 演化版 24.1R1 之后,主机网络命名空间中想要进行 DNS 解析的容器需要将选项传递
--dns ::1给docker run命令。Junos OS 演化版 23.4 及更低版本不需要:--dns ::1
如果您的容器需要与 Netlink 相关的处理,则还需要在 Junos OS 演化版中使用以下 CLI 配置启用 Netlink 异步 API (
nlsd) 进程:[edit] user@host# set system processes nlsd enable
需要 PacketIO 和 Netlink 功能的原生 Linux 或基于容器的应用程序应动态链接。我们建议使用基于 Ubuntu 的 Docker 容器,因为它们是唯一获得瞻博网络官方认证的容器。基于 Ubuntu 的容器应使用与基本 Junos Evolved OS glibc兼容的 glibc 。
为 Docker 容器选择 VRF
对于 Junos OS 演化版 23.4R1 及更低版本,容器从 Docker 进程继承虚拟路由和转发 (VRF)。为了在不同的 VRF 中运行容器,需要在相应的 VRF 中启动 Docker 进程实例。该 docker@vrf.service 实例允许在相应的 VRF 中启动进程。如果未指定 VRF,则 VRF 默认为 vrf0。
默认运行docker.service。vrf:none
对于 Junos OS 演化版 24.1R1 及更高版本,建议使用 ip vrf exec task 命令将容器中的特定任务绑定到特定的 Linux VRF。这需要使用选项 --privileged启动容器,并且容器需要安装兼容版本 iproute2 的容器。容器还应与主机共享网络命名空间。您还可以使用 socket 选项 SO_BINDTODEVICE 将容器中特定任务或应用程序的套接字绑定到特定的 Linux VRF 设备,在这种情况下 iproute2 不需要。
命令 ip vrf show 会列出所有可用的 Linux VRF。如果您选择使用 iproute2将容器中任务的套接字绑定到 VRF,我们建议使用 --env-file=/run/docker-vrf0/jnet.env覆盖一些 env 变量,因此 libnli.so 不会预加载以避免它干扰 iproute2。
您可以使用以下命令启动容器并将与容器任务关联的套接字绑定到默认 vrf vrf0 :
[vrf:none] user@host:~# docker -H unix:///run/docker-vrf0.sock run --rm -it –-privileged --network=host --ipc=host --cap-add=NET_ADMIN --mount source=jnet,destination=/usr/evo --device=/dev/jtd0 -v /dev/mcgrp:/dev/mcgrp -v /dev/shm:/dev/shm --env-file=/run/docker-vrf0/jnet.env --dns ::1 debian:stretch bash # explicitly preload libsi.so and avoid libnli.so. Bind ping’s socket to vrf0 (default) VRF [vrf:none] user@host: my-container/# LD_PRELOAD=libsi.so.0 ip vrf exec vrf0 ping 1.2.3.4
使用这种方法,与容器中不同任务关联的不同套接字可以与不同的 VRF 相关联,而不是将所有套接字绑定到一个 VRF。
特定 VRF 的 Docker 进程侦听位于 /run/docker-vrf.sock 的相应套接字。
这是在 Linux 上看到的 VRF,而不是 Junos OS 演化版 VRF。该实用程序 evo_vrf_name (从 Junos OS 演化版 24.1 开始提供)可用于查找与 Junos OS 演化版 VRF 对应的 Linux VRF。
Docker 客户端通过使用以下参数与特定于 VRF 的 Docker 进程相关联:
--env-file /run/docker-vrf/jnet.env --host unix:///run/docker-vrf.sock or export DOCKER_HOST=unix:///run/docker-vrf.sock
例如,若要运行容器,请 vrf0 输入以下 Docker 命令和参数:
[vrf:none] user@host:~# docker -H unix:///run/docker-vrf0.sock run --rm -it --network=host --ipc=host --cap-add=NET_ADMIN --mount source=jnet,destination=/usr/evo --device=/dev/jtd0 -v /dev/mcgrp:/dev/mcgrp -v /dev/shm:/dev/shm --env-file=/run/docker-vrf0/jnet.env --dns ::1 debian:stretch ip link
1002: et-01000000000: BROADCAST,MULTICAST,UP mtu 1514 state UP qlen 1
link/ether ac:a:a:18:01:ff brd ff:ff:ff:ff:ff:ff
1001: mgmt-0-00-0000: BROADCAST,MULTICAST,UP mtu 1500 state UP qlen 1
link/ether 50:60:a:e:08:bd brd ff:ff:ff:ff:ff:ff
1000: lo0_0: LOOPBACK,UP mtu 65536 state UP qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
容器只能与单个 VRF 相关联。
修改容器的资源限制
容器的默认资源限制通过位于 /etc/extensions/platform_attributes 的文件进行控制。打开此文件后,您将看到以下文本:
## Edit to change upper cap of total resource limits for all containers. ## applies only to containers and does not apply to container runtimes. ## memory.memsw.limit_in_bytes = EXTENSIONS_MEMORY_MAX_MIB + EXTENSIONS_MEMORY_SWAP_MAX_MIB:-0 ## please start extensions-cglimits.service to apply changes to CPU and Memory values here ## please restart var-extensions.mount to apply changes to partition resize here ## make sure the docker daemon is stopped before changing mount size ## For changing EXTENSIONS_FS_DEVICE_SIZE_MIB, please also remove file rm /var/extensions_fs ## make sure to create a backup before partition resize ## check current defaults, after starting extensions-cglimits.service ## $ /usr/libexec/extensions/extensions_cglimits get ## you can also set current values like this as an alternative to starting extensions-cglimits.service ## $ /usr/libexec/extensions/extensions_cglimits set ## if you set one of the memory values, set the other one as well – mandated by cgroup ## device size limit will be ignored once extensionsfs device is created #EXTENSIONS_FS_DEVICE_SIZE_MIB= #EXTENSIONS_CPU_QUOTA_PERCENTAGE= #EXTENSIONS_MEMORY_MAX_MIB= #EXTENSIONS_MEMORY_SWAP_MAX_MIB=
若要更改容器的资源限制,请向 EXTENSIONS 文件底部的条目添加值。请确保在启动 Docker 进程之前执行此作。
-
EXTENSIONS_FS_DEVICE_SIZE_MIB=控制容器可以使用的最大存储空间。输入值(以兆字节为单位)。默认值为 8000 或 /var 总大小的 30%,以较小者为准。请确保在首次启动 Docker 进程之前添加此条目。如果以后需要更改此值,则需要删除现有分区,这可能会导致此分区上的数据丢失。如果在 Docker 服务启动后需要更改此存储分区,则需要先使用systemctl stop docker命令停止 Docker 进程,然后可以使用systemctl stop var-extensions.mount命令后rm /var/extensions_fs跟命令删除现有分区。更改此属性后,再次启动 Docker 进程,将创建具有指定大小的新分区。您也可以使用命令systemctl restart var-extensions.mount重新启动var-extensions.mount以获得相同的结果。我们建议对分区进行备份,以避免丢失重要数据。建议不要将此值增加到 /var 分区的 30% 以上,因为这会影响 Junos OS Evolved 的正常功能。 -
EXTENSIONS_CPU_QUOTA_PERCENTAGE=控制容器可以使用的最大 CPU 使用率。输入一个值作为 CPU 使用率的百分比。默认值为 20%,但可能因平台而异。 -
EXTENSIONS_MEMORY_MAX_MIB=控制容器可以使用的最大物理内存量。输入值(以兆字节为单位)。默认值为 2000,但可能因平台而异。如果需要修改,还应指定交换值EXTENSIONS_MEMORY_SWAP_MAX_MIB=。请注意,Linuxcgroup不允许为内存和 CPU 限制设置不合理的值。如果集的值未反映在cgroup中,则最可能的原因是值错误(可能非常高或非常低)。 -
EXTENSIONS_MEMORY_SWAP_MAX_MIB=控制容器可以使用的最大交换内存量。输入值(以兆字节为单位)。默认值为可用交换空间的 15%,但可能因平台而异。EXTENSION_MEMORY_MAX_MIB=如果正在修改其中任何一个,则应同时设置和EXTENSIONS_MEMORY_SWAP_MAX_MIB=。建议的掉期值为 的 15%。EXTENSION_MEMORY_MAX_MIB=swap 的实际cgroup值为EXTENSION_MEMORY_MAX_MIB+EXTENSIONS_MEMORY_SWAP_MAX_MIB。
默认情况下,这些值设置为特定于平台的值,因此我们建议在启动容器之前设置这些值。
在修改容器的资源限制之前,请注意配置中必须支持的规模的 CPU 和内存要求。增加容器的资源限制时要小心,以防止它们对系统造成压力。