LoginSignup
30
28

More than 5 years have passed since last update.

AWSでSpinnakerを構築しよう[手順解説]

Last updated at Posted at 2019-04-19

概要

スクリーンショット 2019-04-19 21.20.43.png

Spinnakerとは、NetflixとGoogleを中心に開発されている、マルチクラウドに対応した継続的デリバリー(CD)ツールです。カナリアリリースやB/Gデプロイ、承認制デプロイといった仕組みをカンタンに実現できるそうです。
業務で調査する機会を頂いたので試してみました。

今回はAWS上でSpinnakerを試してみたいという方向けに、Spinnakerサーバを構築する手順を解説します。AWSではSpinnakerのQuickstartが用意されていますが、あまり保守されておらず手順通りに実行しても正常に動作しません(少なくとも私が確認した限りでは…)。そこで、Spinnaker公式のドキュメント「Set up Spinnaker」を利用します。しかし、こちらもひとクセある&ネット上にAWS×Spinnakerの事例がほとんどない状態で苦労します(しました)。これから試したいという方がスムーズにできるように解説していきます。

構築にあたって、HalyardというSpinnaker用のCLIツールを使います。Spinnakerは複数のコンポーネントで構築されているのですが、Halyardを通じてそれらの設定やデプロイを行うことができます。

この解説書を実行すると、最終的に以下のリソースが立ち上がります。AWSの操作方法さえわかれば割と簡単に構築できるので是非試してみてください。

spinnaker.png

1章 Spinnaker用にAWS環境を構築する

この章では、Spinnakerを動かすための基盤を作っていきます。具体的には、VPCやサブネット、IAM Roleといったリソースで構成されています。これらのリソースはSpinnakerの公式が用意しているCloudFormationのテンプレートを用いて作ります。テンプレートは「Spinnaker - Amazon EC2」の2. Download the template locally to your workstation.というところから2つ取得します。

取得したテンプレートである「Managing.yml」と「Managed.yml」をざっくりと説明します。

  • Managing.yml : Spinnakerサーバを動作させるための基盤および認証要素を作成する
  • Managed.yml : Spinnakerサーバの管理対象となるリソースの認証要素を作成する

これらのテンプレートを実行すると以下の赤枠部分のリソースが作られることになります。ちなみにこの手順では、米国西部(オレゴン us-west-2)で作成します。

スクリーンショット_2019-04-18_21_30_33.png

引用元:Spinnaker - Set up AWS Overview

1-1.Managing.ymlのスタックを構築します

Managing.ymlを使ってスタックを作っていきます。パラメータは以下のように設定しましょう。

Key Value 備考
スタックの名前 任意
EksClusterName None SpinnakerサーバにEKSを利用する場合はリソース名を入力します。今回は必要とする知識が少ないEC2を選択するので、Noneにします。
SpinnakerPublicSubnet1CIDR 10.100.10.0/24
SpinnakerPublicSubnet2CIDR 10.100.11.0/24
SpinnakerVPCCIDR 10.100.0.0/16
UseAccessKeyForAuthentication false SpinnakerサーバからAWS上のリソースへの認証方法を決めます。trueはアクセスキーを用います。falseはIAM Roleを用います。
UserAccessKeyForAuthenticationについて

AWSの認証に関するベストプラクティスでは、アクセスキーではなく IAM Roleの使用が推奨されています。
これに倣って、今回はIAM Role(false)を使用します。実際アクセスキーよりもIAM Roleの方が管理の手間が省けて楽です。
アクセスキーのパターンも試しましたが、CFnテンプレートに不備があるため修正が必要でした。(テンプレートの分岐処理がちゃんとできていれば修正作業は不要なはずなんですが、まだそこまで整備されていないようです。)
cf.AWS アクセスキーを管理するためのベストプラクティス

設定を終えたら、スタックを作成しましょう。
なお、このスタックではVPCを作成することになるため、作業するアカウントによっては権限が不足でエラーになる可能性があります。
その場合は、アカウントを切り替えるかVPC作成権限のついたcfnのIAM Roleで実行するようにしてください。

