# Apache storm on kubernetes ## 1. Build docker image of apache storm version 1.1.1 ### create following two files #### - Dockerfile ``` FROM ubuntu:16.04 RUN apt-get update RUN apt-get install -y default-jre wget unzip python RUN echo "JAVA_HOME=\"/usr/lib/jvm/java-8-openjdk-amd64\"" >> /etc/environment ENV JAVA_HOME "/usr/lib/jvm/java-8-openjdk-amd64" ENV STORM_VERSION 1.1.1 ENV STORM_HOME /opt/apache-storm-${STORM_VERSION} RUN echo ${STORM_VERSION} RUN wget -q -O - http://apache.stu.edu.tw/storm/apache-storm-${STORM_VERSION}/apache-storm-${STORM_VERSION}.tar.gz | tar -xzf - -C /opt RUN ln -s $STORM_HOME/bin/storm /usr/bin/storm VOLUME /mnt/storm ADD start_storm.sh /usr/bin/start_storm.sh RUN chmod +x /usr/bin/start_storm.sh ENTRYPOINT ["/usr/bin/start_storm.sh"] ``` #### - start_storm.sh ``` #!/bin/bash storm_version="1.1.1" storm_conf_path="/opt/apache-storm-${storm_version}/conf/storm.yaml" # check environment # ------------------------------------------------------------------- echo "[ environment ]" kernel_ver=`uname -r` release=`cat /etc/lsb-release` echo "KERNEL_VERSION=${kernel_ver}" echo "LSB_RELEASE=${release}" echo "JAVA_HOME=${JAVA_HOME}" echo "JAVA VERSION="; java --version echo "STORM_VERSION=${STORM_VERSION}" echo "STORM_HOME=${STORM_HOME}" echo # config storm.yaml # ------------------------------------------------------------------- echo "[ storm.yaml ]" if [[ -n ${STORM_ZOOKEEPER} ]]; then echo "STORM_ZOOKEEPER=${STORM_ZOOKEEPER}" echo "storm.zookeeper.servers:" > ${storm_conf_path} zm_list=($(echo ${STORM_ZOOKEEPER})) for zm in ${zm_list[@]}; do echo " - \"${zm}\"" >> ${storm_conf_path} done fi if [[ -n ${STORM_NIMBUS} ]]; then echo "STORM_NIMBUS=${STORM_NIMBUS}" nb_list=($(echo ${STORM_NIMBUS})) nb_seed_str="" for nb in ${nb_list[@]}; do nb="\"${nb}\"" if [[ "${#nb_seed_str}" -ne "0" ]]; then nb=", ${nb}" fi nb_seed_str="${nb_seed_str}${nb}" done echo "nimbus.seeds: [${nb_seed_str}]" >> ${storm_conf_path} fi if [[ -n ${STORM_DRPC} ]]; then echo "STORM_DRPC=${STORM_DRPC}" echo "drpc.servers:" > ${storm_conf_path} drpc_list=($(echo ${STORM_DRPC})) for drpc in ${drpc_list[@]}; do echo " - \"${drpc}\"" >> ${storm_conf_path} done fi if [[ -n ${STORM_SUPERVISOR_SLOTS_PORTS} ]]; then echo "STORM_SUPERVISOR_SLOTS_PORTS=${STORM_SUPERVISOR_SLOTS_PORTS}" echo "supervisor.slots.ports:" >> ${storm_conf_path} port_list=($(echo ${STORM_SUPERVISOR_SLOTS_PORTS})) for port in ${port_list[@]}; do echo " - ${port}" >> ${storm_conf_path} done fi if [[ -n ${STORM_LOCAL_DIR} ]]; then echo "STORM_LOCAL_DIR=${STORM_LOCAL_DIR}" echo "storm.local.dir: \"${STORM_LOCAL_DIR}\"" >> ${storm_conf_path} fi echo "${storm_conf_path}"; cat ${storm_conf_path}; echo # run storm roles # ------------------------------------------------------------------- if [[ -n ${STORM_ROLE} ]]; then echo "[ run storm ]" if [[ "${STORM_ROLE}" == "nimbus" ]]; then echo "- run nimbus" /usr/bin/storm nimbus elif [[ "${STORM_ROLE}" == "supervisor" ]]; then echo "- run supervisor" /usr/bin/storm supervisor elif [[ "${STORM_ROLE}" == "ui" ]]; then echo "- run ui" /usr/bin/storm ui elif [[ "${STORM_ROLE}" == "drpc" ]]; then echo "- run drpc" /usr/bin/storm drpc fi echo; echo fi ``` ### build docker image "*docker build --rm -t <dockerhub username>/<image name>:<image tag> .*" to build image ### upload the image to dockerhub "*docker login*" to login your dockerhub account "*docker push <dockerhub username>/<image name>:<image tag>*" to upload your image to dockerhub ## 2. Write YAML file to run apache storm on kubernetes ### Environment Variable in YAML: * STORM_ZOOKEEPER zookeeper IP address, separate with space if multiple IP supplied. * STORM_NIMBUS nimbus hostname, separate with space if multiple name supplied. * STORM_SUPERVISOR_SLOTS_PORTS port number opend on supervisor node, separate with space if multiple port number supplied. * STORM_ROLE role or storm command to run storm. you might specify "nimbus", "supervisor", "ui", or "drpc". * STORM_LOCAL_DIR directory path where jar file kept. ex. "/mnt/storm" > For nimbus node, you have to specified hostname in YAML file. This hostname has to be in the STORM_NIMBUS of Environment Variables. ### Yaml Example #### nimbus-1.yaml ``` apiVersion: v1 kind: Service metadata: name: nimbus-1 labels: app: nimbus-1 spec: ports: - port: 6627 targetPort: 6627 nodePort: 30011 type: NodePort selector: app: nimbus-1 --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nimbus-1 spec: replicas: 1 template: metadata: labels: app: nimbus-1 spec: hostname: nimbus-1 containers: - name: nimbus-1 image: thisistom/storm_base_1.1.1:v1.0 env: - name: STORM_ZOOKEEPER value: "172.22.132.10" - name: STORM_NIMBUS value: "nimbus-1 nimbus-2" - name: STORM_SUPERVISOR_SLOTS_PORTS value: "6700 6701 6702 6703" - name: STORM_ROLE value: "nimbus" - name: STORM_LOCAL_DIR value: "/mnt/storm" ports: - containerPort: 6627 securityContext: privileged: true ``` #### nimbus-2.yaml ``` apiVersion: v1 kind: Service metadata: name: nimbus-2 labels: app: nimbus-2 spec: ports: - port: 6627 targetPort: 6627 nodePort: 30012 type: NodePort selector: app: nimbus-2 --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nimbus-2 spec: replicas: 1 template: metadata: labels: app: nimbus-2 spec: hostname: nimbus-2 containers: - name: nimbus-2 image: thisistom/storm_base_1.1.1:v1.0 env: - name: STORM_ZOOKEEPER value: "172.22.132.10" - name: STORM_NIMBUS value: "nimbus-1 nimbus-2" - name: STORM_SUPERVISOR_SLOTS_PORTS value: "6700 6701 6702 6703" - name: STORM_ROLE value: "nimbus" - name: STORM_LOCAL_DIR value: "/mnt/storm" ports: - containerPort: 6627 securityContext: privileged: true ``` #### supervisor.yaml ``` apiVersion: v1 kind: Service metadata: name: supervisor labels: app: supervisor spec: ports: - port: 6700 name: slot6700 nodePort: 30030 - port: 6701 name: slot6701 nodePort: 30031 - port: 6702 name: slot6702 nodePort: 30032 - port: 6703 name: slot6703 nodePort: 30033 type: NodePort selector: app: supervisor --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: supervisor spec: replicas: 3 template: metadata: labels: app: supervisor spec: containers: - name: supervisor image: thisistom/storm_base_1.1.1:v1.0 env: - name: STORM_ZOOKEEPER value: "172.22.132.10" - name: STORM_NIMBUS value: "nimbus-1 nimbus-2" - name: STORM_SUPERVISOR_SLOTS_PORTS value: "6700 6701 6702 6703" - name: STORM_ROLE value: "supervisor" - name: STORM_LOCAL_DIR value: "/mnt/storm" ports: - containerPort: 6700 name: slot6700 - containerPort: 6701 name: slot6701 - containerPort: 6702 name: slot6702 - containerPort: 6703 name: slot6703 securityContext: privileged: true ``` #### ui.yaml ``` apiVersion: v1 kind: Service metadata: name: ui labels: app: ui spec: ports: - port: 8080 targetPort: 8080 nodePort: 30021 type: NodePort selector: app: ui --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: ui spec: replicas: 1 template: metadata: labels: app: ui spec: containers: - name: ui image: thisistom/storm_base_1.1.1:v1.0 env: - name: STORM_ZOOKEEPER value: "172.22.132.10" - name: STORM_NIMBUS value: "nimbus-1 nimbus-2" - name: STORM_SUPERVISOR_SLOTS_PORTS value: "6700 6701 6702 6703" - name: STORM_ROLE value: "ui" - name: STORM_LOCAL_DIR value: "/mnt/storm" ports: - containerPort: 8080 securityContext: privileged: true ``` ### run storm on kubernetes ![](https://i.imgur.com/mKHutk0.png) ![](https://i.imgur.com/EUtVPSC.png) > Above YAML example will create 2 nimbus, 3 supervisor and 1 ui and use NodePort mode to expose service. #### Open storm ui *http://<kubernete node ip>:<service port>* ![](https://i.imgur.com/190foTQ.png) ## 3. Run storm-starter example > need to install default-jdk, git, maven, ruby, python in order to build storm-starter ### #### get apache storm-starter and build ![](https://i.imgur.com/bnT7hCQ.png) ![](https://i.imgur.com/T3IRYXb.png) #### package jar file ![](https://i.imgur.com/eIueA0N.png) ![](https://i.imgur.com/GIpCsff.png) #### upload the jar to nimbus then submit topology ![](https://i.imgur.com/LRSS3RD.png) > You might install openssh-client in nimbus to scp jar file to nimbus and run below storm command to submit topology >*storm jar ./storm-starter-1.1.1.jar org.apache.storm.starter.RollingTopWords production-topology remote* #### UI: Topology "production-topology" submitted ![](https://i.imgur.com/UNfM7sO.png) #### UI: Stats, Spouts and Bolts ![](https://i.imgur.com/HpUTPjO.png) #### UI: Topology Visuallization ![](https://i.imgur.com/OyzRGYr.png)