< 개요 >

 

Apache NiFi 가 기본 설정값으로 설치되었다면, NiFi WebUI 에는 누구나 접근이 가능하기 때문에,

TLS(Transport Layer Security) 를 적용하여 인증서가 있는 사용자만 https 를 통해 접근할 수 있도록 한다.

여기서는 Docker NiFi Container 를 이용한 Cluster 를 기준으로 설명한다.

 

JAVA 가 설치되어있고, JAVA_HOME 이 설정되어 있어야 한다.

 

총 3 대의 서버를 사용하며, 이름은 server1, server2, server3 으로 부른다.

각 서버당 하나의 Docker NiFi Container, Zookeeper Container 를 설치하여 Cluster 를 만든다.

각 서버에 생성하는 Docker NiFi Container 의 이름은 nifi1, nifi2, nifi3 으로 한다.

각 서버에 생성하는 Zookeeper Container 의 이름은 zkp1, zkp2, zkp3 으로 한다.

 

 

 

 

 

1.

Docker Swarm 기능을 사용하여 각 서버간 docker 네트워크를 구성한다. 

 

server 1 에서)

sudo docker swarm init --advertise-addr [host IP(server 1 의 ip 주소)]
예 ) sudo docker swarm init --advertise-addr 10.35.103.194

 

위의 명령어를 실행하면 해당 docker swarm 에 join 할 수 있는 join 명령어가 반환됨.
아래와 같은 명령어들이 반환되고 server 2, 3 에서 해당 명령어를 실행하여 swarm 에 join

아래 명령어는 내가 만든 토큰값이 적용되었기 때문에, 이걸 보는 개발자들은

이걸 복붙하지 말고 각자 리턴된 명령어를 사용하길 바람.

 

server 2 에서)
sudo docker swarm join --token SWMTKN-1-4jeu4zabv082iqr93jwbqp7evkc2j8nxn4kcgto3lc5qtjnv4a-9qftkjhthjpphdy3ihnf53wvf

 

server 3 에서)
sudo docker swarm join --token SWMTKN-1-4jeu4zabv082iqr93jwbqp7evkc2j8nxn4kcgto3lc5qtjnv4a-9qftkjhthjpphdy3ihnf53wvf

 

 

 

2.

server 1 에서)

아래 명령어를 통해 overlay network 를 생성한다.

 

sudo docker network create -d=overlay --attachable --subnet 11.0.0.0/24 nifi-net

 

subnet 옵션을 줌
각 Docker Container 에 구체적인 ip를 주어 명확히 구분하기 위함

 

 

 

 

3.

아래부터 nifi 를 다운받고 설치할 디렉터리를 $NIFI_HOME 이라고 한다.

server1 에서 아래 작업을 진행한다.

 

NiFi toolkit 을 다운받는다. 링크 : https://nifi.apache.org/download.html

 

 

$NIFI_HOME 에 nifi-toolkit-1.12.1-bin.tar.gz 를 받으면 된다.

 

* 글을 쓰는 현재(21년 3월 2일) NiFi 버전은 1.13.0 이지만 이미지는 옛날 이미지를 사용함

 

 

 

 

4.

아래 명령으로 압축 해제

 

tar zxvf nifi-toolkit-1.12.1-bin.tar.gz

 

 

 

 

5.

아래 위치로 이동

 

cd $NIFI_HOME/nifi-toolkit-1.12.1/bin

 

 

 

 

6.

toolkit 을 사용하여 인증서를 생성한다.

 

./tls-toolkit.sh standalone -n 'nifi[1-3]' -c 'ca.nifi' -C 'CN=localhost' -O -o $NIFI_HOME/certs

 

$NIFI_HOME/certs 위치에 CN=localhost.p12, CN=localhost.password, nifi1, nifi2, nifi3 이 생성된다.

생성된 nifi1, nifi2, nifi3 디렉터리마다 keystore.jks, truststore.jks, nifi.properties 가 포함되어있다.

생성된 nifi1, nifi2, nifi3 디렉터리는 이름에 맞춰 각 서버에 정해진 path($NIFI_HOME/certs) 로 (scp 등을 통해) 전송한다.

 

참고로 ./tls-toolkit.sh standalone -h 명령을 통해 도움말을 볼 수 있다.

 

 

 

 

7.

아래 명령어를 이용하여 Docker NiFi Container 를 각 서버에 설치한다.
아래 명령어는 --network 라는 옵션이 포함되어 있으므로 각 서버 상황에 맞게 수정한다.

 

server1 에서 nifi1 container 를 실행

 

docker run -itd --name nifi1 --network nifi-net \

-v $NIFI_HOME/certs/nifi1:/opt/certs \

-p 8443:8443 \

-e NIFI_CLUSTER_IS_NODE=true \

-e NIFI_ELECTION_MAX_WAIT='1 min' \

-e NIFI_ZK_CONNECT_STRING='zkp1:2181,zkp2:2181,zkp3:2181' \

