我目前正在尝试在 Docker 容器中运行 NTE,但没有成功。
我面临的问题是 Nuance 转录引擎拒绝启动,并出现以下错误 -
2017-12-06T12:15:53.402Z - 错误:初始化配方执行器时出错消息=初始化转录器时出错:TypeError:快速通行证模块初始化期间 MREC 失败
2017-12-06T12:15:53.407Z - 致命:错误:[/mrec/release/mrec/1.34.100/17834/src/fileutil/dsmsetdata.cpp 975 2] SDVoc_NewFromFile:MREC-{d4fdd844-90d8-5bb4-9899-01 3410017834}-{186fb965-6316-5a3d-8e46-68769c99fb0e}-ilgls-SDAPI-{ec4e36b2-c053-470c-91fd-bece096fefe6}-record MREC-{d4fdd844-90d8-5bb4-9899-013410017834}-{186fb965 -6316-5a3d-8e46-68769c99fb0e}-ilgls-SDAPI-{ec4e36b2-c053-470c-91fd-bece096fefe6}-record(有关错误的一般文档,请参阅 mrec/doc/client.txt。)source=latt icegeneratoraddon.node
我已经验证了许可服务器和转录引擎的 docker 容器可以相互访问,并且我已经做了一些调查斯特拉塞查看正在进行的系统调用。
Strace 输出:
rt_sigprocmask(SIG_SETMASK,[INT CHLD],NULL,8) = 0 clone(child_stack=0,flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,child_tidptr=0x7f0b4b8a49d0) = 227 rt_sigprocmask(SIG_SETMASK,[],NULL,8) = 0 rt_sigprocmask(SIG_BLOCK,[CHLD],[],8) = 0 rt_sigprocmask(SIG_SETMASK,[],NULL,8) = 0 rt_sigprocmask(SIG_BLOCK,[CHLD],[],8) = 0 rt_sigaction(SIGINT,{0x43d6c0,[],SA_RESTORER, 0x7f0b4af0b510}, {SIG_DFL, [], SA_RESTORER, 0x7f0b4af0b510}, 8) = 0 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 227 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=227, si_status=0, si_utime=184, si_stime=17} --- wait4(-1, 0x7ffd6d7c9adc, WNOHANG, NULL) = -1 ECHILD (没有子进程) rt_sigreturn() = 0 rt_sigaction(SIGINT,{SIG_DFL,[],SA_RESTORER,0x7f0b4af0b510},{0x43d6c0,[],SA_RESTORER,0x7f0b4af0b510},8) = 0 rt_sigprocmask(SIG_BLOCK,NULL,[],8) = 0 read(255,“”,508) = 0 exit_group(0) = ?
+++ 退出,结果为 0 +++
我注意到,由 clone 系统调用产生的子进程在 docker 中被杀死,而完全相同的进程在主机本身上运行良好。
以下是有关该系统的一些信息:
docker 版本客户端版本:1.7.1 客户端 API 版本:1.19 Go 版本(客户端):go1.4.2 Git commit(客户端):786b29d/1.7.1 OS/Arch(客户端):linux/amd64 服务器版本:1.7.1 服务器 API 版本:1.19 Go 版本(服务器):go1.4.2 Git commit(服务器):786b29d/1.7.1 OS/Arch(服务器):linux/amd64
lsb 发布:LSB_VERSION=base-4.0-amd64:base-4.0-ia32:base-4.0-noarch:core-4.0-amd64:core-4.0-ia32:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-ia32:printing-4.0-noarch
Docker 容器 lsb-release:LSB_VERSION=base-4.0-amd64:base-4.0-ia32:base-4.0-noarch:core-4.0-amd64:core-4.0-ia32:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-ia32:printing-4.0-noarch
主机操作系统:CentOS 版本 6.9(最终版) Docker 容器操作系统:CentOS 版本 6.9(最终版)
如果问题偏离主题,我提前表示歉意。
问候
答案1
Nuance 明确表示他们不支持 Docker。不过,他们确实提供了一种解决方法,但我尚未验证其是否有效。不过,它可能对你有帮助:
本文适用于 NTE3.1,您可以将其用作参考。不保证它适用于 NTE4。
要求
尽管 NTE 官方支持 RHEL 6,但强烈建议使用 RHEL 7,因为 Docker 官方要求内核 3.10 或更高版本。您目前可以通过 EPEL 6 安装 Docker 1.7,但它目前是一个旧版本,必须进行例外(且不情愿)修改才能支持 RHEL 6。据我们了解,这种例外不会重复出现。
限制
NTE 的当前设计使每个实例都具有自己的作业队列。因此,Docker 的优势有限,因为您不能简单地将实例添加到负载均衡器后面的引擎池中。只有在同一主机上部署容器时,才能利用实例之间的共享内存。事实上,每个容器都必须依赖主机的共享内存 (/dev/shm)。尽管 Docker 允许您创建一个独立的共享内存块供容器共享,但它始终以 noexec 形式挂载,因此与 MREC 不兼容。当使用主机的 /dev/shm 时,其原始挂载参数将保持原样。
目前也不建议使用 Docker 作为许可证管理器。它是第三方软件,与 MAC 地址绑定。插入许可证文件的过程也需要通过 Web 门户进行手动干预。
建议的架构
如果 Docker 受到 NTE 设计的限制,那么我们可以从容器中获益吗?在同一台服务器上部署多个引擎是目前最好的用例。由于每个进程都位于自己的命名空间中,因此这带来了以下优势:?配置文件可以在容器之间共享,包括 HTTP/HTTPS 端口。每个实例都必须配置不同的端口转发规则,但就每个 NTE 进程而言,它将监听端口 8080 并将日志写入 $NTE_DATA_DIR。?使用 Docker Compose 之类的工具,我们可以轻松地同时配置、启动或关闭多个 NTE 实例。
以下是 Docker Compose 环境的示例文件:
Dockerfile
来自 centos:7
复制 ./nte-3.1.1-201609292006.el6.x86_64.rpm /tmp/
运行 yum -y 更新
运行 yum -y 安装 /tmp/nte-3.1.1-201609292006.el6.x86_64.rpm
运行 rm /tmp/nte-3.1.1-201609292006.el6.x86_64.rpm
通用.yml
版本:'2'
服务:
日期:
建造: 。
图片:nte:3.1.1
工作目录:$NTE_ROOT_DIR
入口点: bash -c ./startEngine.sh
ipc:主机
ulimits:
核:
软:-1
困难:-1
卷:
/tmp/核心:/tmp/核心
$NTE_DATA_DIR/配置:$NTE_DATA_DIR/配置
$NTE_DATA_DIR/语言包:$NTE_DATA_DIR/语言包
$NTE_ROOT_DIR/许可证:$NTE_ROOT_DIR/许可证
docker-compose.yml
版本:'2'
服务:
nte1:
延伸:
文件:common.yml
服务:nte 容器名称:“nte-instance-1”
端口:-“8080:8080” nte2:
延伸:
文件:common.yml
服务:nte
容器名称:“nte-instance-2”
端口:
- “8081:8080”
Dockerfile 很简单。当我们构建 NTE Docker 镜像时,我们只需复制一个 NTE RPM,安装它,然后删除它。
common.yml 包含所有实例之间的共享规范。在这里我们可以配置通用参数,例如入口点(启动容器时要启动的命令)、主机和容器之间的共享文件夹、IPC 命名空间和 ulimits。
docker-compose.yml 是 Docker Compose 实际读取的输入。这是实例(或 Docker Compose 术语中的服务)具体定义的地方。在这种情况下,我们有两个 NTE 引擎:nte1 和 nte2。它们都继承了 common.yml 中的规范,并添加了特定于容器的信息,例如主机上应该打开哪个端口才能与引擎通信。nte1 可通过主机上的端口 8080 访问,nte2 可通过端口 8081 访问。
请注意,端口转发仅在需要从 Docker 环境之外的进程访问引擎的情况下才是必要的。例如,如果唯一向 NTE 发出调用的客户端是您的 Web 服务器,您可以在容器内运行该服务器,它将能够通过 Docker 的私有网络访问每个引擎。
完成所有这些设置后,调用“docker-compose up”将同时启动 nte1 和 nte2。
如果你成功实现了这一点,我很想听听你是如何做到的。
答案2
山tmfs——/dev/shm并运行- 特权
Dockerfile
FROM centos:7
ENV NTE_ROOT_DIR=/usr/local/Nuance/Transcription_Engine
ENV NTE_DATA_DIR=/var/local/Nuance/Transcription_Engine
ADD license /license
COPY install/nte-3.1.0-201609260952.el6.x86_64.rpm /install/nte.rpm
COPY install/nte-por-bra-3.1.6-3.0.0-201605182043.el6.noarch.rpm /install/nte-por-bra.rpm
COPY entrypoint.sh /app/entrypoint.sh
RUN yum install -y /install/nte.rpm /install/nte-por-bra.rpm net-tools bc && rm -rf /install
COPY install/development.yaml $NTE_DATA_DIR/config/development.yaml
ENTRYPOINT ["sh", "/app/entrypoint.sh"]
入口点
#!/bin/bash
mkdir -p /dev/shm
mount -t tmpfs -o defaults tmpfs /dev/shm
cd $NTE_ROOT_DIR && sh startEngine.sh
构建并运行
docker build -t nte:v3 .
docker run -it --rm --net=host --privileged nte:v3