文件编号:GZ-DEV-PULSAR-INSTALL
文件版本:1.0
保密级别:保密
| 文件创建人 | 陈宗朗 | 文件创建时间 | 2023-07-01 | |
| 文件最后编辑人 | 陈宗朗 | 文件最后编辑时间 | 2023-07-11 | |
| 文件审阅人 | 文件审阅时间 | |||
| 文件批准人 | 文件批准时间 | |||
| 文件发布范围 | 内部研发&运维 | |||
文档修订记录
| 版本号 | 修订日期 | 修订人 | 修订说明 | 修订状态 | 审核人 | 批准人 |
| V1.0 | 2023-07-01 | 陈宗朗 | 初版 | A | ||
| V1.1 | 2023-07-01 | 陈宗朗 | 修订 | M |
修订状态:A--增加,M--修改,D--删除
日期格式:YYYY-MM-DD
跨主机基于Docker 部署 Pulsar 集群。
采用三台或以上服务器实现整个 Docker Swarm 集群。
Pulsar 使用 Docker 接入 Swarm 网络部署,不使用 Swarm 进行服务编排。
APP 服务使用 Swarm 进行编排。
RELEASE: CentOS Linux release 7.9.2009 (Core)
SOFTWARE:minimal
node-01:192.168.159.151
node-02:192.168.159.152
node-03:192.168.159.153
docker
apachepulsar/pulsar-all:2.11.1
在所有主机上按照如下规则修改 firewalld 的配置:
x
echo "add pulsar cluster ports..."firewall-cmd --zone=docker --add-port=2181/tcp --permanentfirewall-cmd --zone=docker --add-port=8080/tcp --permanentfirewall-cmd --zone=docker --add-port=6650/tcp --permanentecho "add swarm cluster ports..."firewall-cmd --zone=docker --add-port=2377/tcp --permanent firewall-cmd --zone=docker --add-port=7946/tcp --permanent firewall-cmd --zone=docker --add-port=7946/udp --permanent firewall-cmd --zone=docker --add-port=4789/udp --permanentfirewall-cmd --reload
注意事项
需要注意在网卡配置中是否存在 ZONE=docker ,否则不生效。端口策略可按照如下思路设计:
内网:ZONE=docker
公网:ZONE=public
注意:严禁直接暴露端口在公网环境。
在 node-01 执行命令:
xxxxxxxxxxdocker swarm init --advertise-addr 192.168.159.151 --listen-addr 192.168.159.151可看到返回加入 Swarm 集群的命令:
xSwarm initialized: current node (dic2wg88o13jbjxod6oh0qxdy) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-655ujo9pb22s0u329itecjf8u8lzmenadsuqlluu9xeqabdnwe-0t2yh3v86h2gdght3r4gtvamp 192.168.159.151:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.注意,此时的 token 是用于加入
worker节点,并非我们需要加入manager节点的 token。
在 node-01 获取加入管理节点命令:
xxxxxxxxxxdocker swarm join-token manager如果想要获取加入
worker节点的 token,将命令改成docker swarm join-token worker即可。
可看到返回加入管理节点的命令:
xxxxxxxxxxTo add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-655ujo9pb22s0u329itecjf8u8lzmenadsuqlluu9xeqabdnwe-f5dlwk5ohwdj16rckokrzdumq 192.168.159.151:2377分别在 node-02 和 node-03 执行加入管理节点的命令:
xxxxxxxxxxdocker swarm join --token SWMTKN-1-655ujo9pb22s0u329itecjf8u8lzmenadsuqlluu9xeqabdnwe-f5dlwk5ohwdj16rckokrzdumq 192.168.159.151:2377如无意外,可看到添加成功的信息:
xxxxxxxxxxThis node joined a swarm as a manager.回到 node-01 执行 docker node ls 命令查看节点情况:
xxxxxxxxxxID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSIONdic2wg88o13jbjxod6oh0qxdy * node-01 Ready Active Leader 20.10.16jcs2sl9qigmliojpt437hssdm node-02 Ready Active Reachable 20.10.16un7e0bfo5i22uc0xss2apqtcx node-03 Ready Active Reachable 20.10.16可看到 node-01 在 MANAGER 标注了 * 和 Leader,说明此时的管理和领导节点均是 node-01。
ID:节点 ID,节点的唯一标识符。
HOSTNAME:节点的主机名。
STATUS:节点状态。
AVAILABILITY:表示调度程序是否可以将任务分配给节点。
Active:可以将任务分配给该节点。
Pause:调度程序不向该节点分配新任务,但现有任务仍然运行。
Drain:调度程序不向该节点分配新任务,已经存在的任务也将被调用到Active节点上。
MANAGER STATUS:表示是否参与集群的管理(没有值则代表不参与)。
Leader:代表为集群做出所有的集群管理和编排决策。
Reachable:表示该节点为参与Raft仲裁的manager节点。如果Leader节点不可用,则该节点有资格成为新的Leader节点。
Unavailable:表示该节点是一个无法与其他manager通信的节点。如果manager节点变为此状态,则应该添加一个新的manager节点到集群中,或者将一个工作节点提升为一个manager。
在任一管理节点执行如下命令创建名为 myapp 的 overlay 网络:
xxxxxxxxxxdocker network create -d overlay --attachable myapp
--attachable声明当前创建的网络为:其他节点可以访问的网络。
网络创建完成后,在任一管理节点执行 docker network ls 可以看到创建完成的 myapp 网络:
xxxxxxxxxxNETWORK ID NAME DRIVER SCOPE4a72bbeffbb8 bridge bridge local4745b6b1d9f9 docker_gwbridge bridge local477401a250c1 host host localtgureb3sg8oz ingress overlay swarm2kekj9ksfrnx myapp overlay swarm
本章节的部署,基于 Swarm 集群网络实现,并非直接部署在 Swarm 集群上面。
为便于管理,创建 pulsar 用户用于安装 Pulsar 集群:
xxxxxxxxxxuseradd pulsarpasswd pulsar为便于使用,给数据库用户添加 sudo 权限:
xxxxxxxxxxvim /etc/sudoers
在 root ALL=(ALL) ALL 增加如下内容并保存:
xxxxxxxxxxpulsar ALL=(ALL) ALL将新添加的用户添加到 docker 用户组,并重启 docker 服务:
xxxxxxxxxxusermod -aG docker pulsarsystemctl restart docker
为便于数据管理,切换到 pulsar 用户创建数据目录:
xxxxxxxxxxsu - pulsar mkdir -p zookeeper/data bookkeeper/{journal,ledgers}
分别在三台节点启动 zookeeper 容器:
node-01
x
docker run -itd --user=root --net=myapp --privileged=true -p 2181:2181 \-e metadataStoreUrl=zk:zookeeper01:2181,zookeeper02:2181,zookeeper03:2181 \-e cluster-name=pulsar-cluster \-v /home/pulsar/zookeeper/data:/pulsar/data/zookeeper \--restart=always \--name zookeeper --hostname zookeeper01 \apachepulsar/pulsar-all:2.11.1 \bash -c "echo 1 > data/zookeeper/myid && \echo 'client.sasl=false' >> conf/zookeeper.conf && \echo 'server.1=zookeeper01:2888:3888' >> conf/zookeeper.conf && \echo 'server.2=zookeeper02:2888:3888' >> conf/zookeeper.conf && \echo 'server.3=zookeeper03:2888:3888' >> conf/zookeeper.conf && \bin/apply-config-from-env.py conf/zookeeper.conf && bin/generate-zookeeper-config.sh conf/zookeeper.conf && exec bin/pulsar zookeeper"node-02
x
docker run -itd --user=root --net=myapp --privileged=true -p 2181:2181 \-e metadataStoreUrl=zk:zookeeper01:2181,zookeeper02:2181,zookeeper03:2181 \-e cluster-name=pulsar-cluster \-v /home/pulsar/zookeeper/data:/pulsar/data/zookeeper \--restart=always \--name zookeeper --hostname zookeeper02 \apachepulsar/pulsar-all:2.11.1 \bash -c "echo 2 > data/zookeeper/myid && \echo 'client.sasl=false' >> conf/zookeeper.conf && \echo 'server.1=zookeeper01:2888:3888' >> conf/zookeeper.conf && \echo 'server.2=zookeeper02:2888:3888' >> conf/zookeeper.conf && \echo 'server.3=zookeeper03:2888:3888' >> conf/zookeeper.conf && \bin/apply-config-from-env.py conf/zookeeper.conf && bin/generate-zookeeper-config.sh conf/zookeeper.conf && exec bin/pulsar zookeeper"node-03
xxxxxxxxxxdocker run -itd --user=root --net=myapp --privileged=true -p 2181:2181 \-e metadataStoreUrl=zk:zookeeper01:2181,zookeeper02:2181,zookeeper03:2181 \-e cluster-name=pulsar-cluster \-v /home/pulsar/zookeeper/data:/pulsar/data/zookeeper \--restart=always \--name zookeeper --hostname zookeeper03 \apachepulsar/pulsar-all:2.11.1 \bash -c "echo 3 > data/zookeeper/myid && \echo 'client.sasl=false' >> conf/zookeeper.conf && \echo 'server.1=zookeeper01:2888:3888' >> conf/zookeeper.conf && \echo 'server.2=zookeeper02:2888:3888' >> conf/zookeeper.conf && \echo 'server.3=zookeeper03:2888:3888' >> conf/zookeeper.conf && \bin/apply-config-from-env.py conf/zookeeper.conf && bin/generate-zookeeper-config.sh conf/zookeeper.conf && exec bin/pulsar zookeeper"注意:3 个 zookeeper 启动命令,
--hostname和myid是根据节点来对应角色规划来设置的,并非是一致的。如果将容器日志输出到文件,在启动命令前加上
export PULSAR_LOG_APPENDER=RollingFile即可。
在任一节点执行初始化元数据操作:
xxxxxxxxxxdocker run --user=root --privileged=true --net=myapp \--name initialize-pulsar-cluster-metadata \apachepulsar/pulsar-all:2.11.1 \bash -c "bin/pulsar initialize-cluster-metadata \--cluster pulsar-cluster \--zookeeper zookeeper01:2181,zookeeper02:2181,zookeeper03:2181 \--configuration-store zookeeper01:2181,zookeeper02:2181,zookeeper03:2181 \--web-service-url broker01:8080,broker02:8080,broker03:8080 \--broker-service-url pulsar://broker01:6650,broker02:6650,broker03:6650 "等待一会可看到如下信息输出,说明初始化完毕:
xxxxxxxxxxINFO org.apache.bookkeeper.stream.storage.impl.cluster.ZkClusterInitializer - Successfully initialized the stream cluster :num_storage_containers: 16
INFO org.apache.pulsar.PulsarClusterMetadataSetup - Cluster metadata for 'pulsar-cluster' setup correctly
在三台节点上启动 bookkeeper 容器:
node-01
xxxxxxxxxxdocker run -itd --user=root --net=myapp --privileged=true \-v /home/pulsar/bookkeeper/journal:/pulsar/data/bookkeeper/journal \-v /home/pulsar/bookkeeper/ledgers:/pulsar/data/bookkeeper/ledgers \-e zkServers=zookeeper01:2181,zookeeper02:2181,zookeeper03:2181 \-e metadataStoreUrl=zk:zookeeper01:2181,zookeeper02:2181,zookeeper03:2181 \--restart=always \--name bookkeeper \--hostname bookkeeper01 \apachepulsar/pulsar-all:2.11.1 \bash -c "sed -i 's/# extraServerComponents=/extraServerComponents=org.apache.bookkeeper.stream.server.StreamStorageLifecycleComponent/g' conf/bookkeeper.conf && \sed -i 's/prometheusStatsHttpPort=8000/prometheusStatsHttpPort=8001/g' conf/bookkeeper.conf && \sed -i 's/httpServerPort=8000/httpServerPort=8002/g' conf/bookkeeper.conf && \bin/apply-config-from-env.py conf/bookkeeper.conf && exec bin/pulsar bookie"node-02
xxxxxxxxxxdocker run -itd --user=root --net=myapp --privileged=true \-v /home/pulsar/bookkeeper/journal:/pulsar/data/bookkeeper/journal \-v /home/pulsar/bookkeeper/ledgers:/pulsar/data/bookkeeper/ledgers \-e zkServers=zookeeper01:2181,zookeeper02:2181,zookeeper03:2181 \-e metadataStoreUrl=zk:zookeeper01:2181,zookeeper02:2181,zookeeper03:2181 \--restart=always \--name bookkeeper \--hostname bookkeeper02 \apachepulsar/pulsar-all:2.11.1 \bash -c "sed -i 's/# extraServerComponents=/extraServerComponents=org.apache.bookkeeper.stream.server.StreamStorageLifecycleComponent/g' conf/bookkeeper.conf && \sed -i 's/prometheusStatsHttpPort=8000/prometheusStatsHttpPort=8001/g' conf/bookkeeper.conf && \sed -i 's/httpServerPort=8000/httpServerPort=8002/g' conf/bookkeeper.conf && \bin/apply-config-from-env.py conf/bookkeeper.conf && exec bin/pulsar bookie"node-03
xxxxxxxxxxdocker run -itd --user=root --net=myapp --privileged=true \-v /home/pulsar/bookkeeper/journal:/pulsar/data/bookkeeper/journal \-v /home/pulsar/bookkeeper/ledgers:/pulsar/data/bookkeeper/ledgers \-e zkServers=zookeeper01:2181,zookeeper02:2181,zookeeper03:2181 \-e metadataStoreUrl=zk:zookeeper01:2181,zookeeper02:2181,zookeeper03:2181 \--restart=always \--name bookkeeper \--hostname bookkeeper03 \apachepulsar/pulsar-all:2.11.1 \bash -c "sed -i 's/# extraServerComponents=/extraServerComponents=org.apache.bookkeeper.stream.server.StreamStorageLifecycleComponent/g' conf/bookkeeper.conf && \sed -i 's/prometheusStatsHttpPort=8000/prometheusStatsHttpPort=8001/g' conf/bookkeeper.conf && \sed -i 's/httpServerPort=8000/httpServerPort=8002/g' conf/bookkeeper.conf && \bin/apply-config-from-env.py conf/bookkeeper.conf && exec bin/pulsar bookie"在三台节点都启动后,在任一节点执行 docker logs -f bookkeeper 可看到类似如下关键日志输出:
xxxxxxxxxxINFO org.apache.bookkeeper.proto.PerChannelBookieClient - Successfully connected to bookie: bookkeeper01:3181 [id: 0x2d587be5, L:/10.0.1.9:41048 - R:bookkeeper01/10.0.1.9:3181]INFO org.apache.bookkeeper.proto.PerChannelBookieClient - Successfully connected to bookie: bookkeeper02:3181 [id: 0xb4980f09, L:/10.0.1.9:32810 - R:bookkeeper02/10.0.1.10:3181]INFO org.apache.bookkeeper.proto.PerChannelBookieClient - Successfully connected to bookie: bookkeeper03:3181 [id: 0x0d814823, L:/10.0.1.9:53252 - R:bookkeeper03/10.0.1.11:3181]在任一节点执行初始化元数据操作:
xxxxxxxxxxdocker exec -i --user=root \--privileged=true \bookkeeper \bash -c "bin/bookkeeper shell metaformat"等待执行过程中,根据提示输入 Y 即可看到如下 Successfully formatted BookKeeper metadata 日志信息:
xxxxxxxxxx2023-07-01T23:57:45,753+0000 [main-EventThread] INFO org.apache.bookkeeper.zookeeper.ZooKeeperWatcherBase - ZooKeeper client is connected now.Ledger root already exists. Are you sure to format bookkeeper metadata? This may cause data loss. (Y or N) Y2023-07-01T23:58:16,037+0000 [main] INFO org.apache.bookkeeper.discover.ZKRegistrationManager - Successfully formatted BookKeeper metadata2023-07-01T23:58:16,176+0000 [main] INFO org.apache.zookeeper.ZooKeeper - Session: 0x200013ad91a0006 closed2023-07-01T23:58:16,176+0000 [main-EventThread] INFO org.apache.zookeeper.ClientCnxn - EventThread shut down for session: 0x200013ad91a0006
在三台节点上启动 broker 容器:
node-01
xxxxxxxxxxdocker run -itd --user=root --net=myapp -p 6650:6650 -p 8080:8080 \--privileged=true \-e metadataStoreUrl=zk:zookeeper01:2181,zookeeper02:2181,zookeeper03:2181 \--restart=always \--name broker \--hostname broker01 \apachepulsar/pulsar-all:2.11.1 \bash -c "sed -i 's/clusterName=/clusterName=pulsar-cluster/g' conf/broker.conf && \sed -i 's/bindAddress=0.0.0.0/bindAddress=broker01/g' conf/broker.conf && \bin/apply-config-from-env.py conf/broker.conf && exec bin/pulsar broker"node-02
xxxxxxxxxxdocker run -itd --user=root --net=myapp -p 6650:6650 -p 8080:8080 \--privileged=true \-e metadataStoreUrl=zk:zookeeper01:2181,zookeeper02:2181,zookeeper03:2181 \--restart=always \--name broker \--hostname broker02 \apachepulsar/pulsar-all:2.11.1 \bash -c "sed -i 's/clusterName=/clusterName=pulsar-cluster/g' conf/broker.conf && \sed -i 's/bindAddress=0.0.0.0/bindAddress=broker02/g' conf/broker.conf && \bin/apply-config-from-env.py conf/broker.conf && exec bin/pulsar broker"node-03
xxxxxxxxxxdocker run -itd --user=root --net=myapp -p 6650:6650 -p 8080:8080 \--privileged=true \-e metadataStoreUrl=zk:zookeeper01:2181,zookeeper02:2181,zookeeper03:2181 \--restart=always \--name broker \--hostname broker03 \apachepulsar/pulsar-all:2.11.1 \bash -c "sed -i 's/clusterName=/clusterName=pulsar-cluster/g' conf/broker.conf && \sed -i 's/bindAddress=0.0.0.0/bindAddress=broker03/g' conf/broker.conf && \bin/apply-config-from-env.py conf/broker.conf && exec bin/pulsar broker"等待启动完成后,可看到 pulsar 服务已启动完成的日志输出:
xxxxxxxxxxINFO org.apache.pulsar.PulsarBrokerStarter - PulsarService started.
可执行命令验证是否启动集群:
xxxxxxxxxxdocker exec -i --user=root --privileged=true bookkeeper \bash -c "bin/bookkeeper shell bookiesanity"如果不出意外,会看到成功的提示:
xxxxxxxxxxINFO org.apache.bookkeeper.tools.cli.commands.bookie.SanityTestCommand - Bookie sanity test succeeded
完成启动后,即可通过 pulsar-admin 命令查看集群的节点情况:
xxxxxxxxxxdocker exec -i --user=root --privileged=true broker \bash -c "bin/pulsar-admin --admin-url http://broker01:8080 brokers list pulsar-cluster"如不出意外,可看到终端显示的 broker 节点:
xxxxxxxxxx"broker01:8080""broker02:8080""broker03:8080"
获取 Pulsar Cluster 的部署信息:
xxxxxxxxxxdocker exec -i --user=root --privileged=true broker \bash -c "bin/pulsar-admin --admin-url http://broker01:8080 clusters get pulsar-cluster"等待返回结果:
xxxxxxxxxx{ "serviceUrl" : "broker01:8080,broker02:8080,broker03:8080", "brokerServiceUrl" : "pulsar://broker01:6650,broker02:6650,broker03:6650", "brokerClientTlsEnabled" : false, "tlsAllowInsecureConnection" : false, "brokerClientTlsEnabledWithKeyStore" : false, "brokerClientTlsTrustStoreType" : "JKS", "brokerClientTlsKeyStoreType" : "JKS"}查看 Cluster 列表:
xxxxxxxxxxdocker exec -i --user=root --privileged=true broker \bash -c "bin/pulsar-admin --admin-url http://broker01:8080 clusters list"等待返回结果,可看到刚刚创建的集群:
xxxxxxxxxxpulsar-cluster
到此,Pulsar 集群已搭建完成,可以进行测试了,使用 pulsar-client 命令生产并消费消息。
首先开启一个终端,执行消费监听,这样就可以实时查看到生产的消息,例如计划消费 100 条消息,可在 node-01 上面执行如下命令:
xxxxxxxxxxdocker exec -i --user=root --privileged=true broker \bash -c "bin/pulsar-client --url pulsar://broker01:6650 consume persistent://public/default/test -s 'first-subscription' -n 100"再开一个终端,执行生产消息,例如在 node-02 上面执行如下命令:
xxxxxxxxxxdocker exec -i --user=root --privileged=true broker \bash -c "bin/pulsar-client --url pulsar://broker01:6650 produce \ persistent://public/default/test \ -n 1 \ -m 'Hello Pulsar'"此时可看到在生产端看到如下输出信息,表示已生产了一条消息:
xxxxxxxxxxINFO org.apache.pulsar.client.cli.PulsarClientTool - 1 messages successfully produced回到消费监听端,可看到已经消费了一条消息:
xxxxxxxxxx----- got message -----key:[null], properties:[], content:Hello Pulsar至此,已完成 Pulsar 集群的搭建及测试。
新建一个 HTML 页面 index.html
xxxxxxxxxx<html> <head><title>Hello Docker</title></head> <body> <p>Hello Docker! This is a docker config page.</p> </body></html>创建配置 homepage
xxxxxxxxxxdocker config create homepage index.html创建 Nginx 配置文件 site.conf
xxxxxxxxxxserver { listen 80;
location / { root /usr/share/nginx/html; index index.html index.htm; }}创建配置 nginx_config
xxxxxxxxxxdocker config create nginx_config site.conf
xxxxxxxxxxdocker service create \ --name nginx --replicas 3 --network myapp \ --config source=nginx_config,target=/etc/nginx/conf.d/site.conf \ --config source=homepage,target=/usr/share/nginx/html/index.html \ --publish published=3000,target=80 \ nginx