tips:スタック作成時に、BaseIAMRoleの重複によるエラーが起きた場合

既にAWS内にBaseIAMRoleがある場合、リソースが重複してCfnの実行が止まってしまうためエラーになっています。
まず、Managing.ymlBaseIAMRoleをコメントアウトします。

Managing.yml
 Resources:

  # BaseIAMRole:
  #   Properties:
  #     RoleName: BaseIAMRole
  #     AssumeRolePolicyDocument:
  #       Statement:
  #         - Action:
  #             - sts:AssumeRole
  #           Effect: Allow
  #           Principal:
  #             Service:
  #               - ec2.amazonaws.com
  #       Version: '2012-10-17'
  #     Path: /
  #   Type: AWS::IAM::Role

続いてBaseInstanceProfileのRolesをRole名で指定します。(94行目)
これは、既にAWSを上にBaseIAMRoleが存在するため、テンプレートからではなくAWS上のリソース名で指定する必要があるためです。

Managing.yml
  # Creates Instance Profile to be used by any APP created by Spinnaker. Spinnaker has passRole access only to this instance Profile
  BaseInstanceProfile:
      DependsOn: SpinnakerAuthRole
      Condition: CreateEc2Role
      Properties:
        InstanceProfileName: BaseInstanceProfile
        Path: /
        Roles:
          - BaseIAMRole
      Type: AWS::IAM::InstanceProfile

1-2. Managed.ymlのスタックを構築します

次にManaged.ymlからスタックを作っていきます。
以下参考に入力してください。

Key Value 備考
スタックの名前 任意 cfn上での識別するためのものなのであまり深く考えなくてOKです
AuthArn 例:arn:aws:iam::1234567890:role/SpinnakerAuthRole Managing テンプレートの出力からコピー
ManagingAccountId 例:1234567890 Managing テンプレートの出力からコピー

なお、ここで入力するパラメータはManaging.ymlで作ったスタックの出力欄からコピペしてきましょう。
スクリーンショット_2019-04-19_21_41_24.png

値の入力が完了したら、スタックの作成をします。以上でCloudFormation上に「Managing」と「Managed」の2つのスタックが構築されました。

2章 Spinnaker用のEC2インスタンスを設定する

スクリーンショット 2019-04-19 21.43.04.png

2-1.Spinnaker用のインスタンスを作ります

今回は、インスタンスとしてEC2を選択します。
細かい設定は下の方にまとめますが、ポイントをいくつか説明します。

Spinnaker用EC2インスタンスの作成ポイント

  • AMIはUbuntuの14.04か16.04にする。Spinnakerの推奨OS。
  • インスタンスタイプは、T2系非推奨。スペックが低いと途中で処理落ちする。今回はm5でやる。
  • IAM RoleはManagingで作ったものを適用する。 ちゃんと設定しないとSpinnakerサーバがAWSのリソースにアクセスできない。

以下の設定を終えたらインスタンスを作成しましょう。

AMIの選択

項目 備考
AMI Ubuntu Server 16.04 LTS (HVM), SSD Volume Type SpinnakerのUbuntuの推奨バージョンは 14.04 or 16.04です。

インスタンスタイプの選択

項目 備考
インスタンスタイプ m5.xlarge インスタンスのスペックが貧弱すぎると、処理の途中で止まってしまいます。

インスタンスの設定

項目 備考
ネットワーク SpinnakerVPC
サブネット SpinnakerVPC.external.us-west-2a なぜかサブネットが2つともパブリックなのでどちらでもOK。
本番運用なら踏み台を挟んで、このインスタンスはプライベートにおいたほうが良いです。今回は手間を省くためパブリックに立てます。
自動割当パブリックIP 有効 今回は直接sshしたいので有効化します。セキュリティはSGでカバーします。
IAM ロール test-spinnaker-managing-SpinnakerInstanceProfile-XXXXXX Managingテンプレートで作成したロールです。ここで指定する物理IDはCFnのリソース欄から特定できます

セキュリティグループ

タイプ プロトコル ポート範囲 ソース 備考
SSHTCP 22 カスタム $your_ip_address 任意 $your_ip_addressに任意のIPを入れてください。
これを設定しないとどこからでもsshし放題になるので注意してください。

