17
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

はじめに

最近話題の Spinnaker を Google Kubernetes Engine(GKE)上に構築していきます。
簡単に試すのであれば、Google Cloud Launcher から試せます。
今回は、Spinnaker のデプロイ管理ツールである Halyard を用いて Spinnaker をデプロイしていきます。

本記事は、以下のドキュメントを参考に Spinnaker の構築を試したものです。

以下の環境を構築することを目指します。
Halyard インスタンスを含むデプロイ環境

環境

  • macOS High Sierra Version 10.13.6
  • Google Cloud SDK 240.0.0
  • Spinnaker 1.13.0

Spinnaker とは

Spinnaker とは、マルチクラウドに対応した継続デリバリのプラットフォームです。
パイプライン管理の機能を備え、Red/Black デプロイ(Blue/Green デプロイ)やカナリアリリースにも対応しています。
Netflix によって OSS 化され、Google を始め、様々な企業やコミュニティが開発に参加しています。

Google Cloud SDK をインストールする

以下のドキュメントを参考に Google Cloud SDK をインストールし、プロジェクトの設定をしてください。
Google Cloud SDK documentation

API を有効にする

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

  • Identity and Access Management (IAM) API
  • Cloud Resource Manager API
  • Kubernetes Engine API

以下のコマンドで API を有効にします。

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

サービスアカウントの作成

Halyard をインストールするインスタンスで使用するサービスアカウントを作成します。

$ 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 のサービスアカウントに以下のロールを付与します。

  • roles/iam.serviceAccountKeyAdmin
  • roles/container.admin
$ 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

Spinnaker で利用する Google Cloud Storage(GCS)と Google Container Registry(GCR)のサービスアカウントを作成します。

$ GCS_SA=gcs-service-account

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

作成した GCS と GCR のサービスアカウントに以下のロールを付与します。

  • roles/storage.admin
  • roles/browser
$ 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 \
    --role roles/browser \
    --member serviceAccount:$GCS_SA_EMAIL

Spinnaker の永続データを保存する GCS のバケットを作成する

バケット名は、GCS 全体で一意である必要があることに注意してください。
サンプルとして my-spin-bucket という名前で作成しています。

$ GCS_CLASS=multi_regional
$ GCS_BUCKET=my-spin-bucket

$ gsutil mb -p $GCP_PROJECT -c $GCS_CLASS -l asia gs://$GCS_BUCKET/

GKE クラスタの構築

Spinnaker のデプロイには、以下のいずれかに対応する必要があります。

  • レガシー認証を有効にする
  • RBAC を設定する

今回は RBAC を設定することで進めます。

まずは GKE を作成しましょう。
デフォルトで作成されるクラスタの設定に一部オプションを加えて作成します。
GKE のバージョンは、執筆時点(2019/03)の最新 1.12.6-gke.7 を使用します。
サンプルとして spinnaker-cluster という名前で作成しています。

$ gcloud config set container/new_scopes_behavior true

$ GKE_CLUSTER_NAME=spinnaker-cluster
$ GKE_CLUSTER_ZONE=asia-northeast1-a
$ GKE_CLUSTER_VERSION=1.12.6-gke.7

$ gcloud container --project $GCP_PROJECT clusters create $GKE_CLUSTER_NAME \
    --zone $GKE_CLUSTER_ZONE \
    --no-enable-basic-auth \
    --no-issue-client-certificate \
    --cluster-version $GKE_CLUSTER_VERSION \
    --machine-type "n1-standard-1" \
    --image-type "COS" \
    --num-nodes "3" \
    --disk-type "pd-standard" \
    --disk-size "100" \
    --metadata disable-legacy-endpoints=true \
    --scopes gke-default \
    --enable-cloud-logging \
    --enable-cloud-monitoring \
    --enable-ip-alias \
    --addons HorizontalPodAutoscaling,HttpLoadBalancing \
    --enable-autorepair

Halyard 実行用のインスタンス作成

作成した Halyard 用のサービスアカウントでインスタンスを作成します。
サンプルとして halyard-host という名前で作成しています。

$ HALYARD_HOST=halyard-host

$ gcloud compute instances create $HALYARD_HOST \
    --project=$GCP_PROJECT \
    --zone=asia-northeast1-a \
    --scopes=cloud-platform \
    --service-account=$HALYARD_SA_EMAIL \
    --image-project=ubuntu-os-cloud \
    --image-family=ubuntu-1804-lts \
    --machine-type=n1-standard-4

作成したインスタンスに SSH で接続します。

$ gcloud compute ssh $HALYARD_HOST \
    --project=$GCP_PROJECT \
    --zone=asia-northeast1-a \
    --ssh-flag="-L 9000:localhost:9000" \
    --ssh-flag="-L 8084:localhost:8084"

以降 SSH 内でコマンドを実行します。

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
$ kubectl version

Halyard をインストール

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

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

認証情報を設定

Kubernetes クラスタの認証情報を取得する

作成した Kubernetes クラスタの認証情報を取得します。

$ GCP_PROJECT=$(gcloud info --format='value(config.project)')
$ GKE_CLUSTER_NAME=spinnaker-cluster
$ GKE_CLUSTER_ZONE=asia-northeast1-a

$ gcloud container clusters get-credentials $GKE_CLUSTER_NAME \
    --zone $GKE_CLUSTER_ZONE \
    --project $GCP_PROJECT

GCS のサービスアカウントのファイルを作成する

