从 Docker 容器访问 SDK

因为 Cumulus Linux 是 Linux,所以您可以在系统上安装和运行容器,并完全访问流行的容器管理生态系统。 只要系统内存、存储和 CPU 容量与应用程序需求成比例,就没有限制。 为了保护系统的主要功能(例如网络控制和数据平面)免受与其他应用程序的资源争用,您可以定义资源上限。

要安装 Docker 引擎,请参阅 Cumulus Linux 上的 Docker

Docker 引擎安装过程取决于您运行的 Cumulus Linux 版本。 对于运行 Cumulus Linux 4.3.0 及更高版本的 NVIDIA Spectrum 交换机,安装或升级过程会安装 Docker 软件包。 Docker 软件包包括 Docker Engine,以及运行 Docker 服务所需的依赖项和配置文件。

需要与网络数据平面集成的应用程序

两类主要应用程序需要与网络数据平面集成

  • 通过标准接口与系统交互的应用程序; 例如,通过 netlink 或命令行(Linux 工具,如 iproute2)在 Linux 内核中安装路由或 ACL。 switchd 将内核数据平面设置卸载到 ASIC。 使用标准接口可以实现更便携的应用程序。
  • 需要通过 ASIC SDK 更原生访问转发 ASIC 的应用程序,以访问 Linux 内核和其他标准接口未公开的硬件功能。

直接应用程序访问 ASIC SDK

NVIDIA Spectrum sx_sdk 是一个独立的进程,它支持通过带有 IPC 通信的 sx_api 库同时从多个应用程序客户端进行访问。 为了让容器化应用程序访问 SDK,您需要在 SDK 进程继续在容器主机上本地运行时,使 sx_api 和一些其他文件可供容器使用。

Cumulus Linux 提供两个选项。 您可以:

  • 在运行时将所需文件复制到容器。
  • 补丁容器映像。

在运行时将文件复制到容器

