Storm on OpenShift

作者: 小白_18M | 来源:发表于2017-09-30 16:18 被阅读160次

    背景

    OpenShift是目前比较主流的基于Kubernetes的容器云解决方案,OpenShift在kubernetes基础上提供了快速部署k8s集群的Ansible脚本,DevOps能力以及一个易于使用的前端界面。本文主要讨论如何在OpenShift上拉起Storm集群。

    Storm架构

    Storm的架构是Slave-Master模式的,一个完整的Storm集群需要以下四种服务:
    - 一个或多个Nimbus服务,storm集群的管理节点,可以实现基于Zookeeper的HA方案

    - 一个UI服务,提供监控集群和拓扑(topology)运行前端界面

    - 一个DRPC服务,提供了用户和正在运行的拓扑交互的分布式RPC接口

    - 若干个Supervisor服务,storm集群的计算节点

    Zookeeper方案

    Storm集群的正常运行还需要依赖Zookeeper,因为Storm各组件的服务发现,nimbus节点的HA以及topology的信息都是存储在Zookeeper里的。

    可以通过两种方式来为OpenShift上的Storm编排提供Zookeeper服务:

    - 独占的Zookeeper集群: 在OpenShift集群上为每个Storm集群动态的启动一个独占的Zookeeper集群的编排,其至少包含三个Zookeeper镜像并提供外部存储方案(如GlusterFS)来持久化Zookeeper的数据

    - 共享的Zookeeper集群:提前创建一个zookeeper集群,各storm集群实例共享使用;共享的zookeeper集群可以由OpenShift托管的zookeeper编排,也可以是在OpenShift集群外部的若干台与OpenShift集群保持网络连通的虚拟机或物理机器上手工搭建的Zookeeper集群;共享zk的方式需要考虑多个storm集群之间的数据冲突问题,因为storm集群会默认将数据存储到zookeeper的"/storm"目录下,所以每个storm集群实例在zookeeper上都需要有自己独立的数据存储目录,可以通过storm的配置项“storm.zookeeper.root”来指定。

    Storm镜像构建

    我们需要为storm的每个组件构建单独的docker镜像,即storm编排需要一个nimbus镜像,一个ui镜像,一个supervisor镜像以及一个drpc镜像。由于storm的apache官方安装包里包含了所有的组件,管理员可以根据不同的配置文件(conf/storm.yaml)和启动命令来决定当前启动的是哪一个组件,所以用于构建各个组件镜像的Dockerfile也只有启动命令和配置文件的差异。

    以nimbus镜像的Dockerfile为例:

    FROM docker.io/nathonfowlie/centos-jre

    # 0.10.0

    ENV STORM_VERSION 0.10.0

    ENV APACHE_MIRROR http://apache.cs.utah.edu/storm

    RUN curl -o /opt/apache-storm.tar.gz ${APACHE_MIRROR}/apache-storm-${STORM_VERSION}/apache-storm-${STORM_VERSION}.tar.gz && \

    tar -C /opt -xzf /opt/apache-storm.tar.gz && \

    rm /opt/apache-storm.tar.gz && \

    mv /opt/apache-storm-${STORM_VERSION} /opt/apache-storm && \

    mkdir -p /opt/apache-storm/storm-local && \

    mkdir -p /opt/apache-storm/logs && \

    mkdir -p /opt/apache-storm/logback-dist && \

    mkdir -p /opt/apache-storm/conf-dist && \

    cp /opt/apache-storm/conf/* /opt/apache-storm/conf-dist/

    COPY logback-cluster.xml /opt/apache-storm/logback/cluster.xml

    COPY logback-cluster.xml /opt/apache-storm/logback-dist/cluster-console.xml

    COPY storm.yaml /opt/apache-storm/conf/

    WORKDIR /opt/apache-storm

    RUN chmod 777 -R /opt/apache-storm

    EXPOSE 6700 6701 6702 6703 8080 6627 3772

    VOLUME ["/opt/apache-storm/conf", "/opt/apache-storm/logback", "/opt/apache-storm/logs", "/opt/apache-storm/storm-local"]

    CMD ["bin/storm nimbus"]

    各镜像的Dockerfile差异主要在storm.yaml和CMD里的启动命令:

    - nimbus的启动命令是"bin/storm nimbus",storm.yaml如下:

    storm.zookeeper.servers:

    - 10.128.0.46

    storm.zookeeper.root: "/storm_001"

    nimbus.thrift.port: 6627

    storm.yaml三个参数分别指出了zookeeper集群的地址,storm数据在zookeeper里的存储位置,nimbus的thrift监听端口

    - ui的启动命令是"bin/storm ui",storm.yaml如下:

    storm.zookeeper.servers:

    - 10.128.0.46

    storm.zookeeper.root: "/storm_001"

    nimbus.thrift.port: 6627

    nimbus.host: "sb-instanceid-sn"

    ui.port: 8080

    storm.ymal里的四个参数分别代表zookeeper集群地址,storm数据在zookeeper里的存储目录,nimbus的thrift监听端口,nimbus服务的列表(nimbus HA场景下需要配多个),ui服务的监听端口

    - supervisor的启动命令是"bin/storm supervisor",storm.yaml如下:

    storm.zookeeper.servers:

    - 10.128.0.46

    storm.zookeeper.root: "/storm_001"

    nimbus.thrift.port: 6627

    nimbus.host: "sb-instanceid-sn"

    storm.yaml里的四个参数分别代表zookeeper集群地址,storm数据在zookeeper里的存储目录,nimbus的thrift监听端口,nimbus服务的列表(nimbus HA场景下需要配多个)

    - drpc的启动命令是"bin/storm drpc",storm.yaml如下:

    storm.zookeeper.servers:

    - 10.128.0.46

    storm.zookeeper.root: "/storm_001"

    nimbus.thrift.port: 6627

    nimbus.host: "sb-instanceid-sn"

    drpc.port: 3772

    storm.yaml里的五个参数分别代表zookeeper集群地址,storm数据在zookeeper里的存储目录,nimbus的thrift监听端口,nimbus服务的列表(nimbus HA场景下需要配多个),drpc服务监听端口

    storm编排

    storm的编排将启动包含1个nimbus服务,1个ui服务,1个drpc服务以及2个supervisor服务在内的storm集群环境。要实现这样的配置的storm集群,需要为nimbus/ui/drpc/supervisor分别创建rc(replication controller),由kubernetes保证各个组件的服务可用性以及备份数目,具体配置如下:

    - nimbus的rc,启动一个运行storm nimbus服务的pod并开放6627端口,nimbus rc的yaml如下:

    apiVersion: v1

    kind: ReplicationController

    metadata:

        name: storm-nimbus

    spec:

        replicas: 1

        selector:

            storm: nimbus

        template:

            metadata:

                labels:

                    storm: nimbus

            spec:

                containers:

                    - name: nimbus

                       image: storm_nimbus:0.10.0

                       ports:

                            - containerPort: 6627

                volumeMounts:

                - name: storm-data

                  mountPath: /opt/apache-storm/storm-local

            volumes:

           - name: storm-data

             emptyDir: {}

    - ui的rc,将启动一个运行storm ui服务的pod并开放8080端口,ui rc的yaml如下:

    apiVersion: v1

    kind: ReplicationController

    metadata:

        name: storm-ui

    spec:

        replicas: 1

        selector:

            storm: ui

        template:

            metadata:

                labels:

                    storm: ui

            spec:

               containers:

               - name: ui

                 image: storm_ui:0.10.0

                 ports:

                     - containerPort: 8080

                 volumeMounts:

                 - name: storm-data

                   mountPath: /opt/apache-storm/storm-local

               volumes:

               - name: storm-data

                 emptyDir: {}

    - supervisor的rc将启动2个运行storm supervisor服务的pod,supervisor rc的yaml文件如下:

    apiVersion: v1

    kind: ReplicationController

    metadata:

        name: storm-supervisor

    spec:

        replicas: 2

        selector:

            storm: supervisor

        template:

            metadata:

                labels:

                    storm: supervisor

            spec:

               containers:

               - name: supervisor

                 image: storm_supervisor:0.10.0

                 volumeMounts:

                 - name: storm-data

                   mountPath: /opt/apache-storm/storm-local

               volumes:

               - name: storm-data

                 emptyDir: {}

    - drpc的rc将启动一个运行storm drpc服务的pod并开放3772端口,drpc rc的yaml文件如下:

    apiVersion: v1

    kind: ReplicationController

    metadata:

        name: storm-drpc

    spec:

        replicas: 1

        selector:

            storm: drpc

        template:

            metadata:

                labels:

                    storm: drpc

            spec:

                containers:

                - name: drpc

                  image: storm_drpc:0.10.0

                  ports:

                      - containerPort: 3772

                 volumeMounts:

                 - name: storm-data

                   mountPath: /opt/apache-storm/storm-local

               volumes:

               - name: storm-data

                 emptyDir: {}

    各个组件的rc创建后,我们还需要考虑服务暴露的问题,即将storm集群中需要被用户和应用访问的服务暴露为kubernetes的service;在storm集群环境中用户或应用程序需要连接nimbus服务去提交topology的jar包,需要访问storm ui查看storm的集群状态和topology执行情况,需要通过drpc服务提供的drpc接口与topology交互。所以,我们需要为nimbus,ui,drpc各自创建一个service。

    在OpenShift/Kubernetes中,可以通过两种方式将service暴露到集群之外:

    - nodeport,在OpenShift/Kubernetes集群的所有node节点上开放一个指定端口,在集群外部可以用集群内任何一个node的ip/hostname加上该指定端口访问service

    - external IP,将service绑定到OpenShift/Kubernetes集群内的某个指定节点的指定端口上,在集群外部可以通过该节点的ip/hostname加端口访问service

    以下以external IP方式为例,nimbus/ui/drpc的service的yaml文件示例如下:

    - nimbus的service

    apiVersion: v1

    kind: Service

    metadata:

        name: storm-nimbus

    spec:

        selector:

            storm: nimbus

        ports:

        - protocol: TCP

          port: 6627

        externalIPs:

        - 10.1.236.92

    - ui的service

    apiVersion: v1

    kind: Service

    metadata:

        name: sb-instanceid-su

    spec:

        selector:

            sb-instanceid-storm: ui

        ports:

        - protocol: TCP

          port: 8080

        externalIPs:

        - 10.1.236.92

    - drpc的service

    apiVersion: v1

    kind: Service

    metadata:

        name: sb-instanceid-sd

    spec:

        selector:

            sb-instanceid-storm: drpc

        ports:

        - protocol: TCP

          port: 3772

        externalIPs:

        - 10.1.130.155

    测试

    1 登陆OpenShift集群

    2 通过oc命令创建nimbus/ui/supervisor/drpc的rc

    3 通过oc命令创建nimbus/ui/supervisor/drpc的service

    4 通过oc命令查看storm集群的pods以及services的运行状况

    5 打开浏览器,通过storm-ui service提供的external IP和8080端口访问storm ui: http://10.1.236.92:8080

    6 在客户端机器(比如自己的laptop)上下载与集群上运行的storm版本一致apache storm的安装包,如:http://apache.cs.utah.edu/storm/apache-storm-0.10.0/apache-storm-0.10.0.tar.gz

    7 解压并进入目录apache-storm-0.10.0/conf,修改storm.yaml配置文件,指向storm集群的nimbus service暴露出来的external ip和端口(详见步骤4的截图):

    storm.zookeeper.servers:

    - 10.128.0.46

    nimbus.thrift.port: 6627

    nimbus.host: 10.1.236.92

    8 通过storm命令行远程连接到storm的nimbus服务,查看storm集群中在执行的topology列表(当前列表为空)

    9 如果需要提交topology的jar包到storm集群,则可以在客户端直接执行./bin/storm jar  <topology-jar-path> <topology-jar-class>

    改进

    未来可以改进的地方包括:

    1 通过docker的启动脚本动态注入storm.yaml需要的配置项,包括:

    - storm.zookeeper.servers

    - storm.zookeeper.root

    - nimbus.thrift.port

    - nimbus.host

    - drpc.port

    - ui.port

    2 支持nimbus HA,目前仅支持单nimbus (nimbus HA特性只支持storm 1.0.0以上的storm版本,并且nimbus的配置项名称从nimbus.host修改为了nimbus.seeds)

    3 支持supervisor数目的动态配置,目前是固定的一个编排启动2个supervisor

    相关文章

      网友评论

        本文标题:Storm on OpenShift

        本文链接:https://www.haomeiwen.com/subject/djakextx.html