etcd는 3가지 방식으로 클러스터를 구성할 수 있다.


https://coreos.com/etcd/docs/latest/v2/clustering.html


- Static : 클러스터 주소와 크기를 안 상태에서 설정하는 것을 말한다. --initial-cluster를 사용한다. 일반적으로 사용하는 방식이다.

- etcd Discovery : 클러스터 환경에서 DHCP를 사용하는 환경에서 사용된다. 정적 설정이 아닌 동적 설정(discovery) 환경에서 적합. etcd노드를 추가할때 주로 사용하며 --discovery를 사용한다.

- DNS Discovery : 클러스터 환경에서 DHCP를 사용하는 환경에서 사용된다. 정적 설정이 아닌 동적 설정(discovery) 환경에서 적합. DNS의 SRV 레코드를 사용해 etcd 노드를 추가한다. --discovery-srv를 사용한다.




가장 쉬운 방식인 static으로 구성한다. 


https://github.com/etcd-io/etcd/releases에서 etcd 3.2.9 바이너리를 다운받는다. (현재 기준)

$ wget etcd.zip


zip 파일을 풀어 1, 2, 3 디렉토리로 binary를 복사한다.


$ ls -al 하면 다음 디렉토리와 같다.

drwxr-xr-x   8 samuel.kim  staff       272  7 25 02:13 1

drwxr-xr-x   8 samuel.kim  staff       272  7 25 02:13 2

drwxr-xr-x   8 samuel.kim  staff       272  7 25 02:13 3


 

1번 디렉토리로 이동

./etcd --name etcd1 \

--initial-advertise-peer-urls http://172.26.100.161:2380 \

--listen-peer-urls http://172.26.100.161:2380 \

--listen-client-urls http://172.26.100.161:2379,http://127.0.0.1:2379 \

--advertise-client-urls http://172.26.100.161:2379 \

--initial-cluster-token "etcd-cluster" \

--initial-cluster etcd1=http://172.26.100.161:2380,etcd2=http://172.26.100.161:2480,etcd3=http://172.26.100.161:2580 \

--initial-cluster-state new



다른 터미널을 열어, 2번 디렉토리로 이동

./etcd --name etcd2 \

--initial-advertise-peer-urls http://172.26.100.161:2480 \

--listen-peer-urls http://172.26.100.161:2480 \

--listen-client-urls http://172.26.100.161:2479,http://127.0.0.1:2479 \

--advertise-client-urls http://172.26.100.161:2479 \

--initial-cluster-token "etcd-cluster" \

--initial-cluster etcd1=http://172.26.100.161:2380,etcd2=http://172.26.100.161:2480,etcd3=http://172.26.100.161:2580 \

--initial-cluster-state new




다른 터미널을 열어, 3번 디렉토리로 이동

./etcd --name etcd3 \

--initial-advertise-peer-urls http://172.26.100.161:2580 \

--listen-peer-urls http://172.26.100.161:2580 \

--listen-client-urls http://172.26.100.161:2579,http://127.0.0.1:2579 \

--advertise-client-urls http://172.26.100.161:2579 \

--initial-cluster-token "etcd-cluster" \

--initial-cluster etcd1=http://172.26.100.161:2380,etcd2=http://172.26.100.161:2480,etcd3=http://172.26.100.161:2580 \

--initial-cluster-state new




3대를 모두 실행할 때까지 클러스터링이 안되서 warning이 발생할 수 있다. 



etcd 디렉토리에 디폴트로 etcd3.etcd 데이터 디렉토리가 생성된다.


사용자 지정을 하고 싶다면 --data-dir /opt/etcd/data 와 같이 진행한다.





다른 터미널을 열어, 4번 디렉토리로 이동

./etcd --name etcd4 \

--initial-advertise-peer-urls http://172.26.100.161:2680 \

--listen-peer-urls http://172.26.100.161:2680 \

