Outsider's Dev Story

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

Hylyard로 Spinnaker를 Kubernetes에 설치하기

전에 CD(Continuous Delivery) 도구인 Spinnaker를 테스트해 보려고 Docker for Mac에서 kubernetes를 사용해 봤는데 본격적으로 사용해 보려고 하니 클라우드에서 테스트를 해보고 싶었다. 이전에는 Spinnaker가 목적이 아니라 Chaos Monkey가 목적이라서 로컬에서 테스트했지만, Spinnaker 자체를 보려고 하니 실제 프로덕션에서는 어떻게 동작하는 지도 관심이 갔다.

처음에는 데모/평가용 설치를 해보려고 했지만 Google Cloud Launcher로 실행해 보려고 했지만, GCP를 잘 몰라서 그런지 제대로 실행 안 되는 문제를 도저히 해결할 수 없어서 실제 프로덕션 환경과 똑같이 설치하는 쪽으로 넘어갔다.

Spinnaker 관리 도구 Halyard 설치하기

Spinnaker를 프로덕션 환경에서 설치하려면 Spinnaker를 관리하는 Halyard라는 도구를 설치해야 한다. 문서에 따르면 로컬에 설치하거나 Docker를 이용해서 사용할 수 있는 것 같은데 Docker를 이용하면 생각지 못한 문제를 겪을 것 같아서 나는 로컬에 직접 Halyard를 설치했다. 참고로 Halyard는 Linux와 macOS에만 설치 가능한 것으로 보인다.

먼저 Hylyard 설치 스크립트를 다운 받는다.

$ curl -O https://raw.githubusercontent.com/spinnaker/halyard/master/install/macos/InstallHalyard.sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  4420  100  4420    0     0  11282      0 --:--:-- --:--:-- --:--:-- 11304

다운받은 스크립트를 실행한다. 참고로 Hylyard를 설치하려면 Java 8 이상이 필요하고 설치되어 있지 않다면 Java >=8 not yet installed - please install java >=8. 오류가 발생한다.

$ $ sudo bash InstallHalyard.sh
Halyard version will be stable
Halconfig will be stored at /Users/jeonghunbyeon/.hal/config
Uninstall script is located at /Users/jeonghunbyeon/.hal/uninstall.sh
Java is already installed & at the right version
~/bin/installhalyard.fbmx ~/bin
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  186M  100  186M    0     0  19.7M      0  0:00:09  0:00:09 --:--:-- 19.8M
x halyard/
x halyard/config/
x halyard/config/halyard.yml
x halyard/lib/
x halyard/lib/aws-java-sdk-lex-1.11.251.jar
... 중략 ...
x halyard/bin/hal.bat
x halyard/bin/halyard.bat
x halyard/bin/hal
x halyard/bin/halyard
x hal
x update-halyard
~/bin
The halyard daemon isn't running yet... starting it manually...
1.6.0-20180806143444

제대로 설치되었는지 다음 명령어로 확인해 볼 수 있다.

$ hal -v
1.6.0-20180806143444


GKE에 Spinnaker 설치하기

Halyard가 Spinnaker의 생명주기를 관리해 주기 때문에 다양한 환경에 설치할 수 있다.(Spinnaker가 Kubernetes에 맞춰진 도구는 아니다.) 문서를 보면 EKS, GKE 뿐만 아니라 DC/OS, Google App Engine, AWS 등 다양한 환경에 설치할 수 있고 나 같은 경우는 Kubernetes와 사용해 보려는 것이 목적이었기 때문에 Kubernetes Provider V2 (Manifest Based)를 선택했다. 어차피 Kubernetes와 연동해서 사용하면 Kubernetes가 어디에 설치되어 있는가는 큰 상관이 없으므로 AWS EKS나 Google GKE인가에 상관없이 "Kubernetes (legacy provider)"와 "Kubernetes Provider V2 (Manifest Based)"로만 나뉘게 된다.

