【2019年4月版】docker push -> Spinnaker -> deploy on GKE


Spinnakerでdocker pushをトリガーに自動デプロイをしてみます

外部サービスではなく自前クラウドの中にCI環境構築するJenkins XのようなSpinnakerをGKE(Google Kubernetes Engine)上に構築し、docker pushをトリガーにGKEにデプロイするCI環境を構築してみたいと思います。

Spinnakerの構築手順はそれなりにボリュームあるのでこちらのページもご参考にしてください。

Spinnaker全体像

Spinnakerの動作環境はSpinnaker本体と「spinnakerをデプロイする」Halyardという2つのモジュールに分かれ、さらにそれぞれ、Spinnaker->GKE, Halyard->GCEと実行するVM環境も異なります。

そしてもう一つ、この図の左上の"Your Workstation"のマシンですが、最終的にこのマシンでブラウザからSpinnakerを操作しますブラウザからlocalhost:9000にアクセスできる環境が必須です!!
(自分は調子こいてcloud shellから実施して最後の最後で詰みました。)

Spinnakerのインストールを実行する環境

OSはGoogle Cloud SDK(gcloudコマンド)が動く環境であればOKです。
そして何より、ブラウザが動く環境です。(トラウマ)

環境の構築

それでは以下の公式サイトのご案内に従ってインストールを行います。

0.準備

0-1. Google Cloud SDK のインストール

こちらのサイトからCloud SDKをダウウンロードしてインストールをお願いします。
https://cloud.google.com/sdk/downloads#interactive

0-2. Cloud SDK の初期設定

gcloudコマンドにより使用するGoogle Cloud Platformのプロジェクトにログインします。

$ gcloud auth login

もしくは、ログイン済みの場合でプロジェクトを変更する場合は

$ gcloud config set project <プロジェクト名>

とします。

1. Kubernetes クラスタの作成

以下の画面から Spinnaker を動かしたいクラスタを作成しておきます。

また、以下のAPIを有効にします。

2. Halyard用サービスアカウントのセットアップ

これ以降はターミナル、コマンドプロンプトなどを開き、gcloudコマンドで作業を行っていきます。

まずHalyardが動くVM用にサービスアカウントをセットアップします。

$ GCP_PROJECT=$(gcloud info --format='value(config.project)')
$ HALYARD_SA=halyard-service-account

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

$ HALYARD_SA_EMAIL=$(gcloud iam service-accounts list \
    --project=$GCP_PROJECT \
    --filter="displayName:$HALYARD_SA" \
    --format='value(email)')

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

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

ここでは halyard-service-account に以下のロールを割り当てています。

  • roles/iam.serviceAccountKeyAdmin
  • roles/container.admin

3.Cloud Storage、Container Registry のサービスアカウント設定

続いて後ほどのSpinnakerで使用するGCSとGCR用のサービスアカウントも設定します。

$ GCS_SA=gcs-service-account

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

$ GCS_SA_EMAIL=$(gcloud iam service-accounts list \
    --project=$GCP_PROJECT \
    --filter="displayName:$GCS_SA" \
    --format='value(email)')

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

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

ここでは gcs-service-account に以下のロールを割り当てています。

  • roles/storage.admin
  • roles/browser

4.Halyard用VMの作成

HalyardをホストするVMの作成を行います。

$ HALYARD_HOST=$(echo $USER-halyard-`date +%m%d` | tr '_.' '-')

$ gcloud compute instances create $HALYARD_HOST \
    --project=$GCP_PROJECT \
    --zone=us-central1-f \
    --scopes=cloud-platform \
    --service-account=$HALYARD_SA_EMAIL \
    --image-project=ubuntu-os-cloud \
    --image-family=ubuntu-1404-lts \
    --machine-type=n1-standard-4

ここではユーザー名-halyard-月日のマシン名でVMを作成してます。

5.ポート転送付きでSSH

作成したVMに対して、ポート転送付きでSSH接続します。

$ gcloud compute ssh $HALYARD_HOST \
    --project=$GCP_PROJECT \
    --zone=us-central1-f \
    --ssh-flag="-L 9000:localhost:9000" \
    --ssh-flag="-L 8084:localhost:8084"

これ以降はこのVMの中からの操作となります。

6. Halyard のインストール

6-1. kubectlのインストール

Halyardのツールはkubectlが必要です。以下のコマンドで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

6-2. Halyardのインストール

いよいよHalyardをインストールします。

$ curl -O https://raw.githubusercontent.com/spinnaker/halyard/master/install/debian/InstallHalyard.sh

$ sudo bash InstallHalyard.sh

$ . ~/.bashrc

7. 認証情報のセットアップ

Spinnaker に持たせる各種の認証情報を以下の手順でセットアップします。

7-1. Kubernetesの認証情報取得

