1、权限管理
- ZooKeeper的权限管理,即ACL控制功能。一个ZooKeeper的znode存储两部分内容:数据和状态,状态中包含ACL信息。
- 每一个znode都会有自己的ACL列表,ACL列表包括:
- [scheme:id:permissions]
- 和Acl相关的zkCli.sh命令:
- getAcl:获取znode权限信息。
- setAcl:设置znode权限信息。
- addauth:输入注册用户(认证授权信息),输入时使用明文密码,在zk中密码是以密文加密形式存在。
1.1、ACL列表释义
- [scheme:id:permissions]
- scheme:ZooKeeper提供六种验证模式(scheme)。
- id:表示可以访问znode的用户。
- permissions:权限列表。
1、验证模式(scheme)
- world:创建节点时默认使用的验证模式,id是anyone(表示授权给任何人),permissions是cdrwa。授权模式为world:anyone:[permissions]。
- auth:授权给通过addauth命令添加的用户,授权模式为auth:user:password:[permissions]。不使用任何id,代表任何已确认用户。
- digest:授权给通过addauth命令添加的用户,授权模式为digest:user:BASE64(SHA1(password)):permissions。密码为加密后密码。
- ip:授权给客户端的IP地址,也可以是网段,例如10.1.1.0/24
- host:授权给客户端的主机名(namehost),也可以使用主机名的后缀。例如,设置为hh.com可以匹配host1.hh.com和host2.hh.com,但不能匹配host1.zookeeper.com。
- super:超级管理员拥有所有权限。
2、Zookeeper用户(id)
3、权限列表(permissions)
- 权限列表可以使用:cdrwa
- create:可以创建子znode(执行Create操作)。
- read:可以获取znode的数据,以及子znode列表(执行GetData和GetChildren操作)。
- write:可以设置znode数据(执行SetData操作)。
- delete:可以删除子znode(执行Delete操作)。
- admin:可以设置znode的权限(执行setAcl操作)。
- 权限列表也可以使用:int型数字
- 5个二进制位分别表示setacl、delete、create、write、read。比如0x1f=adcwr,0x1=----r,0x15=a-c-r。
1.2、示例
1、使用super验证模式
- zookeeper.DigestAuthenticationProvider.superDigest(只适用于Java系统属性)系统属性指定了"super"用户的密码摘要信息(该功能默认不启用),以super用户认证的客户端会跳过所有ACL检查。该系统属性的值形式为super:encoded_digest。
- 可以使用org.apache.zookeeper.server.auth.DigestAuthenticationProvider工具生成加密摘要,使用方式如下:
]# java $JAVA_OPTS org.apache.zookeeper.server.auth.DigestAuthenticationProvider super:asdf super:asdf->super:T+4Qoey4ZZ8Fnni1Yl2GZtbH2W4=
- 配置超级管理员super:
--配置超级管理员用户和密码 ]# vim /etc/profile export SERVER_JVMFLAGS SERVER_JVMFLAGS=-Dzookeeper.DigestAuthenticationProvider.superDigest=super:T+4Qoey4ZZ8Fnni1Yl2GZtbH2W4= --使超级管理员用户生效 ]# source /etc/profile ]# zkServer.sh restart --使用超级管理员用户 ]# zkCli.sh [zk: localhost:2181(CONNECTED) 0] addauth digest super:asdf
- 此时,您将作为超级用户进行身份验证,不会受到任何acl的限制。
- 不安全连接
- 由于ZooKeeper客户端和服务器端之间的连接没有加密,所以不应该在不受信任的链接上使用超级密码。使用super密码最安全的方法是使用super密码在与ZooKeeper服务器相同的机器上运行客户端。
2、使用world验证模式
[zk: localhost:2181(CONNECTED) 0] getAcl / 'world,'anyone: cdrwa [zk: localhost:2181(CONNECTED) 1] setAcl / world:anyone:crw [zk: localhost:2181(CONNECTED) 3] getAcl / 'world,'anyone: crw
3、使用auth验证模式
将设置一个znode的权限为:scheme是auth,id是cdz,permissions是cra。
[zk: localhost:2181(CONNECTED) 0] create /auth Created /auth [zk: localhost:2181(CONNECTED) 1] setAcl /auth auth:cdz:cdz:cra Acl is not valid : /auth --报错原因是没有cdz用户 [zk: localhost:2181(CONNECTED) 2] addauth digest cdz:123456 --使用addauth添加cdz用户,密码为123456,模式是digest [zk: localhost:2181(CONNECTED) 3] setAcl /auth auth:cdz:123456:cra --为/auth znode添加Acl权限 [zk: localhost:2181(CONNECTED) 4] getAcl /auth 'digest,'cdz:hGq0vr1Ww1PViRKdAf5fa9ua7q8= : cra
- 开启另一个窗口:
[zk: localhost:2181(CONNECTED) 0] getAcl /auth Authentication is not valid : /auth --读取失败,是因为没有登录cdz [zk: localhost:2181(CONNECTED) 1] addauth digest cdz:123456 --登录cdz [zk: localhost:2181(CONNECTED) 2] getAcl /auth 'digest,'cdz:hGq0vr1Ww1PViRKdAf5fa9ua7q8= --读取成功 : cra
4、使用digest验证模式
- digest与auth的最大区别是:在设置用户时,auth使用的密码是明文,digest是密文。
- 将设置一个znode的权限为:scheme是digest,id是asd,permissions是ca。
[zk: localhost:2181(CONNECTED) 0] create /digest Created /digest [zk: localhost:2181(CONNECTED) 1] getAcl /digest 'world,'anyone : cdrwa [zk: localhost:2181(CONNECTED) 2] setAcl /digest digest:asd:hGq0vr1Ww1PViRKdAf5fa9ua7q8=:ca [zk: localhost:2181(CONNECTED) 3] getAcl /digest Authentication is not valid : /digest [zk: localhost:2181(CONNECTED) 4] addauth digest super:asdf [zk: localhost:2181(CONNECTED) 5] getAcl /digest 'digest,'asd:hGq0vr1Ww1PViRKdAf5fa9ua7q8= : ca
5、使用ip验证模式
[zk: localhost:2181(CONNECTED) 0] create /ip Created /ip [zk: localhost:2181(CONNECTED) 1] getAcl /ip 'world,'anyone : cdrwa [zk: localhost:2181(CONNECTED) 2] setAcl /ip ip:127.0.0.1:ra [zk: localhost:2181(CONNECTED) 3] getAcl /ip 'ip,'127.0.0.1 : ra
2、配额管理
- ZooKeeper可以限制一个znode的子znode的数量和znode数据大小。
- ZooKeeper提供了znode节点数量和节点数据大小的配额管理的支持。我们可以通过配置来指定某个子树的配额,该子树就会被跟踪,如果该子树超过了配额限制,就会记录一条警告日志,但操作还是可以继续执行。此时,ZooKeeper会检测是否超过了某个配额限制,但不会阻止处理流程。
- 配额管理的跟踪功能是在特殊的/zookeeper子树中完成的,所以应用程序不能在这个子树中存储自己的数据,/zookeeper子树只应该被ZooKeeper服务使用,而/zookeeper/quota就是这样一个例子。为了对应用程序/application/superApp创建配额,我们需要在/zookeeper/quota/application/superApp节点下创建两个子节点zookeeper_limits和zookeeper_stats。
- 对于znode数量的限制被称为count,而对于znode数据大小的限制被称为bytes。在zookeeper_limits和zookeeper_stats中通过count=n、bytes=m来指定配额,其中n和m均为整数。在zookeeper_limits中,n和m表示将会触发的警告级别(如果配置为-1就不会触发警告信息)。在zookeeper_stats中,n和m分别表示子树中当前znode数量和子树中数据大小的当前字节数。
- 注意:对元数据的配额跟踪
- 对于子树中znod数据的字节数配额跟踪功能,并不会包含每个znode的元数据的开销,元数据的大小大约100字节,所以如果每个znod的数据大小都比较小,跟踪znode的数量比跟踪znode数据的大小更加实用。
[zk: localhost:2181(CONNECTED) 0] create /application "" Created /application [zk: localhost:2181(CONNECTED) 1] create /application/superApp "super" Created /application/superApp [zk: localhost:2181(CONNECTED) 2] setquota -b 10 /application/superApp [zk: localhost:2181(CONNECTED) 3] listquota /application/superApp absolute path is /zookeeper/quota/application/superApp/zookeeper_limits Output quota for /application/superApp count=-1,bytes=10 Output stat for /application/superApp count=1,bytes=5
- 我们创建了/application/superApp,且该节点的数据为5个字节(一个单词"super"),之后我们为/application/superApp设置了配额限制为10个字节。当我们列出/application/superApp的配置限制时,我们看到数据大小配额还有5个字节的余量,而我们没有对znode数量的进行限制,因此配额中count的值为-1。
- 如果我们发送命令get /zookeeper/quota/application/superApp/zookeeper_stats,我们可以直接访问该节点数据,而不需要使用zkCli中的quota命令。事实上,我们可以通过创建或删除这些节点来创建或删除配额。如果我们运行以下命令:
[zk: localhost:2181(CONNECTED) 4] create /application/superApp/lotsOfData "ThisIsALotOfData"
- 我们应该可以在日志中看到如下信息:
--cat /usr/local/apache-zookeeper-3.5.9-bin/logs/zookeeper-root-server-localhost.localdomain.out 2022-01-18 06:40:19,251 [myid:1] - WARN [CommitProcWorkThread-1:DataTree@386] - Quota exceeded: /application/superApp bytes=21 limit=10
3、多租赁配置
- 配额、一些节流配置选项和acl都值得考虑使用ZooKeeper来服务于多租赁(multitenancy)。这样做有一些令人信服的理由:
- 为了提供可靠的服务,ZooKeeper服务器需要运行在专用的硬件设备上,让多个应用程序共享硬件可以更合理性的利用资源。
- 我们发现,在大多数情况下,Zookeeper的流量很具有突发性:配置或状态的变化的突发操作会导致很高的负载,从而导致服务长时间的不可用。如果应用程序之间的活动爆发不相关,让这些应用程序共享服务器可以更有效地利用硬件资源。不过还要注意,当某个服务器失联时所产生的峰值,某些写得不太规范的应用程序在处理Disconnected事件时,产生的负载高于其所需要的资源。
- 通过共享硬件,我们可以获得更好的故障容错性:如果两个应用程序,从之前各自三个服务器的集群转移到一个由5台服务器组成的集群,虽然服务器变少了,但可以承受两台而不是一台服务器故障了。
- 当ZooKeeper服务于多租赁时,运维人员一般会将数据树分割为不同的子树,一个子树专用一个应用程序。开发人员在设计应用程序时可以考虑在其所用的znode前添加前缀,但还有一个更简单的方法来隔离各个应用程序:在连接串中指定路径部分。每个应用程序的开发人员在进行应用程序开发时,就像使用专用的ZooKeeper服务一样。如果运维人员决定将应用程序部署到/application/newapp之下,应用程序可以使用host:port/application/newapp连接串,而不仅仅是host:port,这样应用程序就会觉得它正在使用一个专用的服务。与此同时,运维人员还可以为/application/newapp节点配置配额限制,以便跟踪应用程序的空间使用情况。
4、通过JMX进行监控
- 四字母命令可以用于系统的监控,但是它们没有提供控制或更改系统的方法,ZooKeeper通过标准Java管理协议:JMX (Java management Extensions),提供了更强大的监控和管理功能。有很多关于如何设置和使用JMX的书,也有很多用于JMX服务器的工具。本节中,我们会使用一个简单的管理控制台工具jconsole来探索通过JMX管理ZooKeeper功能。
- jconsole是Java中自带的工具,在实践中,可以使用JMX工具(如jconsole)来监视远程ZooKeeper服务器。但在本节中,我们将会在ZooKeeper服务器上所使用该工具。
- 首先,我们启动第一个ZooKeeper服务器(即ID为1的服务器)。只需要在命令行中简单的输入jconsole命令就可以启动jconsole工具,jconsole启动后,你就会看到类似图10-7中所示的窗口。
--安装JDK ]# tar zvfx jdk-8u291-linux-x64.tar.gz -C /usr/local/ --在图形界面下执行命令 ]# /usr/local/jdk1.8.0_291/bin/jconsole
- 注意其中带有"zookeeper"名称的进程。对于本地进程,jconsole会自动发现可连接的进程。
- 现在,我们只需要在列表中双击该进程就可以连接到ZooKeeper进程上。因为我们没有启用SSL,此时会提示我们关于非安全连接的选项,单击非安全连接按钮,之后屏幕中就会出现图10-8所示的窗口。
- 如图所示,我们可以通过该工具获取关于ZooKeeper进程的各种的统计信息。JMX支持通过MBean (Managed Beans)向远程管理器公开定制的信息。虽然名字听起来比较笨拙,但却是暴露信息和操作的一个非常灵活的方式。jconsole会在最右侧的选项卡中列出该进程暴露的所有MBean信息,如图10-9所示。
- 在MBean列表中我们可以看到ZooKeeper所使用且暴露出来的组件信息。我们比较关心Zookeeper服务的信息,因此我们双击该列表项,我们会看到一个层次列表副本以及这些副本的信息。如果我们打开某些列表中的子项,我们会看到图10-10所示的信息。
- 不但包含自己副本的信息,还包括一些关于其他副本的信息,实际上只是联系信息。因为服务器1对其他副本的信息所知不多,所以服务器1无法展示更多其他副本信息。不过,服务器1很了解自己的信息,所以它可以暴露更多的信息。
1