Spinnaker를 Kubernests와 함께 사용할 만한지 확인해 보려는 게 목적이었으므로 GKE에 Kubernetes 클러스터를 생성하고 Spinnaker 설치에 들어갔다.

설치한 GKE 클러스터를 kubectl이 컨텍스트로 사용하도록 gcloud로 인증정보를 가져온다.

$ gcloud container clusters get-credentials spinnaker-test
Fetching cluster endpoint and auth data.
kubeconfig entry generated for spinnaker-test.

kubectl로 확인해도 같은 컨텍스트를 보고 있는 걸 알 수 있다.

$ kubectl config get-contexts
CURRENT   NAME                                                 CLUSTER                                              AUTHINFO                                             NAMESPACE
          docker-for-desktop                                   docker-for-desktop-cluster                           docker-for-desktop
*         gke_devenv-205606_asia-northeast1-a_spinnaker-test   gke_devenv-205606_asia-northeast1-a_spinnaker-test   gke_devenv-205606_asia-northeast1-a_spinnaker-test
          tf_gke_devenv-205606_asia-northeast1-a_sebak-test    tf_gke_devenv-205606_asia-northeast1-a_sebak-test    tf_gke_devenv-205606_asia-northeast1-a_sebak-test

이후 설치 과정을 따라가다 보니 spinnaker라는 네임스페이스를 사용하는 것 같아서 네임스페이스를 새로 생성했다. 이는 실제로 운영하면서 다시 확인해 봐야 한다. 네임스페이스를 만들려고 ns.json 파일을 다음과 같이 만든다.

{
  "kind": "Namespace",
  "apiVersion": "v1",
  "metadata": {
    "name": "spinnaker",
    "labels": {
      "name": "spinnaker"
    }
  }
}

정의한 네임스페이스를 Kubernetes에 생성한다.

$ kubectl create -f ns.json
namespace "spinnaker" created

Kubernetes 프로바이더를 활성화한다.

$ hal config provider kubernetes enable
The halyard daemon isn't running yet... starting it manually...
+ Get current deployment
  Success
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.fasterxml.jackson.databind.util.ClassUtil (file:/opt/halyard/lib/jackson-databind-2.8.8.jar) to constructor java.lang.Void()
WARNING: Please consider reporting this to the maintainers of com.fasterxml.jackson.databind.util.ClassUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
+ Edit the kubernetes provider
  Success
+ Successfully enabled kubernetes

k8s-account라는 이름으로 어카운트를 설정한다.

$ hal config provider kubernetes account add k8s-account \
     --provider-version v2 \
     --context $(kubectl config current-context)
+ Get current deployment
  Success
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.fasterxml.jackson.databind.util.ClassUtil (file:/opt/halyard/lib/jackson-databind-2.8.8.jar) to constructor java.lang.Void()
WARNING: Please consider reporting this to the maintainers of com.fasterxml.jackson.databind.util.ClassUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
+ Add the k8s-account account
  Success
+ Successfully added account k8s-account for provider
  kubernetes.

아티팩트를 활성화한다.

$ hal config features edit --artifacts true
+ Get current deployment
  Success
+ Get features
  Success
- No changes supplied.

이제 환경을 선택하라고 나오는데 환경으로는 "Distributed installation", "Local installations", "Local git installations"가 있다. 나같은 경우는 Kubernetes에 설치할 것이므로 "Distributed installation"를 선택했다. 환경설정을 위해 ACCOUNT 환경변수를 설정하고 아래 명령어를 실행한다.

$ ACCOUNT=k8s-account

$  hal config deploy edit --type distributed --account-name $ACCOUNT
+ Get current deployment
  Success
+ Get the deployment environment
  Success
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.fasterxml.jackson.databind.util.ClassUtil (file:/opt/halyard/lib/jackson-databind-2.8.8.jar) to constructor java.lang.Void()
WARNING: Please consider reporting this to the maintainers of com.fasterxml.jackson.databind.util.ClassUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
+ Edit the deployment environment
  Success
