Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

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