zookeeper ACL使用

 生產環境中,常常會有多個項目使用zookeeper,例如多個hbase集羣。每一個項目搭建一套獨立的zookeeper,不管從機器成本,仍是運維成本,都是一筆額外的開銷。java

然而多項目,多集羣共用zookeeper又涉及一個權限隔離的問題。zookeeper自己提供了ACL機制,表示爲scheme:id:permissions,第一個字段表示採用哪種機制,第二個id表示node

用戶,permissions表示相關權限(如只讀,讀寫,管理等)。zookeeper提供了以下幾種機制(scheme):apache

  • world: 它下面只有一個id, 叫anyone, world:anyone表明任何人,zookeeper中對全部人有權限的結點就是屬於world:anyone的
  • auth: 它不須要id, 只要是經過authentication的user都有權限(zookeeper支持經過kerberos來進行authencation, 也支持username/password形式的authentication)
  • digest: 它對應的id爲username:BASE64(SHA1(password)),它須要先經過username:password形式的authentication
  • ip: 它對應的id爲客戶機的IP地址,設置的時候能夠設置一個ip段,好比ip:192.168.1.0/16, 表示匹配前16個bit的IP段
  • super: 在這種scheme狀況下,對應的id擁有超級權限,能夠作任何事情(cdrwa)

下面演示一個經過digest(用戶名密碼的方式)爲建立的節點設置ACL的例子:框架

複製代碼
import org.apache.zookeeper.*; import org.apache.zookeeper.server.auth.DigestAuthenticationProvider; import org.apache.zookeeper.data.*; import java.util.*; public class NewDigest { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub //new一個acl List<ACL> acls = new ArrayList<ACL>(); //添加第一個id,採用用戶名密碼形式 Id id1 = new Id("digest", DigestAuthenticationProvider.generateDigest("admin:admin")); ACL acl1 = new ACL(ZooDefs.Perms.ALL, id1); acls.add(acl1); //添加第二個id,全部用戶可讀權限 Id id2 = new Id("world", "anyone"); ACL acl2 = new ACL(ZooDefs.Perms.READ, id2); acls.add(acl2); // zk用admin認證,建立/test ZNode。  ZooKeeper zk = new ZooKeeper( "host1:2181,host2:2181,host3:2181", 2000, null); zk.addAuthInfo("digest", "admin:admin".getBytes()); zk.create("/test", "data".getBytes(), acls, CreateMode.PERSISTENT); } }
複製代碼

 然而,ACL畢竟僅僅是訪問控制,並不是完善的權限管理,經過這種方式作多集羣隔離,還有不少侷限性:運維

(1)ACL並沒有遞歸機制,任何一個znode建立後,都須要單獨設置ACL,沒法繼承父節點的ACL設置。ide

(2)除了ip這種scheme,digest和auth的使用對用戶都不是透明的,這也給使用帶來了很大的成本,不少依賴zookeeper的開源框架也沒有加入對ACL的支持,例如hbase,stormspa

相關文章
相關標籤/搜索