+ Successfully updated your deployment environment.

다음은 Spinnaker의 설정 등을 관리할 스토리지를 설정해 주어야 한다. AWS S3, Redis, Google Cloud Storage(GCS) 등을 선택할 수 있는데 어차피 GKE로 설정하고 있으므로 GCS를 선택했다.

GCS 스토리지를 설정한다.

$ PROJECT=$(gcloud info --format='value(config.project)')
$ BUCKET_LOCATION=asia
$ SERVICE_ACCOUNT_DEST=/Users/jeonghunbyeon/boscoin/infrastructure/gcp/test2-env/credentials.json

$ hal config storage gcs edit --project $PROJECT \
    --bucket-location $BUCKET_LOCATION \
    --json-path $SERVICE_ACCOUNT_DEST
+ Get current deployment
  Success
+ Get persistent store
  Success
- No changes supplied.

스토리지 소스를 GCS로 지정한다.

$ hal config storage edit --type gcs
+ Get current deployment
  Success
+ Get persistent storage settings
  Success
- No changes supplied.

이제 설정이 끝났으니 정말 Spinnaker를 배포할 차례이다. 다음 명령어로 배포할 Spinnaker 버전을 확인할 수 있다.

$ hal version list
+ Get current deployment
  Success
+ Get Spinnaker version
  Success
+ Get released versions
  Success
+ You are on version "1.8.5", and the following are available:
 - 1.6.2 (GLOW):
   Changelog: https://gist.github.com/spinnaker-release/3fc52e64bae26f8ea1c68bcd8383d4b5
   Published: Fri Jul 27 06:55:31 KST 2018
   (Requires Halyard >= 0.41.0)
 - 1.7.7 (Ozark):
   Changelog: https://gist.github.com/spinnaker-release/8fa68517da00675a028dbd62c72d6748
   Published: Fri Jul 27 06:28:03 KST 2018
   (Requires Halyard >= 1.0.0)
 - 1.8.4 (Dark):
   Changelog: https://gist.github.com/spinnaker-release/ad1c07a861e61c1d4777da7b5c6bda24
   Published: Fri Jul 27 07:04:25 KST 2018
   (Requires Halyard >= 1.0.0)
 - 1.8.5 (Dark):
   Changelog: https://gist.github.com/spinnaker-release/19a850b9081d0fd00a9ac607dfc3d8e0
   Published: Fri Aug 03 05:40:52 KST 2018
   (Requires Halyard >= 1.0.0)

테스트에서 최신 버전을 사용하지 않을 이유가 없으므로 1.8.5를 선택하고 버전을 설정한다.

$ VERSION=1.8.5
$ hal config version edit --version $VERSION
+ Get current deployment
  Success
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.fasterxml.jackson.databind.util.ClassUtil (file:/opt/halyard/lib/jackson-databind-2.8.8.jar) to constructor java.lang.Void()
WARNING: Please consider reporting this to the maintainers of com.fasterxml.jackson.databind.util.ClassUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
+ Edit Spinnaker version
  Success
+ Spinnaker has been configured to update/install version "1.8.5".
  Deploy this version of Spinnaker with `hal deploy apply`.

설정이 끝났으므로 Spinnaker를 배포한다.

$ hal deploy apply
+ Get current deployment
  Success
+ Prep deployment
  Success
Problems in default.security:
- WARNING Your UI or API domain does not have override base URLs
  set even though your Spinnaker deployment is a Distributed deployment on a
  remote cloud provider. As a result, you will need to open SSH tunnels against
  that deployment to access Spinnaker.
? We recommend that you instead configure an authentication
  mechanism (OAuth2, SAML2, or x509) to make it easier to access Spinnaker
  securely, and then register the intended Domain and IP addresses that your
  publicly facing services will be using.

