GCPにSpinnakerをインストールするための手順を整理しました

2021-02-25CI/CD,GCP

はじめに

前回でようやくSpinnakerが生まれてきた背景やできることを大まかにつかめました。

ここからは実際にインストールしてみたいと思います。

検証環境

項目選定
クラウドGCP ( Google Cloud Platform )
デプロイ環境GKE ( Google Kubernetes Engine )
Spinnakerインストール環境GCE ( Google Compute Engine )

前提条件

  • 作業用PCで gcloud コマンド ( Google Cloud SDK ) が実行できること
  • GCP 上に GKEクラスタ が構築済みであること

作業用PC での作業

まずは自分の作業用PCで作業を行います。

1. コマンドラインから各種作業を実行するための準備

コマンドラインで作業を進めていくに当たり、いくつかのAPIを 有効化 します。

以下の2つの Google APIを有効にします。
Google Cloud Console Webページから有効にしても良いですが、ここでは gcloud コマンドで有効化します。

$ gcloud services enable \
    iam.googleapis.com \
    cloudresourcemanager.googleapis.com

2. Halyardをインストールする Compute Engine インスタンスを作成

Halyard をインストールする Compute Engineインスタンス を作成します。

その前にまずはインスタンスに割り当てる サービスアカウト を作成し、 以下の2つの ロール を割り当てます。

  • roles/iam.serviceAccountKeyAdmin
  • roles/container.admin
$ GCP_PROJECT=$(gcloud info --format='value(config.project)')
$ GCP_ZONE=$(gcloud info --format='value(config.properties.compute.zone)')
$ HALYARD_HOST=halyard-host
$ HALYARD_SERVICE_ACCOUNT=halyard-service-account

# HalyardをインストールするGCEインスタンスのサービスアカウントを作成
$ gcloud iam service-accounts create ${HALYARD_SERVICE_ACCOUNT} \
    --project=${GCP_PROJECT} \
    --display-name ${HALYARD_SERVICE_ACCOUNT}

# 以降の手続きを連続して実行するとサービスアカウントが見つからないエラーが発生することがあるため多少待ちます。
$ sleep 10

# サービスアカウントに、2つのロールを割り当てる
$ HALYARD_SERVICE_ACCOUNT_EMAIL=$(
    gcloud iam service-accounts list \
      --project=${GCP_PROJECT} \
      --filter="displayName:${HALYARD_SERVICE_ACCOUNT}" \
      --format='value(email)'
  )

$ gcloud projects add-iam-policy-binding ${GCP_PROJECT} \
    --role roles/iam.serviceAccountKeyAdmin \
    --member serviceAccount:${HALYARD_SERVICE_ACCOUNT_EMAIL}

$ gcloud projects add-iam-policy-binding ${GCP_PROJECT} \
    --role roles/container.admin \
    --member serviceAccount:${HALYARD_SERVICE_ACCOUNT_EMAIL}

次に サービスアカウント を使って、 Compute Engine インスタンス を作成します。

$ HALYARD_SERVICE_ACCOUNT_EMAIL=$(
    gcloud iam service-accounts list \
      --project=${GCP_PROJECT} \
      --filter="displayName:${HALYARD_SERVICE_ACCOUNT}" \
      --format='value(email)'
  )

$ gcloud compute instances create ${HALYARD_HOST} \
    --project=${GCP_PROJECT} \
    --zone=${GCP_ZONE} \
    --scopes=cloud-platform \
    --service-account=${HALYARD_SERVICE_ACCOUNT_EMAIL} \
    --image-project=ubuntu-os-cloud \
    --image-family=ubuntu-1804-lts \
    --machine-type=n1-standard-4

3. GCS(Storage)とGCR(Container Registry)へアクセスするためのサービスアカウントを作成

今度は Halyard ではなく、 Spinnaker のための設定です。

GKE 上にインストールされる Spinnaker は、 GCSGCR の利用を行うため、 Spinnaker 用のサービスアカウントとロールの割当を行います。

サービスアカウント を作成し、 以下の2つの ロール を割り当てます。

  • roles/storage.admin
  • roles/browser
$ GCP_PROJECT=$(gcloud info --format='value(config.project)')
$ GCS_SERVICE_ACCOUNT=spin-gcs-service-account

$ gcloud iam service-accounts create $GCS_SERVICE_ACCOUNT \
    --project=$GCP_PROJECT \
    --display-name $GCS_SERVICE_ACCOUNT

# 以降の手続きを連続して実行するとサービスアカウントが見つからないエラーが発生することがあるため多少待ちます。
$ sleep 10

