Skip to content
This repository has been archived by the owner on Aug 23, 2020. It is now read-only.

Docker network option #1496

Merged
merged 11 commits into from
Jul 18, 2019
Merged

Conversation

nuriel77
Copy link
Contributor

@nuriel77 nuriel77 commented Jun 15, 2019

Description

The current hard coded configuration of --remote true seems based on the premise that a user should want to run IRI docker container in a bridged network. (this configuration ensures that IRI listens on 0.0.0.0 and is therefore available for NAT).

Should a user prefer to run IRI on the host network, it seems useful to have the option to set --remote to false, thereby retaining the same behavior of a non-dockerized IRI, binding API port to localhost of the host.

With regards to why a user should choose to run IRI on host network the main reason is performance:
From https://docs.docker.com/engine/reference/run/#network-settings

Compared to the default bridge mode, the host mode gives significantly better networking performance since it uses the host’s native networking stack whereas the bridge has to go through one level of virtualization through the docker daemon. It is recommended to run containers in this mode when their networking performance is critical, for example, a production Load Balancer or a High Performance Web Server.

In addition to making the --remote option configurable, the java.net.preferIPv4Stack option has also been made configurable. And I have done some improvements on the Dockerfile and documentation. Details are in comments below.

Type of change

  • Enhancement (a non-breaking change which adds functionality)
  • Comments enhancement

How Has This Been Tested?

Tested by starting up with the variable, also tested overriding the default variable in docker cli.

Checklist:

  • My code follows the style guidelines for this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@GalRogozinski GalRogozinski requested review from geminoz and sadjy June 16, 2019 19:24
Copy link

@sadjy sadjy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 small point to correct.

docker/entrypoint.sh Outdated Show resolved Hide resolved
@GalRogozinski GalRogozinski removed the request for review from geminoz June 18, 2019 07:22
@nuriel77
Copy link
Contributor Author

nuriel77 commented Jun 18, 2019

Hi @sadjy , thanks.
Please see my latest PR commit.

Changes

  • Dockerfile: ENV on one line, put all the comments above. Added new ENV for IRI jar filename.
  • Dockerfile: removed jq and curl, not sure if these are really required? (can add back if needed for any purpose)
  • entrypoint.sh: find the jar file in the given path, save to variable. This is then used by -jar

Docker Build output

All the ENVs configured on a single layer (step 10/12):

...
Processing triggers for libc-bin (2.27-3ubuntu1) ...
Removing intermediate container ca4d56dd8672
 ---> 7ebe36bf474c
Step 8/12 : COPY --from=local_stage_build /iri/target/iri*.jar /iri/target/
 ---> 4c32594a61ad
Step 9/12 : COPY docker/entrypoint.sh /
 ---> 86997eab7b69
Step 10/12 : ENV JAVA_OPTIONS="-XX:+UnlockExperimentalVMOptions -XX:+DisableAttachMechanism -XX:InitiatingHeapOccupancyPercent=60 -XX:G1MaxNewSizePercent=75 -XX:MaxGCPauseMillis=10000 -XX:+UseG1GC"     JAVA_MIN_MEMORY=2G     JAVA_MAX_MEMORY=4G     DOCKER_IRI_JAR_PATH="/iri/target"     DOCKER_IRI_JAR_FILE="iri*.jar"     DOCKER_IRI_REMOTE_LIMIT_API="interruptAttachToTangle, attachToTangle, addNeighbors, removeNeighbors, getNeighbors"     DOCKER_IRI_MONITORING_API_PORT_ENABLE=0     DOCKER_IRI_MONITORING_API_PORT_DESTINATION=14265     DOCKER_IRI_REMOTE=true
 ---> Running in 7f96fafc15b4
Removing intermediate container 7f96fafc15b4
 ---> 9dadd49b4aaa
Step 11/12 : WORKDIR /iri/data
 ---> Running in 6c41470ed9a8
Removing intermediate container 6c41470ed9a8
 ---> c953855e5e09
Step 12/12 : ENTRYPOINT [ "/entrypoint.sh" ]
 ---> Running in 00961d11f72c
Removing intermediate container 00961d11f72c
 ---> 837de2918f38
Successfully built 837de2918f38
Successfully tagged test:nuri

Explanation about entrypoint change

Regarding the $DOCKER_IRI_JAR_PATH: actually the script is seeking for iri*.jar but the expansion of * cannot happen within double quotes. Therefore, the safest way to allow any directory name and keep functionality is to split the file and directory names into two variables.

Test Examples

In order to test, this is an "override" entrypoint script that copies the jar file into a directory with space in the name:

#!/bin/bash
# See Dockerfile and DOCKER.md for further info

if [ "${DOCKER_IRI_MONITORING_API_PORT_ENABLE}" == "1" ]; then
  nohup socat -lm TCP-LISTEN:14266,fork TCP:127.0.0.1:${DOCKER_IRI_MONITORING_API_PORT_DESTINATION} &
fi

# Just as temporary test, make sure we actually
# have something in a 
mkdir -p "/iri/target hello/"
cp "/iri/target/iri-1.7.0-DEV-1844bec.jar" "/iri/target hello/"

IRI_JAR_FILE=$(find "$DOCKER_IRI_JAR_PATH" -type f -name "$DOCKER_IRI_JAR_FILE" -print -quit)
if [[ "${IRI_JAR_FILE}x" == "x" ]]
then
  >&2 echo "ERROR: File '$DOCKER_IRI_JAR_FILE' not found in path '$DOCKER_IRI_JAR_PATH'"
  exit 1