+ Preparation complete... deploying Spinnaker
+ Get current deployment
  Success
+ Apply deployment
  Success
+ Run `hal deploy connect` to connect to Spinnaker.

설치 중에 인증과 관련해서 안내 메시지가 나오지만 여기서는 일단 설치해서 테스트해보는 것이 목적이므로 그냥 넘어간다. 프로덕션에서 실제 배포 도구로 사용하려면 세세한 설정을 손봐야 할 것 같다.

설치가 끝났으므로 설치한 Spinnaker에 접속해 보자. 그냥은 접속되지 않으므로 다음 명령어로 Kubernetes에 설치한 Spinnaker에 접속할 수 있다. 이 명령어가 로컬에서 Kubernetes 클러스터로 터널링을 해주는 거로 보인다.

$ hal deploy connect
+ Get current deployment
  Success
+ Connect to Spinnaker deployment.
  Success
Forwarding from 127.0.0.1:8084 -> 8084
Forwarding from [::1]:8084 -> 8084
Forwarding from 127.0.0.1:9000 -> 9000
Forwarding from [::1]:9000 -> 9000

9000 포트는 Spinnaker의 관리 UI인 Deck이고 8084 포트는 API 게이트웨이인 gate이다.

http://localhost:9000/로 접속하면 다음과 같이 Spinnaker 화면을 볼 수 있다.

Spinnaker UI

글이 길어져서 Spinnaker로 배포 설정하는 부분은 좀 더 공부해보고...

2018/08/16 02:52 2018/08/16 02:52

기술 뉴스 #108 : 18-08-15

웹개발 관련

  • Google AMP — A 70% drop in our conversion rate. : 자사의 웹사이트에 AMP를 도입한 후 문제점을 지적한 글이다. 초기 의욕적으로 빠른 웹사이트를 위해 AMP를 도입했지만 Google의 프레임 속에 나오기 때문에 피싱 사이트처럼 보이고 구글 CDN을 통해서 제공되기 때문에 문제점을 찾기위한 디버깅이 쉽지 않으며 전환율을 올리기 위한 노력도 웹사이트와 따로 AMP를 위해서 새로 해야 한다고 하고 있다. 모두 AMP 때문은 아니겠지만 전환율이 70% 줄어들었다고 한다.(영어)
  • The Cost Of JavaScript In 2018 : 웹사이트에서 자바스크립트 용량이 크면 비용이 얼마나 많이 드는지 설명한 글이다. 브라우저가 자바스크립트를 어떻게 처리하고 있고 평균 모바일 디바이스와 네트워크 속도를 고려했을 때의 영향을 생각하면 사용자가 실제로 웹사이트를 사용하는데 걸리는 시간(Time to Interactive)이 얼마나 중요한지 설명하고 있다. 마지막으로 Code Sptting을 이용하고 Lighthouse 등을 이용해서 어떻게 JavaScript 파일의 용량을 줄 일 수 있는지 설명하고 있다. 글이 상당히 길지만, 전체적으로 파악하기 좋은 내용이다.(영어)
  • 난 React와 Vue에서 완전히 똑같은 앱(todo)을 만들었다. 여기 그 차이점이 있다.(번역글) : 얼마전 소개한 I created the exact same app in React and Vue. Here are the differences.의 번역 글로 React와 Vue로 todo앱을 만들면서 차이점을 비교한 글이다.(한국어)
  • 타입스크립트, 써야 할까? : 타입스크립트를 써야 하는 이유를 정리한 글로 러닝 커브, 생산성, 안정성, 커뮤니티 등의 관점으로 설명하고 있다. 개인적으로 타입스크립트를 좋아하진 않는 편이지만 타입스크립트가 줄 수 있는 장점과 부족한 점이 잘 정리되어 있다.(한국어)
  • Introducing Electron Fiddle : 코드스니펫을 쉽게 공유하는 Fiddle 서비스처럼 쉽게 코드를 테스트해볼 수 있도록 Electron Fiddle의 초기 버전이 공개되었다. 아직 개발 중이다.(영어)