# サービスアカウントに、2つのロールを割り当てる
$ GCS_SERVICE_ACCOUNT_EMAIL=$(
    gcloud iam service-accounts list \
      --project=$GCP_PROJECT \
      --filter="displayName:$GCS_SERVICE_ACCOUNT" \
      --format='value(email)'
  )

$ gcloud projects add-iam-policy-binding $GCP_PROJECT \
    --role roles/storage.admin \
    --member serviceAccount:$GCS_SERVICE_ACCOUNT_EMAIL

$ gcloud projects add-iam-policy-binding $GCP_PROJECT \
    --role roles/browser \
    --member serviceAccount:$GCS_SERVICE_ACCOUNT_EMAIL

4. Spinnaker用の永続化ストレージを作成

Spinnaker は永続化ストレージを必要とします。

WebのUIからいろいろ操作した際の設定情報などを保存する領域でしょうか?

ともかく必要ということなので、事前に作成しておきましょう。

GCSのバケット名はGCP内の全ユーザで一意な名前をつける必要があります。重複しないようにプロジェクト名を付与しておきました。

$ BUCKET=spinnaker-bucket-$(gcloud config get-value project)

$ gsutil mb -p $(gcloud config get-value project) -l asia "gs://$BUCKET/"

ようやく、作業用PCで必要な作業は終了です。大変ですが次へ進みましょう。。。。

Compute Engine インスタンス での作業

1. Compute Engine インスタンス にssh接続

先程作成したインスタンスにssh接続します。

変わったオプションとして、sshのポートフォワーディング設定を行っています。
これは、セットアップの最期でSpinnakerのWeb UIにブラウザで接続するためです。
少しややこしいですが、セットアップの最期で以下のようなポートフォワーディングが設定され、作業用PCのの9000ポート、8084ポートがSpinnakerの9000ポート、8084ポートに直結されます。

詳細はまた後ほど。

$ gcloud compute ssh $HALYARD_HOST \
    --project=$GCP_PROJECT \
    --zone=${GCP_ZONE} \
    --ssh-flag="-L 9000:localhost:9000" \
    --ssh-flag="-L 8084:localhost:8084"

2. Halyard のインストール

ようやく Halyard サーバのセットアップに進みます。

当面は何も考えずコマンドをターミナルに貼り付けていけばOKです。

kubectl コマンドのインストール

$ KUBECTL_LATEST=$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_LATEST}/bin/linux/amd64/kubectl
$ chmod +x kubectl
$ sudo mv kubectl /usr/local/bin/kubectl

JDK のインストール

Halyard はどうやらJavaのアプリケーションのようです。
実行には Java が必要です。

$ sudo apt install openjdk-11-jdk -y
Halyard のインストール

Halyard のインストールスクリプトをダウンロードして実行します。

実行時に Halyard の実行用ユーザ( root 以外)を指定する必要があるため、 halyard というLinuxユーザを作成し指定しました。

$ curl -O https://raw.githubusercontent.com/spinnaker/halyard/master/install/debian/InstallHalyard.sh
$ sudo bash InstallHalyard.sh --user $USER -y
$ . ~/.bashrc

Halyard のバージョンを確認すると、以下のようになっていました。

$ hal -v
1.41.0-20210212020018

3. Halyard がGKEクラスタへ接続できるようにする

以下の2つの環境変数は、ご自分のインストール先クラスタの設定に従ってください。

  • GKE_CLUSTER_NAME
  • GKE_CLUSTER_ZONE

わからない場合には 作業用PC にて gcloud container clusters list | awk '{ print $1, $2 }' | column -t を実行し、結果から探すことができます。

$ GKE_CLUSTER_NAME={YOUR_GKE_CLUSTER_NAME}
$ GKE_CLUSTER_ZONE={YOUR_GKE_CLUSTER_ZONE}

$ gcloud container clusters get-credentials ${GKE_CLUSTER_NAME} \
    --zone=${GKE_CLUSTER_ZONE}

4. SpinnakerGKE にリソースをデプロイするための権限を付与

HalyardSpinnaker の設定が行ったり来たりですが、ここでは Spinnaker の設定を。
SpinnakerGKE クラスタを操作してカナリアデプロイ、ブルーグリーンデプロイの機能を提供sルウため、大きな権限を付与してやる必要があります。

$ CONTEXT=$(kubectl config current-context)

# This service account uses the ClusterAdmin role -- this is not necessary, 
# more restrictive roles can by applied.
$ kubectl apply --context $CONTEXT \
    -f https://www.spinnaker.io/downloads/kubernetes/service-account.yml