-e NIFI_CLUSTER_NODE_PROTOCOL_PORT=9999 \

-e AUTH=tls \

-e KEYSTORE_PATH=/opt/certs/keystore.jks \

-e KEYSTORE_TYPE=JKS \

-e KEYSTORE_PASSWORD=[nifi.security.keystorePasswd] \

-e TRUSTSTORE_PATH=/opt/certs/truststore.jks \

-e TRUSTSTORE_PASSWORD=[nifi.security.truststorePasswd] \

-e TRUSTSTORE_TYPE=JKS \

-e INITIAL_ADMIN_IDENTITY='CN=localhost' \

-e NIFI_WEB_HTTPS_HOST='nifi1' \

apache/nifi:latest bash

 

server2 에서 nifi2 container 를 실행

 

docker run -itd --name nifi1 --network nifi-net \

-v $NIFI_HOME/certs/nifi2:/opt/certs \

-p 8443:8443 \

-e NIFI_CLUSTER_IS_NODE=true \

-e NIFI_ELECTION_MAX_WAIT='1 min' \

-e NIFI_ZK_CONNECT_STRING='zkp1:2181,zkp2:2181,zkp3:2181' \

-e NIFI_CLUSTER_NODE_PROTOCOL_PORT=9999 \

-e AUTH=tls \

-e KEYSTORE_PATH=/opt/certs/keystore.jks \

-e KEYSTORE_TYPE=JKS \

-e KEYSTORE_PASSWORD=[nifi.security.keystorePasswd] \

-e TRUSTSTORE_PATH=/opt/certs/truststore.jks \

-e TRUSTSTORE_PASSWORD=[nifi.security.truststorePasswd] \

-e TRUSTSTORE_TYPE=JKS \

-e INITIAL_ADMIN_IDENTITY='CN=localhost' \

-e NIFI_WEB_HTTPS_HOST='nifi2' \

apache/nifi:latest bash

 

server3 에서 nifi3 container 를 실행

 

docker run -itd --name nifi1 --network nifi-net \

-v $NIFI_HOME/certs/nifi3:/opt/certs \

-p 8443:8443 \

-e NIFI_CLUSTER_IS_NODE=true \

-e NIFI_ELECTION_MAX_WAIT='1 min' \

-e NIFI_ZK_CONNECT_STRING='zkp1:2181,zkp2:2181,zkp3:2181' \

-e NIFI_CLUSTER_NODE_PROTOCOL_PORT=9999 \

-e AUTH=tls \

-e KEYSTORE_PATH=/opt/certs/keystore.jks \

-e KEYSTORE_TYPE=JKS \

-e KEYSTORE_PASSWORD=[nifi.security.keystorePasswd] \

-e TRUSTSTORE_PATH=/opt/certs/truststore.jks \

-e TRUSTSTORE_PASSWORD=[nifi.security.truststorePasswd] \

-e TRUSTSTORE_TYPE=JKS \

-e INITIAL_ADMIN_IDENTITY='CN=localhost' \

-e NIFI_WEB_HTTPS_HOST='nifi3' \

apache/nifi:latest bash

 

 

 

명령어 내의 nifi.security.keystorePasswd, nifi.security.truststorePasswd 는

각 서버 내 $NIFI_HOME/certs/nifi? 위치에 있는 nifi.properties 에서 가져올 수 있다.

 

예를 들어 server2 의 $NIFI_HOME/certs/nifi2/nifi.properties 를 열었을 때 다음과 같은 값이 뜬다면

 

cat nifi.properties | grep store

 

Docker NiFi Container 실행 명령어는 다음과 같게 된다.

 

docker run -itd --name nifi1 --network nifi-net \

-v $NIFI_HOME/certs/nifi2:/opt/certs \

-p 8443:8443 \

-e NIFI_CLUSTER_IS_NODE=true \

-e NIFI_ELECTION_MAX_WAIT='1 min' \

-e NIFI_ZK_CONNECT_STRING='zkp1:2181,zkp2:2181,zkp3:2181' \

-e NIFI_CLUSTER_NODE_PROTOCOL_PORT=9999 \

-e AUTH=tls \

-e KEYSTORE_PATH=/opt/certs/keystore.jks \

-e KEYSTORE_TYPE=JKS \

-e KEYSTORE_PASSWORD=Kukj3lybk8QqB/bG9a6M7PbIprhLybACvc81HMyDl6w \

-e TRUSTSTORE_PATH=/opt/certs/truststore.jks \

-e TRUSTSTORE_PASSWORD=R9HS6dS28JUc7+dtwhAOfTtYfItoByzJUcFTylraF0g \

-e TRUSTSTORE_TYPE=JKS \

-e INITIAL_ADMIN_IDENTITY='CN=localhost' \

-e NIFI_WEB_HTTPS_HOST='nifi2' \

apache/nifi:latest bash

 

 

 

 

 

8.