キーペア

「既存のキーペアの選択」、「新しいキーペアの選択」どちらでもOKです。
キーペアを登録していない場合は後者を選択しましょう。

次はSpinnakerを導入します。

3章 Spinnakerの導入

スクリーンショット 2019-04-19 21.44.56.png

いよいよSpinnakerを導入していきます。
ここはつまづくことが多いので設定に注意しながらやりましょう。

3-1.SpinnakerサーバにSSHする

以下のコマンドでSSHします。

Client
$ ssh -L 9000:localhost:9000 -L 8084:localhost:8084 -L 8087:localhost:8087  ubuntu@xxx.xxx.xxx.xxx -i $key_pair 

9000や8084といった値はフォワーディングするポートを指します。ポートフォワーディングによって、クライアントとSpinnakerを構成するコンポーネントをつなぐことで、クライアントのlocalhostからSpinnakerのUIに接続することができるようになります。また、さきほど登録したキーペアの指定を忘れないようにしましょう。

3-2.Spinnakerの導入

ここからSpinnakerを導入していきます。
hal というコマンドがSpinnakerのコマンドラインツール、Halyardになります。
以下にterminal上の操作をまとめました。

ubuntu@SpinnakerServer
## Halyardをインストールする
## @see https://www.spinnaker.io/setup/install/halyard/
$ curl -O $ https://raw.githubusercontent.com/spinnaker/halyard/master/install/debian/InstallHalyard.sh
$ sudo bash InstallHalyard.sh
#ユーザーを選択する必要がでるので、ubuntuと入力

## halのバージョンを確認
$ hal -v


## AWSの設定をするため、設定を変数に入れる
$ REGION=us-west-2 #使っているリージョン名に応じて変えてください
$ AWS_ACCOUNT_NAME=my-aws-account #これは任意の名前でOKです。SpinnakerのUI上にAWSのアカウント名として表示されます。
$ ACCOUNT_ID=1234567890 #AWSアカウントのIDを入れてください

## HalyardのクラウドプロバイダーとしてAWSを設定する
## @see https://www.spinnaker.io/setup/install/providers/aws/aws-ec2/
$ hal config provider aws account add $AWS_ACCOUNT_NAME \
    --account-id ${ACCOUNT_ID} \
    --assume-role role/spinnakerManaged

$ hal config provider aws enable


## Halyardのデプロイタイプをlocaldebianに設定
## see https://www.spinnaker.io/setup/install/environment/
$ hal config deploy edit --type localdebian


## Spinnakerのデータを保存する永続化ストレージとしてS3を設定
## S3上に「spin-12367957-d6a2-4bfe5-8f2e4-a84drgdb8549e28」といった形式でバケットが作成される
## see https://www.spinnaker.io/setup/install/storage/s3/
$ hal config storage s3 edit --region $REGION

$ hal config storage edit --type s3


## 設定した内容でSpinnakerをデプロイ
## see https://www.spinnaker.io/setup/install/deploy/

## Halyardのバージョンを確認して設定する。今回は最新の1.13.4にした
$ hal version list
$ hal config version edit --version 1.13.4

## 設定した内容でSpinnakerをデプロイ
$ sudo hal deploy apply
$ hal deploy connect

## デプロイはここまでで一旦完了
## ただし、この段階だと正常に動かないので以下の対応を行う

## redisを起動する。また、再起動時に自動で起動するように設定する
## redisが起動していないとSpinnakerの中のgateというコンポーネントにエラーが生じるため、この対応を行う
$ sudo systemctl enable redis-server.service
$ sudo systemctl start redis-server.service

## spinnakerを再起動。また、自動で起動するように設定する
## これで全てのコンポーネントが正常に立ち上がる
$ sudo systemctl enable spinnaker.service
$ sudo systemctl restart spinnaker.service

3-3.Spinnakerの立ち上がりを確認する

先程のterminalの操作でSpinnakerが立ち上がったはずです。
しかし、Spinnakerの立ち上がりは少し遅いので、netstatを用いて確認しましょう。

