You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker部署NiFi 1.17.0:无ID时通过API自动化更新控制器与处理器

问题描述

我需要用Docker部署NiFi 1.17.0,实现自动化启动流程:每次新建容器实例时自动加载模板,无需手动登录UI修改配置,通过bash脚本完成以下操作:

  • 更新某个控制器服务的字段
  • 更新某个处理器的属性

已知操作流程:

  1. 针对控制器服务:停止处理器 → 禁用控制器服务 → 更新控制器服务 → 启用控制器服务 → 启动处理器
  2. 针对处理器:停止处理器 → 更新属性 → 启动处理器

但每次加载模板后,所有处理器和控制器服务的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 19:10:53