주요글: 도커 시작하기
반응형

암바리(https://ambari.apache.org/)는 오픈소스 하둡 관리 도구이다. 설치부터, 설정 관리, 오퍼레이션, 모니터링, 통지 등 하둡 클러스터를 관리하는데 필요한 기본 기능을 제공한다. 암바리를 사용하다보면 레거시 환경의 통지 시스템을 이용해서 암바리의 문제 상황을 문자나 메신저 등으로 통지 받고 싶을 때가 있다. 하지만 아쉽게도 암바리는 이메일과 SNMP 트랩만 이용해서 문제를 통지하기 때문에, 암바리 Alert을 레거시 환경에 바로 붙일 수 없다.


왓츠업과 같이 SNMP를 지원하는 도구를 이용해서 이미 모니터링을 하고 있다면 이를 사용하면 된다. SNMP 기반의 모니터링 도구가 없거나 적합하지 않은 경우에는 암바리가 발생하는 SNMP 트랩을 직접 수신해서 처리하는 방식으로 레거시와 연동을 처리해야 한다.


[암바리 SNMP Alert 설정 화면]


암바리의 Alert SNMP 트랩 구성


암바리는 Alert 발생시 SNMP Alert 설정 화면에서 입력한 정보를 이용해서 트랩을 발생시킨다.

  • OID : 1.3.6.1.6.3.1.1.5.4와 같은 OID 문자열
  • Hosts : 트랩을 수신할 SNMP 트랩 리시버 서버의 호스트
  • Port : 리시버 서버가 사용할 포트 번호 (UDP 포트)
OID 값으로 "1.3.6.1.6.3.1.1.5.4"를 입력한 경우 트랩은 다음과 같이 구성된다.
  • OID(1.3.6.1.6.3.1.1.4.1.0), OBJECT IDENTIFIER[6] = 1.3.6.1.6.3.1.1.5.4
  • OID(1.3.6.1.6.3.1.1.5.4), OCTET STRING[4] = 상세메시지(body)
  • OID(1.3.6.1.6.3.1.1.5.4), OCTET STRING[4] = 요약메시지(subject)

상세 메시지는 몸체 내용에 해당하며, 다음과 같은 구조의 메시지를 갖는다. (마지막 줄에 공백 문자가 존재한다.)


\n

[Alert] Supervisor Process\n

[Service] STORM\n

[Component] SUPERVISOR\n

[Host] skt-phddtn3\n

\n

TCP OK - 0.000s response on port 56431\n

    


요약 메시지는 다음과 같은 구조를 갖는다.(마지막 줄에 공백 문자가 존재한다.)


\n

      [OK] Supervisor Process\n

    


요약 메시지는 Alert의 심각도로 시작한다. 심각도에는 OK, WARNING, CRITICAL, UNKNOWN이 존재한다.


트랩 리시버는 OID로부터 값을 읽어와 메시지를 알맞게 변환한 뒤 심각도에 따라 알맞은 처리를 하면 된다. 예를 들어, 심각도가 CRITICAL이면 SMS로 문자를 발송하고, WARNING이면 메신저로 메시지를 보내는 등의 작업을 하면 된다.


SNMP4J를 이용한 암바리 트랩 수신


트랩을 받기 위한 SNMP 도구가 따로 없다면 직접 트랩 리시버를 구현해야 한다. 다행히 SNMP 자체를 잘 몰라도 SNMP4J(http://www.snmp4j.org/)를 사용하면 쉽게 암바리 Alert 처리를 위한 트랩 리서버를 구현할 수 있다. 다음은 SNMP4J를 이용한 트랩 리시버를 구현한 코드 예이다.


public class TrapReceiver {

    private int port;

    private MultiThreadedMessageDispatcher dispatcher;

    private Snmp snmp = null;

    private Address listenAddress;

    private ThreadPool threadPool;


    private NotificationHandler notificationHandler;

    private int threadPoolSize;


    public TrapReceiver(int port) {

        this.port = port;

        this.threadPoolSize = 10;

    }


    public void init() throws IOException {

        threadPool = ThreadPool.create("Trap", threadPoolSize);

        dispatcher = new MultiThreadedMessageDispatcher(

              threadPool, new MessageDispatcherImpl());

        listenAddress = GenericAddress.parse("udp:0.0.0.0/" + port);

        TransportMapping<?> transport = 

                new DefaultUdpTransportMapping((UdpAddress) listenAddress);


        snmp = new Snmp(dispatcher, transport);

        snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1());

        snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());


        snmp.listen();


        snmp.addCommandResponder(new CommandResponder() {

            @Override

            public void processPdu(CommandResponderEvent event) {

                handleNotification(event);

            }

        });

    }


    private void handleNotification(CommandResponderEvent event) {

        if (notificationHandler == null) {

            return;

        }

        notificationHandler.handle(createNotification(event));

    }


    private Notification createNotification(CommandResponderEvent event) {

        OID trapOID = (OID) event.getPDU().getVariable(SnmpConstants.snmpTrapOID);

        List<String> values = new ArrayList<>(2);

        Vector<? extends VariableBinding> varBinds = event.getPDU().getVariableBindings();

        if (varBinds != null && !varBinds.isEmpty()) {

            Iterator<? extends VariableBinding> varIter = varBinds.iterator();

            while (varIter.hasNext()) {

                VariableBinding var = varIter.next();

                if (var.getOid().equals(trapOID)) {

                    values.add(var.getVariable().toString());

                }

            }

        }

        return new Notification(values.get(0), values.get(1));

    }


    public void close() {

        try {

            snmp.close();

        } catch (IOException e) {

        }

        threadPool.stop();

    }


    public void setNotificationHandler(NotificationHandler notificationHandler) {

        this.notificationHandler = notificationHandler;

    }

}


이 코드에서 createNotification() 메서드가 트랩 메시지를 처리하는 코드이다. 암바리가 생성하는 트랩은 지정한 OID에 해당하는 첫 번째 변수에 상세 내용(몸체), 두 번째 변수에 요약 내용(제목)을 메시지로 전달한다. 따라서, 지정 OID를 갖는 메시지 값을 차례대로 저장한 뒤 각각 순서대로 몸체와 제목으로 사용하면 된다. 제목은 [OK], [CRITICAL]는 심각도를 포함하고 있으므로 이 값을 이용해서 트랩을 어떻게 처리할지 결정할 수 있다.


몸체 메시지에는 서비스 종류, 호스트 정보 등이 포함되어 있으므로 이 정보를 사용해서 서비스 담당자별로 통지하거나 장비 담당자에게 메시지를 보내는 것과 같은 처리를 할 수 있다.


+ Recent posts