その他
    ホーム 技術発信 あぴらぼ式 [GCP] Cloud BuildでGKEのデプロイ by Slack
    [GCP] Cloud BuildでGKEのデプロイ by Slack
     

    [GCP] Cloud BuildでGKEのデプロイ by Slack

    Information

    この記事はアピリッツの技術ブログ「あぴらぼ式」から移行した記事です。情報が古い可能性がありますのでご注意ください。

    Cloud BuildでGKEのデプロイ

    Cloud BuildでGAE/Goデプロイ by Slack の番外編として、Cloud Build を使ってGKE(Google Kubernetes Engine)にデプロイをする設定を実施してみたいと思います。

    アプリのコードはこちらです。アプリ自体はGo言語のWebアプリケーションフレームワークGinのQuick Startを少し改変したものです。

    Cloud Buildに代入変数を設定する

    Slack ~ BitBucket ~ Code Source Repositories ~ Code Buildのトリガーの設定はGAE/Goと同じ手順ですので割愛しますが、1点のみ変更があります。

    Cloud Buildのトリガーを設定する際に、設定項目の一番下にある、代入変数を設定します。

    ‘_GKE_CLUSTER_NAME’として’cluster-xxx’を、’_GKE_ZONE’として’us-west2-a’として設定します。こうすることで、cloudbuild.yamlで${_GKE_CLUSTER_NAME}, ${_GKE_ZONE}として、それぞれ設定した値を参照できるので、cloudbuild.yamlに対するハードコーディングを減らせます。

    Cloud BuildにGKEの管理権限を与える

    Cloud BuildのIAMアカウントに対して、GKEの管理権限を与えます。

    IAM管理画面より、xxxxxxxxxxxxxxxxx@cloudbuild.gserviceaccount.comとなっているアカウントの鉛筆マークを選択して編集モードに入ります。

    “+別の役割を追加”のリンクをクリックして、”Kubernetes Engine管理者”,”Kubernetes Engine Cluster管理者”,”サービスアカウントユーザ”の権限を追加します。

    となっていれば設定完了です。

    カスタムクラウドビルダーとしてHelmを登録

    今回のアプリではデプロイにHelmを使用しています。

    Cloud Build でhelmコマンドを実行するためのカスタムクラウドビルダーが、コミュニティにより提供されています。

    [blogcard url=https://github.com/GoogleCloudPlatform/cloud-builders-community/tree/master/helm]

    Cloud Shellを起動して以下を実行します。

    git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git
    cd cloud-builders-community/helm
    gcloud builds submit . --config=cloudbuild.yaml

    実行がおわると、gcr.io/$PROJECT_ID/helmとしてGCRに登録されますので、Cloud Build内でビルダーとして指定できるようになります。

    [memo title=”MEMO”]ちなみにCloudBuildでは、Cloud Buildを起動したプロジェクトのIDを$PROJECT_IDとして利用できます。そのため、GCRのレジストリを指定するときに$PROJECT_IDを指定しておけば、色々なプロジェクトでも置換の必要なく実行できます[/memo]

    GKEクラスターの構築~アプリの初期設定

    GKEにアプリケーションをデプロイするにあたって、まずKubernetesのクラスターを構築と、アプリの初期設定を行います。

    Cloud Shellを起動して、

    git clone https://bitbucket.org/appiritslabo/gke-sample.git
    cd gke-sample
    gcloud builds submit . --config=cloud_build/init.yaml \
      --substitutions=_GKE_ZONE=us-west2-a,_GKE_CLUSTER_NAME=cluster-xxx,_GKE_MACHINE_TYPE=g1-small

    を実行します。

    このコマンドによって、us-west2-aのゾーンに、g1-smallのマシンタイプのノード1個で構成されたcluster-xxxという名前のクラスターが作成されます。

    それぞれの値を変更することで、クラスターのパラメータを制御できますが、_GKE_ZONEと_GKE_CLUSTER_NAMEを変更した場合は、前述したCloud Buildのトリガー設定も合わせて変更してあげる必要があります。

    このコマンドを叩くことで、クラスター作成〜アプリの初期設定までのcloud_build用のタスク(cloud_build/init.yaml)を実行します。

    steps:
    - name: 'gcr.io/cloud-builders/gcloud'
      args: ['container', 'clusters', 'create', '${_GKE_CLUSTER_NAME}', '--zone', '${_GKE_ZONE}', '--num-nodes', '1', '-m', ${_GKE_MACHINE_TYPE}]
    
    - name: 'gcr.io/$PROJECT_ID/helm'
      args: ['init']
      env:
        - 'CLOUDSDK_COMPUTE_ZONE=${_GKE_ZONE}'
        - 'CLOUDSDK_CONTAINER_CLUSTER=${_GKE_CLUSTER_NAME}'
    
    - name: 'gcr.io/cloud-builders/kubectl'
      args: ['create', 'serviceaccount', '--namespace', 'kube-system', 'tiller']
      env:
        - 'CLOUDSDK_COMPUTE_ZONE=${_GKE_ZONE}'
        - 'CLOUDSDK_CONTAINER_CLUSTER=${_GKE_CLUSTER_NAME}'
    
    - name: 'gcr.io/cloud-builders/kubectl'
      args: ['create', 'clusterrolebinding', 'tiller-cluster-rule', '--clusterrole=cluster-admin', '--serviceaccount=kube-system:tiller']
      env:
        - 'CLOUDSDK_COMPUTE_ZONE=${_GKE_ZONE}'
        - 'CLOUDSDK_CONTAINER_CLUSTER=${_GKE_CLUSTER_NAME}'
    
    - name: 'gcr.io/cloud-builders/kubectl'
      args: ['patch', 'deploy', '--namespace', 'kube-system', 'tiller-deploy', '-p', '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}']
      env:
        - 'CLOUDSDK_COMPUTE_ZONE=${_GKE_ZONE}'
        - 'CLOUDSDK_CONTAINER_CLUSTER=${_GKE_CLUSTER_NAME}'
    
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build', '.', '-t', 'gcr.io/$PROJECT_ID/app:init']
    
    - name: 'gcr.io/cloud-builders/docker'
      args: ['push', 'gcr.io/$PROJECT_ID/app:init']
    
    - name: 'gcr.io/$PROJECT_ID/helm'
      args: ['install', '--name', 'apps', '--set', 'image_tag=init', 'deploy-app']
      env:
        - 'CLOUDSDK_COMPUTE_ZONE=${_GKE_ZONE}'
        - 'CLOUDSDK_CONTAINER_CLUSTER=${_GKE_CLUSTER_NAME}'

    詳細には立ち入りませんが、流れとしては、

    1. クラスターの作成
    2. helmの初期化
    3. tillerの権限設定その1
    4. tillerの権限設定その2
    5. tillerの権限設定その3
    6. アプリの初回イメージ作成
    7. アプリの初回イメージpush
    8. helmでアプリをインストール(Deployment、およびServiceの作成)

    となります。

    上記が終了すれば、Kubernetes Engineのサービス一覧画面に表示されたdeploy-test-frontend-svcのエンドポイントにアクセスすることで、アプリにアクセスできます。

    上記のエンドポイントは環境によって変動します。

    cloudbuild.yamlの中身

    steps:
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build', '.', '-t', 'gcr.io/$PROJECT_ID/app:$COMMIT_SHA']
    
    - name: 'gcr.io/cloud-builders/docker'
      args: ["push", "gcr.io/$PROJECT_ID/app:$COMMIT_SHA"]
    
    - name: 'gcr.io/$PROJECT_ID/helm'
      args: ['upgrade', '--set', 'image_tag=$COMMIT_SHA', 'apps', 'deploy-app']
      env:
        - 'CLOUDSDK_COMPUTE_ZONE=${_GKE_ZONE}'
        - 'CLOUDSDK_CONTAINER_CLUSTER=${_GKE_CLUSTER_NAME}'

    cloudbuild.yamlは3つのステップで成り立っています。

    1. COMMIT_SHAのタグでイメージをビルド
    2. ビルドしたイメージをPush
    3. Pushしたイメージのタグを指定してアプリを更新(Helmによってデプロイ)

    ここまでの設定が終われば、GAE/Goの時と同じように、Slack上でプルリクエストをマージすると、GKE上にデプロイされるはずです。

    終わりに

    番外編として、Cloud Buildを使ってGKEにアプリケーションをデプロイする設定をしてみましたが、Cloud BuildがGAEへもGKEへもデプロイするように設定できる柔軟性を持っているだけでなく、コンテナイメージのビルド(もともとCloud BuilderはCloud Container Builderと呼ばれていて、こちらの使い方がメインでした)や、クラスターの作成など、さまざまな用途に利用できることがお分りいただけたのではないでしょうか。

    記事を共有