目录
前面我们讲解了zookeeper的节点的增删改查操作,接下来我们来看下zookeeper的一些高级特性:
1.监听器
十分重要,后面说操作zookeeper的API时再细说
1.1监听当前节点
get 节点路径 watch 注册一个监听,一次性的
stat 节点路径 watch 也是同样的效果
无法监听子节点的改变
先创建一个节点/cjian ,然后通过 get /cjian watch 命令给该节点注册一个监听:
[zk: localhost:2181(CONNECTED) 8] create /cjian "123"
Created /cjian
[zk: localhost:2181(CONNECTED) 9] get /cjian watch
123
cZxid = 0x26
ctime = Thu Jan 28 14:31:06 CST 2021
mZxid = 0x26
mtime = Thu Jan 28 14:31:06 CST 2021
pZxid = 0x26
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
为了更好的演示效果,我们再开一个客户端,去修改下/cjian节点的值:
[zk: localhost:2181(CONNECTED) 2] get /cjian
123
cZxid = 0x26
ctime = Thu Jan 28 14:31:06 CST 2021
mZxid = 0x26
mtime = Thu Jan 28 14:31:06 CST 2021
pZxid = 0x26
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
[zk: localhost:2181(CONNECTED) 3] set /cjian "456"
cZxid = 0x26
ctime = Thu Jan 28 14:31:06 CST 2021
mZxid = 0x27
mtime = Thu Jan 28 14:33:33 CST 2021
pZxid = 0x26
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
另一个窗口的回应:
[zk: localhost:2181(CONNECTED) 10]
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/cjian
1.2监听子节点
ls 节点路径 watch 注册的监听器能够监听该节点下所有子节点的增加和删除操作,无法监听修改
ls2 节点路径 watch
我们来给/cjian注册一下监听(A窗口)
[zk: localhost:2181(CONNECTED) 11] ls /cjian watch
[]
然后在另一个客户端,创建子节点:
[zk: localhost:2181(CONNECTED) 30] create /cjian/node1 "123"
Created /cjian/node1
A窗口效果:
[zk: localhost:2181(CONNECTED) 11] ls /cjian watch
[]
[zk: localhost:2181(CONNECTED) 12]
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/cjian
2.ACL权限控制
zookeeper类似文件系统,客户端可以创建节点、更新节点、删除节点。那么如何做到节点的权限的控制呢?
ACL:全称 access control list,访问控制列表可以做到这一点
- zookeeper的权限控制是基于每个znode节点的
- 需要对每个节点设置权限,每个znode支持多种权限控制和多个权限
- 子节点不会继承父节点的权限,客户端无权访问某个节点,但可能无权访问它的子节点。
权限模式:
方案 | 描述 |
world | 只有一个用户:anyone,代表登陆zookeeper的所有人(默认) |
ip | 对客户端使用IP地址的认证 |
auth | 使用已添加认证的用户 |
digest | 使用“用户名:密码”方式认证 |
授予的权限:
权限 | ACL简写 | 描述 |
create | c | 可以创建子节点 |
delete | d | 可以删除子节点(仅下一级节点) |
read | r | 可以读取节点数据及显示子节点列表 |
write | w | 可以设置节点数据 |
admin | a | 可以设置节点访问控制列表权限 |
授权的相关命令:
命令 | 使用方式 | 描述 |
getAcl | getAcl [path] | 读取ACL权限 |
setAcl | setAcl [path] | 设置ACL权限 |
addauth | addauth [scheme] [auth] | 添加认证用户 |
[zk: localhost:2181(CONNECTED) 35] getAcl /cjian
'world,'anyone
: cdrwa
2.1 world授权模式
我们重行创建/cjian 节点,并查看它的acl:
[zk: localhost:2181(CONNECTED) 45] create /cjian "123"
Created /cjian
[zk: localhost:2181(CONNECTED) 46] getAcl /cjian
'world,'anyone
: cdrwa
拿掉它的w权限:
[zk: localhost:2181(CONNECTED) 47] setAcl /cjian world:anyone:cdra
cZxid = 0x43
ctime = Thu Jan 28 15:33:42 CST 2021
mZxid = 0x43
mtime = Thu Jan 28 15:33:42 CST 2021
pZxid = 0x43
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
[zk: localhost:2181(CONNECTED) 48] getAcl /cjian
'world,'anyone
: cdra
尝试修改:
[zk: localhost:2181(CONNECTED) 49] set /cjian "456"
Authentication is not valid : /cjian
如果我们将权限全部拿掉呢?
[zk: localhost:2181(CONNECTED) 50] setAcl /cjian world:anyone:
cZxid = 0x43
ctime = Thu Jan 28 15:33:42 CST 2021
mZxid = 0x43
mtime = Thu Jan 28 15:33:42 CST 2021
pZxid = 0x43
cversion = 0
dataVersion = 0
aclVersion = 2
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
[zk: localhost:2181(CONNECTED) 51] getAcl /cjian
'world,'anyone
:
[zk: localhost:2181(CONNECTED) 52] get /cjian
Authentication is not valid : /cjian
[zk: localhost:2181(CONNECTED) 53] rmr /cjian
Authentication is not valid : /cjian
[zk: localhost:2181(CONNECTED) 54] set /cjian "11111"
Authentication is not valid : /cjian
[zk: localhost:2181(CONNECTED) 55] create /cjian/node1 "node1"
Authentication is not valid : /cjian/node1
[zk: localhost:2181(CONNECTED) 56] addauth digest super:superpw
[zk: localhost:2181(CONNECTED) 57] getAcl /cjian
'world,'anyone
:
[zk: localhost:2181(CONNECTED) 58] delete /cjian
[zk: localhost:2181(CONNECTED) 59] get /cjian
Node does not exist: /cjian
如果没有权限了,可以通过 addauth digest super:superpw 切换到超级用户
2.2 IP授权模式
远程登录zookeeper的命令:./zkCli.sh -server ip
由于条件限制,没法真正的演示:
[zk: localhost:2181(CONNECTED) 63] create /cjian "123"
Created /cjian
[zk: localhost:2181(CONNECTED) 64] getAcl /cjian
'world,'anyone
: cdrwa
[zk: localhost:2181(CONNECTED) 67] setAcl /cjian ip:127.0.0.1:cdrwa
cZxid = 0x4b
ctime = Thu Jan 28 15:46:27 CST 2021
mZxid = 0x4b
mtime = Thu Jan 28 15:46:27 CST 2021
pZxid = 0x4b
cversion = 0
dataVersion = 0
aclVersion = 2
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
[zk: localhost:2181(CONNECTED) 68] getAcl /cjian
'ip,'127.0.0.1
: cdrwa
[zk: localhost:2181(CONNECTED) 69] set /cjian "456"
Authentication is not valid : /cjian
给某个节点赋予多个ip的acl权限:
[zk: localhost:2181(CONNECTED) 82] getAcl /test
'ip,'127.0.0.1
: cdrwa
[zk: localhost:2181(CONNECTED) 83] setAcl /test ip:127.0.0.1:cdrwa,ip:127.0.0.2:cdrwa
cZxid = 0x51
ctime = Thu Jan 28 15:50:34 CST 2021
mZxid = 0x51
mtime = Thu Jan 28 15:50:34 CST 2021
pZxid = 0x51
cversion = 0
dataVersion = 0
aclVersion = 2
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
[zk: localhost:2181(CONNECTED) 84] getAcl /test
'ip,'127.0.0.1
: cdrwa
'ip,'127.0.0.2
: cdrwa
[zk: localhost:2181(CONNECTED) 85]
2.3 auth授权模式
添加认证用户:addauth digest 用户名:密码
设置权限 setAcl 节点名称 auth:用户名:cdrwa
客户端1:
[zk: localhost:2181(CONNECTED) 104] create /test 123
Created /test
[zk: localhost:2181(CONNECTED) 105] getAcl /test
'world,'anyone
: cdrwa
[zk: localhost:2181(CONNECTED) 106] addauth digest cjian:111111
[zk: localhost:2181(CONNECTED) 107] setAcl /test auth:cjian:cdrwa
cZxid = 0x5e
ctime = Thu Jan 28 16:48:36 CST 2021
mZxid = 0x5e
mtime = Thu Jan 28 16:48:36 CST 2021
pZxid = 0x5e
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
[zk: localhost:2181(CONNECTED) 108] getAcl /test
'digest,'super:g9oN2HttPfn8MMWJZ2r45Np/LIA=
: cdrwa
'digest,'cjian:ST25maIOy8WImjpR7Nf2/D2wFXQ=
: cdrwa
有两个auth是因为之前我们执行了 addauth digest super:superpw 命令
客户端2:
[zk: localhost:2181(CONNECTED) 4] ls /
[cjian, zookeeper, test]
[zk: localhost:2181(CONNECTED) 5] get /test
Authentication is not valid : /test
[zk: localhost:2181(CONNECTED) 6] addauth digest cjian:111111
[zk: localhost:2181(CONNECTED) 7] get /test
123
cZxid = 0x5e
ctime = Thu Jan 28 16:48:36 CST 2021
mZxid = 0x5e
mtime = Thu Jan 28 16:48:36 CST 2021
pZxid = 0x5e
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
2.4 digest授权模式
digest不用先进行认证用户的添加,且密码是需要经过SHA1及BASE64加密后的
setACL 节点路径 digest:用户名:密码:acl权限
linux环境下加密命令:echo -n user:password | openssl dgst -binary -sha1 | openssl base64
echo -n cjian:111111 | openssl dgst -binary -sha1 | openssl base64
ST25maIOy8WImjpR7Nf2/D2wFXQ=setACL /test digest:cjian:ST25maIOy8WImjpR7Nf2/D2wFXQ=:cdrwa
以上四种可以混合使用 中间使用,分割:
setAcl /test ip:127.0.0.1:cdrwa,auth:cjian:cdrwa,digest:cjian:ST25maIOy8WImjpR7Nf2/D2wFXQ=:cdrwa
2.5ACl超级管理员
Linux下:
zookeeper的权限管理模式有一种叫做super,该模式提供一个超管可以方便的访问任何权限的节点
假设这个超管是:super:admin,需要先为超管生成密码的密文
echo -n super:admin | openssl dgst -binary -sha1 | openssl base64
xQJmxLMiHGwaqBvst5y6rkB6HQs=
然后打开bin/zkServer.sh服务器脚本文件,找到这一行:
nohup "$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \
这就是脚本启动zookeeper的命令,默认只有以上两个配置项,我们需要加一个超管的配置项:
"-Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBvst5y6rkB6HQs="
修改完后变成:
nohup "$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}"
"-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}"
"-Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBvst5y6rkB6HQs=" \
-cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &
之后启动zookeeper,输入如下命令添加权限即可
addauth digest super:admin