Docker部署NiFi 1.17.0:无ID时通过API自动化更新控制器与处理器
问题描述
我需要用Docker部署NiFi 1.17.0,实现自动化启动流程:每次新建容器实例时自动加载模板,无需手动登录UI修改配置,通过bash脚本完成以下操作:
- 更新某个控制器服务的字段
- 更新某个处理器的属性
已知操作流程:
- 针对控制器服务:停止处理器 → 禁用控制器服务 → 更新控制器服务 → 启用控制器服务 → 启动处理器
- 针对处理器:停止处理器 → 更新属性 → 启动处理器
但每次加载模板后,所有处理器和控制器服务的ID都会变化,请问如何在未知ID的情况下通过API实现上述自动化?另外,如何通过API上传并使用模板?
当前使用的Dockerfile:
FROM ubuntu:20.04 # Args ENV NIFI_SERVER_IP "some ip" ENV BASE_DIR "some path" # Create our workdir RUN mkdir -p ${BASE_DIR} && cd ${BASE_DIR} # Set workdir WORKDIR ${BASE_DIR} # Copy bootstrap to workdir COPY script.sh . # Run the bootstrap RUN apt-get update && apt-get install curl -y RUN ./script.sh ${NIFI_SERVER_IP} # Set workdir to new workdir #WORKDIR ${BASE_DIR}/something i didnt want to share/nifi-1.17.0/bin # Command to run when container starts #CMD ["./nifi.sh","start"]
当前使用的脚本script.sh:
#!/bin/bash apt-get update DEBIAN_FRONTEND=noninteractive apt-get install dialog DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata DEBIAN_FRONTEND=noninteractive apt-get install wget -y DEBIAN_FRONTEND=noninteractive apt-get install git-all -y wget https://archive.apache.org/dist/nifi/1.17.0/nifi-1.17.0-bin.zip DEBIAN_FRONTEND=noninteractive apt install unzip -y unzip nifi-1.17.0-bin.zip cd nifi-1.17.0 sed -i 's/127.0.0.1/0.0.0.0/g' conf/nifi.properties sed -i "s/nifi.web.proxy.host=/nifi.web.proxy.host=$1:8443/g" conf/nifi.properties DEBIAN_FRONTEND=noninteractive apt-get install java-11-openjdk -y DEBIAN_FRONTEND=noninteractive apt-get install openjdk-11 -y DEBIAN_FRONTEND=noninteractive apt-get install openjdk-11-jre -y echo "export JAVA_HOME='/usr/lib/jvm/java-11-openjdk-amd64/'" >> ~/.bashrc cd bin ./nifi.sh start ./nifi.sh set-single-user-credentials admin nifipassword1 ./nifi.sh stop
解决方案
一、优化Docker构建与启动流程
原Dockerfile在构建阶段启动NiFi后又停止,建议将NiFi的安装、配置放在构建阶段,启动和自动化配置放在容器启动时执行,避免构建阶段的无效操作。
优化后的Dockerfile
FROM ubuntu:20.04 ENV NIFI_VERSION=1.17.0 ENV BASE_DIR=/opt/nifi ENV NIFI_HOME=${BASE_DIR}/nifi-${NIFI_VERSION} ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 # 安装依赖(包含jq用于解析JSON) RUN apt-get update && apt-get install -y --no-install-recommends \ curl wget unzip openjdk-11-jre-headless jq \ && rm -rf /var/lib/apt/lists/* # 创建工作目录并下载解压NiFi RUN mkdir -p ${BASE_DIR} \ && wget -q https://archive.apache.org/dist/nifi/${NIFI_VERSION}/nifi-${NIFI_VERSION}-bin.zip \ && unzip -q nifi-${NIFI_VERSION}-bin.zip -d ${BASE_DIR} \ && rm nifi-${NIFI_VERSION}-bin.zip # 配置NiFi基础参数 RUN sed -i 's/127.0.0.1/0.0.0.0/g' ${NIFI_HOME}/conf/nifi.properties \ && echo "export JAVA_HOME=${JAVA_HOME}" >> /etc/profile # 复制自动化初始化脚本 COPY init_nifi.sh ${BASE_DIR}/ RUN chmod +x ${BASE_DIR}/init_nifi.sh WORKDIR ${NIFI_HOME}/bin # 启动NiFi并执行自动化配置,最后保持容器运行 CMD ["bash", "-c", "./nifi.sh start && ${BASE_DIR}/init_nifi.sh && tail -f ../logs/nifi-app.log"]
配套的init_nifi.sh启动脚本
#!/bin/bash set -e # 等待NiFi服务完全启动 echo "等待NiFi服务启动..." until curl -s http://localhost:8080/nifi-api/access/config &>/dev/null; do sleep 5 done # 设置单用户凭证 ${NIFI_HOME}/bin/nifi.sh set-single-user-credentials admin nifipassword1 # 获取认证Token TOKEN=$(curl -s -X POST http://localhost:8080/nifi-api/access/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "username=admin&password=nifipassword1") # 后续模板上传、组件配置更新逻辑写在这里 # ...
二、NiFi API自动化操作详解
1. 上传模板
假设你的模板文件名为my_template.xml,上传命令如下:
# 上传模板并获取模板ID TEMPLATE_ID=$(curl -s -X POST http://localhost:8080/nifi-api/templates/upload \ -H "Authorization: Bearer ${TOKEN}" \ -F "template=@/path/to/my_template.xml" | jq -r '.template.id') echo "上传的模板ID: ${TEMPLATE_ID}"
2. 实例化模板到画布
指定模板放置的画布坐标(x、y),完成实例化:
# 实例化模板到根进程组 curl -s -X POST http://localhost:8080/nifi-api/process-groups/root/template-instance \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "templateId": "'${TEMPLATE_ID}'", "originX": 100, "originY": 100 }'
3. 通过名称动态获取组件ID
每次实例化模板后组件ID会变化,通过名称过滤查询组件:
获取指定名称的处理器ID(示例:名称为"GetFile"的处理器)
PROCESSOR_ID=$(curl -s http://localhost:8080/nifi-api/flow/process-groups/root \ -H "Authorization: Bearer ${TOKEN}" | jq -r ".flow.processors[] | select(.name == \"GetFile\") | .id") echo "处理器GetFile的ID: ${PROCESSOR_ID}"
获取指定名称的控制器服务ID(示例:名称为"StandardSSLContextService"的控制器)
CONTROLLER_SERVICE_ID=$(curl -s http://localhost:8080/nifi-api/flow/process-groups/root \ -H "Authorization: Bearer ${TOKEN}" | jq -r ".flow.controllerServices[] | select(.name == \"StandardSSLContextService\") | .id") echo "控制器服务StandardSSLContextService的ID: ${CONTROLLER_SERVICE_ID}"
4. 自动化更新控制器服务流程
按照停止处理器→禁用控制器→更新控制器→启用控制器→启动处理器的步骤执行:
# 1. 停止目标处理器 curl -s -X PUT http://localhost:8080/nifi-api/processors/${PROCESSOR_ID}/run-status \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{"state": "STOPPED"}' # 2. 禁用目标控制器服务 curl -s -X PUT http://localhost:8080/nifi-api/controller-services/${CONTROLLER_SERVICE_ID}/state \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{"state": "DISABLED"}' # 3. 更新控制器服务属性(示例:更新密钥库路径和密码) curl -s -X PUT http://localhost:8080/nifi-api/controller-services/${CONTROLLER_SERVICE_ID} \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "component": { "properties": { "Keystore File": "/opt/nifi/conf/keystore.jks", "Keystore Password": "password123" } }, "revision": { "version": 0 } }' # 4. 启用控制器服务 curl -s -X PUT http://localhost:8080/nifi-api/controller-services/${CONTROLLER_SERVICE_ID}/state \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{"state": "ENABLED"}' # 5. 启动处理器 curl -s -X PUT http://localhost:8080/nifi-api/processors/${PROCESSOR_ID}/run-status \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{"state": "RUNNING"}'
5. 自动化更新处理器属性流程
按照停止处理器→更新属性→启动处理器的步骤执行:
# 1. 停止目标处理器 curl -s -X PUT http://localhost:8080/nifi-api/processors/${PROCESSOR_ID}/run-status \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{"state": "STOPPED"}' # 2. 更新处理器属性(示例:更新GetFile的输入目录) curl -s -X PUT http://localhost:8080/nifi-api/processors/${PROCESSOR_ID} \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "component": { "properties": { "Input Directory": "/opt/nifi/input" } }, "revision": { "version": 0 } }' # 3. 启动处理器 curl -s -X PUT http://localhost:8080/nifi-api/processors/${PROCESSOR_ID}/run-status \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{"state": "RUNNING"}'
注意事项
- 确保容器内安装
jq工具,用于解析API返回的JSON数据,优化后的Dockerfile已包含该依赖 - NiFi启动需要约10-30秒,脚本中加入等待逻辑避免API调用失败
- 单用户模式下的Token有效期较长,足够完成所有自动化配置
- 如果需要外部访问NiFi,需修改
nifi.properties中的nifi.web.http.host或nifi.web.proxy.host参数
内容的提问来源于stack exchange,提问作者neonly
相关产品推荐
相关产品推荐