ubuntu@SpinnakerServer
$ netstat -tulpn

まず、立ち上げ直後の状況は以下のような感じです。127.0.0.1:XXXXでLISTENしてるプロセスが4つしかありません。

スクリーンショット_2019-04-18_15_47_43.png

2,3分待つと全て立ち上がります。合計で9つになりました。

スクリーンショット_2019-04-18_15_53_29.png

参考までに、上記のポートがSpinnaker上のどのコンポーネントに対応しているかまとめました。解説欄に「注意」とあるのは、調査の段階でよくエラーの原因となっていたコンポーネントです。あまり触れていないコンポーネントは公式のアーキテクチャ解説をざっくり意訳してます。

コンポーネント ポート 解説
Deck 9000 注意
ブラウザベースのUIを提供する。
これが正常に起動しないと、Spinnakerの画面が表示されない。
Igor 8088 CI系の動作を管理する。
例えばJenkinsやTravisCI経由でパイプラインを動作させるといった役割を担う。
Echo 8089 通知系を管理する。
具体的には、slack通知やメールの送信、Githubのwebhookを受け取る。
Clouddriver 7002 クラウドプロバイダ(AWS、GCPなど)へのリクエストや
デプロイされたリソースのインデクス・キャッシュ周りを管理する。
Front50 8080 注意
Spinnaker上のデータを管理する。
様々なストレージとのインターフェース的な役割をする。
ストレージの設定不備でエラーを起こしがち。
Orca 8083 オーケストレーションエンジン。
特定のオペレーションやパイプラインを管理する。
Gate 8084 注意
SpinnakerのAPI Gateway。
これが正常立ち上がらないとと何もできない。
こちらもエラーの主要因。
Rosco 8087 クラウドプロバイダに応じたマシンイメージ(AWSならAMI)を作成する。
Redis 6379 注意
このRedisが起動していないとGate が正常に立ち上がらない。

3-4.Spinnakerにブラウザからアクセスする

既にSSHでポートフォワーディングしているので、localhostからSpinnakerを確認することができるはずです。 http://localhost:9000/ にアクセスしてみましょう。以下のような画面が表示されるはずです。

スクリーンショット 2019-04-18 22.17.57.png

以上で、Spinnakerの構築は完了です。

課題

一通り構築を終えて感じた課題をまとめます

トラブルシューティングが結構大変

  • まだ開発段階のため、頻繁に仕様が変わる
  • GCPの事例は見つかるが、AWSの事例はあまりない
  • 公式ドキュメントが英語しかないので英語は避けて通れない

こういったことから不具合の原因究明が結構大変でした。
特に最初の方はこの辺のコストがかかることを覚悟する必要がありそうです。

Spinnaker公式のCFnテンプレートに問題がある

今回利用したテンプレートは、リソースの設計が誤っていてセキュリティ的にも微妙な構成です。
ex.パブリックサブネット×2の構成、踏み台を返さず直接インスタンスにsshする構成
お試しであれば問題ないですが、本番導入する場合はテンプレートを自作する必要があると思います。

次回はSpinnakerのパイプライン機能を用いて、 Continuous Delivery をどのように実現できるか試してみたいと思います。
まだSpinnakerを触り始めたばかりなので、知見を共有していただけると嬉しいです。

おまけ アクセスキーを用いる場合の注意点

「1章 Spinnaker用にAWS環境を構築する」で IAM Roleを認証方法に選びましたが、アクセスキーを選択する場合の注意点も念の為記載します。

アクセスキーを選択した上でmanaging.ymlを実行しようとするとエラーになります。アクセスキーを使用する場合ResourcesSpinnakerInstanceProfileは不要になるのですが、その場合でもOutputsとしてInstanceProfileのArnを出力しようとするのが原因です。これを避けるためには、OutputsSpinnakerInstanceProfileArnをコメントアウトする必要があります。

  EksClusterName:
      Condition: SupportEKS
      Value: !Ref EksClusterName

   # SpinnakerInstanceProfileArn:
   #   Value: !GetAtt SpinnakerInstanceProfile.Arn

  VpcId:
      Value: !Ref SpinnakerVPC
30
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
28