一、 zookeeper简介(是什么?为什么?怎么用?)
- zookeeper是什么?
- zookeeper 是一个负责各种管理基础服务管理服务,包括:配置管理、名字服务、分布式锁、集群管理。
- 为什么需要zookeeper?
- 本来在一个单机程序中,上述的几个管理比较简单,但是在分布式程序中,这是一个通用的需求,且不简单,所以直接使用成熟的zookeeper是很好的选择。kafka也是分布式应用,直接底层依赖了zookeeper。
- 怎么用这个zookeeper?
-
zk相当于一个服务,启动了之后通过网络通信完成功能,所以可以docker或者直接启动软件包的sh脚本来启动它
二、zookeeper集群搭建( Zookeeper集群部署之普通Docker部署方式)
环境准备。测试环境使用一台虚拟机,并装好docker与配好阿里云加速镜像
- 规划zookeeper配置
容器名称 | ip | myid | 端口1 | 端口2 | 端口3 | 宿主机配置文件 | 宿主机data目录 |
---|---|---|---|---|---|---|---|
zk1 | ip1 | 1 | 2181 | 2881 | 3881 | /root/zookeeper/zk1/conf/zoo.cfg | /root/zookeeper/zk1/data |
zk2 | ip2 | 2 | 2182 | 2882 | 3882 | /root/zookeeper/zk2/conf/zoo.cfg | /root/zookeeper/zk2/data |
zk3 | ip3 | 3 | 2183 | 2883 | 3883 | /root/zookeeper/zk2/conf/zoo.cfg | /root/zookeeper/zk3/data |
- 创建目录
mkdir -p /root/zookeeper/zk1/data
mkdir -p /root/zookeeper/zk2/data
mkdir -p /root/zookeeper/zk3/data
mkdir -p /root/zookeeper/zk1/conf
mkdir -p /root/zookeeper/zk2/conf
mkdir -p /root/zookeeper/zk3/conf
- 创建zoo.cfg文件
vim /root/zookeeper/zk1/conf/zoo.cfg
vim /root/zookeeper/zk2/conf/zoo.cfg
vim /root/zookeeper/zk3/conf/zoo.cfg
- zoo.cfg文件的内容,这个来源于zookeeper程序包下的根目录下的conf目录下的zoo_sample.cfg文件
- zk1的zoo.cfg;
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/data
dataLogDir=/datalog
# the port at which the clients will connect
# 每个zookeeper容器使用的配置这里不一样
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
# 这里使用的我的虚拟机的ip
server.1=192.168.117.132:2881:3881
server.2=192.168.117.132:2882:3882
server.3=192.168.117.132:2883:3883
- zk2的 zoo.cfg, 复制 zk1的zoo.cfg,然后修改clientPort=2182
cp /root/zookeeper/zk1/conf/zoo.cfg /root/zookeeper/zk2/conf/zoo.cfg
# 然后vim修改
vim /root/zookeeper/zk2/conf/zoo.cfg
修改clientPort=2182 保存
- zk3 的 zoo.cfg, 复制 zk1的zoo.cfg,然后修改clientPort=2183
- 以上准备好了zk集群的基础配置
- 启动容器三个zookeeper,在一台机器上(生产环境应该多台机器,每台机器部一个zookeeper)
# zookeeper
# docker --net host是指docker容器使用宿主机ip模式
# /opt/zookeeper-3.4.13/conf/zoo.cfg 这个挂载得看你的镜像版本
docker run --rm --name zk1 --net host -v /root/zookeeper/zk1/data:/data -v /root/zookeeper/zk1/conf/zoo.cfg:/opt/zookeeper-3.4.13/conf/zoo.cfg -p 2181:2181 -p 2881:2881 -p 3881:3881 -t wurstmeister/zookeeper
docker run --rm --name zk2 --net host -v /root/zookeeper/zk2/data:/data -v /root/zookeeper/zk2/conf/zoo.cfg:/opt/zookeeper-3.4.13/conf/zoo.cfg -p 2182:2182 -p 2882:2882 -p 3882:3882 -t wurstmeister/zookeeper
docker run --rm --name zk3 --net host -v /root/zookeeper/zk3/data:/data -v /root/zookeeper/zk3/conf/zoo.cfg:/opt/zookeeper-3.4.13/conf/zoo.cfg -p 2183:2183 -p 2883:2883 -p 3883:3883 -t wurstmeister/zookeeper
5.1 如果遇到docker创建目录失败,权限问题。
- 原因:centos7中安全模块selinux把权限禁掉了
- 临时解决方式: 宿主机执行命令
setenforce 0
- 解决方式详细:https://www.cnblogs.com/smiler/p/10302975.html
三、kafka集群构建
kafka集群直接使用命令启动
- 启动kafka的broker
# kafka1
docker run -p 9092:9092 -p 19092:19092 --name kafka1 --restart=on-failure \
-e KAFKA_BROKER_ID=1 \
-e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=INTERNAL:PLAINTEXT,EXTERNAL:SASL_PLAINTEXT \
-e KAFKA_INTER_BROKER_LISTENER_NAME=INTERNAL \
-e KAFKA_ZOOKEEPER_CONNECT=192.168.0.127:2181,192.168.0.128:2181,192.168.0.129:2181 \
-e KAFKA_ADVERTISED_LISTENERS=INTERNAL://192.168.0.127:19092,EXTERNAL://公网IP:9092 \
-e KAFKA_LISTENERS=INTERNAL://0.0.0.0:19092,EXTERNAL://0.0.0.0:9092 \
-e KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL:PLAIN \
-e KAFKA_SASL_ENABLED_MECHANISMS=PLAIN \
-e KAFKA_LOG_DIRS=/kafka/kafka-logs \
-e KAFKA_LOG_RETENTION_HOURS=72 \
-e KAFKA_LOG_SEGMENT_BYTES=20971520 \
-e KAFKA_OPTS="-Djava.security.auth.login.config=/opt/kafka/config/kafka_server_jaas.conf" \
-v /root/kafka1/logs:/kafka/kafka-logs \
-v /root/kafka1/kafka_server_jaas.conf:/opt/kafka/config/kafka_server_jaas.conf \
-t wurstmeister/kafka
# kafka2
docker run -p 9092:9092 -p 19092:19092 --name kafka2 --restart=on-failure \
-e KAFKA_BROKER_ID=2 \
-e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=INTERNAL:PLAINTEXT,EXTERNAL:SASL_PLAINTEXT \
-e KAFKA_INTER_BROKER_LISTENER_NAME=INTERNAL \
-e KAFKA_ZOOKEEPER_CONNECT=192.168.0.127:2181,192.168.0.128:2181,192.168.0.129:2181 \
-e KAFKA_ADVERTISED_LISTENERS=INTERNAL://192.168.0.128:19092,EXTERNAL://公网IP:9092 \
-e KAFKA_LISTENERS=INTERNAL://0.0.0.0:19092,EXTERNAL://0.0.0.0:9092 \
-e KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL:PLAIN \
-e KAFKA_SASL_ENABLED_MECHANISMS=PLAIN \
-e KAFKA_LOG_DIRS=/kafka/kafka-logs \
-e KAFKA_LOG_RETENTION_HOURS=72 \
-e KAFKA_LOG_SEGMENT_BYTES=20971520 \
-e KAFKA_OPTS="-Djava.security.auth.login.config=/opt/kafka/config/kafka_server_jaas.conf" \
-v /root/kafka2/logs:/kafka/kafka-logs \
-v /root/kafka2/kafka_server_jaas.conf:/opt/kafka/config/kafka_server_jaas.conf \
-t wurstmeister/kafka
# kafka3
docker run -p 9092:9092 -p 19092:19092 --name kafka3 --restart=on-failure \
-e KAFKA_BROKER_ID=3 \
-e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=INTERNAL:PLAINTEXT,EXTERNAL:SASL_PLAINTEXT \
-e KAFKA_INTER_BROKER_LISTENER_NAME=INTERNAL \
-e KAFKA_ZOOKEEPER_CONNECT=192.168.0.127:2181,192.168.0.128:2181,192.168.0.129:2181 \
-e KAFKA_ADVERTISED_LISTENERS=INTERNAL://192.168.0.129:19092,EXTERNAL://公网IP:9092 \
-e KAFKA_LISTENERS=INTERNAL://0.0.0.0:19092,EXTERNAL://0.0.0.0:9092 \
-e KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL:PLAIN \
-e KAFKA_SASL_ENABLED_MECHANISMS=PLAIN \
-e KAFKA_OPTS="-Djava.security.auth.login.config=/opt/kafka/config/kafka_server_jaas.conf" \
-e KAFKA_LOG_DIRS=/kafka/kafka-logs \
-e KAFKA_LOG_RETENTION_HOURS=72 \
-e KAFKA_LOG_SEGMENT_BYTES=20971520 \
-v /root/kafka3/logs:/kafka/kafka-logs \
-v /root/kafka3/kafka_server_jaas.conf:/opt/kafka/config/kafka_server_jaas.conf \
-t wurstmeister/kafka
- kafka_server_jaas.conf
KafkaServer {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="admin"
password="skieer@2019"
user_admin="skieer@2019"
user_producer="producer@2019";
};
- kafka管理界面 使用kafka-manager镜像
docker run -d --net host --restart=always --name=kafka-manager -p 9000:9000 \
-e ZK_HOSTS="192.168.117.132:2181,192.168.117.132:2182,192.168.117.132:2183" sheepkiller/kafka-manager
- 打开浏览器,访问 http://宿主机ip:9000 ,就可以看见管理界面
-
ps: 如果 http://宿主机ip:9000 访问受限,可以使用xshell隧道转发
-
然后在打开浏览器即可
-
最后运行的容器:
四、关于kafka的 Listener 的设置
非常详细的解释 https://rmoff.net/2018/08/02/kafka-listeners-explained/
kafka的brokers相互之间的通信会使用对内address,而外部client连接一个broker后会获取metadata,然后使用metadata中的对外address,配置 KAFKA_ADVERTISED_LISTENERS
- 对于:
- (1)外部需要访问kafka,会用到对外address
- (2)但docker内部网络又解析不了对外的address(如果可以解析的话,对外对内都用一个address即可)
KAFKA_LISTENERS: INTERNAL://0.0.0.0:29092,EXTERNAL://0.0.0.0:9092
KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka0:29092,EXTERNAL://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
- 调试工具 kafkacat
# 连接某个broker获取metadata
docker run --net host --interactive --rm edenhill/kafkacat:1.5.0 kafkacat -b 127.0.0.1:9200 -L
# 消费 连接某个broker,消费某个topic
docker run --net host --interactive --rm edenhill/kafkacat:1.5.0 kafkacat -b 127.0.0.1:9094 -C -t t92
# 消费 连接某个broker,消费某个topic的最近的200条数据
docker run --net host --interactive --rm edenhill/kafkacat:1.5.0 kafkacat -b 127.0.0.1:9094 -C -t topicA -p 0 -o -200 -e
五. 题外话
docker的网络模式 ,docker自身有四种网络模式,还有一些自定义的网络模式,我们今天主要来了解一下自身的四种网络模式
Host:容器使用宿主机的网卡是IP端口,不会虚拟自己的网卡,也不会配置自己的IP;设置命令如下:
docker run --net=hostContainer:容器不会虚拟自己的网卡,也不会配置自己的IP,而是和一个指定容器共享IP和端口范围。
docker run --net=container:containerName/containerIdNone:关闭容器网络功能。
docker run --net=noneBridge:该模式会为每一个容器虚拟网卡并设置IP,并将容器连接到宿主机中创建好的docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信
docker run --net=bridge
# 查看docker网络模式
docker network ls
附:
参考:Docker下Zookeeper集群搭建