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

[python] whois 모듈

python 2018. 9. 3. 14:24


python의 whois 모듈을 사용하면 whois 웹 검색과 동일한 결과를 얻을 수 있다..




$ pip install python-whois



$ python

Python 3.7.0 (default, Sep  3 2018, 12:00:39)

[Clang 7.3.0 (clang-703.0.31)] on darwin

Type "help", "copyright", "credits" or "license" for more information.




>>> import whois

>>> print(whois.whois('appspot.com'))


{

  "domain_name": [

    "APPSPOT.COM",

    "appspot.com"

  ],

  "registrar": "MarkMonitor, Inc.",

  "whois_server": "whois.markmonitor.com",

  "referral_url": null,

  "updated_date": [

    "2018-02-06 10:30:28",

    "2018-02-06 02:30:29-08:00"

  ],

  "creation_date": [

    "2005-03-10 02:27:55",

    "2005-03-09 18:27:55-08:00"

  ],

  "expiration_date": [

    "2019-03-10 01:27:55",

    "2019-03-09 00:00:00-08:00"

  ],

  "name_servers": [

    "NS1.GOOGLE.COM",

    "NS2.GOOGLE.COM",

    "NS3.GOOGLE.COM",

    "NS4.GOOGLE.COM",

    "ns1.google.com",

    "ns2.google.com",

    "ns4.google.com",

    "ns3.google.com"

  ],

  "status": [

    "clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited",

    "clientTransferProhibited https://icann.org/epp#clientTransferProhibited",

    "clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited",

    "serverDeleteProhibited https://icann.org/epp#serverDeleteProhibited",

    "serverTransferProhibited https://icann.org/epp#serverTransferProhibited",

    "serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited",

    "clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)",

    "clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited)",

    "clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)",

    "serverUpdateProhibited (https://www.icann.org/epp#serverUpdateProhibited)",

    "serverTransferProhibited (https://www.icann.org/epp#serverTransferProhibited)",

    "serverDeleteProhibited (https://www.icann.org/epp#serverDeleteProhibited)"

  ],

  "emails": [

    "abusecomplaints@markmonitor.com",

    "whoisrelay@markmonitor.com"

  ],

  "dnssec": "unsigned",

  "name": null,

  "org": "Google LLC",

  "address": null,

  "city": null,

  "state": "CA",

  "zipcode": null,

  "country": "US"

}

>>> print(whois.whois('naver.com'))

{

  "domain_name": [

    "NAVER.COM",

    "naver.com"

  ],

  "registrar": "Gabia, Inc.",

  "whois_server": "whois.gabia.com",

  "referral_url": null,

  "updated_date": [

    "2016-08-05 06:37:57",

    "2018-02-28 11:27:15"

  ],

  "creation_date": [

    "1997-09-12 04:00:00",

    "1997-09-12 00:00:00"

  ],

  "expiration_date": [

    "2023-09-11 04:00:00",

    "2023-09-11 00:00:00"

  ],

  "name_servers": [

    "NS1.NAVER.COM",

    "NS2.NAVER.COM",

    "ns1.naver.com",

    "ns2.naver.com"

  ],

  "status": [

    "clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited",

    "clientTransferProhibited https://icann.org/epp#clientTransferProhibited",

    "clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited",

    "ok https://icann.org/epp#ok"

  ],

  "emails": [

    "white.4818@navercorp.com",

    "dl_ssl@navercorp.com",

    "abuse@gabia.com"

  ],

  "dnssec": "unsigned",

  "name": "NAVER Corp.",

  "org": "NAVER Corp.",

  "address": "6 Buljung-ro, Bundang-gu, Seongnam-si, Gyeonggi-do, 463-867, Korea",

  "city": "Gyeonggi",

  "state": null,

  "zipcode": "463463",

  "country": "KR"

}

>>> print(whois.whois('abc.com'))