--listen-client-urls http://172.26.100.161:2679,http://127.0.0.1:2679 \

--advertise-client-urls http://172.26.100.161:2679 \

--initial-cluster-token "etcd-cluster" \

--initial-cluster etcd1=http://172.26.100.161:2380,etcd2=http://172.26.100.161:2480,etcd3=http://172.26.100.161:2580,etcd4=http://172.26.100.161:2680 \

--initial-cluster-state new




* 주의 할 점.



etcd1,etcd2,etcd3에 없는 etcd4를 실행하면..

4번에서는 에러가 많이 발생한다. 

2018-09-05 02:13:01.674392 E | rafthttp: request sent was ignored (cluster ID mismatch: peer[6564723d6ed1fc93]=c00bfb0bce868ccb, local=fbee3df97f467d62)

2018-09-05 02:13:01.674400 E | rafthttp: request sent was ignored (cluster ID mismatch: peer[edbc16344886488f]=c00bfb0bce868ccb, local=fbee3df97f467d62)


1,2,3번 에서는 

2018-09-05 02:13:19.659255 E | rafthttp: request cluster ID mismatch (got fbee3df97f467d62 want c00bfb0bce868ccb)

2018-09-05 02:13:19.659316 E | rafthttp: request cluster ID mismatch (got fbee3df97f467d62 want c00bfb0bce868ccb)


따라서 1,2,3번에서 --initial-cluster에 etcd4를 추가하고 --initial-cluster-state new 대신 --initial-cluster-state existing를 실행하면 좋을 것 같지만.. 동작이 안된다. 


etcdctl member add etcd4 http://172.26.100.161:2680





* 클러스터링 멤버 구성



 ./etcdctl member list

6564723d6ed1fc93, started, etcd2, http://172.26.100.161:2480, http://172.26.100.161:2479

edbc16344886488f, started, etcd3, http://172.26.100.161:2580, http://172.26.100.161:2579

fc0c8fe65a431b34, started, etcd1, http://172.26.100.161:2380, http://172.26.100.161:2379



여기서 하나를 뺀다.

./etcdctl member remove 6564723d6ed1fc93

Member 6564723d6ed1fc93 removed from cluster c00bfb0bce868ccb


 ./etcdctl member list

edbc16344886488f, started, etcd3, http://172.26.100.161:2580, http://172.26.100.161:2579

fc0c8fe65a431b34, started, etcd1, http://172.26.100.161:2380, http://172.26.100.161:2379


이때 etcd2는 종료된다.

다시 etcd2를 실행하면, 마지막에 아래 로그가 나오고 종료된다.


2018-09-05 05:16:18.342165 I | rafthttp: stopped peer 2fa514e820fdcf1e



아래와 같이 등록해도.  한번 빠지면 끝이다..

./etcdctl member add etcd4  --peer-urls=http://172.26.100.161:2479





클러스터 멤버 추가는 2점대와 동일하다.


Posted by '김용환'
,



jenkins 배치 설치를 쿠버네티스로 진행하려 했는데, 


기존처럼  master, slave 구조로 사용할 수 없다. 


https://cloud.google.com/solutions/jenkins-on-kubernetes-engine



The Kubernetes plugin enables using Kubernetes service accounts for authentication, and creating labeled executor configurations with different base images. The plugin creates a pod when an executor is required and destroys the pod when a job ends.




job 단위로 pod를 구성하기 때문에 job을 dockernize를 해야 한다.

job이 실행할 때 pod로 생성한다. 그리고 job이 종료될 때는 해당 pod를 종료한다. 


 따라서 과거처럼 slave에 바이너를 설치하면 사용하는 경우(hdfs 설정, kafka를 사용하는 경우라면) 이 방법을 쓰지 못한다.


job 단위의 dockernize 형태를 구성해야 형태로 구성하는 것이 쿠버네티스 위에서 젠킨스 job을 실행할 수 있다.