그 밖의 프로그래밍 관련

블록체인 관련

  • ERC Token Standards for Dummies, Like Me : 이더리움을 이용해서 토큰을 만들 때 많이 사용하는 ERC 20를 설명하는 글이다. ERC(Ethereum Request for Comment) 20가 어떤 구조로 되어있고 솔리디티로 어떻게 사용하는지를 설명하고 ERC 20에서 잘못 트랜잭션을 만들었을 때 묶여버려서 토큰을 사용할 수 없게 되는 문제를 해결하는 ERC 223와 ERC 827이 각각 어떻게 다른지를 설명하고 있다. ERC 20를 보기만 하다가 그 기본 내용에 대해 이해하기 좋은 글이다.(영어)
  • What we learned building our first Ethereum Dapp : Ethereum과 Solidity 개발을 배우려고 사이드 프로젝트로 Ethereum Dapp을 만든 경험을 공유한 글이다. 학습 용도에 맞는 요구사항에 따라 픽셀을 광고판처럼 파는 Eth Plot을 만들고 이때 사용한 스마트 콘트랙트, IFPS, Truffle, Ganache, MetaMask 등의 스택을 설명하고 가장 중요한 부분인 스마트 콘트랙트를 어떻게 개발했는지 자세히 설명하고 있다.(영어)
  • Dweb 소개 : 중앙화된 웹이 아니라 분산화된 웹이라는 개념으로 Dweb을 소개한 글로 현재 2편까지 공개되어 있다. 블록체인을 얘기하고 있진 않은데 원래의 웹은 분산화하려고 나왔지만, 지금은 중앙화되었다는 점에서 관심 있는 접근방법이다.(한국어)

볼만한 링크

  • 하스스톤x프로듀스48 사건으로 보는 마케팅이야기 : 프로듀스48에서 자신이 응원하는 아이돌에 투표하도록 여러 가지 마케팅을 하다가 하스스톤 사용자에게 팩을 사주고 투표 인증을 요구하면서 진행된 과정을 설명한 글이다. 이런 일이 있었는지 몰랐지만 이런 식의 재치있는 마케팅을 좋아하는지라 재미있게 보았다.(한국어)
  • Pseudo Localization @ Netflix : 하면서 영어로 작성된 메뉴나 문구 등이 다른 언어로 번역되면서 40% 이상 길어져서 레이아웃이 깨지는 문제를 Netflix가 어떻게 개선했는지 설명한 글이다. Pseudo Localization라고 Find Help Online라는 문구를 영어처럼 읽을 수 있는 ASCII 문자 [ƒîกี้ð Ĥéļþ Öกี้ļîกี้é one two]로 변환해서 실제 번역문은 아니지만 길어진 텍스트를 바로 테스트해 볼 수 있도록 개선한 애기이다. 마지막에는 이렇게 만든 시스템을 각 조직에 적용할 수 있도록 홍보하고 교육하는 부분도 중요하다고 강조하고 있다.(영어)

IT 업계 뉴스

  • Gerald M. Weinberg has died : "프로그래밍 심리학", "대체 뭐가 문제야?", "테크니컬 리더" 등의 책을 쓴 제럴드 M. 와인버그가 8월 7일 86세의 나이로 별세했다. 삼가 고인의 명복을 빕니다.(영어)

프로젝트

  • The Open Guide to Amazon Web Services : AWS의 각 서비스의 사용방법과 팁을 모아놓은 저장소.
  • lazygit : 터미널에서 UI로 Git을 사용할 수 있는 도구.
  • Filament : 안드로이드, 리눅스, macOS, 윈도우즈에서 사용할 수 있는 렌더링 엔진으로 구글이 만들었다.

버전 업데이트

2018/08/15 19:39 2018/08/15 19:39