각 서버의 NiFi Container 를 멈추고 Container 내부의 nifi.properties 와 authorizers.xml 을 docker cp 명령으로 가져온다.

 

server 1 에서

docker cp nifi1:/opt/nifi/nifi-current/conf/nifi.properties .
docker cp nifi1:/opt/nifi/nifi-current/conf/authorizers.xml .

 

server 2 에서

docker cp nifi2:/opt/nifi/nifi-current/conf/nifi.properties .
docker cp nifi2:/opt/nifi/nifi-current/conf/authorizers.xml .

 

server 3 에서

docker cp nifi3:/opt/nifi/nifi-current/conf/nifi.properties .
docker cp nifi3:/opt/nifi/nifi-current/conf/authorizers.xml .

 

 

 

 

 

9.

nifi.properties 내의 nifi.cluster.protocol.is.secure 값을 true 로 수정한다.

 

 

 

10.

 

authorizers.xml 내에 다음과 같이 값을 추가한다.

 

userGroupProvider 에 Initial User Identity 추가

accessPolicyProvider 에 Node Identity 추가

 

 

 

 

 

11.

각 서버의 NiFi Container 내부로, 수정한 nifi.properties 와 authorizers.xml 을 docker cp 명령으로 넣어준다.

 

server 1 에서

docker cp nifi.properties nifi1:/opt/nifi/nifi-current/conf/
docker cp authorizers.xml nifi1:/opt/nifi/nifi-current/conf/

 

server 2 에서

docker cp nifi.properties nifi2:/opt/nifi/nifi-current/conf/
docker cp authorizers.xml nifi2:/opt/nifi/nifi-current/conf/

 

server 3 에서

docker cp nifi.properties nifi3:/opt/nifi/nifi-current/conf/
docker cp authorizers.xml nifi3:/opt/nifi/nifi-current/conf/

 

 

 

 

 

12.

각 서버의 NiFi Container 를 재실행한다.

 

 

 

 

13.

각 서버에서 각각 zkp1, zkp2, zkp3 을 설치하고 zookeeper 를 실행한다.

 

server 1 에서

docker run -itd --name zkp1 --network nifi-net -e ZOO_MY_ID=1 -e ZOO_SERVERS='server.1=0.0.0.0:2888:3888;2181 server.2=zkp2:2888:3888;2181 server.3=zkp3:2888:3888;2181' zookeeper bash

docker exec zkp1 sh -c "apt-get update ; apt-get install -y procps"

docker exec zkp1 sh -c "bin/zkServer.sh start"

 

server 2 에서

docker run -itd --name zkp2 --network nifi-net -e ZOO_MY_ID=2 -e ZOO_SERVERS='server.1=zkp1:2888:3888;2181 server.2=0.0.0.0:2888:3888;2181 server.3=zkp3:2888:3888;2181' zookeeper bash

docker exec zkp2 sh -c "apt-get update ; apt-get install -y procps"

docker exec zkp2 sh -c "bin/zkServer.sh start"

 

server 3 에서

docker run -itd --name zkp3 --network nifi-net -e ZOO_MY_ID=3 -e ZOO_SERVERS='server.1=zkp1:2888:3888;2181 server.2=zkp2:2888:3888;2181 server.3=0.0.0.0:2888:3888;2181' zookeeper bash

docker exec zkp3 sh -c "apt-get update ; apt-get install -y procps"

docker exec zkp3 sh -c "bin/zkServer.sh start"

 

procps 를 설치하는 이유는, Container 에 자체에 ps 명령어가 없어서 FAILED TO START 가 뜨기 때문이다.

zkServer.sh 를 뜯어보면 ps 의 반환값을 기반으로 STARTED 와 FAILED TO START 가 나뉘는데 ps 명령어 자체가 없어서 무조건 FAILED TO START 가 뜬다.

 

 

 

 

 

14.

각 서버에서 아래 명령어를 통해 log 를 살펴본다.

 

예를 들면 server 1 에서

docker logs -f nifi1

 

 

 

 

 

 

15.

이전 포스팅을 참고하여, 위에서 생성한 인증서를 브라우저에 추가한 후,

https://[NiFi Container IP Address]:8443 으로 접근을 시도한다.

 

인증서와 비밀번호의 위치는 $NIFI_HOME/certs

 

 

 

 

 

16.

Clustering 이 잘 된 것을 볼 수 있다.

처음에는 접근시 모든 권한이 없기 때문에, admin 역할을 하려면 권한을 직접 위임한다.

 

 

참고로 위의 이미지는 local 에서 실행했을 때이다.

 

 

 

 

 

참고

https://nifi.apache.org/docs/nifi-docs/html/walkthroughs.html#creating-and-securing-a-nifi-cluster-with-the-tls-toolkit

https://github.com/apache/nifi 

https://docs.cloudera.com/HDPDocuments/HDF3/HDF-3.4.0/installing-upgrading-nifi/content/standalone_instance__two-way_ssl.html

+ Recent posts