{

  "domain_name": [

    "ABC.COM",

    "abc.com"

  ],

  "registrar": "CSC CORPORATE DOMAINS, INC.",

  "whois_server": "whois.corporatedomains.com",

  "referral_url": null,

  "updated_date": [

    "2018-08-08 23:38:25",

    "2018-08-08 17:11:02"

  ],

  "creation_date": "1996-05-22 04:00:00",

  "expiration_date": "2019-05-23 04:00:00",

  "name_servers": [

    "ORNS01.DIG.COM",

    "ORNS02.DIG.COM",

    "SENS01.DIG.COM",

    "SENS02.DIG.COM",

    "orns02.dig.com",

    "orns01.dig.com",

    "sens02.dig.com",

    "sens01.dig.com"

  ],

  "status": [

    "clientTransferProhibited https://icann.org/epp#clientTransferProhibited",

    "serverDeleteProhibited https://icann.org/epp#serverDeleteProhibited",

    "serverTransferProhibited https://icann.org/epp#serverTransferProhibited",

    "serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited",

    "clientTransferProhibited http://www.icann.org/epp#clientTransferProhibited",

    "serverDeleteProhibited http://www.icann.org/epp#serverDeleteProhibited",

    "serverTransferProhibited http://www.icann.org/epp#serverTransferProhibited"

  ],

  "emails": [

    "domainabuse@cscglobal.com",

    "Corp.DNS.Domains@disney.com"

  ],

  "dnssec": "unsigned",

  "name": "ABC, Inc.; Domain Administrator",

  "org": "ABC, Inc.",

  "address": "77 West 66th Street",

  "city": "New York",

  "state": "NY",

  "zipcode": "10023-6298",

  "country": "US"

}



Posted by '김용환'
,



Microservices A Practical Guide를 번역 완료했다. 



https://leanpub.com/microservices-recipes



https://www.amazon.com/Microservices-Practical-Guide-Eberhard-Wolff/dp/1717075908









처음에 클라우드 개발 팀에 합류할 때 처음에 많이 당황했었다. 


그동안 사내 장비만 가지고 Monolithic한 사고 방식으로 많은 개발 방식을 가지고 있었던 지라...개발 방법론이 달랐던 것에 당황했다. 자바 주도적인 개발에서 폴리그랏 마이크로 서비스 개발 방식으로 잘 배워야겠다라는 마음 가짐이 생겼다.


이전 조직에서 ruby, python, R언어도 나름 쓰고 있었지만. 클라우드 개발 팀은 (내 생전 처음 본) 오픈 소스들을 사용하고 있었고 특히 go언어, 고급스러운 python 코딩을 하고 있었다. 많이 그 동안 내가 알던 세계를 떠나오길 잘했다 라는 생각이 들었다.


클라우드/마이크로 서비스는 점점 많이 사용될 것 같다.

그리고 마이크로 서비스 개발 / 비동기 철학에 대한 많은 이해가 보편화될 것 같다.


그런 시대적인 상황에서 이 책을 만나게 되었다.


마이크로 서비스 아키텍처와 오픈 소스, 통신 방법, DDD에 대한 설명이 잘 담겨 있어서 개발자라면 꼭 봐야할 것 같다. 예시를 step-by-step 으로 천천히 설명하지는 않지만 예시 프로젝트를 실행하고 데모를 실행할 때 오는 좋은 충격은 너무 좋았다!!



처음 이 책을 번역해 달라는 출판사의 요청을 거절했었다. 영어 품질이 조금 좋지 않았지만 우려와 달리 생각보다 굉장히 Practical했고.. 저자의 마이크로 서비스 아키텍트에 대한 의도를 느낄 수 있어서 좋았다. 


(내 경험상) 'Spring 마이크로 서비스' 책 보다는 이 책이 더 나은 것 같다는 생각이 들었다. 


아키텍트, 개발자가 쓱쓱 보기에 괜찮은 책인 것 같다.










Posted by '김용환'
,