아래 문서를 보면..다음과 같이 되어 있다. 



https://www.blazemeter.com/blog/how-to-setup-scalable-jenkins-on-top-of-a-kubernetes-cluster



After both builds are completed, you should see that both build executors have been removed and are not available inside the cluster anymore:



실제 해보니.. 정말 그렇게 동작한다. 

다음을 참조한다.


http://knight76.tistory.com/entry/kubernetes-kubernetesjenkins-%EC%97%B0%EB%8F%99-%EB%A0%88%EC%8B%9C%ED%94%BC




Posted by '김용환'
,





집킨(zipkin)은 복잡한 시스템에서

마이크로 서비스의 상호 작용에 대한 개요를 파악하는 데 도움이 될 수 있다.






스프링 클라우드 Sleuth(https://cloud.spring.io/spring-cloud-sleuth/)는

스프링 부트 애플리케이션과 집킨을 통합할 수 있는 매우 쉬운 방법을 제공한다.


문서는 다음과 같다.

https://coe.gitbook.io/guide/log/sleuth



스프링 클라우드 Sleuth는 추적 ID와 범위(span) ID가 생성되고 통신 중에 전달되도록 한다.

그리고 추적 데이터를 집킨 서버로 전송한다.



스프링 클라우드에 zipkin 관련 프로젝트(spring-cloud-starter-zipkin)가 있다.


예시는 다음을 참조한다.

https://www.baeldung.com/tracing-services-with-zipkin





또한 스프링 클라우드 Sleuth를 사용해 추적 ID만 전송할 수도 있다(http://cloud.spring.io/spring-cloud-static/spring-cloud-sleuth/1.2.5.RELEASE/single/spring-cloud-sleuth.html#_only_sleuth_log_correlation).


로그에 추적 ID를 저장하고 있다면 요청에 대한 모든 로그 정보를 로그 분석에서 사용할 수 있다.

Posted by '김용환'
,



open stack vm 인스턴스를 생성할 때 동일한 pm에 있으면, 

pm이 장애가 발생했을 때 같이 인스턴스가 종료되기 때문에 위험할 수 있다. 


같은 pm 장비에 vm 장비가 없도록 하는 것을 anti-affinity라는 정책인데. 그룹(group)에만  적용할 수 있다.

인스턴스 사용하는 방법은 다음과 같다.




$ openstack server group list


+--------------------------------------+--------------------+---------------+

| ID                                                           | Name                       |         Policies      |

+--------------------------------------+--------------------+---------------+

+--------------------------------------+--------------------+---------------+





anti-affinity 정책을 포함한 그룹을 추가한다.


$ openstack server group create stats-tsdb-read --policy anti-affinity


+----------+--------------------------------------+

| Field    | Value                                |

+----------+--------------------------------------+

| id       | 1cd7538d-23c4-493e-8684-3bf46c440864 |

| members  |                                      |

| name     | stats-tsdb-read                      |

| policies | anti-affinity                        |

+----------+--------------------------------------+





이제 stats-tsdb-read group으로 서버를 추가한다. 


$ openstack server create --flavor large --image ubuntu-16.04 --availability-zone US_WEST --hint group=1cd7538d-23c4-493e-8684-3bf46c440864 stats-tsdb-01



$ openstack server create --flavor large --image ubuntu-16.04 --availability-zone US_WEST --hint group=1cd7538d-23c4-493e-8684-3bf46c440864 stats-tsdb-02





만약 잘못만들었다면 다음과 같이 그룹을 삭제한다.


$ openstack server group delete stats-tsdb


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 '김용환'
,


TSDB에서 다음과 같은 에러가 발생했다.

(기본 설정에는 채널 사이즈가 정해져 있지 않다.)


net.opentsdb.tsd.ConnectionManager$ConnectionRefusedException: Channel size (201) exceeds total 



connection limit(200), 즉 채널 사이즈가 작아서 발생한 것이다.



설정을 보면 200으로 되어 있다.


# Sets the maximum number of connections a TSD will handle, additional connections are immediately closed. (from 2.3)

tsd.core.connections.limit = 200




이를 큰 값으로 (예, 500)수정하면 해당 트래픽 상황에서는 더 이상 문제가 생기지 않는다.





Posted by '김용환'
,

grafana에서 특정 metric을 downsample을 1m으로 하면 잘 보이는 장점이 있다.

그러나 해당 메트릭 패널이 많이 모인 dashboard에서는 당연히 DataSource(예, tsdb)가 영향을 받을 수 있다. 

따라서 auto downsampling을 하는 게 좋다.

자세한 내용은 아래를 참고한다.

https://railsadventures.wordpress.com/2015/07/17/advanced-grafana-using-automatic-intervals/


Posted by '김용환'
,


opentsdb 개발 환경 구성하기


$ git clone https://github.com/OpenTSDB/opentsdb.git

$ cd opentsdb

$ sh build.sh pom.xml

$ mvn compile



intellij에서 open project... maven 기반으로 읽는다. 


그래도 source generated되는게 있어서 완벽하지 않지만 그럭저럭 쓸만하다.



Posted by '김용환'
,

[openstack] flavor 추가

Cloud 2018. 6. 16. 11:54


admin 권한으로 보고 사용할 수 있는 openstack에서의 flavor가 따로 있다.

내 계정으로는 admin 권한으로 사용할 수 있는 flavor는 admin권한의 flavor의 subset이다.


따라서 내 계정으로 가지고 있는 않는 flavor로 openstack instance를 생성하고 싶다면, 프로젝트에 flavor 생성 권한이 있어야 한다.


현재 가지고 있는 권한은 다음과 같다. 


$ openstack --os-project-name GOOGLE_PLUS flavor list


+--------------------------------------+-----------+------+------+-----------+-------+-----------+

| ID                                   | Name      |  RAM | Disk | Ephemeral | VCPUs | Is Public |

+--------------------------------------+-----------+------+------+-----------+-------+-----------+

| 9933ea88-9535-4b04-add8-910e08c01aea | m1.medium | 

| cdb20a75-87a5-43d3-b75b-a5331cad8cb7 | m1.small  | 

| e3739ce3-746c-4e3f-820e-eb9803fa4e62 | m1.large  | 

+--------------------------------------+-----------+------+------+-----------+-------+-----------+



admin 권한으로 접속해 사용할 수 있는(권한을 줄 수 있는) flavor를 확인한다. 

$ openstack flavor list
...
| 66be1e64-2776-4457-a31e-923340e583a2 | r1.xlarge |...
..



여전히 admin 권한으로 66be1e64-2776-4457-a31e-923340e583a2 flavor를 내 프로젝트에 추가한다.

$ openstack flavor set 66be1e64-2776-4457-a31e-923340e583a2 --project GOOGLE_PLUS

그리고 제대로 추가되었는지 확인한다.

 $ openstack --os-project-name KEMI-SAURON flavor list
+--------------------------------------+-----------+-------+------+-----------+-------+-----------+
| ID                                   | Name      |   RAM | Disk | Ephemeral | VCPUs | Is Public |
+--------------------------------------+-----------+-------+------+-----------+-------+-----------+
| 66be1e64-2776-4457-a31e-923340e583a2 | r1.xlarge | 
| 9933ea88-9535-4b04-add8-910e08c01aea | m1.medium | 
| cdb20a75-87a5-43d3-b75b-a5331cad8cb7 | m1.small  | 
| e3739ce3-746c-4e3f-820e-eb9803fa4e62 | m1.large  | 
+--------------------------------------+-----------+-------+------+-----------+-------+-----------+


openstack horizon 또는 cli를 사용할 때 추가된 flavor로 인스턴스를 생성할 수 있다. 







Posted by '김용환'
,