以下の手順で ~/.kube/configを生成します。以下のYOUR_GKE_CLUSTER_NAMEYOUR_GKE_CLUSTER_ZONEは生成したKubernetesクラスタの情報をコピペしてください。

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

$ gcloud config set container/use_client_certificate true

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

7-2. Cloud Storage用の認証情報セットアップ

$ GCS_SA=gcs-service-account
$ GCS_SA_DEST=~/.gcp/gcp.json

$ mkdir -p $(dirname $GCS_SA_DEST)

$ GCS_SA_EMAIL=$(gcloud iam service-accounts list \
    --filter="displayName:$GCS_SA" \
    --format='value(email)')

$ gcloud iam service-accounts keys create $GCS_SA_DEST \
    --iam-account $GCS_SA_EMAIL

8. Spinnakerの設定

Halyardに、デプロイするSpinnaker のバージョンを指定します。ここでは最新バージョンとします。

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

引き続き、以下のように設定をしていきます。
Spinnaker の永続化には CloudStrageを使用します。

$ hal config storage gcs edit \
    --project $(gcloud info --format='value(config.project)') \
    --json-path ~/.gcp/gcp.json

$ hal config storage edit --type gcs

Container Registryからpullしますよ~

hal config provider docker-registry enable

hal config provider docker-registry account add my-gcr-account \
    --address gcr.io \
    --password-file ~/.gcp/gcp.json \
    --username _json_key

Kubernetes providerのv2を使います。

$ hal config provider kubernetes enable

$ hal config provider kubernetes account add my-k8s-account \
    --docker-registries my-gcr-account \
    --context $(kubectl config current-context) \
    --provider-version v2

9. デプロイ&接続

以下のコマンドで Halyard にすべての設定を反映させ、GKE に Spinnaker をデプロイさせます。

hal config deploy edit \
    --account-name my-k8s-account \
    --type distributed

hal deploy apply

デプロイ完了したら以下のコマンドでSpinnaker に接続します。

$ 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ポートの転送していますメッセージが出たら、ブラウザからhttp://localhost:9000を開きます。

はい!Spinnaker の起動いっちょ上がり!

Spinnaker での設定

以下でデプロイの設定を行います。Spinnakerでは"Application"、および複数のアプリケーションを包括する"Project"の単位で管理が可能です。

ここでは単一のApplicationの登録方法を説明します。

0. その前に

以下のSpinnakerの選択画面ではDocker Imageを自動で選択していきますが、自動で選択するためにはあらかじめImageがデプロイされていないとダメです!

ですので、gcloudコマンドであらかじめdocker imageをpushしておきます。

$ gcloud docker -- push gcr.io/<プロジェクト名>/<イメージ名>:latest

1. Create Application

画面右上のActionメニューからCreate Applicationを選択します。

アプリケーション名と通知先のメールアドレスは必須項目です。

test-app-1という安易な名前で作ってみます。。。

で、PIPELINESから行いたい処理を追加していきます。


最初は何もないのでConfigure a new Pipeline.をクリック

first-pipelineとイージーな名前を付けて作成してみました。

まずAutomated TriggersからAdd Triggerをクリックします。
追加されたトリガーのTypeにDocker Registryを選択したところです。

先の手順でサービスの設定がうまくいっていればmy-gcr-accountが選択できると思います。

以下、Organizationにてプロジェクト名を選択、Imageにてイメージ名を選択、Tagにlatestと順次設定を行えばOKです。
画面右下のSave Changesをクリックして保存されます。

トリガーの設定はこれでOKです。

続いてメインの処理を追加します。上に戻って・・・

Add Stageをクリックします。そしてTypeにてDeploy(Manifest)を選択した状態です。

画面下の方に・・・

どーん!と広大なテキストエリアが広がっておりますので、ここにymlをベタ貼りいたします。

右下のSave Changesで保存されます。
ちなみにある程度の書式チェックはしてくれるようです。賢い!

ymlが複数ある場合にも同様にAdd Stageでタスクをガンガン追加していけます。
設定の手順は以上です。

Spinnakerから手動でパイプライン実行

上記の設定後はコンソールなどからgcloud docker pushしてパイプラインが動くと思いますが、手動でトリガーする場合は以下の手順になります。

Spinnaker画面、ヘッダーのPIPELINESをクリックすると先ほど登録したパイプラインが表示されているはずです。

実行したいパイプライン(ここではfirst-pipeline)の行の右端にあるStart Manual Executionをクリックします。


確認が出るのでRunをクリックします。

このように詳しく進捗状況を教えてくれます。

Spinnaker 悪くないかも

他社のクラウドサービス系はリポジトリをグローバルに出さないとフックできないですが、Spinnakerは自前K8s内にCIを構築できるのでソースコードを完全に外に出さないで済みます。
お蔭で構成がかなりアレで慣れないと構築するの大変ですが、いったん構築してしまえば使うのは割と簡単です。
GUIもよくできてます。

Spinnaker 悪くないかも、でした!