사내 기준 베이스 이미지(RHEL 8.10 또는 UBI 8) 위에 NiFi 2.x 를 얹은 컨테이너 이미지를 만든다. 호스트 볼륨과 권한이 맞아야 하므로 사용자 uid 와 그룹 gid 를 고정한다.
FROM registry.access.redhat.com/ubi8/ubi:8.10
LABEL MAINTAINER="haedongg@gmail.com"
ARG NIFI_VERSION=2.5.0
ARG NIFI_UID=1000
ARG NIFI_GID=1000
ENV NIFI_HOME=/opt/nifi \
JAVA_HOME=/usr/lib/jvm/java-21-openjdk \
PATH=/usr/lib/jvm/java-21-openjdk/bin:$PATH
RUN dnf -y install java-21-openjdk-headless tar gzip procps-ng && dnf clean all
RUN groupadd -g ${NIFI_GID} nifi && \
useradd -u ${NIFI_UID} -g ${NIFI_GID} -m -d /home/nifi -s /bin/bash nifi
COPY nifi-${NIFI_VERSION}-bin.zip /tmp/
RUN mkdir -p /opt/apps && \
unzip -q /tmp/nifi-${NIFI_VERSION}-bin.zip -d /opt/apps && \
rm -f /tmp/nifi-${NIFI_VERSION}-bin.zip && \
ln -s /opt/apps/nifi-${NIFI_VERSION} ${NIFI_HOME} && \
chown -R nifi:nifi /opt/apps/nifi-${NIFI_VERSION}
USER nifi
WORKDIR /opt/nifi
EXPOSE 8080 11443 6342
ENTRYPOINT ["/opt/nifi/bin/nifi.sh", "run"]
심볼릭 링크 /opt/nifi → /opt/apps/nifi-2.5.0 을 두면 버전을 올릴 때 링크만 바꾸면 되고, 설정 파일과 스크립트의 경로를 손대지 않아도 된다. 다만 NIFI_HOME 을 링크로 두면 일부 스크립트가 readlink 로 실제 경로를 잡으므로, 문제가 생기면 readlink -f /opt/nifi 로 실제 경로를 먼저 확인한다.
nifi.sh run 은 포그라운드 실행이다. nifi.sh start 는 부트스트랩 프로세스를 백그라운드로 띄우고 곧바로 반환하므로 컨테이너가 즉시 종료된다. 컨테이너의 ENTRYPOINT 는 반드시 run 이어야 한다.
표준 출력으로 로그를 보내려면 logback.xml 의 root 로거가 CONSOLE appender 를 참조해야 한다. 기본값은 파일 appender 다.
이미지를 만든 뒤 컨테이너에 들어가 다음을 확인한다.
readlink -f /opt/nifi
ls -l /opt/nifi/bin/nifi.sh
id
java -version
ls -ld /opt/nifi/conf /opt/nifi/logs /opt/nifi/work
grep -E '^nifi.web.http.(host|port)' /opt/nifi/conf/nifi.properties
nifi.sh 에 실행 권한이 있어야 하고, conf · logs · work · database_repository · flowfile_repository · content_repository · provenance_repository · state 가 실행 사용자 소유여야 한다. Kubernetes 에서는 fsGroup 을 같은 gid 로 주어야 PVC 마운트 지점의 소유자가 맞는다.
services:
nifi:
image: registry.example.com/nifi:2.5.0
container_name: nifi
ports:
- '8080:8080'
environment:
NIFI_WEB_HTTP_PORT: '8080'
NIFI_SENSITIVE_PROPS_KEY: '${NIFI_SENSITIVE_PROPS_KEY}'
volumes:
- ./conf:/opt/nifi/conf
- ./state:/opt/nifi/state
- ./database_repository:/opt/nifi/database_repository
- ./flowfile_repository:/opt/nifi/flowfile_repository
- ./content_repository:/opt/nifi/content_repository
- ./provenance_repository:/opt/nifi/provenance_repository
- ./logs:/opt/nifi/logs
restart: unless-stopped
공식 apache/nifi 이미지의 경로는 /opt/nifi/nifi-current/... 이다. 직접 만든 이미지와 경로가 다르므로 볼륨 경로를 그대로 베껴 쓰면 안 된다.
NiFi 2.x 공식 이미지는 기본적으로 HTTPS 단일 사용자 모드로 뜬다. HTTP 로 쓰려면 nifi.properties 를 직접 넣어 HTTPS 관련 값을 비워야 한다.
NiFi Stateless 는 플로우를 상시 구동하는 서버 없이, 플로우 정의를 입력으로 받아 한 번 실행하고 끝나는 실행 엔진이다. 상태 저장과 UI 가 없고 저장소도 메모리 기반이므로, 함수처럼 짧게 도는 작업이나 다른 시스템에 임베드하는 용도에 맞는다. 큐에 쌓아 두고 흐르게 하는 일반 NiFi 의 운영 모델과는 성격이 다르다.
apache/nifi-stateless 라는 공식 이미지는 없다. 배포본에 포함된 bin/nifi-stateless.sh 와 nifi-stateless-assembly 를 베이스 이미지에 얹고, 플로우 정의(JSON) 와 파라미터 파일을 넣어 ENTRYPOINT 를 nifi-stateless.sh 로 잡는 방식으로 만든다. 세부 실행 옵션은 버전마다 다르므로 배포본 안의 스크립트를 확인한다 (확인 필요).
NiFi Pod 안에서 컨테이너 이미지를 만들려는 요구가 있는데, 권장하지 않는다. NiFi 컨테이너에는 빌드 도구가 없고, 호스트의 도커 소켓을 마운트하면 노드 전체에 대한 권한을 주는 것과 같다.
이미지 빌드는 별도 Job 으로 분리하고 데몬 없이 빌드하는 도구를 쓴다. kaniko 또는 buildah 를 쓰면 권한 상승 없이 레지스트리로 곧장 푸시할 수 있다. NiFi 플로우에서 빌드를 촉발해야 한다면 InvokeHTTP 로 CI 파이프라인을 호출하는 편이 낫다.