fi

# Let's output what file was found
echo "$IRI_JAR_FILE"

exec java \
  $JAVA_OPTIONS \
  -Xms$JAVA_MIN_MEMORY \
  -Xmx$JAVA_MAX_MEMORY \
  -Djava.net.preferIPv4Stack=true \
  -jar "$IRI_JAR_FILE" \
  --remote "$DOCKER_IRI_REMOTE" --remote-limit-api "$DOCKER_IRI_REMOTE_LIMIT_API" \
  "$@"

Setting awkward characters

Docker run and set the path in environment variable:

# docker run --rm -it -v $(pwd)/entrypoint.sh:/entrypoint.sh -e DOCKER_IRI_JAR_PATH="/iri/target hello/" -e DOCKER_IRI_JAR_FILE="iri*.jar" test:nuri
/iri/target hello/iri-1.7.0-DEV-1844bec.jar
Logging - property 'logging-level' set to: [INFO]
06/18 11:27:17.906 [main] INFO  IRI$IRILauncher:188 - Configuration is created using command line args only
06/18 11:27:17.912 [main] INFO  IRI$IRILauncher:189 - parsed the following cmd args: [--remote, true, --remote-limit-api, interruptAttachToTangle, attachToTangle, addNeighbors, removeNeighbors, getNeighbors]
06/18 11:27:17.916 [main] INFO  IRI$IRILauncher:119 - Welcome to IRI 1.7.0-DEV-${git.commit.id.abbrev}

This should work for any "awkward" characters (quotes, $, *, etc...)
Example with $ sign in directory name:

root@snap:/home/nuriel# docker run --rm -it -v $(pwd)/entrypoint.sh:/entrypoint.sh -e DOCKER_IRI_JAR_PATH='/iri/target$hello/' -e DOCKER_IRI_JAR_FILE="iri*.jar" test:nuri
/iri/target$hello/iri-1.7.0-DEV-1844bec.jar
Logging - property 'logging-level' set to: [INFO]
...etc...

File not found

If file is not found:

root@snap:/home/nuriel# docker run --rm -it -e DOCKER_IRI_JAR_PATH='/iri/target*hello/' -e DOCKER_IRI_JAR_FILE="iri*.jar" test:nuri
find: '/iri/target*hello/': No such file or directory
ERROR: File 'iri*.jar' not found in path '/iri/target*hello/'
root@snap:/home/nuriel# docker run --rm -it -e DOCKER_IRI_JAR_PATH='/iri/target/' -e DOCKER_IRI_JAR_FILE="i_am_no_here.jar" test:nuri
ERROR: File 'i_am_no_here.jar' not found in path '/iri/target/'

Using defaults

root@snap:/home/nuriel# docker run --rm -it test:nuri
Logging - property 'logging-level' set to: [INFO]
06/18 12:53:42.827 [main] INFO  IRI$IRILauncher:188 - Configuration is created using command line args only
06/18 12:53:42.832 [main] INFO  IRI$IRILauncher:189 - parsed the following cmd args: [--remote, true, --remote-limit-api, interruptAttachToTangle, attachToTangle, addNeighbors, removeNeighbors, getNeighbors]
06/18 12:53:42.834 [main] INFO  IRI$IRILauncher:119 - Welcome to IRI 1.7.0-DEV-${git.commit.id.abbrev}

Copy link

@sadjy sadjy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @nuriel77, brilliant! Thank you for your very much appreciated contribution. :)

@nuriel77
Copy link
Contributor Author

Hi @sadjy ... About this last commit: this kind of came up recently that users wanted to use IPv6.
I have been doing some testing and one can only make use IPv6 when the prefer-IPv4 flag is set to false.
I've tested this by binding the API_HOST to an IPv6 address (works perfectly). Have even tested with Luca's recent ICC/network rewrite binding the neighbor socket to IPv6 address.

By passing -e DOCKER_JAVA_NET_PREFER_IPV4_STACK=false or true, it gets properly configured. Output of ps aux:

java -XX:+UnlockExperimentalVMOptions -XX:+DisableAttachMechanism -XX:InitiatingHeapOccupancyPercent=60 -XX:G1MaxNewSizePercent=75 -XX:MaxGCPauseMillis=10000 -XX:+UseG1GC -Xms1g -Xmx3000m -Djava.net.preferIPv4Stack=false -jar /iri/target/iri-1.7.0-DEV-5fec537.jar --remote false --remote-limit-api removeNeighbors, addNeighbors, getNeighbors -p 14265 --api-host 2a01:xxx:xxx:xxxx::1 --neighboring-socket-port 15600 -c /iri/conf/iri.ini --milestone-start 0 --milestone-keys 16 --max-depth 1000

@GalRogozinski
Copy link
Contributor

@nuriel77
I am currently planning to merge this after IRI 1.8.0 is released. The reason is that I don't want too many changes for the upcoming release, and merging this PR requires changes in our internal CI (buildkite) infra.

So it will be in IRI 1.8.1. If you have good reasons to think it should be in 1.8.0, you can voice them and I may reconsider :-)

@nuriel77
Copy link
Contributor Author

nuriel77 commented Jul 2, 2019

@GalRogozinski Thanks.

There is no urgency. If someone was to complain about wanting to bind to some specific interface/IPv6 I can help them setup a custom entrypoint script, that should solve it.

@GalRogozinski GalRogozinski merged commit 3fd31ff into iotaledger:dev Jul 18, 2019
@jakubcech jakubcech mentioned this pull request Aug 1, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants