Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.

기술 뉴스 #104 : 18-06-16

웹개발 관련

  • Chrome 64, Node.js v10에서는 GC가 mark하는 동안 앱이 멈추지 않습니다 : Chrome 64에서 GC가 개선된 내용을 설명한 글이다. GC가 정리해야 할 객체를 마킹할 때 JavaScript 실행이 멈추게 되는데 워커 스레드에 이를 위임해서 동시에 처리하면서 앱이 멈추지 않게 65 ~ 70% 정도 시간이 줄어들었다고 한다. 이런 내부 내용을 꼭 알 필요는 없지만, JavaScript 코드를 작성할 때 성능에 영향을 주는 부분이므로 한번 읽어둘 필요는 있다고 생각한다.(한국어)
  • An overview of Visual Studio Code for front-end developers : VS Code를 사용하기 편하게 설정하는 방법을 설명한 글이다. 프론트엔드 플러그인 위주로 설명하고 있지만, 꼭 프론트엔드에 국한된 것은 아니고 폰트나 테마, 터미널 등을 설정해서 VS Code에서 개발하기 편한 환경을 구성하는 방법이 정리되어 있다.(영어)

그 밖의 프로그래밍 관련

  • How to setup Service Discovery in Amazon Elastic Container Service : AWS의 ECS 서비스에서 로드밸런서 대신 Consul을 이용해서 DNS 수준에서 서비스 디스커버리를 이용할 수 있는데 이번에 Route53과 통합되어 서비스 디스커버리를 이용하는 방법에 대한 설명이다. 컨테이너를 쓰면 서비스 디스커버리가 꼭 필요해지는데 다른 설치 없이 사용할 수 있다는 점이 장점으로 보인다.(영어)
  • Hashing in Action: Understanding bcrypt : 비밀번호 해싱에 사용하는 bcrypt에 대해 설명한 글이다. 비밀번호를 해싱할 때 bcrypt의 동작 방식을 단계별로 설명하고 bcrypt가 왜 미래의 하드웨어 발전에도 안전한지를 설명한다. 마지막으로 Node.js 라이브러리로 사용하는 방법을 보여주는데 Node.js를 사용하지 않더라도 언어별로 bcrypt 라이브러리는 있으므로 유용한 글이다.(영어)

볼만한 링크

IT 업계 뉴스

프로젝트

  • prerender-loader : Webpack 빌드시에 초기 HTML 페이지를 정적으로 만들어서 클라이언트에 제공할 수 있게 해주는 모듈.
  • mobx-vue : MobX의 Vue.js 바인딩
  • Polly.JS : Netflix에서 공개한 오픈소스로 HTTP 요청을 녹화해서 다시 실행할 수 있다.
  • Sonar : iOS/Android 앱을 디버깅할 수 있는 데스크톱 플랫폼으로 페이스북이 공개했다.
  • docz : MDX 기반으로 쉽게 문서 페이지를 작성할 수 있는 도구.
  • Vue Native : Vue로 크로스 클랫폼 모바일 앱을 만들 수 있는 프레임워크.
  • CLA Assistant : GitHub에서 코드 기여를 받을 때 라이센스 동의를 받는 CLA를 쉽게 GitHub와 연동해서 검증할 수 있는 서비스.
  • MapKit JS : Apple Maps를 웹에서 사용할 수 있는 JavaScript 라이브러리
  • vivid.js : SVG 아이콘 JavaScript 라이브러리.

버전 업데이트

2018/06/16 05:47 2018/06/16 05:47

Spinnaker를 로컬에서 Kubernetes로 실행하기

Spinnaker는 Netflix에서 만든 지속적 배포 도구다. 프로덕션에서 사용해 본 적은 없지만, AWS나 GCP 같은 퍼블릭 클라우드나 Kubernetes와 통합되어 배포를 할 수 있다. 많은 기능을 제공하는 만큼 꽤 복잡해 보이지만 나 같은 경우는 배포 도구로 테스트를 해본 것은 아니고 Korea Chaos Engineering Community에서 Chaos Monkey를 공부하다 보니 Chaos Monkey가 지금은 Spinnaker와 통합되어 있어서 Spinnaker를 설치해 봤다.

Spinnaker 설치 문서를 보면 Halyard라고 하는 Spinnaker를 관리해주는 도구를 설치해서 설정하는 방법이 나오는데 나는 Spinnaker 자체가 목적이 아니었기 때문에 퍼블릭 클라우드가 아니라 로컬에서 테스트를 해보고 싶었다. 그래서 로컬에서 Spinnaker를 사용해 보기 위해 Spinnaker Chart를 사용했다. 나 같은 경우 Spinnaker의 상세 내용이 궁금한 게 아니라 Chaos Monkey를 테스트해보기 위한 환경으로 Spinnaker가 필요했기 때문에 Chart를 선택했는데 작업하면서 고생을 꽤 많이 해서 나중에 로컬에서 테스트해 볼 수 있도록 따로 정리해둔다.

Spinnaker Chart로 Spinnaker 실행하기

HelmKubernetes의 패키지 관리자이다. Kubernetes에 컨테이너를 배포하려면 여러 가지 리소스를 구성해서 배포하게 되는데 이렇게 복잡한 애플리케이션을 미리 템플릿처럼 구성해 놓은 Chart로 쉽게 배포할 수 있는 도구이다. 여기서 Spinnaker Chart라는 것은 Helm의 Chart로 만들어진 Spinnaker를 얘기한다.

Helm 같은 경우 macOS라면 brew install kubernetes-helm로 설치할 수 있다. Kubernets위에 띄울 것이므로 minikube를 설치하거나 Docker for Mac의 Kubernetes를 활성화 해야 한다.

Helm을 설치했으면 helm init으로 초기화한다.

$ helm init
$HELM_HOME has been configured at /Users/outsider/.helm.

Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.

Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
Happy Helming!