$ TOKEN=$(kubectl get secret --context $CONTEXT \
   $(kubectl get serviceaccount spinnaker-service-account \
       --context $CONTEXT \
       -n spinnaker \
       -o jsonpath='{.secrets[0].name}') \
   -n spinnaker \
   -o jsonpath='{.data.token}' | base64 --decode)

$ kubectl config set-credentials ${CONTEXT}-token-user --token $TOKEN

$ kubectl config set-context $CONTEXT --user ${CONTEXT}-token-user

5. Spinnaker 用のサービスアカウント設定ファイルを作成

先程作成した、GCS + GCRアクセス用のサービスアカウント設定をjsonファイルとして書き出しておきましょう。

$ GCS_SERVICE_ACCOUNT=spin-gcs-service-account
$ GCS_SERVICE_ACCOUNT_JSON=~/.gcp/spin-gcs-service-account.json

$ mkdir -p $(dirname $GCS_SERVICE_ACCOUNT_JSON)

$ GCS_SERVICE_ACCOUNT_EMAIL=$(
    gcloud iam service-accounts list \
      --filter="displayName:${GCS_SERVICE_ACCOUNT}" \
      --format='value(email)'
  )

$ gcloud iam service-accounts keys create ${GCS_SERVICE_ACCOUNT_JSON} \
    --iam-account ${GCS_SERVICE_ACCOUNT_EMAIL}

6. Spinnaker デプロイのための設定

もう一息です。

Spinnaker デプロイのための最終設定です。

最新バージョンのHalyardを利用するように設定

$ hal config version edit --version $(hal version latest -q)

Spinnaker内部で利用する永続化ストレージとしてGCSを利用するように設定

永続化ストレージとして利用するバケットの設定と、それにアクセスするための認証ファイルを登録します。

$ BUCKET_LOCATION=ASIA
$ BUCKET=spinnaker-bucket-$(gcloud config get-value project)

$ hal config storage gcs edit \
    --project $(gcloud config get-value project) \
    --bucket-location $BUCKET_LOCATION \
    --bucket $BUCKET \
    --json-path ${GCS_SERVICE_ACCOUNT_JSON}

$ hal config storage edit --type gcs

Spinnaker内部でDocker RegistryからPullできるように設定

$ hal config provider docker-registry enable

$ hal config provider docker-registry account add spin-gcr-account \
  --address gcr.io \
  --password-file ${GCS_SERVICE_ACCOUNT_JSON} \
  --username _json_key

$ hal config provider kubernetes enable

$ hal config provider kubernetes account add spin-k8s-account \
    --docker-registries spin-gcr-account

$ hal config deploy edit \
    --account-name spin-k8s-account \
    --type distributed

7. Spinnaker をデプロイする

$ hal deploy apply

8. 正しくデプロイされたかを確認

正しく Spinnaker がデプロイされたかを、 spinnaker ネームスペース内のポッドを一覧表示することで確認してみます。

$ kubectl get po -n spinnaker
NAME                               READY   STATUS              RESTARTS   AGE
spin-clouddriver-c7645796b-48ng8   0/1     ContainerCreating   0          2m39s
spin-deck-5d6f6dddb8-nqxs6         0/1     ContainerCreating   0          2m40s
spin-echo-877847cc-pnp5n           0/1     Running             0          2m41s
spin-front50-54c9766cf8-hvppk      0/1     ContainerCreating   0          2m38s
spin-gate-8597889bf6-xvlmp         1/1     Running             0          2m41s
spin-igor-5df7f459cb-blmlf         0/1     Running             0          2m40s
spin-orca-7c96479dcd-rptjw         0/1     ContainerCreating   0          2m39s
spin-redis-797b49464-rmwjf         1/1     Running             0          2m40s
spin-rosco-67fdc579ff-c4hcd        0/1     ContainerCreating   0          2m38s

すべてのポッドの "READY" フィールドが "1/1" になるまで待ちましょう。6分ぐらいかかります。

9. ブラウザでWeb UIにアクセスする

最期に、 Compute Engine インスタンス から Spinnaker ポッドへのポートフォワードを設定します。

$ hal deploy connect

この状態で、作業用PCで以下のURLをブラウザ表示します。

  • http://localhost:9000/

以下のようなページが表示されればセットアップ成功です。

ひとこと

おそらく何度もハマることと思います。
僕は何度もハマりました。

実はこのエントリも何度か書き直しています。

そのかわり、Spinnakerのセットアップの手助けになるエントリに仕上がったという自負があります!

参考ページ

2021-02-25CI/CD,GCP