storm docker容器集群化
1 docker镜像制作
1.1 storm docker镜像制作预备
配置docker镜像下载加速
https://www.jianshu.com/p/84b6fe281b4d
root@sure-PC:~/storm# cat /etc/docker/daemon.json
{
"registry-mirrors": [
"https://hub-mirror.c.163.com",
"https://1nj0zren.mirror.aliyuncs.com",
"https://docker.mirrors.ustc.edu.cn",
"http://f1361db2.m.daocloud.io",
"https://registry.docker-cn.com"
]
}
查看镜像信息:
查看docker日志:
centos: journalctl -u docker
https://blog.csdn.net/warrior_0319/article/details/79713155
dockerfile语法:
https://www.runoob.com/docker/docker-dockerfile.html
https://linuxhandbook.com/create-custom-docker-image/
/root/storm:
apache-storm-1.0.8-SNAPSHOT
Dockerfile
Dockerfile内容:
FROM openjdk:16-slim-buster
COPY ./apache-storm-1.0.8-SNAPSHOT /opt/apache-storm-1.0.8
构建镜像:
cd /root/storm
docker build -t storm:1.0 .
基于镜像storm:1.0生成一个交互容器执行命令,执行完即删除:
docker run --rm -it storm:1.0 /bin/bash
这时如果通过命令docker run -it -d storm:1.0
运行容器,容器立马就退出了。
如何保证容器启动后不退出?这要求容器启动后有一个前台常驻进程不退出。
root@sure-PC:~/storm# cat Dockerfile
FROM openjdk:16-slim-buster
COPY ./apache-storm-1.0.8-SNAPSHOT /opt/apache-storm-1.0.8
CMD ["/bin/sh"] #保证容器不退出
后台运行容器:docker run --name storm -it -d storm:1.0.8
root@sure-PC:~/storm# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f96cdff86ea9 storm:1.0 "/bin/sh" About a minute ago Up About a minute storm
容器不再退出。
参考:https://www.jb51.net/article/155093.htm
如何查看docker hub上镜像的dockerfile?以zookeeper为例:
https://hub.docker.com/_/zookeeper?tab=description
1.2 需要制作的镜像
-
- storm镜像
-
- zookeeper镜像
storm的镜像中需要包含jdk和storm包。我没有直接使用docker-hub上的jdk镜像,因为本文主要目的在于学习。
zookeeper镜像需要包含jdk和storm。
系统镜像我使用centos,没有用alpine,因为我本地的jdk文件无法在其中运行。
这里https://blog.csdn.net/justlpf/article/details/102840550有人基于alpine制作jdk容器。
由于我只需java运行时,因此只用jdk包中的jre目录即可。
1.2.1 Storm镜像
root@sure-PC:~/storm# cat Dockerfile
FROM centos:centos7
COPY ./apache-storm-1.0.8-SNAPSHOT /opt/apache-storm-1.0.8
COPY ./jre /opt/jre
WORKDIR /opt/apache-storm-1.0.8
ENV JAVA_HOME=/opt/jre \
STORM_HOME=/opt/apache-storm-1.0.8
ENV PATH=$PATH:$JAVA_HOME/bin:$STORM_HOME/bin
#需要使用ip命令查看ip路由,vim编辑文件, lsof查看连接
RUN yum -y install iproute vim lsof
CMD ["/bin/sh"]
docker build -t storm:1.1 .
通过这个Dockfile能做出一个storm的镜像,但只是启动一个该镜像的容器,storm还没运行起来。
那如何启动storm对应的角色(nimbus、supervisor和ui)呢?可以定义一个ROLE环境变量的值来判断启动那个角色。
添加启动脚本start-storm.sh,根据角色执行不同启动命令:
root@sure-PC:~/storm# cat start-storm.sh
#!/bin/sh
role=${ROLE}
cd /opt
case "$role" in
"nimbus")
exec nohup storm nimbus
;;
"supervisor")
exec nohup storm supervisor
;;
"ui")
exec nohup storm ui
;;
*)
echo "unrecognized role: $role" >> nohup.log
esac
注意:命令得前台运行,要不然容器就会退出。
这时storm镜像的Dockerfile:
root@sure-PC:~/storm# cat Dockerfile
FROM centos:centos7
COPY ./apache-storm-1.0.8-SNAPSHOT /opt/apache-storm-1.0.8
COPY ./jre /opt/jre
COPY ./start-storm.sh /opt/start-storm.sh
WORKDIR /opt/apache-storm-1.0.8
ENV JAVA_HOME=/opt/jre \
STORM_HOME=/opt/apache-storm-1.0.8
ENV PATH=$PATH:$JAVA_HOME/bin:$STORM_HOME/bin
RUN yum -y install iproute net-tools vim
ENTRYPOINT ["/opt/start-storm.sh"]
1.2.2 zookeeper镜像
参考了这个github小项目的方法:
https://github.com/cheyang/zookeeper_cluster_deployment/blob/master/docker_compose.md
2 多个容器的编排 - docker-compose
2.1 通过docker-compose为各服务容器指定ip
https://blog.csdn.net/hechaojie_com/article/details/83625265
https://www.jb51.net/article/155093.htm
参数说明:
https://docs.docker.com/compose/
https://docs.docker.com/compose/compose-file/
https://blog.csdn.net/qq_36148847/article/details/79427878
2.2 一个demo
root@sure-PC:~/storm# cat docker-compose.yml
version: '2'
services:
storm:
image: storm:1.1
container_name: storm
restart: always #前台进程退出后就会重启容器
tty: true
networks:
extnetwork: #使用指定的网络
ipv4_address: 172.19.0.2 #指定ip
networks:
extnetwork: #自定义网络
ipam:
config:
- subnet: 172.19.0.0/16
gateway: 172.19.0.1
启动定义的容器服务storm:
docker-compose up -d storm
启动整个服务:docker-compose up
若是要后台运行: docker-compose up -d
若不使用默认的docker-compose.yml 文件名:docker-compose -f server.yml up -d
https://blog.csdn.net/pushiqiang/article/details/78682323
2.3 storm配置
问题:storm和zookeeper的文件中需要配置ip,如何让这些容器获取彼此的ip信息呢?
在docker-compose中指定的container_name可以作为这个容器的域名。因此可以通过容器名来引用其他容器ip。
http://storm.apache.org/releases/current/Setting-up-a-Storm-cluster.html
storm.yml:
########### These MUST be filled in for a storm configuration
storm.zookeeper.servers:
- "zk1" #zk容器域名
- "zk2"
- "zk3"
storm.local.dir: "/opt/data"
nimbus.host: "storm-nimbus" #storm-nimbus为nimbus容器域名
supervisor.slots.ports:
- 6700
- 6701
- 6702
- 6703
2.4 zookeeper配置
root@21afafecd75c:/opt# cat zookeeper/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/tmp/zookeeper
镜像中有一个服务启动脚本run.sh。在docker-compose中定义了一些环境变量,容器运行时执行这个脚本会读取这些变量的值写入到zoo.cfg中。
root@21afafecd75c:/opt# cat run.sh
#!/bin/sh
ZOO_CFG="/opt/zookeeper/conf/zoo.cfg"
# Output server ID
echo "server id (myid): ${SERVER_ID}"
echo "${SERVER_ID}" > /tmp/zookeeper/myid
# Add additional ZooKeeper servers into the zoo.cfg file
echo "${ADDITIONAL_ZOOKEEPER_1}" >> ${ZOO_CFG}
echo "${ADDITIONAL_ZOOKEEPER_2}" >> ${ZOO_CFG}
echo "${ADDITIONAL_ZOOKEEPER_3}" >> ${ZOO_CFG}
echo "${ADDITIONAL_ZOOKEEPER_4}" >> ${ZOO_CFG}
echo "${ADDITIONAL_ZOOKEEPER_5}" >> ${ZOO_CFG}
echo "${ADDITIONAL_ZOOKEEPER_6}" >> ${ZOO_CFG}
echo "${ADDITIONAL_ZOOKEEPER_7}" >> ${ZOO_CFG}
echo "${ADDITIONAL_ZOOKEEPER_8}" >> ${ZOO_CFG}
echo "${ADDITIONAL_ZOOKEEPER_9}" >> ${ZOO_CFG}
echo "${ADDITIONAL_ZOOKEEPER_10}" >> ${ZOO_CFG}
# Start Zookeeper
/opt/zookeeper/bin/zkServer.sh start-foreground
运行时配置为:
root@21afafecd75c:/opt# cat zookeeper/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/tmp/zookeeper
server.1=zk1:2888:3889 #zk1为容器域名
server.2=zk2:2888:3889
server.3=zk3:2888:3889
clientPort=2181
3.5 最终的docker-compose.yml
root@sure-PC:~/storm# cat docker-compose.yml
version: '3.6'
services:
zk1:
image: garland/zookeeper
container_name: zk1
volumes:
- ./data/zk1:/tmp/zookeeper
environment:
- SERVER_ID=1
- ADDITIONAL_ZOOKEEPER_4=clientPort=2181
- ADDITIONAL_ZOOKEEPER_1=server.1=zk1:2888:3889
- ADDITIONAL_ZOOKEEPER_2=server.2=zk2:2888:3889
- ADDITIONAL_ZOOKEEPER_3=server.3=zk3:2888:3889
networks:
- extnetwork
zk2:
image: garland/zookeeper
container_name: zk2
volumes:
- ./data/zk2:/tmp/zookeeper
environment:
- SERVER_ID=2
- ADDITIONAL_ZOOKEEPER_4=clientPort=2181
- ADDITIONAL_ZOOKEEPER_1=server.1=zk1:2888:3889
- ADDITIONAL_ZOOKEEPER_2=server.2=zk2:2888:3889
- ADDITIONAL_ZOOKEEPER_3=server.3=zk3:2888:3889
networks:
- extnetwork
zk3:
image: garland/zookeeper
container_name: zk3
volumes:
- ./data/zk3:/tmp/zookeeper
environment:
- SERVER_ID=3
- ADDITIONAL_ZOOKEEPER_4=clientPort=2181
- ADDITIONAL_ZOOKEEPER_1=server.1=zk1:2888:3889
- ADDITIONAL_ZOOKEEPER_2=server.2=zk2:2888:3889
- ADDITIONAL_ZOOKEEPER_3=server.3=zk3:2888:3889
networks:
- extnetwork
storm-nimbus:
image: storm:1.1
container_name: storm-nimbus
restart: always
environment:
- ROLE=nimbus
volumes:
- ./data/nimbus:/opt/apache-storm-1.0.8/logs
networks:
- extnetwork
storm-supervisor-1:
image: storm:1.1
container_name: storm-worker-1
restart: always
environment:
- ROLE=supervisor
volumes:
- ./data/supervisor-1:/opt/apache-storm-1.0.8/logs
networks:
- extnetwork
storm-supervisor-2:
image: storm:1.1
container_name: storm-worker-2
restart: always
environment:
- ROLE=supervisor
volumes:
- ./data/supervisor-2:/opt/apache-storm-1.0.8/logs
networks:
- extnetwork
storm-ui:
image: storm:1.1
container_name: storm-ui
restart: always
environment:
- ROLE=ui
volumes:
- ./data/ui:/opt/apache-storm-1.0.8/logs
networks:
- extnetwork
networks:
extnetwork:
ipam:
config:
- subnet: 172.19.0.0/16
gateway: 172.19.0.1
最终的目录结构为:
root@sure-PC:~/storm# ll
drwxr-xr-x 12 root root 4.0K 11月 21 19:42 apache-storm-1.0.8-SNAPSHOT
drwxr-xr-x 9 root root 4.0K 11月 22 21:38 data //运行时生存,映射的storm和zk的日志目录
-rw-r--r-- 1 root root 2.2K 11月 22 21:04 docker-compose.yml
-rw-r--r-- 1 root root 349 11月 22 21:55 Dockerfile
drwxr-xr-x 5 root root 4.0K 11月 21 22:52 jre
-rwxr-xr-x 1 root root 253 11月 22 21:56 start-storm.sh
这个的docker-compose.yml定义了一个storm集群:
其中zk集群由3个容器节点组成,nimbus一个节点,用于处理任务的supervisor节点两个,ui节点一个。
在storm目录下,先执行docker build -t storm:1.1 .
生成storm镜像,
然后执行命令docker-compose up
即可运行这个storm集群。
nimbus容器:
supervisor容器:
获取ui容器ip:
docker inspect storm-ui |grep Add
浏览器访问:172.19.0.6:8080
至此,咱们通过docker-compose在单机上搭建storm集群完成。这个集群离生产还差得太多,
只作为学习容器的一个demo。这样,我们便能在本地对storm集群的行为进行更直接的分析和开发。