Unlike setting up an HTTP cluster, setting up an Apache NiFi cluster with SSL enabled in Docker introduces a new challenge: Hostname verification. Don’t worry we got you covered on how to run Apache NiFi Cluster in Docker with SSL enabled. However, let’s understand the problem first.
For added security, if HTTPS connections are enabled, Apache NiFi will verify the Hostname of requests. Therefore each request sent to Apache NiFi must have a predefined hostname. Not only the external requests, but peer-to-peer communication of NiFi nodes in a cluster also go through HTTPS and are subject to hostname verification. If the hostname provided in the HTTPS request does not match the hostname defined in the SSL certificate, NiFi will throw a javax.net.ssl.SSLPeerUnverifiedException.
If you are traditionally deploying Apache NiFi: individual servers with known IP addresses, it is easy to create certificates with those IP addresses. However, in a dynamic environment like Docker, the hostname of a container is defined at the runtime if you need flexible scaling options. Since Docker doesn’t provide an option to define the hostname pattern in a scalable cluster, we have to stick to hard-coded Apache NiFi containers with predefined hostnames to create a cluster. The disadvantage of this method is that it is hard to scale up/down a cluster with hard-coded containers. Instead, you can also set up an HTTP cluster and create a load balancer with HTTPS frontend and SSL Termination between the client and NiFi UI. However, in this article, we will stick to the SSL configuration at the cluster level.
If you are new to NiFi, I recommend spinning up a single-node NiFi instance first before diving into this article. Follow this article to run a single node NiFi on Docker: How to Run Apache NiFi on Docker?
Create SSL Certificates
Step 1:
The first step is creating a self-signed certificate. Though other tools can be used, Apache NiFi Toolkit is used in this article because it generates everything you need with a single command. Download the latest Apache NiFi Toolkit from the official website.
Step 2:
Extract the archived file, and change the terminal directory to that folder.
Step 3:
Run the following command to generate the SSL certificates and the necessary configurations.
The above command generates the certificate, key, keystore, truststore, and the properties file for a NiFi server deployed in localhost. Note that the Subject Alternative Names have four servers. These names will be the hostnames of our hardcoded Apache NiFi containers in Step 1.3. Therefore add as many hostnames as possible based on your cluster size.
Create A NiFi Cluster Using Docker Compose
Though you can use plain Docker commands, Docker compose is used here to make the instructions clear. In addition, you can also add additional services in the same Docker compose configuration.
Step 1:
Create a new folder named nifi
anywhere you want.
Step 2:
Copy the keystore.jks, truststore.jks, nifi-cert.pem, and nifi-key.key in to this folder.
Step 3:
Create a new file named docker-compose.yml
with the following content:
Note that the NiFi server is configured with a single username (admin
) and password (ctsBtRBKHRAx69EqUghvvgEvjnaLjFEB
). Running the above configuration will create two NiFi containers using the keystore and truststore generated in Step 1.3. Both NiFi services have the same configuration except for the hostname and container_name. The hostname must match the subjectAlternativeNames
provided in Step 1.3 and each container must have a unique hostname. Nginx is used to load balance the requests to the NiFi UI.
Zookeeper is used for leader election in the NiFi cluster and the Nginx is used to provide a single endpoint for the NiFi dashboard. Nginx also sets the header to localhost (See Step 5) to satisfy the NiFi hostname verification.
Step 4:
In the above configuration, random KEYSTORE_PASSWORD
and TRUSTSTORE_PASSWORD
are used. Open the nifi.properties
file generated in Step 1.3 and search for nifi.security.keystorePasswd
and nifi.security.truststorePasswd
. Use the value of nifi.security.keystorePasswd
as the value of KEYSTORE_PASSWORD
and the value of nifi.security.truststorePasswd
as the value of TRUSTSTORE_PASSWORD
.
Step 5:
Create a new file named nginx.conf
with the following content. The Nginx is configured with HTTPS using the same certificates used for Apache NiFi. Note the header name is set to localhost because NiFi will verify the hostname in the request with the hostname defined in the SSL certificate. If you have additional NiFi containers, add them to the upstream configuration in the “nginx.conf”.
Run The NiFi Cluster in Docker with SSL
Step 1:
Open a terminal in the “nifi” folder and run the following command. Please note that you must have the Docker Compose installed.
Step 2:
Wait for some time for the NiFi to boot up and then visit https://localhost:8443/nifi from your browser. You will see a warning page because we are using a self-signed certificate.
Step 3:
Accept the risk and visit the page. Use the username: admin
and password: ctsBtRBKHRAx69EqUghvvgEvjnaLjFEB
as defined in the docker-compose.yml to login.
Step 4:
Check the “Cluster” option from the hamburger menu. You must see the NiFi containers defined in the docker-compose.yml as the members of the NiFi cluster.
Congratulations! now you have an SSL-enabled Apache NiFi cluster running in Docker.
Have you found this article useful? Please let me know below in the comments. Knowing someone found my articles useful motivates me to write more. Also, comment below if you face any issues with following this article or getting it working. I will try my best to help you resolve the problem. The Java Helps community is also willing to help each other and grow together.