$ helm version
Client: &version.Version{SemVer:"v2.8.2", GitCommit:"a80231648a1473929271764b920a8e346f6de844", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.8.2", GitCommit:"a80231648a1473929271764b920a8e346f6de844", GitTreeState:"clean"}

helm version을 실행해서 결과가 제대로 나오면 잘 초기화된 것이다. Server 같은 경우 시간이 약간 걸리므로 init 후 잠시 기다려야 나오기도 한다.

Docker for mac의 리소스 설정 화면

Spinnaker는 자원을 엄청 많이 먹는다. 그래서 기본 Docker for Mac의 설정으로는 Spinnaker를 띄우다가 죽는 경우가 많다. 컨테이너를 실행할 리소스가 부족하면 컨테이너를 띄우지 못하므로 미리 넉넉하게 CPU와 메모리의 자원을 늘려준다. 위의 설정이 적당한 사이즈를 검증한 것은 아니고 적당히 넉넉하게 준 것일 뿐이다.

Spinnaker Chart 문서를 보면 helm install --name my-release stable/spinnaker로 설치하라고 안내되어 있다. 이렇게 차트를 띄우는 것은 간단하지만 기본 설정에 Chaos Monkey가 활성화되어 있지 않아서 나 같은 경우는 삽질을 꽤 많이 했다. 이 글에서는 Chaos Monkey를 설명하는 것이 아니므로 Spinnaker를 실행하는 것만 다루겠다.

$ helm install --name chaos --timeout 900 stable/spinnaker
NAME:   chaos
LAST DEPLOYED: Tue Jun 12 03:08:08 2018
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME                              DATA  AGE
chaos-jenkins                     3     4m
chaos-jenkins-tests               1     4m
chaos-minio-config-cm             1     4m
chaos-jenkins-jobs                3     4m
chaos-spinnaker-s3-config         1     4m
chaos-spinnaker-spinnaker-config  18    4m
chaos-spinnaker-tests             1     4m

==> v1/PersistentVolumeClaim
NAME           STATUS  VOLUME                                    CAPACITY  ACCESS MODES  STORAGECLASS  AGE
chaos-jenkins  Bound   pvc-6522cfd5-6da2-11e8-b627-025000000001  8Gi       RWO           hostpath      4m
chaos-minio    Bound   pvc-65235644-6da2-11e8-b627-025000000001  10Gi      RWO           hostpath      4m
chaos-redis    Bound   pvc-6523d704-6da2-11e8-b627-025000000001  8Gi       RWO           hostpath      4m

==> v1/Service
NAME                         TYPE       CLUSTER-IP      EXTERNAL-IP  PORT(S)                      AGE
chaos-jenkins-agent          ClusterIP  10.110.153.209  <none>       50000/TCP                    4m
chaos-jenkins                ClusterIP  10.99.241.101   <none>       8080/TCP                     4m
chaos-minio-svc              ClusterIP  10.103.164.250  <none>       9000/TCP                     4m
chaos-redis                  ClusterIP  10.100.92.62    <none>       6379/TCP                     4m
chaos-spinnaker-clouddriver  ClusterIP  10.101.226.217  <none>       7002/TCP                     4m
chaos-spinnaker-deck         ClusterIP  10.103.122.125  <none>       9000/TCP                     4m
chaos-spinnaker-echo         ClusterIP  10.97.63.191    <none>       8089/TCP                     4m
chaos-spinnaker-front50      ClusterIP  10.106.231.178  <none>       8080/TCP                     4m
chaos-spinnaker-gate         ClusterIP  10.110.68.76    <none>       8084/TCP                     4m
chaos-spinnaker-igor         ClusterIP  10.107.135.157  <none>       8088/TCP,8080/TCP,50000/TCP  4m
chaos-spinnaker-orca         ClusterIP  10.105.37.76    <none>       8083/TCP                     4m
chaos-spinnaker-rosco        ClusterIP  10.110.171.251  <none>       8087/TCP                     4m

==> v1beta1/Deployment
NAME                         DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
chaos-jenkins                1        1        1           1          4m
chaos-minio                  1        1        1           1          4m
chaos-redis                  1        1        1           1          4m
chaos-spinnaker-clouddriver  1        1        1           1          4m
chaos-spinnaker-deck         1        1        1           1          4m
chaos-spinnaker-echo         1        1        1           1          4m
chaos-spinnaker-front50      1        1        1           1          4m
chaos-spinnaker-gate         1        1        1           1          4m
chaos-spinnaker-igor         1        1        1           1          4m
chaos-spinnaker-orca         1        1        1           1          4m
chaos-spinnaker-rosco        1        1        1           1          4m

==> v1/Pod(related)
NAME                                          READY  STATUS   RESTARTS  AGE
chaos-jenkins-6f5c947578-qkzx2                1/1    Running  0         4m
chaos-minio-cf6479bbd-lq8fv                   1/1    Running  0         4m
chaos-redis-845456446f-shd6z                  1/1    Running  0         4m
chaos-spinnaker-clouddriver-5984568f6d-tgrb4  1/1    Running  0         4m
chaos-spinnaker-deck-5d7c958b48-xmhmg         1/1    Running  0         4m
chaos-spinnaker-echo-79dcfd57b6-lkh9w         1/1    Running  0         4m
chaos-spinnaker-front50-56d67686cd-dlfmn      1/1    Running  1         4m
chaos-spinnaker-gate-57ccc7d564-vt6bl         1/1    Running  2         4m
chaos-spinnaker-igor-9bb764469-9pcs9          1/1    Running  0         4m
chaos-spinnaker-orca-9cb74c84c-6lz2j          1/1    Running  0         4m
chaos-spinnaker-rosco-f67886cc5-58z7m         1/1    Running  0         4m

==> v1/Secret
NAME                      TYPE    DATA  AGE
chaos-jenkins             Opaque  2     4m
chaos-minio-user          Opaque  2     4m
chaos-redis               Opaque  1     4m
chaos-spinnaker-registry  Opaque  1     4m


NOTES:
1. You will need to create 2 port forwarding tunnels in order to access the Spinnaker UI:
  export DECK_POD=$(kubectl get pods --namespace default -l "component=deck,app=chaos-spinnaker" -o jsonpath="{.items[0].metadata.name}")
  kubectl port-forward --namespace default $DECK_POD 9000

2. Visit the Spinnaker UI by opening your browser to: http://127.0.0.1:9000

For more info on the Kubernetes integration for Spinnaker, visit:
  http://www.spinnaker.io/docs/kubernetes-source-to-prod

Spinnaker를 실행하기 위해서 상당히 많은 리소스가 실행된 것을 볼 수 있다. 실행 환경의 사양에 따라 다르겠지만 앞에서 설명한 Docker의 자원을 늘려주지 않으면 실행하다가 실패하는 경우가 많았고 helm의 기본 타임아웃이 300인데 이 시간 내에 안 뜨는 경우도 많아서 시간을 늘려주었다.

Chart가 제대로 떴으면 마지막에 안내가 나온 대로 명령어를 실행한다.

$ export DECK_POD=$(kubectl get pods --namespace default -l "component=deck,app=chaos-spinnaker" -o jsonpath="{.items[0].metadata.name}")

$ kubectl port-forward --namespace default $DECK_POD 9000

이제 브라우저에서 http://127.0.0.1:9000에 접속해 보면 Spinnaker를 확인해 볼 수 있다.

Spinnaker 화면

2018/06/12 11:32 2018/06/12 11:32