elasticsearch에 /를 포함하는 id를 저장하고 싶을때..

/를 사용하면 path 구분자에 걸린다. 


따라서 url에 / 대신 %2F를 사용하면 정상적으로 작동한다.




curl -X PUT "es.google.io:9200/google-host-staging/host/service.dos%2F0" -H 'Content-Type: application/json' -d'

{

   "service":"0",

   "host":"service.dos"

}

'






Posted by '김용환'
,





상태가 없는 애플리케이션은 클러스터의 다른 노드에서 간단히 재시작할 수 있지만,,


상태가 있어야 하는 쿠버네티스 애플리케이션은 어떻게 구축할까?



쿠버네티스는 상태를 갖는 애플리케이션을 처리할 수 ​​있다.  이를 통해 장애 안정성 및 로드 밸런싱을 용이해진다.





애플리케이션이 상태를 갖는다면 즉, 도커 볼륨에 특정 데이터를 저장해야 한다면, 


애플리케이션이 실행되는 각 노드에서 필요한 도커 볼륨을 사용할 수 있어야 한다. 




따라서 상태를 갖는 애플리케이션의 처리가 더욱 복잡해진다. 



그래서 쿠버네티스는 영구 볼륨(persistent volumes)(https://kubernetes.io/docs/concepts/storage/persistent-volumes/)과 



상태 저장 셋(stateful sets)(https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-storage)을 제공한다.







또 다른 방법은 operators(https://coreos.com/operators)을 사용하는 것이다. 


operators을 사용하면 상태를 갖는 애플리케이션을 자동으로 설치할 수 있다. 



예를 들어 프로메테우스(Prometheus) operator(https://github.com/coreos/prometheus-operator)가 있다. 


프로메테우스 operator는 쿠버네티스 클러스터에 모니터링 시스템인 프로메테우스를 설치할 수 있다. 


또한 Prometheus, ServiceMonitor, Altermanager와 같은 프로메테우스 컴포넌트에 대한 쿠버네티스 자원을 소개하며 프로메테우스 컴포넌트를 포드, 서비스, 배포 대신 쿠버네티스 설정으로 사용할 수 있다. 



프로메테우스 operator는 프로메테우스가 모니터링 데이터를 저장하는 방법을 결정해 핵심 과제를 해결한다.

Posted by '김용환'
,



마라톤(marathon)은 url 상태 체크가 있는데. traffic이 많이 오면  health check 실패되어 자동 실행되고 그런게 좀 있었는데.


쿠버네티스는 url 헬스 체크외에 파일 체크 기능이 생겼다..


https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/




쿠버네티스는 Liveness Probe(https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/)를 통해 포드의 장애를 파악한다. 


사용자 지정 Liveness Probe를 사용하여 애플리케이션의 요구에 맞춰 컨테이너가 새로 시작되는 시점을 결정할 수 있다.



한편,


Readiness Probe(https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#define-readiness-probes)는 컨테이너가 요청을 처리할 수 ​​있는지 여부를 나타낸다. 


예를 들어 애플리케이션이 많은 양의 데이터를 처리하거나 아직 완전히 시작되지 않은 경우에 요청이 블럭되면 Readiness Probe는 애플리케이션의 상태를 쿠버네티스에 알린다. 


Liveness Probe와는 달리 Readiness Probe가 실패했다고 해서 컨테이너가 재시작되지 않는다. 


쿠버네티스는 일정 시간 후에 포드가 요청을 처리할 수 있는 지 여부를 Readiness Probe를 통해 신호를 보낸다고 가정한다.





<Liveness Probe>


ports:

- name: liveness-port

  containerPort: 8080

  hostPort: 8080


livenessProbe:

  httpGet:

    path: /healthz

    port: liveness-port

    


<Rediness Probe>

    

readinessProbe:

  exec:

    command:

    - cat

    - /tmp/healthy

  initialDelaySeconds: 5

  periodSeconds: 5

Posted by '김용환'
,

authz, authn

영어앤영문권 2018. 8. 10. 10:31

authorization, authentication 길게 얘기하니까 발음도 그렇구 단어도 비슷하다



축약어 있나 확인해봤더니  authz, authn이라 한다.


출처 


https://en.wikipedia.org/wiki/Web_API_security


AUTHN (authentication) and AUTHZ (authorization)

Posted by '김용환'
,


elasticsearch5.4에서 _id만 저장하는 테스트를 진행했다.


 testcase 시나리오는 다음과 같다.


index를 생성한다.

_id만 저장한다.

_id를 읽는다. 정상적이면 성공, 그러나 실패



성공한 것처럼 보인다... 그러나, 실제 curl로 _id를 document를 요청하면 데이터는 없다고 나온다!!


(사실 문법 에러는 아니지만,, 저장은 안해.. 라는 것으로 보인다)



따라서 아무리 간단한 데이터를 저장하더라도 _id와 field 데이터 하나 정도는 저장해야 디스크에 저장하길 바란다.

(당연하지만..)






Posted by '김용환'
,



아래와 같은 toMap 코드를 사용하면 NPE 에러가 발핸다.


    final Map<String, Object> valueMap = pingFailedHosts

        .stream()

        .collect(Collectors.toMap(c->c, null));

        


toMap 메소드는 KeyMapper와 ValueMapper를 전달하는 형태인데. 

public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}


toMap 원형 함수를 보면, mergeFunction , mapSupplier가 추가된다. 

public static <T, K, U, M extends Map<K, U>>
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction,
Supplier<M> mapSupplier) {
BiConsumer<M, T> accumulator
= (map, element) -> map.merge(keyMapper.apply(element),
valueMapper.apply(element), mergeFunction);
return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
}


https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html



toMap 메소드의 매개변수를 보면, mergeFunction이 Map.merge()와 연관되어 있음을 알 수 있다. 

Parameters:
keyMapper - a mapping function to produce keys
valueMapper - a mapping function to produce values
mergeFunction - a merge function, used to resolve collisions between values associated with the same key, as supplied to Map.merge(Object, Object, BiFunction)
mapSupplier - a function which returns a new, empty Map into which the results will be inserted







코드를 따라가 들어가면


private static <K, V, M extends Map<K,V>>
BinaryOperator<M> mapMerger(BinaryOperator<V> mergeFunction) {
return (m1, m2) -> {
for (Map.Entry<K,V> e : m2.entrySet())
m1.merge(e.getKey(), e.getValue(), mergeFunction);
return m1;
};
}


m1.merge() 메소드가 바로 Map.merge() 메소드이다.


여기 코드 보면, value 값이 not null이어야 한다. 


default V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
Objects.requireNonNull(value)
;
V oldValue = get(key);
V newValue = (oldValue == null) ? value :
remappingFunction.apply(oldValue, value);
if(newValue == null) {
remove(key);
} else {
put(key, newValue);
}
return newValue;
}


코드의 주석이나, 오라클 javadoc 문서를 보면 역시 NPE를 발행하는 코드임을 확인할 수 있다.


NullPointerException - if the specified key is null and this map does not support null keys or the value or remappingFunction is null





따라서 key나 value의 값이 null일 확률이 높다면, toMap()를 사용하지 말아야 한다.


아래와 같이 naive하게 개발하는 것이 좋다.


    final Map<String, String> valueMap2 = Arrays.asList("cacti.google.com", "sun.google.com")

        .stream()

        .collect(HashMap::new, (m,v)->m.put(v, null), HashMap::putAll);




Posted by '김용환'
,