要在运行时将必要文件复制到容器,请按照以下步骤操作

  1. 启动容器。

    • 指定绑定挂载点。
    • 如果您需要将所有 Linux 接口公开给应用程序,请使用 –net=host 选项启动容器。
    • 如果您正在使用 SDK 安装附带的 sx_api_xxx python 脚本,请包含 PYTHONPATH 环境变量设置。
    cumulus@switch:mgmt:~$ sudo docker run -d --name=myapp -it --net=host --mount type=bind,source=/var/run/sx_api.sock,target=/var/run/sx_api.sock --mount type=bind,source=/dev/shm/dpt,target=/dev/shm/dpt --mount type=bind,source=/dev/shm/wjh_acl,target=/dev/shm/wjh_acl --mount type=bind,source=/dev/shm/lag,target=/dev/shm/lag --env PYTHONPATH=$PYTHONPATH:/usr/lib/python2.7/dist-packages myimage
    
  2. 通过运行名为 sdk_prep 的脚本将所需文件复制到容器

    cumulus@switch:mgmt:~$ sudo ./sdk_prep myapp
    #!/bin/bash
    DOCKER_TMP_DIR=/tmp/docker-prep
    test -f $DOCKER_TMP_DIR || mkdir -p $DOCKER_TMP_DIR || (echo "Failed to create prep directory" && exit)
    cp -P --parents /usr/bin/sx*.py ${DOCKER_TMP_DIR}
    cp -P --parents /usr/bin/test_infra_common.py ${DOCKER_TMP_DIR}
    cp -RP --parents /usr/lib/python2.7/dist-packages/python_sdk_api/ ${DOCKER_TMP_DIR}
    cp -P --parents /usr/lib/libsx* ${DOCKER_TMP_DIR}
    cp -P --parents /usr/lib/libsdk* ${DOCKER_TMP_DIR}
    cp -P --parents /usr/lib/libsw* ${DOCKER_TMP_DIR}
    cp -P --parents /usr/lib/libpolicer* ${DOCKER_TMP_DIR}
    cp -P --parents /usr/lib/libbridge* ${DOCKER_TMP_DIR}
    cp -P --parents /usr/lib/librouter* ${DOCKER_TMP_DIR}
    cp -P --parents /usr/lib/libcraccess* ${DOCKER_TMP_DIR}
    cp -P --parents /usr/lib/libautoreg* ${DOCKER_TMP_DIR}
    cp -P --parents /usr/lib/libwjh* ${DOCKER_TMP_DIR}
    cp -P --parents /usr/lib/libscew* ${DOCKER_TMP_DIR}
    cp -P --parents /usr/etc/wjh_lib_conf.xml ${DOCKER_TMP_DIR}
    cp -P --parents /usr/sbin/ip ${DOCKER_TMP_DIR}
    # copy files to container's / (name given in $1)
    docker cp $DOCKER_TMP_DIR/* $1:/
    rm -r $DOCKER_TMP_DIR
    
  3. 验证从容器访问 SDK

    cumulus@switch:mgmt:~$ sudo docker exec -it myapp sx_api_port.py
    [+] opening sdk
    sx_api_open handle:0x55b1a7fab824 , rc 0
    [0x16100, 0x16200, 0x16300, 0x16400, 0x16500, 0x16600, 0x16700, 0x16800]
    sx_api_port_init_set log_port 0x16100 , rc 0
    sx_api_port_swid_list_get swid_cnt:1 , rc 0, swid table:
    [0] swid 0
    sx_api_port_swid_port_list_get port_cnt:38 , rc 0, port table:
    [0] port 0x10100
    [1] port 0x10500
    [2] port 0x10900
    [3] port 0x10d00
    [4] port 0x11100
    

补丁容器映像

您可以将 SDK 文件写入容器映像。 但是,当 SDK 升级时,您可能需要再次修补容器。

对容器的独占 SDK 访问

上述工作流程假设 switchd 继续在系统上运行,并且 switchd 和容器化应用程序都共享 SDK 访问权限。

这种共享访问安排的一个优点是 Cumulus Linux 和 switchd 负责 SDK 初始化,包括 Linux 接口创建、硬件端口 breakout 和完整的转发 ASIC 初始化。 Cumulus Linux 可以继续处理所有网络配置和转发 ASIC 编程,而容器应用程序则专注于特定的用例和特定的 ASIC 资源管理,例如安装 ACL 规则。

这种共享访问安排的一个缺点是,如果应用程序需要写入 switchd 需要访问的相同 ASIC 资源,则可能会出现潜在冲突。 可以对某些资源(ACL 区域)进行分隔,但这并非适用于所有资源。

如果您需要容器化应用程序的独占 SDK 访问权限,则必须在 Cumulus Linux 上禁用 switchdupdate-ports 服务,以便应用程序完全负责处理 Linux 接口生命周期、端口 breakout 和 ASIC 初始化。

cumulus@switch:mgmt:~$ sudo systemctl disable switchd.service
Removed /etc/systemd/system/basic.target.wants/switchd.service.
[Sep-18-00:18:20] cumulus@mlx-3700c-51:~# sudo systemctl disable update-ports.service
Removed /etc/systemd/system/basic.target.wants/update-ports.service.
Removed /etc/systemd/system/switchd.service.wants/update-ports.service.

安全注意事项

使用 Cumulus Linux,管理员可以完全访问容器生态系统中提供的所有安全措施和工具,以保护容器和容器主机。 例如,docker 守护程序架构允许使用授权插件,该插件可以为容器可以做什么和不能做什么提供细粒度的功能和访问控制。 一个这样的插件提供商是 Open Policy Agent

如下所示的配置,以及 docker.conf 文件中启用的授权插件,可确保没有容器可以使用 –privilege 选项运行

cumulus@switch:mgmt:~$ cat /etc/docker/policies/authz.rego
package docker.authz

default allow = false

allow {
  not deny
}

deny {
   privileged_access
}

privileged_access {
   input.Body.HostConfig.Privileged == true
}
cumulus@switch:mgmt:~$ cat /etc/docker/daemon.json
{
   "iptables": false,
   "ip-forward": false,
   "ip-masq": false,
   "exec-opts": ["native.cgroupdriver=systemd"],
   "authorization-plugins": ["openpolicyagent/opa-docker-authz-v2:0.4"]
}
cumulus@switch:mgmt:~$ sudo docker run -d --name=myapp -it --net=host --privileged python:2
docker: Error response from daemon: authorization denied by plugin openpolicyagent/opa-docker-authz-v2:0.4: request rejected by administrative policy.