GCS のサービスアカウントの json ファイルを作成します。

$ 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

Kubernetes クラスタにサービスアカウントを作成する

作成した Kubernetes クラスタに対してサービスアカウントを作成します。
そして作成したサービスアカウントからトークンを取得し、新しいトークンユーザーに付与します。

$ CONTEXT=$(kubectl config current-context)

$ kubectl apply --context $CONTEXT \
    -f https://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

RBAC を設定するに当たって以下の spinnaker-rbac.yml を作成します。

spinnaker-rbac.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: spinnaker-role
rules:
  - apiGroups: ['']
    resources:
      [
        'namespaces',
        'configmaps',
        'events',
        'replicationcontrollers',
        'serviceaccounts',
        'pods/log',
      ]
    verbs: ['get', 'list']
  - apiGroups: ['']
    resources: ['pods', 'services', 'secrets']
    verbs:
      [
        'create',
        'delete',
        'deletecollection',
        'get',
        'list',
        'patch',
        'update',
        'watch',
      ]
  - apiGroups: ['autoscaling']
    resources: ['horizontalpodautoscalers']
    verbs: ['list', 'get']
  - apiGroups: ['apps']
    resources: ['controllerrevisions', 'statefulsets']
    verbs: ['list']
  - apiGroups: ['extensions', 'apps']
    resources: ['deployments', 'replicasets', 'ingresses']
    verbs:
      [
        'create',
        'delete',
        'deletecollection',
        'get',
        'list',
        'patch',
        'update',
        'watch',
      ]
  - apiGroups: ['']
    resources: ['services/proxy', 'pods/portforward']
    verbs:
      [
        'create',
        'delete',
        'deletecollection',
        'get',
        'list',
        'patch',
        'update',
        'watch',
      ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: spinnaker-role-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: spinnaker-role
subjects:
  - namespace: spinnaker
    kind: ServiceAccount
    name: spinnaker-service-account
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: spinnaker-service-account
  namespace: spinnaker

作成した spinnaker-rbac.yml を適用します。

$ kubectl apply --context $CONTEXT -f spinnaker-rbac.yml

Spinnaker の設定

Halyard が最新の Spinnaker のバージョンを使用するように設定します。

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

Spinnaker の設定やパイプライン情報の保存先として GCS を設定します。
--bucket でバケット名を指定しなければ、spin-[UUID] のバケットが自動で作成されます。

$ BUCKET_LOCATION=asia-northeast1
$ BUCKET=my-spin-bucket

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

$ hal config storage edit --type gcs

GCR から pull するように Docker Registry プロバイダの設定をします。

$ 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 プロバイダの設定をします。
今回は Kubernetes V2 プロバイダを使用して進めます。

$ hal config provider kubernetes enable

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

Spinnaker をデプロイ

設定を終えたところで Spinnaker をデプロイしていきます。

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

$ hal deploy apply

Spinnaker をデプロイしたら作成された Pod が 1/1 Running になるまで待機します。

$ kubectl get po -n spinnaker
NAME                                READY   STATUS    RESTARTS   AGE
spin-clouddriver-5fc8d78c9f-rqwn4   1/1     Running   0          9m31s
spin-deck-78df87c4cb-ws5j2          1/1     Running   0          9m30s
spin-echo-75f8d9f955-swnzj          1/1     Running   0          9m31s
spin-front50-69bf559776-bfz5h       1/1     Running   0          9m29s
spin-gate-677dd7889f-vfzm6          1/1     Running   0          9m30s
spin-igor-58b98c69cb-7tq9h          1/1     Running   0          9m30s
spin-orca-5fd4f77c84-f4769          1/1     Running   0          9m29s
spin-redis-55ccd77cbd-5k6dp         1/1     Running   0          9m31s
spin-rosco-b84f686c8-7hbnk          1/1     Running   0          9m28s

デプロイが完了したら Spinnaker に接続します。

$ hal deploy connect

ブラウザで以下のアドレスに接続すると Spinnaker が表示されます。

http://localhost:9000/

アクセスすると以下のようなローディング画面が表示されます。

Spinnaker のローディング画面

ローディングが終わると検索画面が表示されます。

Spinnaker の検索画面

作成したリソースの削除

作成したリソースを削除します。

GKE クラスタを削除します。
y で削除します。

$ gcloud container clusters delete $GKE_CLUSTER_NAME

GCS バケットを削除します。

$ gsutil rm -r gs://$GCS_BUCKET/

Halyard 実行用のインスタンスを削除します。
y で削除します。

$ gcloud compute instances delete $HALYARD_HOST

サービスアカウントに紐付けたロールを削除します。

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

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

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

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

サービスアカウントを削除します。
y で削除します。

$ gcloud iam service-accounts delete $HALYARD_SA_EMAIL
$ gcloud iam service-accounts delete $GCS_SA_EMAIL

さいごに

ここまで Spinnaker の構築を試しました。
Halyard を用いて RBAC を設定した Kubernetes 上に構築すると手順が多くなるので、気軽に試すのであれば Google Cloud Launcher からの構築がスムーズだと感じました。
次回は Spinnaker のパイプラインの構築を試します。

参考

Try out Halyard on GKE - Spinnaker
Deploy to Google Kubernetes Engine with RBAC - Spinnaker
次世代 Continuous Delivery プラットフォームである Spinnaker を体験してみよう! - Mercari Engineering Blog
Spinnaker を導入した - kawabatas 技術ブログ

17
7
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
17
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?