Zookeeper 集羣4字命令白名單 stat is not executed because it is not in the whitelist.

  今天搭建Hbase集羣過程中,在頁面http://hadoop01:16010/zk.jsp發現zk 通訊統計節(Quorum Server Statistics)存在提示stat is not executed because it is not in the whitelist.

解決思路:

[root@hadoop01 bigdata]# echo conf|nc hadoop01 2181
conf is not executed because it is not in the whitelist.
zk的這些指令未在白名單裏。這些指令有
    // specify all of the commands that are available
    static {
        cmd2String.put(confCmd, "conf");
        cmd2String.put(consCmd, "cons");
        cmd2String.put(crstCmd, "crst");
        cmd2String.put(dirsCmd, "dirs");
        cmd2String.put(dumpCmd, "dump");
        cmd2String.put(enviCmd, "envi");
        cmd2String.put(getTraceMaskCmd, "gtmk");
        cmd2String.put(ruokCmd, "ruok");
        cmd2String.put(setTraceMaskCmd, "stmk");
        cmd2String.put(srstCmd, "srst");
        cmd2String.put(srvrCmd, "srvr");
        cmd2String.put(statCmd, "stat");
        cmd2String.put(wchcCmd, "wchc");
        cmd2String.put(wchpCmd, "wchp");
        cmd2String.put(wchsCmd, "wchs");
        cmd2String.put(mntrCmd, "mntr");
        cmd2String.put(isroCmd, "isro");
        cmd2String.put(telnetCloseCmd, "telnet close");
    }

搜索源碼is not executed because it is not in the whitelist.

/** Return if four letter word found and responded to, otw false **/
    private boolean checkFourLetterWord(final Channel channel,
            ChannelBuffer message, final int len) throws IOException
    {
        // We take advantage of the limited size of the length to look
        // for cmds. They are all 4-bytes which fits inside of an int
        if (!FourLetterCommands.isKnown(len)) {
            return false;
        }
 
        String cmd = FourLetterCommands.getCommandString(len);
 
        channel.setInterestOps(0).awaitUninterruptibly();
        packetReceived();
 
        final PrintWriter pwriter = new PrintWriter(
                new BufferedWriter(new SendBufferWriter()));
 
        // ZOOKEEPER-2693: don't execute 4lw if it's not enabled.
        // 注意此處命令是否允許執行,isEnabled方法用於判斷
        if (!FourLetterCommands.isEnabled(cmd)) {
            LOG.debug("Command {} is not executed because it is not in the whitelist.", cmd);
            NopCommand nopCmd = new NopCommand(pwriter, this, cmd +
                    " is not executed because it is not in the whitelist.");
            nopCmd.start();
            return true;
        }
 
        LOG.info("Processing " + cmd + " command from "
                + channel.getRemoteAddress());
 
       if (len == FourLetterCommands.setTraceMaskCmd) {
            ByteBuffer mask = ByteBuffer.allocate(8);
            message.readBytes(mask);
            mask.flip();
            long traceMask = mask.getLong();
            ZooTrace.setTextTraceLevel(traceMask);
            SetTraceMaskCommand setMask = new SetTraceMaskCommand(pwriter, this, traceMask);
            setMask.start();
            return true;
        } else {
            CommandExecutor commandExecutor = new CommandExecutor();
            return commandExecutor.execute(this, pwriter, len, zkServer,factory);
        }
    }
 /**
     * Check if the specified command is enabled.
     *
     * In ZOOKEEPER-2693 we introduce a configuration option to only
     * allow a specific set of white listed commands to execute.
     * A command will only be executed if it is also configured
     * in the white list.
     *
     * @param command The command string.
     * @return true if the specified command is enabled
     */
    public synchronized static boolean isEnabled(String command) {
        // whiteListInitialized是否初始化過的標記,默認是false,whiteListedCommands相關命令加載完成後,就爲true了
        if (whiteListInitialized) {
            return whiteListedCommands.contains(command);
        }
 
        // 參數key名稱zookeeper.4lw.commands.whitelist的值直接用*,則會把cmd2String裏已經緩存的所有指令放到這個白名單裏
        String commands = System.getProperty(ZOOKEEPER_4LW_COMMANDS_WHITELIST);
        if (commands != null) {
            String[] list = commands.split(",");
            for (String cmd : list) {
                if (cmd.trim().equals("*")) {
                    for (Map.Entry<Integer, String> entry : cmd2String.entrySet()) {
                        whiteListedCommands.add(entry.getValue());
                    }
                    break;
                }
                if (!cmd.trim().isEmpty()) {
                    whiteListedCommands.add(cmd.trim());
                }
            }
        }
 
        // It is sad that isro and srvr are used by ZooKeeper itself. Need fix this
        // before deprecating 4lw.
        if (System.getProperty("readonlymode.enabled", "false").equals("true")) {
            whiteListedCommands.add("isro");
        }
        // zkServer.sh depends on "srvr".
        whiteListedCommands.add("srvr");
        whiteListInitialized = true;
        LOG.info("The list of known four letter word commands is : {}", Arrays.asList(cmd2String));
        LOG.info("The list of enabled four letter word commands is : {}", Arrays.asList(whiteListedCommands));
        return whiteListedCommands.contains(command);
    }

解決方法:

方法1和2均可解決,採用其一即可。

1、在zoo.cfg 文件里加入配置項讓這些指令放行

#開啓四字命令
4lw.commands.whitelist=*

2、在zk的啓動腳本zkServer.sh中新增放行指令

    ZOOMAIN="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=$JMXPORT -Dcom.sun.management.jmxremote.authenticate=$JMXAUTH -Dcom.sun.management.jmxremote.ssl=$JMXSSL -Dzookeeper.jmx.log4j.disable=$JMXLOG4J org.apache.zookeeper.server.quorum.QuorumPeerMain"
  fi
else
    echo "JMX disabled by user request" >&2
    ZOOMAIN="org.apache.zookeeper.server.quorum.QuorumPeerMain"
fi

#添加VM環境變量-Dzookeeper.4lw.commands.whitelist=*
ZOOMAIN="-Dzookeeper.4lw.commands.whitelist=* ${ZOOMAIN}"

if [ "x$SERVER_JVMFLAGS" != "x" ]
then
    JVMFLAGS="$SERVER_JVMFLAGS $JVMFLAGS"
fi

注:配置完畢後,記得重啓集羣。./zkServer.sh restart

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章